package org.matheclipse.core.reflection.system;
import static org.matheclipse.core.expression.F.Arg;
import static org.matheclipse.core.expression.F.C1D2;
import static org.matheclipse.core.expression.F.C2;
import static org.matheclipse.core.expression.F.CN1;
import static org.matheclipse.core.expression.F.E;
import static org.matheclipse.core.expression.F.Log;
import static org.matheclipse.core.expression.F.Plus;
import static org.matheclipse.core.expression.F.Power;
import static org.matheclipse.core.expression.F.Re;
import static org.matheclipse.core.expression.F.Cos;
import static org.matheclipse.core.expression.F.Times;
import org.matheclipse.core.eval.exception.Validate;
import org.matheclipse.core.eval.interfaces.AbstractFunctionEvaluator;
import org.matheclipse.core.eval.interfaces.IFunctionEvaluator;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.generic.Functors;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IComplex;
import org.matheclipse.core.interfaces.IComplexNum;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.INumber;
import org.matheclipse.core.interfaces.ISymbol;
/**
* Get the real part of an expression
*
* See: Real part
*/
public class Re implements IFunctionEvaluator {
public Re() {
}
public IExpr evaluate(final IAST ast) {
Validate.checkSize(ast, 2);
IExpr arg1 = ast.arg1();
if (arg1.isSignedNumber()) {
return arg1;
}
if (arg1.isComplex()) {
return ((IComplex) arg1).getRe();
}
if (arg1 instanceof IComplexNum) {
return F.num(((IComplexNum) arg1).getRealPart());
}
if (AbstractFunctionEvaluator.isNegativeExpression(arg1)) {
return Times(CN1, Re(Times(CN1, arg1)));
}
if (arg1.isTimes()) {
if (arg1.getAt(1).isSignedNumber()) {
IAST temp = ((IAST) arg1).clone();
temp.remove(1);
return F.Times(arg1.getAt(1), F.Re(temp));
}
if (arg1.getAt(1).equals(F.CI)) {
// Re(I*temp) -> -Im(temp)
IAST temp = ((IAST) arg1).clone();
temp.remove(1);
return F.Times(F.CN1, F.Im(temp));
}
}
if (arg1.isPlus()) {
return ((IAST) arg1).map(Functors.replace1st(F.Re(F.Null)));
}
if (arg1.isPower()) {
IAST astPower = (IAST) arg1;
if (astPower.arg1().isRealFunction()) {
// test for x^(a+I*b)
IExpr x = astPower.arg1();
if (astPower.get(2).isNumber()) {
// (x^2)^(a/2)*E^(-b*Arg[x])*Cos[a*Arg[x]+1/2*b*Log[x^2]]
IExpr a = ((INumber) astPower.get(2)).getRe();
IExpr b = ((INumber) astPower.get(2)).getIm();
return rePowerComplex(x, a, b);
}
// (x^2)^(a/2)*E^(-b*Arg[x])*Cos[a*Arg[x]+1/2*b*Log[x^2]]
IExpr a = F.eval(F.Re(astPower.get(2)));
IExpr b = F.eval(F.Im(astPower.get(2)));
return rePowerComplex(x, a, b);
}
}
return null;
}
/**
* Evaluate Re(x^(a+I*b))
*
* @param x
* @param a
* the real part of the exponent
* @param b
* the imaginary part of the exponent
* @return
*/
private IExpr rePowerComplex(IExpr x, IExpr a, IExpr b) {
if (x.equals(F.E)) {
// Re(E^(a+I*b)) -> E^a*Cos[b]
return Times(Power(F.E, a), Cos(b));
}
return Times(Times(Power(Power(x, C2), Times(C1D2, a)), Power(E, Times(Times(CN1, b), Arg(x)))),
Cos(Plus(Times(a, Arg(x)), Times(Times(C1D2, b), Log(Power(x, C2))))));
}
public IExpr numericEval(final IAST ast) {
return evaluate(ast);
}
public void setUp(final ISymbol symbol) {
symbol.setAttributes(ISymbol.LISTABLE);
}
}
Ads help maintain this website.