Пример #1
0
        /// <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);
        }
Пример #2
0
        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?
        }