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)); }
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())); } }