// V(A*x) = A*V(x) protected override Expression VisitProduct(Product M) { IEnumerable<Expression> A = M.Terms.Where(i => IsConstant(i)); if (A.Any()) return Product.New(A.Append(Visit(Product.New(M.Terms.Where(i => !IsConstant(i)))))); return base.VisitProduct(M); }
protected override string VisitProduct(Product M) { int pr = Parser.Precedence(Operator.Multiply); Expression N = Product.Numerator(M); string minus = ""; if (IsNegative(N)) { minus = "-"; N = -N; } string n = String.Join(" ", Product.TermsOf(N).Select(i => Visit(i, pr))); string d = String.Join(" ", Product.TermsOf(Product.Denominator(M)).Select(i => Visit(i, pr))); if (d != "1") return minus + Frac(n, d); else return minus + n; }
protected override Expression VisitProduct(Product M) { return ProductRule(M.Terms.First(), M.Terms.Skip(1)); }
// Combine like terms and multiply constants. protected override Expression VisitProduct(Product M) { // Map terms to exponents. DefaultDictionary<Expression, Real> terms = new DefaultDictionary<Expression, Real>(0); // Accumulate constants and sum exponent of each term. Real C = 1; foreach (Expression i in M.Terms.SelectMany(i => Product.TermsOf(Visit(i)))) { if (i is Constant) { Real Ci = (Real)i; // Early exit if 0. if (Ci.EqualsZero()) return 0; C *= Ci; } else { Power Pi = i as Power; if (!ReferenceEquals(Pi, null) && Pi.Right is Constant) terms[Pi.Left] += (Real)Pi.Right; else terms[i] += 1; } } // Build a new expression with the accumulated terms. if (!C.EqualsOne()) { // Find a sum term that has a constant term to distribute into. KeyValuePair<Expression, Real> A = terms.FirstOrDefault(i => Real.Abs(i.Value).EqualsOne() && i.Key is Sum); if (!ReferenceEquals(A.Key, null)) { terms.Remove(A.Key); terms[ExpandExtension.Distribute(C ^ A.Value, A.Key)] += A.Value; } else { terms.Add(C, 1); } } return Product.New(terms .Where(i => !i.Value.EqualsZero()) .Select(i => !i.Value.EqualsOne() ? Power.New(i.Key, Constant.New(i.Value)) : i.Key)); }