public static void main(String[] args) { IExpr expr = F.Plus(F.x, F.Times(F.Pi, F.Sin(F.y))); TreeNode<String> tn1 = convert(expr); // Print: // +-Plus // +-x // +-Times // | +-Pi // | +-Sin // | +-y System.out.println(asciiDisplay(tn1)); }
@Override public IExpr evaluateArg1(final IExpr arg1) { IExpr negExpr = AbstractFunctionEvaluator.getNormalizedNegativeExpression(arg1); if (negExpr.isPresent()) { return Negate(Sinh(negExpr)); } IExpr imPart = AbstractFunctionEvaluator.getPureImaginaryPart(arg1); if (imPart.isPresent()) { return F.Times(F.CI, F.Sin(imPart)); } if (arg1.isZero()) { return F.C0; } return F.NIL; }
@Override public IExpr evaluateArg1(final IExpr arg1) { if (isNegativeExpression(arg1)) { return Times(CN1, Sin(Times(CN1, arg1))); } return null; }
/** * Complex number on unit circle with given argument. * * @param arg * @return complex number on unit circle with given argument */ private static IExpr unit(IExpr arg) { return F.Plus(F.Cos(arg), F.Times(F.CI, F.Sin(arg))); }
@Override public IExpr evaluate(final IAST ast, EvalEngine engine) { Validate.checkSize(ast, 2); return F.Power(F.Sin(F.C1D2.times(ast.arg1())), F.C2); }
/** * <code>Sin(a+b+c+...)</code> * * @param plusAST * @param startPosition * @return */ private static IExpr expandSinPlus(IAST plusAST, int startPosition) { IASTAppendable result = F.PlusAlloc(2); IExpr lhs = plusAST.get(startPosition); if (startPosition == plusAST.size() - 2) { IExpr rhs = plusAST.get(startPosition + 1); result.append(Times(Sin(lhs), Cos(rhs))); result.append(Times(Cos(lhs), Sin(rhs))); } else { result.append(Times(Sin(lhs), expandCosPlus(plusAST, startPosition + 1))); result.append(Times(Cos(lhs), expandSinPlus(plusAST, startPosition + 1))); } return result; }
private IExpr expandCosPlus(IAST plusAST, int startPosition) { if (startPosition > plusAST.size() - 2) { return null; } IAST result = Plus(); if (startPosition == plusAST.size() - 2) { result.add(Times(Cos(plusAST.get(startPosition)), Cos(plusAST.get(startPosition + 1)))); result.add(Times(CN1, Sin(plusAST.get(startPosition)), Sin(plusAST.get(startPosition + 1)))); } else { result.add(Times(Cos(plusAST.get(startPosition)), expandCosPlus(plusAST, startPosition + 1))); result.add(Times(CN1, Sin(plusAST.get(startPosition)), expandSinPlus(plusAST, startPosition + 1))); } return result; }
/** * <code>Sin(a+b+c+...)</code> * * @param plusAST * @param startPosition * @return */ private static IExpr expandCosPlus(IAST plusAST, int startPosition) { IASTAppendable result = F.PlusAlloc(2); IExpr lhs = plusAST.get(startPosition); if (startPosition == plusAST.size() - 2) { IExpr rhs = plusAST.get(startPosition + 1); result.append(Times(Cos(lhs), Cos(rhs))); result.append(Times(CN1, Sin(lhs), Sin(rhs))); } else { result.append(Times(Cos(lhs), expandCosPlus(plusAST, startPosition + 1))); result.append(Times(CN1, Sin(lhs), expandSinPlus(plusAST, startPosition + 1))); } return result; }
private IExpr expandSinPlus(IAST plusAST, int startPosition) { if (startPosition > plusAST.size() - 2) { return null; } IAST result = Plus(); if (startPosition == plusAST.size() - 2) { result.add(Times(Sin(plusAST.get(startPosition)), Cos(plusAST.get(startPosition + 1)))); result.add(Times(Cos(plusAST.get(startPosition)), Sin(plusAST.get(startPosition + 1)))); } else { result.add(Times(Sin(plusAST.get(startPosition)), expandCosPlus(plusAST, startPosition + 1))); result.add(Times(Cos(plusAST.get(startPosition)), expandSinPlus(plusAST, startPosition + 1))); } return result; }
@Override public IExpr evaluate(final IAST ast, EvalEngine engine) { Validate.checkSize(ast, 2); int dim = ast.arg1().isVector(); if (dim > 0) { IAST list = (IAST) ast.arg1(); if (dim == 2) { IExpr r = list.arg1(); IExpr theta = list.arg2(); return F.List(F.Times(r, F.Cos(theta)), F.Times(r, F.Sin(theta))); } else if (dim == 3) { IExpr r = list.arg1(); IExpr theta = list.arg2(); IExpr phi = list.arg3(); return F.List(F.Times(r, F.Cos(theta)), F.Times(r, F.Cos(phi), F.Sin(theta)), F.Times(r, F.Sin(theta), F.Sin(phi))); } } else if (ast.arg1().isList()) { return ((IAST) ast.arg1()).mapThread(F.ListAlloc(ast.size()), ast, 1); } return F.NIL; }
@Override public IExpr evaluate(IAST ast, EvalEngine engine) { IExpr z = ast.arg1(); IExpr m = ast.arg2(); if (m.isZero()) { return F.C0; } if (z.isZero()) { return F.C0; } if (z.equals(F.CPiHalf)) { return F.C0; } if (m.isOne()) { // Abs(Re(z)) <= Pi/2 if (engine.evalTrue(F.LessEqual(F.Abs(F.Re(z)), F.CPiHalf))) { return F.Sin(z); } } if (m.isInfinity() || m.isNegativeInfinity()) { return F.CComplexInfinity; } return F.NIL; }
/** * Evaluate <code>Im(x^(a+I*b))</code> * * @param x * @param a the real part of the exponent * @param b the imaginary part of the exponent * @return */ private IExpr imPowerComplex(IExpr x, IExpr a, IExpr b) { if (x.isE()) { // Im(E^(a+I*b)) -> E^a*Sin[b] return Times(Power(F.E, a), Sin(b)); } return Times(Times(Power(Power(x, C2), Times(C1D2, a)), Power(E, Times(Negate(b), Arg(x)))), Sin(Plus(Times(a, Arg(x)), Times(Times(C1D2, b), Log(Power(x, C2)))))); }
/** * Try using the <code>TrigReduce</code> function to get a <code>Plus(...)</code> expression which could be * integrated. * * @param timesAST * an IAST which is a <code>Times(...)</code> expression * @param arg2 * the symbol to get the indefinite integral for. * @return <code>F.NIL</code> if no trigonometric funtion could be found. */ private static IExpr integrateTimesTrigFunctions(final IAST timesAST, IExpr arg2) { Predicate<IExpr> isTrigFunction = Predicates.isAST(new ISymbol[] { F.Cos, F.Sin }); if (timesAST.has(isTrigFunction, false)) { // use a symbol which is not in the symbols map ISymbol pSymbol = new Symbol("$x$", Context.SYSTEM); IExpr fx = F.eval(F.TrigReduce(timesAST)); if (fx.isPlus()) { // Collect arguments for x // Sin(f_) -> Sin(Collect(f, arg2)) fx = F.eval(F.ReplaceAll(fx, F.List(F.Rule(F.Sin(F.$p(pSymbol)), F.Sin(F.Collect(pSymbol, arg2))), F.Rule(F.Cos(F.$p(pSymbol)), F.Cos(F.Collect(pSymbol, arg2)))))); // Integrate[a_+b_+...,x_] -> Integrate[a,x]+Integrate[b,x]+... return ((IAST) fx).mapThread(F.Integrate(null, arg2), 1); } } return F.NIL; }
/** * <code>Cos(n*theta)</code> * * @param n * @param theta * @return */ private static IExpr expandCosTimes(IInteger n, IExpr theta) { int ni = n.toIntDefault(Integer.MIN_VALUE); if (ni > Integer.MIN_VALUE) { return F.sum(i -> Times(Times(Times(Power(CN1, Times(i, C1D2)), Binomial(n, i)), Power(Cos(theta), Plus(n, Times(CN1, i)))), Power(Sin(theta), i)), 0, ni, 2); } return F.NIL; }
/** * <code>Sin(n*theta)</code> * * @param n * @param theta * @return */ private static IExpr expandSinTimes(IInteger n, IExpr theta) { int ni = n.toIntDefault(Integer.MIN_VALUE); if (ni > Integer.MIN_VALUE) { return F.sum(i -> Times(Times(Times(Power(CN1, Times(Plus(i, CN1), C1D2)), Binomial(n, i)), Power(Cos(theta), Plus(n, Times(CN1, i)))), Power(Sin(theta), i)), 1, ni, 2); } return F.NIL; }
@Override public IExpr e2ComArg(final IComplex base, final IComplex exponent) { if (base.getImaginaryPart().isZero()) { IRational a = base.getRealPart(); IRational b = exponent.getRealPart(); IRational c = exponent.getImaginaryPart(); IExpr temp = // [$ b*Arg(a)+1/2*c*Log(a^2) $] F.Plus(F.Times(b, F.Arg(a)), F.Times(F.C1D2, c, F.Log(F.Sqr(a)))); // $$; return // [$ (a^2)^(b/2)*E^(-c*Arg(a)) * (Cos(temp)+I* Sin(temp)) $] F.Times(F.Power(F.Sqr(a), F.Times(F.C1D2, b)), F.Exp(F.Times(F.CN1, c, F.Arg(a))), F.Plus(F.Cos(temp), F.Times(F.CI, F.Sin(temp)))); // $$; } return F.NIL; }
@Override public IExpr visit(IASTMutable ast) { if (ast.isTimes()) { IExpr expanded = F.evalExpand(ast); if (expanded.isPlus()) { return F.ComplexExpand.of(fEngine, expanded); } } if (ast.isPower() && ast.base().isNegative() // && ast.exponent().isRational()) { IExpr base = ast.base(); if (base.isInteger()) { IExpr exponent = ast.exponent(); // ((base^2)^(exponent/2)) IExpr coeff = F.Power(F.Power(base, F.C2), F.C1D2.times(exponent)); // exponent*Arg(base) IExpr inner = exponent.times(F.Arg(base)); // coeff*Cos(inner) + I*coeff*Sin(inner); IExpr temp = F.Expand.of(fEngine, F.Plus(F.Times(coeff, F.Cos(inner)), F.Times(F.CI, coeff, F.Sin(inner)))); return temp; } } return super.visit(ast); }
@Override public IExpr visit(IAST ast) { if (ast.isTimes()) { IAST result = ORDERLESS_MATCHER.evaluate(ast); if (result != null) { return result; } } else if (ast.isPower()) { if (ast.get(1).isAST() && ast.get(2).isInteger()) { IInteger n = (IInteger) ast.get(2); if (n.isPositive()) { IAST powerArg1 = (IAST) ast.get(1); IExpr x; if (powerArg1.isSin()) { x = powerArg1.get(1); // (1/2-Cos[2*x]/2)*Sin[x]^(n-2) return Times(Subtract(C1D2, Times(C1D2, Cos(Times(C2, x)))), Power(Sin(x), n.subtract(C2))); } else if (powerArg1.isCos()) { x = powerArg1.get(1); // (1/2+Cos[2*x]/2)*Cos[x]^(n-2) return Times(Plus(C1D2, Times(C1D2, Cos(Times(C2, x)))), Power(Cos(x), n.subtract(C2))); } } } } return visitAST(ast); } }
@Override public IExpr visit(IASTMutable ast) { if (ast.isTimes()) { IAST result = ORDERLESS_MATCHER.evaluate(ast, fEngine); if (result.isPresent()) { return result; } } else if (ast.isPower()) { if (ast.base().isAST() && ast.exponent().isInteger()) { IInteger n = (IInteger) ast.exponent(); if (n.isPositive()) { IAST base = (IAST) ast.base(); IExpr x; if (base.isSin()) { x = base.arg1(); // (1/2-Cos[2*x]/2)*Sin[x]^(n-2) return Times(Subtract(C1D2, Times(C1D2, Cos(Times(C2, x)))), Power(Sin(x), n.subtract(C2))); } else if (base.isCos()) { x = base.arg1(); // (1/2+Cos[2*x]/2)*Cos[x]^(n-2) return Times(Plus(C1D2, Times(C1D2, Cos(Times(C2, x)))), Power(Cos(x), n.subtract(C2))); } } } } return visitAST(ast); } }
F.List(j, F.C0, F.Floor(F.Times(F.C1D4, F.Plus(F.CN3, F.Times(F.C2, F.Abs(n)))))))), F.Times(F.CN1, F.Sin(F.Plus(F.Times(F.C1D2, F.Plus(F.CN1D2, n), F.Pi), F .Negate(z))),