/// <summary> /// Finds all terms of a polynomial /// </summary> /// <typeparam name="T"></typeparam> /// <param name="terms"></param> /// <param name="subtree"></param> /// <returns></returns> internal static Dictionary <T, Entity> GatherMonomialInformation <T>(List <Entity> terms, Entity subtree) { var monomialsByPower = new Dictionary <T, Entity>(); // here we fill the dictionary with information about monomials' coefficiants foreach (var child in terms) { // TODO Entity free; object pow; if (typeof(T) == typeof(decimal)) { pow = new TreeAnalyzer.PrimitiveDouble(); } else { pow = new TreeAnalyzer.PrimitiveInt(); } TreeAnalyzer.IPrimitive <T> q = pow as TreeAnalyzer.IPrimitive <T>; ParseMonomial <T>(subtree, child, out free, ref q); if (free == null) { return(null); } if (!monomialsByPower.ContainsKey(q.GetValue())) { monomialsByPower[q.GetValue()] = 0; } monomialsByPower[q.GetValue()] += free; } // TODO: do we need to simplify all values of monomialsByPower? return(monomialsByPower); }
internal static void ParseMonomial <T>(Entity aVar, Entity expr, out Entity freeMono, ref TreeAnalyzer.IPrimitive <T> power) { if (expr.FindSubtree(aVar) == null) { freeMono = expr; return; } freeMono = 1; // a * b bool allowFloat = typeof(T) == typeof(decimal); foreach (var mp in TreeAnalyzer.LinearChildren(expr, "mulf", "divf", Const.FuncIfMul)) { if (mp.FindSubtree(aVar) == null) { freeMono *= mp; } else if (mp.entType == Entity.EntType.OPERATOR && mp.Name == "powf") { var pow_num = MathS.CanBeEvaluated(mp.Children[1]) ? mp.Children[1].Eval() : mp.Children[1]; // x ^ a is bad if (pow_num.entType != Entity.EntType.NUMBER) { freeMono = null; return; } // x ^ 0.3 is bad if (!allowFloat && !pow_num.Eval().IsInteger()) { freeMono = null; return; } if (mp == aVar) { if (allowFloat) { (power as TreeAnalyzer.PrimitiveDouble).Add(pow_num.GetValue().Real); } else { (power as TreeAnalyzer.PrimitiveInt).Add(pow_num.GetValue().Real.AsInt()); } } else { if (!MathS.CanBeEvaluated(mp.Children[1])) { freeMono = null; return; } Entity tmpFree; // TODO object pow; if (typeof(T) == typeof(decimal)) { pow = new TreeAnalyzer.PrimitiveDouble(); } else { pow = new TreeAnalyzer.PrimitiveInt(); } TreeAnalyzer.IPrimitive <T> q = pow as TreeAnalyzer.IPrimitive <T>; ParseMonomial <T>(aVar, mp.Children[0], out tmpFree, ref q); if (tmpFree == null) { freeMono = null; return; } else { // Can we eval it right here? mp.Children[1] = mp.Children[1].Eval(); freeMono *= MathS.Pow(tmpFree, mp.Children[1]); power.AddMp(q.GetValue(), mp.Children[1].GetValue()); } } } else if (mp == aVar) { if (allowFloat) { (power as TreeAnalyzer.PrimitiveDouble).Add(1); } else { (power as TreeAnalyzer.PrimitiveInt).Add(1); } } else { // a ^ x, (a + x) etc. are bad if (mp.FindSubtree(aVar) != null) { freeMono = null; return; } freeMono *= mp; } } // TODO: do we need to simplify freeMono? }