// V((A*x)^n) = A^(1/n)*V(x^n) protected override Expression VisitPower(Power P) { if (!IsConstant(P.Right)) return base.VisitPower(P); Expression L = P.Left.Factor(); IEnumerable<Expression> A = Product.TermsOf(L).Where(i => IsConstant(i)); if (A.Any()) return Product.New(Power.New(Product.New(A), 1 / P.Right), Visit(Product.New(Product.TermsOf(L).Where(i => !IsConstant(i))))); return base.VisitPower(P); }
protected override Expression VisitPower(Power P) { Expression f = P.Left; Expression g = P.Right; if (g.DependsOn(x)) { // f(x)^g(x) return Product.New(P, Sum.New( Product.New(Visit(f), Binary.Divide(g, f)), Product.New(Visit(g), Call.Ln(f)))).Evaluate(); } else { // f(x)^g return Product.New( g, Power.New(f, Binary.Subtract(g, 1)), Visit(f)).Evaluate(); } }
/// <summary> /// Expand a power expression. /// </summary> /// <param name="f"></param> /// <param name="x"></param> /// <returns></returns> private static Expression ExpandPower(Power f, Expression x) { // Get integral exponent of f. int n = Power.IntegralExponentOf(f); // If this is an an integral constant negative exponent, attempt to use partial fractions. if (n < 0 && !ReferenceEquals(x, null)) { Expression b = f.Left.Factor(x); if (n != -1) b = Power.New(b, Math.Abs(n)); return ExpandPartialFractions(1, b, x); } // If f is an add expression, expand it as if it were multiplication. if (n > 1 && f.Left is Sum) { Expression e = f.Left; for (int i = 1; i < n; ++i) e = Distribute(f.Left, e); return e; } return f; }
protected override Expression VisitPower(Power P) { Expression L = Visit(P.Left); Expression R = Visit(P.Right); if (R.IsInteger()) { // Transform (x*y)^z => x^z*y^z if z is an integer. Product M = L as Product; if (!ReferenceEquals(M, null)) return Visit(Product.New(M.Terms.Select(i => Power.New(i, R)))); } // Transform (x^y)^z => x^(y*z) if z is an integer. Power LP = L as Power; if (!ReferenceEquals(LP, null)) { L = LP.Left; R = Visit(Product.New(P.Right, LP.Right)); } // Handle identities. Real? LR = AsReal(L); if (EqualsZero(LR)) return 0; if (EqualsOne(LR)) return 1; Real? RR = AsReal(R); if (EqualsZero(RR)) return 1; if (EqualsOne(RR)) return L; // Evaluate result. if (LR != null && RR != null) return Constant.New(LR.Value ^ RR.Value); else return Power.New(L, R); }
protected override string VisitPower(Power P) { int pr = Parser.Precedence(Operator.Power); return Visit(P.Left, pr) + "^{" + Visit(P.Right, pr) + "}"; }