Пример #1
0
        public override Term CheckAddReduce(Term t)
        {
            if (t.GetType() == typeof(Multiplication))
            {
                Multiplication cMult = (Multiplication)t;

                List <Term> a = Parameters.ToList(), b = cMult.Parameters.ToList();
                List <Term> commonTerms = new List <Term>();

                for (int i = 0; i < a.Count; i++)
                {
                    for (int k = 0; k < b.Count; k++)
                    {
                        if (a[i] == b[k])
                        {
                            commonTerms.Add(a[i]);
                            a.RemoveAt(i);
                            b.RemoveAt(k);
                            i--;
                            break;
                        }
                    }
                }

                if (a.Count == 0)
                {
                    a.Add(1);
                }
                if (b.Count == 0)
                {
                    a.Add(1);
                }

                commonTerms.Add(new Addition((a.Count == 1) ? a[0] : new Multiplication(a.ToArray()), (b.Count == 1) ? b[0] : new Multiplication(b.ToArray())).Reduce());

                for (int i = 0; i < commonTerms.Count; i++)
                {
                    if (commonTerms[i].GetType() == typeof(Real) && ((Real)commonTerms[i]).Value == 0)
                    {
                        return(0);
                    }
                }

                if (commonTerms.Count == 1)
                {
                    Term term = commonTerms[0];
                    if (IsMulInverse)
                    {
                        term.IsMulInverse = !commonTerms[0].IsMulInverse;
                    }
                    if (IsMulInverse)
                    {
                        term.IsAddInverse = !commonTerms[0].IsAddInverse;
                    }
                    return(term);
                }

                return(new Multiplication(IsAddInverse, IsMulInverse, commonTerms.ToArray()));
            }

            if (Parameters.Any(x => x == t))
            {
                IEnumerable <Term> terms = Parameters.Where(x => x != t);
                return(new Multiplication(IsAddInverse, IsMulInverse, t, new Addition(terms.Count() > 1 ? new Multiplication(terms.ToArray()) : terms.First(), 1).Reduce()));
            }

            return(null);
        }
Пример #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()));
            }
        }