diff --git a/poincare/src/absolute_value.cpp b/poincare/src/absolute_value.cpp index 0a27a5718..44c45e734 100644 --- a/poincare/src/absolute_value.cpp +++ b/poincare/src/absolute_value.cpp @@ -47,13 +47,27 @@ Expression AbsoluteValue::shallowReduce(Context & context, Preferences::AngleUni #endif #endif Expression c = childAtIndex(0); - ComplexPolar polar = c.complexPolar(context, angleUnit); - if (!polar.isUninitialized()) { - Expression n = polar.norm(); - replaceWithInPlace(n); - // We have to deepReduce because the complexPolar function returns an Expression reduced only BottomUp - return n.deepReduce(context, angleUnit, target); + if (c.isReal(context, angleUnit)) { + float app = c.approximateToScalar(context, angleUnit); + if (!std::isnan(app) && app >= 0) { + // abs(a) = a with a > 0 + replaceWithInPlace(c); + return c; + } else if (!std::isnan(app) && app < 0) { + // abs(a) = -a with a < 0 + Multiplication m(Rational(-1), c); + replaceWithInPlace(m); + return m.shallowReduce(context, angleUnit, target); + } } + if (c.type() == ExpressionNode::Type::ComplexCartesian) { + ComplexCartesian complexChild = static_cast(c); + Expression childNorm = complexChild.norm(context, angleUnit, target); + replaceWithInPlace(childNorm); + return childNorm.shallowReduce(context, angleUnit, target); + } + // abs(-x) = abs(x) + c.makePositiveAnyNegativeNumeralFactor(context, angleUnit); return *this; } diff --git a/poincare/src/complex_argument.cpp b/poincare/src/complex_argument.cpp index 8e70e417c..fa0b69ae8 100644 --- a/poincare/src/complex_argument.cpp +++ b/poincare/src/complex_argument.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include extern "C" { #include } @@ -43,12 +45,28 @@ Expression ComplexArgument::shallowReduce(Context & context, Preferences::AngleU return SimplificationHelper::Map(*this, context, angleUnit); } #endif - ComplexPolar polar = c.complexPolar(context, angleUnit); - if (!polar.isUninitialized()) { - Expression a = polar.arg(); - replaceWithInPlace(a); - // We have to deepReduce because the complexPolar function returns an Expression reduced only BottomUp - return a.deepReduce(context, angleUnit, target); + if (c.isReal(context, angleUnit)) { + float app = c.approximateToScalar(context, angleUnit); + if (std::isnan(app)) { + ComplexCartesian complexChild = ComplexCartesian::Builder(c, Rational(0)); + Expression arg = complexChild.argument(context, angleUnit, target); + replaceWithInPlace(arg); + return arg.shallowReduce(context, angleUnit, target); + } else if (app >= 0) { + Expression result = Rational(0); + replaceWithInPlace(result); + return result; + } + assert(app < 0); + Expression result = Constant(Ion::Charset::SmallPi); + replaceWithInPlace(result); + return result; + } + if (c.type() == ExpressionNode::Type::ComplexCartesian) { + ComplexCartesian complexChild = static_cast(c); + Expression childArg = complexChild.argument(context, angleUnit, target); + replaceWithInPlace(childArg); + return childArg.shallowReduce(context, angleUnit, target); } return *this; } diff --git a/poincare/src/imaginary_part.cpp b/poincare/src/imaginary_part.cpp index 4c7f494a4..f8ae8fe45 100644 --- a/poincare/src/imaginary_part.cpp +++ b/poincare/src/imaginary_part.cpp @@ -36,17 +36,16 @@ Expression ImaginaryPart::shallowReduce(Context & context, Preferences::AngleUni return SimplificationHelper::Map(*this, context, angleUnit); } #endif - if (c.type() == ExpressionNode::Type::Rational) { + if (c.isReal(context, angleUnit)) { Expression result = Rational(0); replaceWithInPlace(result); return result; } - ComplexCartesian cartesian = c.complexCartesian(context, angleUnit); - if (!cartesian.isUninitialized()) { - Expression im = cartesian.imag(); - replaceWithInPlace(im); - // We have to deepReduce because the complexCartesian function returns an Expression reduced only BottomUp - return im.deepReduce(context, angleUnit, target); + if (c.type() == ExpressionNode::Type::ComplexCartesian) { + ComplexCartesian complexChild = static_cast(c); + Expression i = complexChild.imag(); + replaceWithInPlace(i); + return i.shallowReduce(context, angleUnit, target); } return *this; } diff --git a/poincare/src/real_part.cpp b/poincare/src/real_part.cpp index 696a09f61..3bd0b688c 100644 --- a/poincare/src/real_part.cpp +++ b/poincare/src/real_part.cpp @@ -36,16 +36,15 @@ Expression RealPart::shallowReduce(Context & context, Preferences::AngleUnit ang return SimplificationHelper::Map(*this, context, angleUnit); } #endif - if (c.type() == ExpressionNode::Type::Rational) { + if (c.isReal(context, angleUnit)) { replaceWithInPlace(c); return c; } - ComplexCartesian cartesian = c.complexCartesian(context, angleUnit); - if (!cartesian.isUninitialized()) { - Expression re = cartesian.real(); - replaceWithInPlace(re); - // We have to deepReduce because the complexCartesian function returns an Expression reduced only BottomUp - return re.deepReduce(context, angleUnit, target); + if (c.type() == ExpressionNode::Type::ComplexCartesian) { + ComplexCartesian complexChild = static_cast(c); + Expression r = complexChild.real(); + replaceWithInPlace(r); + return r.shallowReduce(context, angleUnit, target); } return *this; }