mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-28 10:09:53 +01:00
[poincare] Complex parts getters (realPart, imaginaryPart,
complexNorm...) simplify while building the complex part
This commit is contained in:
@@ -14,7 +14,7 @@ public:
|
||||
return cartesianPartOfComplexFunction(e, context, angleUnit, false);
|
||||
}
|
||||
static Expression realPartRealFunction(const ExpressionNode * e, Context & context, Preferences::AngleUnit angleUnit) {
|
||||
return Expression(e).clone();
|
||||
return Expression(e).clone().deepReduce(context, angleUnit, ExpressionNode::ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
static Expression imaginaryPartRealFunction(const ExpressionNode * e, Context & context, Preferences::AngleUnit angleUnit);
|
||||
// static Expression realPartMatrix(const Expression e, Context & context, Preferences::AngleUnit angleUnit);
|
||||
|
||||
@@ -185,8 +185,8 @@ public:
|
||||
Expression simplify(Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression reduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
static Expression ExpressionWithoutSymbols(Expression expressionWithSymbols, Context & context);
|
||||
Expression radianToDegree();
|
||||
Expression degreeToRadian();
|
||||
Expression radianToDegree(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
Expression degreeToRadian(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target);
|
||||
|
||||
/* Approximation Helper */
|
||||
template<typename U> static U epsilon();
|
||||
|
||||
@@ -40,7 +40,7 @@ Expression AdditionNode::complexPart(Context & context, Preferences::AngleUnit a
|
||||
}
|
||||
result.addChildAtIndexInPlace(part, result.numberOfChildren(), result.numberOfChildren());
|
||||
}
|
||||
return result;
|
||||
return result.shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
|
||||
// Layout
|
||||
|
||||
@@ -13,9 +13,7 @@ Expression ComplexHelper::cartesianPartOfComplexFunction(const ExpressionNode *
|
||||
return Expression();
|
||||
}
|
||||
if (real) {
|
||||
Expression result = e.clone();
|
||||
result.replaceChildAtIndexInPlace(0, e.childAtIndex(0).realPart(context, angleUnit));
|
||||
return result;
|
||||
return e.clone().deepReduce(context, angleUnit, ExpressionNode::ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
return Rational(0);
|
||||
}
|
||||
@@ -31,14 +29,14 @@ Expression ComplexHelper::complexCartesianPartFromPolarParts(const ExpressionNod
|
||||
if (r.isUninitialized() || th.isUninitialized()) {
|
||||
return Expression();
|
||||
}
|
||||
Expression argument = angleUnit == Preferences::AngleUnit::Radian ? th : th.radianToDegree();
|
||||
Expression argument = angleUnit == Preferences::AngleUnit::Radian ? th : th.radianToDegree(context, angleUnit, ExpressionNode::ReductionTarget::BottomUpComputation);
|
||||
Expression trigo;
|
||||
if (isReal) {
|
||||
trigo = Cosine::Builder(argument);
|
||||
} else {
|
||||
trigo = Sine::Builder(argument);
|
||||
}
|
||||
return Multiplication(r, trigo);
|
||||
return Multiplication(r, trigo.shallowReduce(context, angleUnit, ExpressionNode::ReductionTarget::BottomUpComputation)).shallowReduce(context, angleUnit, ExpressionNode::ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ Expression ConjugateNode::realPart(Context & context, Preferences::AngleUnit ang
|
||||
Expression ConjugateNode::imaginaryPart(Context & context, Preferences::AngleUnit angleUnit) const {
|
||||
Expression e = childAtIndex(0)->imaginaryPart(context, angleUnit);
|
||||
if (!e.isUninitialized()) {
|
||||
return Opposite(e);
|
||||
return Opposite(e).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
return Expression();
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ Expression DivisionNode::complexNorm(Context & context, Preferences::AngleUnit a
|
||||
if (r0.isUninitialized() || r1.isUninitialized()) {
|
||||
return Expression();
|
||||
}
|
||||
return Division(r0,r1);
|
||||
return Division(r0,r1).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
|
||||
Expression DivisionNode::complexPart(Context & context, Preferences::AngleUnit angleUnit, bool real) const {
|
||||
@@ -65,11 +65,32 @@ Expression DivisionNode::complexPart(Context & context, Preferences::AngleUnit a
|
||||
if (a.isUninitialized() || b.isUninitialized() || c.isUninitialized() || d.isUninitialized()) {
|
||||
return Expression();
|
||||
}
|
||||
Expression denominator = Addition(Power(c.clone(), Rational(2)), Power(d.clone(), Rational(2)));
|
||||
Expression denominator =
|
||||
Addition(
|
||||
Power(
|
||||
c.clone(),
|
||||
Rational(2)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Power(
|
||||
d.clone(),
|
||||
Rational(2)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
if (real) {
|
||||
return Division(Addition(Multiplication(a, c), Multiplication(b, d)), denominator);
|
||||
return Division(
|
||||
Addition(
|
||||
Multiplication(a, c).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Multiplication(b, d).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
denominator
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
return Division(Subtraction(Multiplication(b, c), Multiplication(a, d)), denominator);
|
||||
return Division(
|
||||
Subtraction(
|
||||
Multiplication(b, c).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Multiplication(a, d).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
denominator).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
|
||||
template<typename T> Complex<T> DivisionNode::compute(const std::complex<T> c, const std::complex<T> d) {
|
||||
|
||||
@@ -424,12 +424,12 @@ Expression Expression::ExpressionWithoutSymbols(Expression e, Context & context)
|
||||
return e;
|
||||
}
|
||||
|
||||
Expression Expression::radianToDegree() {
|
||||
return Multiplication(*this, Division(Rational(180), Constant(Ion::Charset::SmallPi)));
|
||||
Expression Expression::radianToDegree(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
return Multiplication(*this, Division(Rational(180), Constant(Ion::Charset::SmallPi)).shallowReduce(context, angleUnit, target)).shallowReduce(context, angleUnit, target);
|
||||
}
|
||||
|
||||
Expression Expression::degreeToRadian( ) {
|
||||
return Multiplication(*this, Division(Constant(Ion::Charset::SmallPi), Rational(180)));
|
||||
Expression Expression::degreeToRadian(Context & context, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
return Multiplication(*this, Division(Constant(Ion::Charset::SmallPi), Rational(180)).shallowReduce(context, angleUnit, target)).shallowReduce(context, angleUnit, target);
|
||||
}
|
||||
|
||||
Expression Expression::reduce(Context & context, Preferences::AngleUnit angleUnit) {
|
||||
|
||||
@@ -84,7 +84,12 @@ Expression ExpressionNode::complexNorm(Context & context, Preferences::AngleUnit
|
||||
Expression b = imaginaryPart(context, angleUnit);
|
||||
if (!a.isUninitialized() && !b.isUninitialized()) {
|
||||
// sqrt(a^2+b^2)
|
||||
return SquareRoot::Builder(Addition(Power(a, Rational(2)), Power(b, Rational(2))));
|
||||
return SquareRoot::Builder(
|
||||
Addition(
|
||||
Power(a, Rational(2)).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Power(b, Rational(2)).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
return Expression();
|
||||
}
|
||||
@@ -95,15 +100,27 @@ Expression ExpressionNode::complexArgument(Context & context, Preferences::Angle
|
||||
if (!a.isUninitialized() && !b.isUninitialized()) {
|
||||
if (b.type() != Type::Rational || !static_cast<Rational &>(b).isZero()) {
|
||||
// arctan(a/b) or (180/Pi)*arctan(a/b)
|
||||
Expression arcTangent = ArcTangent::Builder(Division(a, b.clone()));
|
||||
Expression arcTangent = ArcTangent::Builder(Division(a, b.clone()).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
if (angleUnit == Preferences::AngleUnit::Degree) {
|
||||
arcTangent = arcTangent.degreeToRadian();
|
||||
arcTangent = arcTangent.degreeToRadian(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
// sign(b) * Pi/2 - arctan(a/b)
|
||||
return Subtraction(Multiplication(SignFunction::Builder(b), Division(Constant(Ion::Charset::SmallPi), Rational(2))), arcTangent);
|
||||
return Subtraction(
|
||||
Multiplication(
|
||||
SignFunction::Builder(b).shallowReduce(context, angleUnit),
|
||||
Division(Constant(Ion::Charset::SmallPi), Rational(2)).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
),
|
||||
arcTangent
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
} else {
|
||||
// (1-sign(a))*Pi/2
|
||||
return Multiplication(Subtraction(Rational(1), SignFunction::Builder(a)), Division(Constant(Ion::Charset::SmallPi), Rational(2)));
|
||||
return Multiplication(
|
||||
Subtraction(
|
||||
Rational(1),
|
||||
SignFunction::Builder(a).shallowReduce(context, angleUnit)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Division(Constant(Ion::Charset::SmallPi), Rational(2)).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
}
|
||||
return Expression();
|
||||
|
||||
@@ -43,8 +43,16 @@ Expression MultiplicationNode::complexCartesianPart(Context & context, Preferenc
|
||||
if (childReal.isUninitialized() || childImag.isUninitialized()) {
|
||||
return Expression();
|
||||
}
|
||||
Expression newReal = Subtraction(Multiplication(real.clone(), childReal.clone()), Multiplication(imag.clone(), childImag.clone()));
|
||||
Expression newImag = Addition(Multiplication(real, childImag), Multiplication(imag, childReal));
|
||||
Expression newReal =
|
||||
Subtraction(
|
||||
Multiplication(real.clone(), childReal.clone()).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Multiplication(imag.clone(), childImag.clone()).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
Expression newImag =
|
||||
Addition(
|
||||
Multiplication(real, childImag).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Multiplication(imag, childReal).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
real = newReal;
|
||||
imag = newImag;
|
||||
}
|
||||
@@ -61,7 +69,7 @@ Expression MultiplicationNode::complexNorm(Context & context, Preferences::Angle
|
||||
}
|
||||
norm.addChildAtIndexInPlace(r, norm.numberOfChildren(), norm.numberOfChildren());
|
||||
}
|
||||
return norm;
|
||||
return norm.shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
|
||||
/*Expression MultiplicationNode::complexArgument(Context & context, Preferences::AngleUnit angleUnit) const {
|
||||
|
||||
@@ -28,15 +28,39 @@ Expression NthRootNode::complexPolarPart(Context & context, Preferences::AngleUn
|
||||
if (r.isUninitialized() || th.isUninitialized() || c.isUninitialized() || d.isUninitialized()) {
|
||||
return Expression();
|
||||
}
|
||||
Expression denominator = Addition(Power(c.clone(), Rational(2)), Power(d.clone(), Rational(2)));
|
||||
Expression denominator =
|
||||
Addition(
|
||||
Power(c.clone(), Rational(2)).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Power(d.clone(), Rational(2)).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
if (isNorm) {
|
||||
// R = e^((c*ln(r)+th*d)/(c^2+d^2))
|
||||
// R = r^(c/(c^2+d^2))*e^(th*d/(c^2+d^2))
|
||||
return Multiplication(Power(r, Division(c, denominator.clone())), Power(Constant(Ion::Charset::Exponential), Division(Multiplication(d, th), denominator)));
|
||||
return Multiplication(
|
||||
Power(
|
||||
r,
|
||||
Division(c, denominator.clone()).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Power(
|
||||
Constant(Ion::Charset::Exponential),
|
||||
Division(
|
||||
Multiplication(d, th).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
denominator)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
//return Power(Constant(Ion::Charset::Exponential), Division(Addition(Multiplication(c, NaperianLogarithm::Builder(r)), Multiplication(d, th)), denominator));
|
||||
} else {
|
||||
// TH = (th*c-d*ln(r))/(c^2+d^2)
|
||||
return Division(Subtraction(Multiplication(th, c), Multiplication(d, NaperianLogarithm::Builder(r))), denominator);
|
||||
return Division(
|
||||
Subtraction(
|
||||
Multiplication(th, c).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Multiplication(
|
||||
d,
|
||||
NaperianLogarithm::Builder(r).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
denominator
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Expression OppositeNode::complexCartesianPart(Context & context, Preferences::An
|
||||
if (a.isUninitialized()) {
|
||||
return Expression();
|
||||
}
|
||||
return Opposite(a);
|
||||
return Opposite(a).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
|
||||
/* Layout */
|
||||
|
||||
@@ -94,11 +94,25 @@ Expression PowerNode::complexPolarPart(Context & context, Preferences::AngleUnit
|
||||
if (norm) {
|
||||
// R = e^(c*ln(r)-th*d)
|
||||
// R = r^c*e^(-th*d)
|
||||
return Multiplication(Power(r, c), Power(Constant(Ion::Charset::Exponential), Opposite(Multiplication(th, d))));
|
||||
return Multiplication(
|
||||
Power(r, c).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Power(
|
||||
Constant(Ion::Charset::Exponential),
|
||||
Opposite(
|
||||
Multiplication(th, d).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
//return Power(Constant(Ion::Charset::Exponential), Subtraction(Multiplication(c, NaperianLogarithm::Builder(r)), Multiplication(d, th)));
|
||||
} else {
|
||||
// TH = d*ln(r)+c*th
|
||||
return Addition(Multiplication(th, c), Multiplication(d, NaperianLogarithm::Builder(r)));
|
||||
return Addition(
|
||||
Multiplication(th, c).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation),
|
||||
Multiplication(
|
||||
d,
|
||||
NaperianLogarithm::Builder(r).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation)
|
||||
).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,7 +462,7 @@ Expression Power::shallowReduce(Context & context, Preferences::AngleUnit angleU
|
||||
/* We do not apply some rules to a^b if:
|
||||
* - the parent node is a logarithm of same base a. In this case there is a
|
||||
* simplication of form ln(e^(3^(1/2))->3^(1/2).
|
||||
* - the reduction is being BottomUp. In this case, we do not yet have any
|
||||
* - the reduction is being BottomUpComputation. In this case, we do not yet have any
|
||||
* information on the parent which could later be a logarithm of the same
|
||||
* base.
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,7 @@ Expression SquareRootNode::complexNorm(Context & context, Preferences::AngleUnit
|
||||
return Expression();
|
||||
}
|
||||
// R = sqrt(r)
|
||||
return SquareRoot::Builder(r);
|
||||
return SquareRoot::Builder(r).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
|
||||
Expression SquareRootNode::complexArgument(Context & context, Preferences::AngleUnit angleUnit) const {
|
||||
@@ -30,7 +30,7 @@ Expression SquareRootNode::complexArgument(Context & context, Preferences::Angle
|
||||
return Expression();
|
||||
}
|
||||
// TH = th/2
|
||||
return Division(th, Rational(2));
|
||||
return Division(th, Rational(2)).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
|
||||
Layout SquareRootNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
|
||||
@@ -30,7 +30,7 @@ Expression SubtractionNode::complexPart(Context & context, Preferences::AngleUni
|
||||
if (a0.isUninitialized() || a1.isUninitialized()) {
|
||||
return Expression();
|
||||
}
|
||||
return Subtraction(a0, a1);
|
||||
return Subtraction(a0, a1).shallowReduce(context, angleUnit, ReductionTarget::BottomUpComputation);
|
||||
}
|
||||
|
||||
bool SubtractionNode::childNeedsParenthesis(const TreeNode * child) const {
|
||||
|
||||
Reference in New Issue
Block a user