/// <summary> /// Actual sorting with sortHash /// </summary> /// <param name="tree"></param> /// <param name="level"></param> internal static void Sort(ref Entity tree, SortLevel level) { Func <Entity, OperatorEntity> funcIfSum = Const.FuncIfSum; Func <Entity, OperatorEntity> funcIfMul = Const.FuncIfMul; for (int i = 0; i < tree.Children.Count; i++) { Entity tmp = tree.Children[i]; Sort(ref tmp, level); tree.Children[i] = tmp; } if (tree.Name != "sumf" && tree.Name != "mulf" && tree.Name != "minusf" && tree.Name != "divf") { return; } var isSum = tree.Name == "sumf" || tree.Name == "minusf"; var linChildren = TreeAnalyzer.LinearChildren(tree, isSum ? "sumf" : "mulf", isSum ? "minusf" : "divf", isSum ? funcIfSum : funcIfMul); var groups = TreeAnalyzer.GroupByHash(linChildren, level); var grouppedChildren = new List <Entity>(); foreach (var list in groups) { grouppedChildren.Add(TreeAnalyzer.MultiHangLinear(list, isSum ? "sumf" : "mulf", isSum ? Const.PRIOR_SUM : Const.PRIOR_MUL)); } tree = TreeAnalyzer.MultiHangLinear(grouppedChildren, isSum ? "sumf" : "mulf", isSum ? Const.PRIOR_SUM : Const.PRIOR_MUL); }
/// <summary> /// Returns information about all monomials of an expression /// </summary> /// <param name="expr"></param> /// <param name="replaceVars"></param> /// <returns></returns> internal static PolyInfo GatherAllPossiblePolynomials(Entity expr, bool replaceVars) { // TODO: refactor expr = expr.DeepCopy(); // Init var res = new PolyInfo(); var mentionedVarList = MathS.Utils.GetUniqueVariables(expr); var newList = new List <string>(); if (replaceVars) { // Replace all variables we can foreach (var varMentioned in mentionedVarList.FiniteSet()) { if (expr.FindSubtree(varMentioned) == null) { continue; } var replacement = TreeAnalyzer.GetMinimumSubtree(expr, varMentioned); res.replacementInfo[varMentioned.Name] = replacement; FindAndReplace(ref expr, replacement, new VariableEntity(PolyInfo.NewVarName(varMentioned.Name))); newList.Add(PolyInfo.NewVarName(varMentioned.Name)); } } else { foreach (var v in mentionedVarList.FiniteSet()) { newList.Add(v.Name); } } // Gather info about each var as if this var was the only argument of the polynomial P(x) foreach (var varMentioned in newList) { List <Entity> children; if (expr.entType == Entity.EntType.OPERATOR && expr.Name == "sumf" || expr.Name == "minusf") { children = TreeAnalyzer.LinearChildren(expr, "sumf", "minusf", Const.FuncIfSum); } else { children = new List <Entity> { expr } }; res.monoInfo[varMentioned] = PolynomialSolver.GatherMonomialInformation <decimal>(children, MathS.Var(varMentioned)); } return(res); } }
/// <summary> /// Converts a tree into binary /// </summary> /// <param name="expr"></param> internal static void OptimizeTree(ref Entity expr) { if (expr.entType == Entity.EntType.OPERATOR) { if (expr.Name == "sumf" || expr.Name == "minusf") { var children = TreeAnalyzer.LinearChildren(expr, "sumf", "minusf", Const.FuncIfSum); expr = TreeAnalyzer.MultiHangBinary(children, "sumf", expr.Priority); } if (expr.Name == "mulf" || expr.Name == "divf") { var children = TreeAnalyzer.LinearChildren(expr, "mulf", "divf", Const.FuncIfMul); expr = TreeAnalyzer.MultiHangBinary(children, "mulf", expr.Priority); } } for (int i = 0; i < expr.Children.Count; i++) { var tmp = expr.Children[i]; OptimizeTree(ref tmp); expr.Children[i] = tmp; } }