コード例 #1
0
        public override Term Reduce()
        {
            Term reducedBase     = Parameters[0].Reduce();
            Term reducedExponent = Parameters[1].Reduce();

            if (reducedExponent.IsOne())
            {
                return(reducedBase);
            }

            Power arg0_parsed = reducedBase as Power;

            if (arg0_parsed != null)
            {
                return(new Power(IsAddInverse, IsMulInverse, arg0_parsed.Parameters[0], arg0_parsed.Parameters[1] * reducedExponent).Reduce());
            }

            return(new Power(reducedBase, reducedExponent));
        }
コード例 #2
0
        public override Term Reduce()
        {
            List <Term> paras = Parameters.Select(x => x.Reduce()).Where(x => !x.IsOne()).ToList();

            if (paras.Where(x => x.IsZero()).Count() > 0)
            {
                return(0);
            }

            // merge branches
            for (int i = 0; i < paras.Count; i++)
            {
                if (paras[i].GetType() == typeof(Multiplication))
                {
                    paras.AddRange(((Multiplication)paras[i]).Parameters);
                    paras.RemoveAt(i);
                }
            }

            // extract sign
            bool isAddInverse = IsAddInverse;

            foreach (Term t in paras)
            {
                if (t.IsAddInverse)
                {
                    isAddInverse = !isAddInverse;
                }
            }

            // merge powers
            List <(Term b, Term p)> powerCounter = new List <(Term, Term)>();

            for (int i = 0; i < paras.Count; i++)
            {
                if (paras[i].GetType() == typeof(Real))
                {
                    continue;
                }

                if (paras[i].GetType() == typeof(Power))
                {
                    Power p     = paras[i] as Power;
                    int   index = powerCounter.FindIndex(x => x.b == p.Parameters[0]);
                    if (index > -1)
                    {
                        if (paras[i].IsMulInverse)
                        {
                            powerCounter[index] = (powerCounter[index].b, powerCounter[index].p - p.Parameters[1]);
                        }
                        else
                        {
                            powerCounter[index] = (powerCounter[index].b, powerCounter[index].p + p.Parameters[1]);
                        }
                    }
                    else
                    {
                        if (p.IsMulInverse)
                        {
                            powerCounter.Add((p.Parameters[0], -p.Parameters[1]));
                        }
                        else
                        {
                            powerCounter.Add((p.Parameters[0], p.Parameters[1]));
                        }
                    }
                }
                else
                {
                    int index = powerCounter.FindIndex(x => x.b == paras[i]);
                    if (index > -1)
                    {
                        if (paras[i].IsMulInverse)
                        {
                            powerCounter[index] = (powerCounter[index].b, powerCounter[index].p - new Real(1));
                        }
                        else
                        {
                            powerCounter[index] = (powerCounter[index].b, powerCounter[index].p + new Real(1));
                        }
                    }
                    else
                    {
                        if (paras[i].IsMulInverse)
                        {
                            powerCounter.Add((paras[i], -new Real(1)));
                        }
                        else
                        {
                            powerCounter.Add((paras[i], new Real(1)));
                        }
                    }
                }
            }

            double real = 1;

            foreach (Real r in paras.Where(x => x.GetType() == typeof(Real)).Cast <Real>())
            {
                if (r.IsMulInverse)
                {
                    real /= r.Value;
                }
                else
                {
                    real *= r.Value;
                }
            }
            if (real != 1)
            {
                powerCounter.Add((new Real(real), 1));
            }

            List <Term> reducedTerms = new List <Term>();

            foreach ((Term b, Term p)powerPair in powerCounter)
            {
                Term p = powerPair.p.Reduce();
                Term b = powerPair.b.Clone();
                if (p.IsOne())
                {
                    b.IsAddInverse = false;
                    b.IsMulInverse = p.IsAddInverse;
                    reducedTerms.Add(b);
                }
                else
                {
                    b.IsMulInverse = false;
                    b.IsAddInverse = false;
                    if (p.IsAddInverse)
                    {
                        reducedTerms.Add(new Power(false, true, b, p));
                    }
                    else
                    {
                        reducedTerms.Add(new Power(false, false, b, p));
                    }
                }
            }

            switch (reducedTerms.Count)
            {
            case 0: return(1);

            case 1:
                if (reducedTerms[0].IsMulInverse)
                {
                    return(new Multiplication(IsAddInverse, IsMulInverse, 1, reducedTerms[0]));
                }
                else
                {
                    return(reducedTerms[0]);
                }

            default: return(new Multiplication(IsAddInverse, IsMulInverse, reducedTerms.ToArray()));
            }
        }