diff --git a/poincare/include/poincare/arc_cosine.h b/poincare/include/poincare/arc_cosine.h index 24c406c14..87de7eae9 100644 --- a/poincare/include/poincare/arc_cosine.h +++ b/poincare/include/poincare/arc_cosine.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace Poincare { @@ -26,7 +27,9 @@ private: /* Simplification */ Expression * shallowReduce(Context& context, AngleUnit angleUnit) override; /* Evaluation */ - template static std::complex computeOnComplex(const std::complex c, AngleUnit angleUnit); + template static std::complex computeOnComplex(const std::complex c, AngleUnit angleUnit) { + return Trigonometry::computeInverseOnComplex(c, angleUnit, std::acos); + } Evaluation * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return ApproximationEngine::map(this, context, angleUnit,computeOnComplex); } diff --git a/poincare/include/poincare/arc_sine.h b/poincare/include/poincare/arc_sine.h index 3a13d14b6..704742e71 100644 --- a/poincare/include/poincare/arc_sine.h +++ b/poincare/include/poincare/arc_sine.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace Poincare { @@ -24,7 +25,9 @@ private: /* Simplification */ Expression * shallowReduce(Context & context, AngleUnit angleUnit) override; /* Evaluation */ - template static std::complex computeOnComplex(const std::complex c, AngleUnit angleUnit); + template static std::complex computeOnComplex(const std::complex c, AngleUnit angleUnit) { + return Trigonometry::computeInverseOnComplex(c, angleUnit, std::asin); + } Evaluation * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return ApproximationEngine::map(this, context, angleUnit, computeOnComplex); } diff --git a/poincare/include/poincare/arc_tangent.h b/poincare/include/poincare/arc_tangent.h index b88f414f0..a2ce8d00a 100644 --- a/poincare/include/poincare/arc_tangent.h +++ b/poincare/include/poincare/arc_tangent.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace Poincare { @@ -24,7 +25,9 @@ private: /* Simplification */ Expression * shallowReduce(Context& context, AngleUnit angleUnit) override; /* Evaluation */ - template static std::complex computeOnComplex(const std::complex c, AngleUnit angleUnit); + template static std::complex computeOnComplex(const std::complex c, AngleUnit angleUnit) { + return Trigonometry::computeInverseOnComplex(c, angleUnit, std::atan); + } Evaluation * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return ApproximationEngine::map(this, context, angleUnit,computeOnComplex); } diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h index 98a7a55e4..abaa2c3ef 100644 --- a/poincare/include/poincare/cosine.h +++ b/poincare/include/poincare/cosine.h @@ -17,7 +17,7 @@ public: Expression * clone() const override; float characteristicXRange(Context & context, AngleUnit angleUnit) const override; template static std::complex computeOnComplex(const std::complex c, AngleUnit angleUnit = AngleUnit::Radian) { - return Trigonometry::computeOnComplex(c, angleUnit, std::cos); + return Trigonometry::computeDirectOnComplex(c, angleUnit, std::cos); } private: /* Layout */ diff --git a/poincare/include/poincare/evaluation.h b/poincare/include/poincare/evaluation.h index 83e94d1c9..357843216 100644 --- a/poincare/include/poincare/evaluation.h +++ b/poincare/include/poincare/evaluation.h @@ -28,7 +28,7 @@ public: template class Complex : public std::complex, public Evaluation { public: - Complex(T a, T b = 0.0) : std::complex(a, b) {} + Complex(T a, T b = -0.0) : std::complex(a, b) {} Complex(std::complex c) : std::complex(c) {} static Complex Undefined() { return Complex(NAN, NAN); diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h index 6d5feb1d4..455f789ae 100644 --- a/poincare/include/poincare/sine.h +++ b/poincare/include/poincare/sine.h @@ -16,7 +16,7 @@ public: Type type() const override; Expression * clone() const override; template static std::complex computeOnComplex(const std::complex c, AngleUnit angleUnit = AngleUnit::Radian) { - return Trigonometry::computeOnComplex(c, angleUnit, std::sin); + return Trigonometry::computeDirectOnComplex(c, angleUnit, std::sin); } private: /* Layout */ diff --git a/poincare/include/poincare/tangent.h b/poincare/include/poincare/tangent.h index d957b55e1..9445a1d9b 100644 --- a/poincare/include/poincare/tangent.h +++ b/poincare/include/poincare/tangent.h @@ -27,7 +27,7 @@ private: Expression * shallowReduce(Context& context, AngleUnit angleUnit) override; /* Evaluation */ template static std::complex computeOnComplex(const std::complex c, AngleUnit angleUnit = AngleUnit::Radian) { - return Trigonometry::computeOnComplex(c, angleUnit, std::tan); + return Trigonometry::computeDirectOnComplex(c, angleUnit, std::tan); } Evaluation * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return ApproximationEngine::map(this, context, angleUnit,computeOnComplex); diff --git a/poincare/include/poincare/trigonometry.h b/poincare/include/poincare/trigonometry.h index a95cfa33f..93a4f4b0d 100644 --- a/poincare/include/poincare/trigonometry.h +++ b/poincare/include/poincare/trigonometry.h @@ -18,7 +18,8 @@ public: constexpr static int k_numberOfEntries = 37; static Expression * table(const Expression * e, Expression::Type type, Context & context, Expression::AngleUnit angleUnit); // , Function f, bool inverse template using Approximation = std::complex (*)(const std::complex&); - template static std::complex computeOnComplex(const std::complex c, Expression::AngleUnit angleUnit, Approximation approximate); + template static std::complex computeDirectOnComplex(const std::complex c, Expression::AngleUnit angleUnit, Approximation approximate); + template static std::complex computeInverseOnComplex(const std::complex c, Expression::AngleUnit angleUnit, Approximation approximate); }; } diff --git a/poincare/src/arc_cosine.cpp b/poincare/src/arc_cosine.cpp index d3a5cb893..d032aeb39 100644 --- a/poincare/src/arc_cosine.cpp +++ b/poincare/src/arc_cosine.cpp @@ -30,13 +30,4 @@ Expression * ArcCosine::shallowReduce(Context& context, AngleUnit angleUnit) { return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit); } -template -std::complex ArcCosine::computeOnComplex(const std::complex c, AngleUnit angleUnit) { - std::complex result = std::acos(c); - if (angleUnit == AngleUnit::Degree && result.imag() == 0.0) { - result *= 180/M_PI; - } - return result; -} - } diff --git a/poincare/src/arc_sine.cpp b/poincare/src/arc_sine.cpp index f24fb158d..641118c73 100644 --- a/poincare/src/arc_sine.cpp +++ b/poincare/src/arc_sine.cpp @@ -30,13 +30,4 @@ Expression * ArcSine::shallowReduce(Context& context, AngleUnit angleUnit) { return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit); } -template -std::complex ArcSine::computeOnComplex(const std::complex c, AngleUnit angleUnit) { - std::complex result = std::asin(c); - if (angleUnit == AngleUnit::Degree && result.imag() == 0.0) { - result *= 180/M_PI; - } - return result; -} - } diff --git a/poincare/src/arc_tangent.cpp b/poincare/src/arc_tangent.cpp index 7a619aaf2..e1b3eadc7 100644 --- a/poincare/src/arc_tangent.cpp +++ b/poincare/src/arc_tangent.cpp @@ -30,13 +30,4 @@ Expression * ArcTangent::shallowReduce(Context& context, AngleUnit angleUnit) { return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit); } -template -std::complex ArcTangent::computeOnComplex(const std::complex c, AngleUnit angleUnit) { - std::complex result = std::atan(c); - if (angleUnit == AngleUnit::Degree && result.imag() == 0.0) { - result *= 180/M_PI; - } - return result; -} - } diff --git a/poincare/src/trigonometry.cpp b/poincare/src/trigonometry.cpp index 45ed90edc..39eea332b 100644 --- a/poincare/src/trigonometry.cpp +++ b/poincare/src/trigonometry.cpp @@ -49,10 +49,7 @@ Expression * Trigonometry::shallowReduceDirectFunction(Expression * e, Context& } Expression::Type correspondingType = e->type() == Expression::Type::Cosine ? Expression::Type::ArcCosine : (e->type() == Expression::Type::Sine ? Expression::Type::ArcSine : Expression::Type::ArcTangent); if (e->operand(0)->type() == correspondingType) { - float trigoOp = e->operand(0)->operand(0)->approximateToScalar(context, angleUnit); - if (e->type() == Expression::Type::Tangent || (trigoOp >= -1.0f && trigoOp <= 1.0f)) { - return e->replaceWith(e->editableOperand(0)->editableOperand(0), true); - } + return e->replaceWith(e->editableOperand(0)->editableOperand(0), true); } if (e->operand(0)->sign() == Expression::Sign::Negative) { Expression * op = e->editableOperand(0); @@ -109,12 +106,6 @@ bool Trigonometry::ExpressionIsEquivalentToTangent(const Expression * e) { Expression * Trigonometry::shallowReduceInverseFunction(Expression * e, Context& context, Expression::AngleUnit angleUnit) { assert(e->type() == Expression::Type::ArcCosine || e->type() == Expression::Type::ArcSine || e->type() == Expression::Type::ArcTangent); - if (e->type() != Expression::Type::ArcTangent) { - float approxOp = e->operand(0)->approximateToScalar(context, angleUnit); - if (approxOp > 1.0f || approxOp < -1.0f) { - return e->replaceWith(new Undefined(), true); - } - } Expression::Type correspondingType = e->type() == Expression::Type::ArcCosine ? Expression::Type::Cosine : (e->type() == Expression::Type::ArcSine ? Expression::Type::Sine : Expression::Type::Tangent); float pi = angleUnit == Expression::AngleUnit::Radian ? M_PI : 180; if (e->operand(0)->type() == correspondingType) { @@ -239,9 +230,9 @@ Expression * Trigonometry::table(const Expression * e, Expression::Type type, Co } template -std::complex Trigonometry::computeOnComplex(const std::complex c, Expression::AngleUnit angleUnit, Approximation approximate) { +std::complex Trigonometry::computeDirectOnComplex(const std::complex c, Expression::AngleUnit angleUnit, Approximation approximate) { std::complex input(c); - if (angleUnit == Expression::AngleUnit::Degree && input.imag() == 0.0) { + if (angleUnit == Expression::AngleUnit::Degree) { input = input*std::complex(M_PI/180.0); } std::complex result = approximate(input); @@ -261,7 +252,18 @@ std::complex Trigonometry::computeOnComplex(const std::complex c, Expressi return result; } -template std::complex Trigonometry::computeOnComplex(const std::complex, Expression::AngleUnit, Approximation); -template std::complex Trigonometry::computeOnComplex(const std::complex, Expression::AngleUnit, Approximation); +template +std::complex Trigonometry::computeInverseOnComplex(const std::complex c, Expression::AngleUnit angleUnit, Approximation approximate) { + std::complex result = approximate(c); + if (angleUnit == Expression::AngleUnit::Degree) { + result *= 180/M_PI; + } + return result; +} + +template std::complex Trigonometry::computeDirectOnComplex(const std::complex, Expression::AngleUnit, Approximation); +template std::complex Trigonometry::computeDirectOnComplex(const std::complex, Expression::AngleUnit, Approximation); +template std::complex Trigonometry::computeInverseOnComplex(const std::complex, Expression::AngleUnit, Approximation); +template std::complex Trigonometry::computeInverseOnComplex(const std::complex, Expression::AngleUnit, Approximation); }