From a9dacd18f336ece5f2eccd2a3fe19bfb2eaafc7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 16 Oct 2017 10:21:12 +0200 Subject: [PATCH] [poincare] Merger Trigonometry and trigonometric function Change-Id: Idff99ad2db109f7085a56daf288831eb2a69aa8b --- poincare/Makefile | 1 - poincare/include/poincare/cosine.h | 6 +- poincare/include/poincare/sine.h | 6 +- .../include/poincare/trigonometric_function.h | 21 ------- poincare/include/poincare/trigonometry.h | 12 +++- poincare/src/trigonometric_function.cpp | 61 ------------------- poincare/src/trigonometry.cpp | 55 +++++++++++++++++ 7 files changed, 71 insertions(+), 91 deletions(-) delete mode 100644 poincare/include/poincare/trigonometric_function.h delete mode 100644 poincare/src/trigonometric_function.cpp diff --git a/poincare/Makefile b/poincare/Makefile index 1afff7f14..f54152165 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -77,7 +77,6 @@ objs += $(addprefix poincare/src/,\ sum.o\ symbol.o\ tangent.o\ - trigonometric_function.o\ trigonometry.o\ undefined.o\ variable_context.o\ diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h index f1d55de09..b5fb746a4 100644 --- a/poincare/include/poincare/cosine.h +++ b/poincare/include/poincare/cosine.h @@ -1,12 +1,12 @@ #ifndef POINCARE_COSINE_H #define POINCARE_COSINE_H -#include +#include namespace Poincare { -class Cosine : public TrigonometricFunction { - using TrigonometricFunction::TrigonometricFunction; +class Cosine : public Trigonometry { + using Trigonometry::Trigonometry; public: Type type() const override; Expression * clone() const override; diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h index 1463a9b9b..a7ae16d71 100644 --- a/poincare/include/poincare/sine.h +++ b/poincare/include/poincare/sine.h @@ -1,12 +1,12 @@ #ifndef POINCARE_SINE_H #define POINCARE_SINE_H -#include +#include namespace Poincare { -class Sine : public TrigonometricFunction { - using TrigonometricFunction::TrigonometricFunction; +class Sine : public Trigonometry { + using Trigonometry::Trigonometry; public: Type type() const override; Expression * clone() const override; diff --git a/poincare/include/poincare/trigonometric_function.h b/poincare/include/poincare/trigonometric_function.h deleted file mode 100644 index 0a1801a83..000000000 --- a/poincare/include/poincare/trigonometric_function.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef POINCARE_TRIGONOMETRIC_FUNCTION_H -#define POINCARE_TRIGONOMETRIC_FUNCTION_H - -#include -#include -#include -#include - -namespace Poincare { - -class TrigonometricFunction : public StaticHierarchy<1> { - using StaticHierarchy<1>::StaticHierarchy; -public: - Expression * immediateSimplify() override; -private: - virtual Trigonometry::Function trigonometricFunctionType() const = 0; -}; - -} - -#endif diff --git a/poincare/include/poincare/trigonometry.h b/poincare/include/poincare/trigonometry.h index 61aceeb08..1074dfebf 100644 --- a/poincare/include/poincare/trigonometry.h +++ b/poincare/include/poincare/trigonometry.h @@ -2,17 +2,25 @@ #define POINCARE_TRIGONOMETRY_H #include +#include +#include +#include +#include namespace Poincare { -class Trigonometry { +class Trigonometry : public StaticHierarchy<1> { + using StaticHierarchy<1>::StaticHierarchy; public: + Expression * immediateSimplify() override; + constexpr static int k_numberOfEntries = 18; +protected: enum class Function { Cosine = 0, Sine = 1, }; + virtual Function trigonometricFunctionType() const = 0; static Expression * table(const Expression * e, Function f, bool inverse); // , Function f, bool inverse - constexpr static int k_numberOfEntries = 18; }; } diff --git a/poincare/src/trigonometric_function.cpp b/poincare/src/trigonometric_function.cpp deleted file mode 100644 index 2796f55e6..000000000 --- a/poincare/src/trigonometric_function.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -extern "C" { -#include -} -#include - -namespace Poincare { - -Expression * TrigonometricFunction::immediateSimplify() { - Expression * lookup = Trigonometry::table(operand(0), trigonometricFunctionType(), false); - if (lookup != nullptr) { - return replaceWith(lookup, true); - } - if (operand(0)->sign() < 0) { - ((Expression *)operand(0))->turnIntoPositive(); - ((Expression *)operand(0))->immediateSimplify(); - if (trigonometricFunctionType() == Trigonometry::Function::Cosine) { - return immediateSimplify(); - } else if (trigonometricFunctionType() == Trigonometry::Function::Sine) { - const Expression * multOperands[2] = {new Rational(Integer(-1)), clone()}; - Multiplication * m = new Multiplication(multOperands, 2, false); - ((Expression *)m->operand(1))->immediateSimplify(); - return replaceWith(m, true)->immediateSimplify(); - } - assert(false); - } - if (operand(0)->type() == Type::Multiplication && operand(0)->operand(1)->type() == Type::Symbol && static_cast(operand(0)->operand(1))->name() == Ion::Charset::SmallPi && operand(0)->operand(0)->type() == Type::Rational) { - Rational * r = static_cast((Expression *)operand(0)->operand(0)); - // Replace argument in [0, Pi[ - if (r->denominator().isLowerThan(r->numerator())) { - IntegerDivision div = Integer::Division(r->numerator(), r->denominator()); - // For Sine, replace argument in [0, Pi/2[ - if (trigonometricFunctionType() == Trigonometry::Function::Sine && r->denominator().isLowerThan(Integer::Addition(div.remainder, div.remainder))) { - div.remainder = Integer::Subtraction(r->denominator(), div.remainder); - } - Rational * newR = new Rational(div.remainder, r->denominator()); - const_cast(operand(0))->replaceOperand(r, newR, true); - const_cast(operand(0))->immediateSimplify(); - if (Integer::Division(div.quotient, Integer(2)).remainder.isOne()) { - Expression * simplifiedCosine = immediateSimplify(); // recursive - const Expression * multOperands[2] = {new Rational(Integer(-1)), simplifiedCosine->clone()}; - Multiplication * m = new Multiplication(multOperands, 2, false); - return simplifiedCosine->replaceWith(m, true)->immediateSimplify(); - } else { - - return immediateSimplify(); // recursive - } - } - assert(r->sign() > 0); - assert(r->numerator().isLowerThan(r->denominator())); - } - return this; -} - -} diff --git a/poincare/src/trigonometry.cpp b/poincare/src/trigonometry.cpp index e23d137f3..7dba4d317 100644 --- a/poincare/src/trigonometry.cpp +++ b/poincare/src/trigonometry.cpp @@ -1,9 +1,64 @@ #include #include +#include +#include +#include +#include +#include #include +extern "C" { +#include +} +#include namespace Poincare { +Expression * Trigonometry::immediateSimplify() { + Expression * lookup = Trigonometry::table(operand(0), trigonometricFunctionType(), false); + if (lookup != nullptr) { + return replaceWith(lookup, true); + } + if (operand(0)->sign() < 0) { + ((Expression *)operand(0))->turnIntoPositive(); + ((Expression *)operand(0))->immediateSimplify(); + if (trigonometricFunctionType() == Trigonometry::Function::Cosine) { + return immediateSimplify(); + } else if (trigonometricFunctionType() == Trigonometry::Function::Sine) { + const Expression * multOperands[2] = {new Rational(Integer(-1)), clone()}; + Multiplication * m = new Multiplication(multOperands, 2, false); + ((Expression *)m->operand(1))->immediateSimplify(); + return replaceWith(m, true)->immediateSimplify(); + } + assert(false); + } + if (operand(0)->type() == Type::Multiplication && operand(0)->operand(1)->type() == Type::Symbol && static_cast(operand(0)->operand(1))->name() == Ion::Charset::SmallPi && operand(0)->operand(0)->type() == Type::Rational) { + Rational * r = static_cast((Expression *)operand(0)->operand(0)); + // Replace argument in [0, Pi[ + if (r->denominator().isLowerThan(r->numerator())) { + IntegerDivision div = Integer::Division(r->numerator(), r->denominator()); + // For Sine, replace argument in [0, Pi/2[ + if (trigonometricFunctionType() == Trigonometry::Function::Sine && r->denominator().isLowerThan(Integer::Addition(div.remainder, div.remainder))) { + div.remainder = Integer::Subtraction(r->denominator(), div.remainder); + } + Rational * newR = new Rational(div.remainder, r->denominator()); + const_cast(operand(0))->replaceOperand(r, newR, true); + const_cast(operand(0))->immediateSimplify(); + if (Integer::Division(div.quotient, Integer(2)).remainder.isOne()) { + Expression * simplifiedCosine = immediateSimplify(); // recursive + const Expression * multOperands[2] = {new Rational(Integer(-1)), simplifiedCosine->clone()}; + Multiplication * m = new Multiplication(multOperands, 2, false); + return simplifiedCosine->replaceWith(m, true)->immediateSimplify(); + } else { + + return immediateSimplify(); // recursive + } + } + assert(r->sign() > 0); + assert(r->numerator().isLowerThan(r->denominator())); + } + return this; +} + static_assert('\x89' == Ion::Charset::SmallPi, "Incorrect"); constexpr const char * cheatTable[Trigonometry::k_numberOfEntries][3] = {{"\x89", "\x89*(-2)^(-1)", "-1"},