示例#1
0
        /// <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;
                }
            }