From 42e4cf408dc7c5208fe870db73cb8930d2fd34fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Wed, 1 Feb 2017 16:07:56 +0100 Subject: [PATCH] [poincare] Enbale to evaluate expression in degrees or radian Change-Id: I8b08e7fa93431817559a594a1ea03d4414f0c830 --- liba/include/math.h | 4 +-- poincare/include/poincare/absolute_value.h | 2 +- poincare/include/poincare/addition.h | 10 +++--- poincare/include/poincare/binary_operation.h | 8 ++--- poincare/include/poincare/cosine.h | 2 +- poincare/include/poincare/derivative.h | 6 ++-- poincare/include/poincare/expression.h | 8 +++-- poincare/include/poincare/float.h | 4 +-- poincare/include/poincare/fraction.h | 6 ++-- poincare/include/poincare/function.h | 2 +- poincare/include/poincare/global_context.h | 2 ++ poincare/include/poincare/integer.h | 4 +-- poincare/include/poincare/integral.h | 10 +++--- poincare/include/poincare/logarithm.h | 2 +- poincare/include/poincare/matrix.h | 4 +-- poincare/include/poincare/multiplication.h | 8 ++--- .../include/poincare/naperian_logarithm.h | 2 +- poincare/include/poincare/nth_root.h | 2 +- poincare/include/poincare/opposite.h | 6 ++-- poincare/include/poincare/parenthesis.h | 4 +-- poincare/include/poincare/power.h | 4 +-- poincare/include/poincare/product.h | 2 +- poincare/include/poincare/sine.h | 2 +- poincare/include/poincare/square_root.h | 2 +- poincare/include/poincare/subtraction.h | 8 ++--- poincare/include/poincare/sum.h | 2 +- poincare/include/poincare/symbol.h | 4 +-- poincare/include/poincare/tangent.h | 2 +- poincare/src/absolute_value.cpp | 4 +-- poincare/src/addition.cpp | 32 ++++++++--------- poincare/src/binary_operation.cpp | 20 +++++------ poincare/src/cosine.cpp | 7 ++-- poincare/src/derivative.cpp | 26 +++++++------- poincare/src/float.cpp | 4 +-- poincare/src/fraction.cpp | 10 +++--- poincare/src/function.cpp | 4 +-- poincare/src/global_context.cpp | 1 + poincare/src/integer.cpp | 6 ++-- poincare/src/integral.cpp | 36 +++++++++---------- poincare/src/logarithm.cpp | 6 ++-- poincare/src/matrix.cpp | 6 ++-- poincare/src/multiplication.cpp | 16 ++++----- poincare/src/naperian_logarithm.cpp | 4 +-- poincare/src/nth_root.cpp | 4 +-- poincare/src/opposite.cpp | 16 ++++----- poincare/src/parenthesis.cpp | 8 ++--- poincare/src/power.cpp | 10 +++--- poincare/src/product.cpp | 8 ++--- poincare/src/sine.cpp | 7 ++-- poincare/src/square_root.cpp | 4 +-- poincare/src/subtraction.cpp | 18 +++++----- poincare/src/sum.cpp | 8 ++--- poincare/src/symbol.cpp | 8 ++--- poincare/src/tangent.cpp | 7 ++-- poincare/src/variable_context.cpp | 2 ++ 55 files changed, 211 insertions(+), 193 deletions(-) diff --git a/liba/include/math.h b/liba/include/math.h index 033059079..406400b05 100644 --- a/liba/include/math.h +++ b/liba/include/math.h @@ -7,8 +7,8 @@ LIBA_BEGIN_DECLS #define NAN (0.0f/0.0f) #define INFINITY __builtin_inff() -#define M_E 2.71828182845904523536028747135266250 -#define M_PI 3.14159265358979323846264338327950288 +#define M_E 2.71828182845904523536028747135266250f +#define M_PI 3.14159265358979323846264338327950288f /* The C99 standard requires isinf and isnan to be defined as macros that can * handle arbitrary precision float numbers. The names of the functions called diff --git a/poincare/include/poincare/absolute_value.h b/poincare/include/poincare/absolute_value.h index c1fd0591d..938d67f68 100644 --- a/poincare/include/poincare/absolute_value.h +++ b/poincare/include/poincare/absolute_value.h @@ -6,7 +6,7 @@ class AbsoluteValue : public Function { public: AbsoluteValue(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 7767e9f69..14e085b98 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -12,8 +12,8 @@ class Addition : public Expression { const Expression * operand(int i) const override; int numberOfOperands() const override; Type type() const override; - float approximate(Context& context) const override; - Expression * evaluate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; Expression * clone() const override; Expression * cloneWithDifferentOperands(Expression** newOperands, int numberOfOperands, bool cloneOperands = true) const override; @@ -21,9 +21,9 @@ class Addition : public Expression { bool isCommutative() const override; private: float operateApproximatevelyOn(float a, float b) const; - Expression * evaluateOn(Expression * a, Expression * b, Context& context) const; - Expression * evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context) const; - Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context) const; + Expression * evaluateOn(Expression * a, Expression * b, Context& context, AngleUnit angleUnit) const; + Expression * evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const; + Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const; const int m_numberOfOperands; Expression ** m_operands; }; diff --git a/poincare/include/poincare/binary_operation.h b/poincare/include/poincare/binary_operation.h index 7681ba6f4..1184675ff 100644 --- a/poincare/include/poincare/binary_operation.h +++ b/poincare/include/poincare/binary_operation.h @@ -12,12 +12,12 @@ class BinaryOperation : public Expression { const Expression * operand(int i) const override; int numberOfOperands() const override; Expression * clone() const override; - Expression * evaluate(Context& context) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; protected: Expression * m_operands[2]; - virtual Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context) const; - virtual Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context) const; - virtual Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context) const; + virtual Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const; + virtual Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context, AngleUnit angleUnit) const; + virtual Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const; }; #endif diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h index 56cbd747e..3460a9224 100644 --- a/poincare/include/poincare/cosine.h +++ b/poincare/include/poincare/cosine.h @@ -6,7 +6,7 @@ class Cosine : public Function { public: Cosine(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/derivative.h b/poincare/include/poincare/derivative.h index 3493edcb9..6d13704e6 100644 --- a/poincare/include/poincare/derivative.h +++ b/poincare/include/poincare/derivative.h @@ -7,13 +7,13 @@ class Derivative : public Function { public: Derivative(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; private: - float growthRateAroundAbscissa(float x, float h, VariableContext variableContext) const; - float approximateDerivate2(float x, float h, VariableContext xContext) const; + float growthRateAroundAbscissa(float x, float h, VariableContext variableContext, AngleUnit angleUnit) const; + float approximateDerivate2(float x, float h, VariableContext xContext, AngleUnit angleUnit) const; constexpr static float k_maxErrorRateOnApproximation = 0.001f; constexpr static float k_minInitialRate = 0.01f; constexpr static float k_rateStepSize = 1.4f; diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 6b6eacdab..ea4bc0080 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -37,6 +37,10 @@ class Expression { Auto = 0, Scientific = 1 }; + enum class AngleUnit { + Degree = 0, + Radian = 1 + }; static Expression * parse(char const * string); virtual ~Expression(); @@ -80,8 +84,8 @@ class Expression { virtual bool isCommutative() const; /* The function evaluate creates a new expression and thus mallocs memory. * Do not forget to delete the new expression to avoid leaking. */ - virtual Expression * evaluate(Context& context) const = 0; - virtual float approximate(Context& context) const = 0; + virtual Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const = 0; + virtual float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const = 0; virtual int writeTextInBuffer(char * buffer, int bufferSize); private: bool sequentialOperandsIdentity(const Expression * e) const; diff --git a/poincare/include/poincare/float.h b/poincare/include/poincare/float.h index 15e5df79a..8cbc75ce4 100644 --- a/poincare/include/poincare/float.h +++ b/poincare/include/poincare/float.h @@ -11,8 +11,8 @@ public: const char * exponent, int exponentLength, bool exponentNegative); ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; - float approximate(Context& context) const override; - Expression * evaluate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * clone() const override; bool valueEquals(const Expression * e) const override; diff --git a/poincare/include/poincare/fraction.h b/poincare/include/poincare/fraction.h index 1d7eac4db..6e5afb59a 100644 --- a/poincare/include/poincare/fraction.h +++ b/poincare/include/poincare/fraction.h @@ -9,13 +9,13 @@ class Fraction : public BinaryOperation { using BinaryOperation::BinaryOperation; public: ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; - float approximate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression** newOperands, int numnerOfOperands, bool cloneOperands = true) const override; private: - Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context) const override; - Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context) const override; + Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const override; + Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const override; }; #endif diff --git a/poincare/include/poincare/function.h b/poincare/include/poincare/function.h index 36319c209..103512629 100644 --- a/poincare/include/poincare/function.h +++ b/poincare/include/poincare/function.h @@ -17,7 +17,7 @@ public: const Expression * operand(int i) const override; int numberOfOperands() const override; Expression * clone() const override; - Expression * evaluate(Context& context) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; protected: Expression ** m_args; int m_numberOfArguments; diff --git a/poincare/include/poincare/global_context.h b/poincare/include/poincare/global_context.h index a2ec4bc38..aed6656e6 100644 --- a/poincare/include/poincare/global_context.h +++ b/poincare/include/poincare/global_context.h @@ -11,6 +11,8 @@ class Integer; class GlobalContext : public Context { public: GlobalContext(); + /* The expression recorded in global context is already a final expression. + * Otherwise, we would need the context and the angle unit to evaluate it */ const Expression * expressionForSymbol(const Symbol * symbol) override; void setExpressionForSymbolName(Expression * expression, const Symbol * symbol) override; static constexpr uint16_t k_maxNumberOfScalarExpressions = 26; diff --git a/poincare/include/poincare/integer.h b/poincare/include/poincare/integer.h index c6ab9a488..12e640a58 100644 --- a/poincare/include/poincare/integer.h +++ b/poincare/include/poincare/integer.h @@ -32,8 +32,8 @@ class Integer : public LeafExpression { Expression * clone() const override; virtual ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; - float approximate(Context& context) const override; - Expression * evaluate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; private: Integer add(const Integer &other, bool inverse_other_negative) const; int8_t ucmp(const Integer &other) const; // -1, 0, or 1 diff --git a/poincare/include/poincare/integral.h b/poincare/include/poincare/integral.h index beaf25765..100fa851c 100644 --- a/poincare/include/poincare/integral.h +++ b/poincare/include/poincare/integral.h @@ -7,7 +7,7 @@ class Integral : public Function { public: Integral(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; @@ -20,12 +20,12 @@ private: }; constexpr static int k_maxNumberOfIterations = 100; #ifdef LAGRANGE_METHOD - float lagrangeGaussQuadrature(float a, float b, VariableContext xContext) const; + float lagrangeGaussQuadrature(float a, float b, VariableContext xContext, AngleUnit angleUnit) const; #else - DetailedResult kronrodGaussQuadrature(float a, float b, VariableContext xContext) const; - float adaptiveQuadrature(float a, float b, float eps, int numberOfIterations, VariableContext xContext) const; + DetailedResult kronrodGaussQuadrature(float a, float b, VariableContext xContext, AngleUnit angleUnit) const; + float adaptiveQuadrature(float a, float b, float eps, int numberOfIterations, VariableContext xContext, AngleUnit angleUnit) const; #endif - float functionValueAtAbscissa(float x, VariableContext xcontext) const; + float functionValueAtAbscissa(float x, VariableContext xcontext, AngleUnit angleUnit) const; }; #endif diff --git a/poincare/include/poincare/logarithm.h b/poincare/include/poincare/logarithm.h index 77f1d943d..e229361df 100644 --- a/poincare/include/poincare/logarithm.h +++ b/poincare/include/poincare/logarithm.h @@ -6,7 +6,7 @@ class Logarithm : public Function { public: Logarithm(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/matrix.h b/poincare/include/poincare/matrix.h index 028352c30..ec326fa1b 100644 --- a/poincare/include/poincare/matrix.h +++ b/poincare/include/poincare/matrix.h @@ -14,8 +14,8 @@ class Matrix : public Expression { int numberOfOperands() const override; Expression * clone() const override; ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; - float approximate(Context& context) const override; - Expression * evaluate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression** newOperands, int numberOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index 907273ecb..f3ae554ae 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -10,13 +10,13 @@ class Multiplication : public BinaryOperation { public: Type type() const override; ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; - float approximate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; Expression * cloneWithDifferentOperands(Expression** newOperands, int numnerOfOperands, bool cloneOperands = true) const override; private: - Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context) const override; - Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context) const override; - Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context) const override; + Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const override; + Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context, AngleUnit angleUnit) const override; + Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const override; }; #endif diff --git a/poincare/include/poincare/naperian_logarithm.h b/poincare/include/poincare/naperian_logarithm.h index 34bb9bef2..35c52e17a 100644 --- a/poincare/include/poincare/naperian_logarithm.h +++ b/poincare/include/poincare/naperian_logarithm.h @@ -6,7 +6,7 @@ class NaperianLogarithm : public Function { public: NaperianLogarithm(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/nth_root.h b/poincare/include/poincare/nth_root.h index b9bb45693..9f3483e20 100644 --- a/poincare/include/poincare/nth_root.h +++ b/poincare/include/poincare/nth_root.h @@ -6,7 +6,7 @@ class NthRoot : public Function { public: NthRoot(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/opposite.h b/poincare/include/poincare/opposite.h index 828110254..04a0f414b 100644 --- a/poincare/include/poincare/opposite.h +++ b/poincare/include/poincare/opposite.h @@ -12,15 +12,15 @@ class Opposite : public Expression { const Expression * operand(int i) const override; int numberOfOperands() const override; Expression * clone() const override; - Expression * evaluate(Context& context) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; - float approximate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression** newOperands, int numnerOfOperands, bool cloneOperands = true) const override; protected: Expression * m_operand; - Expression * evaluateOnMatrix(Matrix * m, Context& context) const; + Expression * evaluateOnMatrix(Matrix * m, Context& context, AngleUnit angleUnit) const; }; #endif diff --git a/poincare/include/poincare/parenthesis.h b/poincare/include/poincare/parenthesis.h index 3c5bf103f..b6bc56089 100644 --- a/poincare/include/poincare/parenthesis.h +++ b/poincare/include/poincare/parenthesis.h @@ -11,8 +11,8 @@ class Parenthesis : public Expression { int numberOfOperands() const override; Expression * clone() const override; ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; - float approximate(Context& context) const override; - Expression * evaluate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression** newOperands, int numnerOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index 54f22e4f5..7cbe4d177 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -10,12 +10,12 @@ class Power : public BinaryOperation { using BinaryOperation::BinaryOperation; public: ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; - float approximate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression** newOperands, int numnerOfOperands, bool cloneOperands = true) const override; private: - Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context) const override; + Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const override; }; #endif diff --git a/poincare/include/poincare/product.h b/poincare/include/poincare/product.h index 248092658..d3fa3638c 100644 --- a/poincare/include/poincare/product.h +++ b/poincare/include/poincare/product.h @@ -6,7 +6,7 @@ class Product : public Function { public: Product(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h index a339c3967..4c0a13de7 100644 --- a/poincare/include/poincare/sine.h +++ b/poincare/include/poincare/sine.h @@ -6,7 +6,7 @@ class Sine : public Function { public: Sine(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/square_root.h b/poincare/include/poincare/square_root.h index abe81f2ec..9f9216f82 100644 --- a/poincare/include/poincare/square_root.h +++ b/poincare/include/poincare/square_root.h @@ -6,7 +6,7 @@ class SquareRoot : public Function { public: SquareRoot(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/subtraction.h b/poincare/include/poincare/subtraction.h index e6516dded..1ad669652 100644 --- a/poincare/include/poincare/subtraction.h +++ b/poincare/include/poincare/subtraction.h @@ -10,14 +10,14 @@ class Subtraction : public BinaryOperation { using BinaryOperation::BinaryOperation; public: ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; - float approximate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression** newOperands, int numnerOfOperands, bool cloneOperands = true) const override; private: - Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context) const override; - Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context) const override; - Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context) const override; + Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const override; + Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context, AngleUnit angleUnit) const override; + Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const override; }; #endif diff --git a/poincare/include/poincare/sum.h b/poincare/include/poincare/sum.h index 4903ae09f..b7aca7e87 100644 --- a/poincare/include/poincare/sum.h +++ b/poincare/include/poincare/sum.h @@ -6,7 +6,7 @@ class Sum : public Function { public: Sum(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/include/poincare/symbol.h b/poincare/include/poincare/symbol.h index cf33aa767..0426b347d 100644 --- a/poincare/include/poincare/symbol.h +++ b/poincare/include/poincare/symbol.h @@ -10,8 +10,8 @@ public: }; Symbol(char name); ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; - float approximate(Context& context) const override; - Expression * evaluate(Context& context) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; + Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; Type type() const override; const char name() const; Expression * clone() const override; diff --git a/poincare/include/poincare/tangent.h b/poincare/include/poincare/tangent.h index f7b817653..80e4e0f56 100644 --- a/poincare/include/poincare/tangent.h +++ b/poincare/include/poincare/tangent.h @@ -6,7 +6,7 @@ class Tangent : public Function { public: Tangent(); - float approximate(Context & context) const override; + float approximate(Context & context, AngleUnit angleUnit) const override; Type type() const override; Expression * cloneWithDifferentOperands(Expression ** newOperands, int numnerOfOperands, bool cloneOperands = true) const override; diff --git a/poincare/src/absolute_value.cpp b/poincare/src/absolute_value.cpp index 3306463e4..ea9cda0ac 100644 --- a/poincare/src/absolute_value.cpp +++ b/poincare/src/absolute_value.cpp @@ -24,8 +24,8 @@ Expression * AbsoluteValue::cloneWithDifferentOperands(Expression** newOperands, return a; } -float AbsoluteValue::approximate(Context& context) const { - return fabsf(m_args[0]->approximate(context)); +float AbsoluteValue::approximate(Context& context, AngleUnit angleUnit) const { + return fabsf(m_args[0]->approximate(context, angleUnit)); } ExpressionLayout * AbsoluteValue::createLayout(DisplayMode displayMode) const { diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 8422f241b..0d29442f6 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -45,20 +45,20 @@ Expression::Type Addition::type() const { return Type::Addition; } -float Addition::approximate(Context& context) const { - float result = m_operands[0]->approximate(context); +float Addition::approximate(Context& context, AngleUnit angleUnit) const { + float result = m_operands[0]->approximate(context, angleUnit); for (int i=1; iapproximate(context); + float next = m_operands[i]->approximate(context, angleUnit); result = this->operateApproximatevelyOn(result, next); } return result; } -Expression * Addition::evaluate(Context& context) const { - Expression * result = m_operands[0]->evaluate(context); +Expression * Addition::evaluate(Context& context, AngleUnit angleUnit) const { + Expression * result = m_operands[0]->evaluate(context, angleUnit); for (int i=1; ievaluate(context); - Expression * newResult = this->evaluateOn(result, next, context); + Expression * next = m_operands[i]->evaluate(context, angleUnit); + Expression * newResult = this->evaluateOn(result, next, context, angleUnit); delete result; result = newResult; delete next; @@ -95,7 +95,7 @@ float Addition::operateApproximatevelyOn(float a, float b) const { return a + b; } -Expression * Addition::evaluateOn(Expression * a, Expression * b, Context& context) const { +Expression * Addition::evaluateOn(Expression * a, Expression * b, Context& context, AngleUnit angleUnit) const { if (a == nullptr || b == nullptr) { return nullptr; } @@ -103,35 +103,35 @@ Expression * Addition::evaluateOn(Expression * a, Expression * b, Context& conte assert(b->type() == Type::Float || b->type() == Type::Matrix); Expression * result = nullptr; if (a->type() == Type::Float && b->type() == Type::Float) { - result = new Float(a->approximate(context) + b->approximate(context)); + result = new Float(a->approximate(context, angleUnit) + b->approximate(context, angleUnit)); } if (a->type() == Type::Float && b->type() == Type::Matrix) { - result = evaluateOnFloatAndMatrix((Float *)a, (Matrix *)b, context); + result = evaluateOnFloatAndMatrix((Float *)a, (Matrix *)b, context, angleUnit); } if (b->type() == Type::Float && a->type() == Type::Matrix) { - result = evaluateOnFloatAndMatrix((Float *)b, (Matrix *)a, context); + result = evaluateOnFloatAndMatrix((Float *)b, (Matrix *)a, context, angleUnit); } if (b->type() == Type::Matrix && a->type() == Type::Matrix) { - result = evaluateOnMatrices((Matrix *)a, (Matrix *)b, context); + result = evaluateOnMatrices((Matrix *)a, (Matrix *)b, context, angleUnit); } return result; } -Expression * Addition::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context) const { +Expression * Addition::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const { Expression * operands[m->numberOfRows() * m->numberOfColumns()]; for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) { - operands[i] = new Float(a->approximate(context) + m->operand(i)->approximate(context)); + operands[i] = new Float(a->approximate(context, angleUnit) + m->operand(i)->approximate(context, angleUnit)); } return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false); } -Expression * Addition::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context) const { +Expression * Addition::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const { if (m->numberOfColumns() != n->numberOfColumns() || m->numberOfRows() != n->numberOfRows()) { return nullptr; } Expression * operands[m->numberOfRows() * m->numberOfColumns()]; for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) { - operands[i] = new Float(m->operand(i)->approximate(context) + n->operand(i)->approximate(context)); + operands[i] = new Float(m->operand(i)->approximate(context, angleUnit) + n->operand(i)->approximate(context, angleUnit)); } return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false); } diff --git a/poincare/src/binary_operation.cpp b/poincare/src/binary_operation.cpp index 8045d72ee..fbe02f387 100644 --- a/poincare/src/binary_operation.cpp +++ b/poincare/src/binary_operation.cpp @@ -35,38 +35,38 @@ Expression * BinaryOperation::clone() const { return this->cloneWithDifferentOperands((Expression**) m_operands, 2, true); } -Expression * BinaryOperation::evaluate(Context& context) const { - Expression * leftOperandEvalutation = m_operands[0]->evaluate(context); - Expression * rightOperandEvalutation = m_operands[1]->evaluate(context); +Expression * BinaryOperation::evaluate(Context& context, AngleUnit angleUnit) const { + Expression * leftOperandEvalutation = m_operands[0]->evaluate(context, angleUnit); + Expression * rightOperandEvalutation = m_operands[1]->evaluate(context, angleUnit); if (leftOperandEvalutation == nullptr || rightOperandEvalutation == nullptr) { return nullptr; } Expression * result = nullptr; if (leftOperandEvalutation->type() == Type::Float && rightOperandEvalutation->type() == Type::Float) { - result = new Float(this->approximate(context)); + result = new Float(this->approximate(context, angleUnit)); } if (leftOperandEvalutation->type() == Type::Matrix && rightOperandEvalutation->type() == Type::Float) { - result = evaluateOnMatrixAndFloat((Matrix *)leftOperandEvalutation, (Float *)rightOperandEvalutation, context); + result = evaluateOnMatrixAndFloat((Matrix *)leftOperandEvalutation, (Float *)rightOperandEvalutation, context, angleUnit); } if (leftOperandEvalutation->type() == Type::Float && rightOperandEvalutation->type() == Type::Matrix) { - result = evaluateOnFloatAndMatrix((Float *)leftOperandEvalutation, (Matrix *)rightOperandEvalutation, context); + result = evaluateOnFloatAndMatrix((Float *)leftOperandEvalutation, (Matrix *)rightOperandEvalutation, context, angleUnit); } if (leftOperandEvalutation->type() == Type::Matrix && rightOperandEvalutation->type() == Type::Matrix) { - result = evaluateOnMatrices((Matrix *)leftOperandEvalutation, (Matrix *)rightOperandEvalutation, context); + result = evaluateOnMatrices((Matrix *)leftOperandEvalutation, (Matrix *)rightOperandEvalutation, context, angleUnit); } delete leftOperandEvalutation; delete rightOperandEvalutation; return result; } -Expression * BinaryOperation::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context) const { +Expression * BinaryOperation::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const { return nullptr; } -Expression * BinaryOperation::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context) const { +Expression * BinaryOperation::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const { return nullptr; } -Expression * BinaryOperation::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context) const { +Expression * BinaryOperation::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const { return nullptr; } diff --git a/poincare/src/cosine.cpp b/poincare/src/cosine.cpp index 5aebf641d..83557dc04 100644 --- a/poincare/src/cosine.cpp +++ b/poincare/src/cosine.cpp @@ -23,6 +23,9 @@ Expression * Cosine::cloneWithDifferentOperands(Expression** newOperands, return c; } -float Cosine::approximate(Context& context) const { - return cosf(m_args[0]->approximate(context)); +float Cosine::approximate(Context& context, AngleUnit angleUnit) const { + if (angleUnit == AngleUnit::Degree) { + return cosf(m_args[0]->approximate(context, angleUnit)*M_PI/180.0f); + } + return cosf(m_args[0]->approximate(context, angleUnit)); } diff --git a/poincare/src/derivative.cpp b/poincare/src/derivative.cpp index 014535ec1..ea1381bbf 100644 --- a/poincare/src/derivative.cpp +++ b/poincare/src/derivative.cpp @@ -26,13 +26,13 @@ Expression * Derivative::cloneWithDifferentOperands(Expression** newOperands, return d; } -float Derivative::approximate(Context& context) const { +float Derivative::approximate(Context& context, AngleUnit angleUnit) const { VariableContext xContext = VariableContext('x', &context); Symbol xSymbol = Symbol('x'); - float x = m_args[1]->approximate(context); + float x = m_args[1]->approximate(context, angleUnit); Float e = Float(x); xContext.setExpressionForSymbolName(&e, &xSymbol); - float functionValue = m_args[0]->approximate(xContext); + float functionValue = m_args[0]->approximate(xContext, angleUnit); /* Ridders' Algorithm * Blibliography: @@ -43,7 +43,7 @@ float Derivative::approximate(Context& context) const { // Initiate hh float h = fabsf(x) < FLT_MIN ? k_minInitialRate : x/1000.0f; - float f2 = approximateDerivate2(x, h, xContext); + float f2 = approximateDerivate2(x, h, xContext, angleUnit); f2 = fabsf(f2) < FLT_MIN ? k_minInitialRate : f2; float hh = sqrtf(fabsf(functionValue/(f2/(powf(h,2.0f)))))/10.0f; hh = fabsf(hh) approximate(xContext); + float expressionPlus = m_args[0]->approximate(xContext, angleUnit); e = Float(x-h); xContext.setExpressionForSymbolName(&e, &xSymbol); - float expressionMinus = m_args[0]->approximate(xContext); + float expressionMinus = m_args[0]->approximate(xContext, angleUnit); return (expressionPlus - expressionMinus)/(2*h); } -float Derivative::approximateDerivate2(float x, float h, VariableContext xContext) const { +float Derivative::approximateDerivate2(float x, float h, VariableContext xContext, AngleUnit angleUnit) const { Symbol xSymbol = Symbol('x'); Float e = Float(x + h); xContext.setExpressionForSymbolName(&e, &xSymbol); - float expressionPlus = m_args[0]->approximate(xContext); + float expressionPlus = m_args[0]->approximate(xContext, angleUnit); e = Float(x); xContext.setExpressionForSymbolName(&e, &xSymbol); - float expression = m_args[0]->approximate(xContext); + float expression = m_args[0]->approximate(xContext, angleUnit); e = Float(x-h); xContext.setExpressionForSymbolName(&e, &xSymbol); - float expressionMinus = m_args[0]->approximate(xContext); + float expressionMinus = m_args[0]->approximate(xContext, angleUnit); return expressionPlus - 2.0f*expression + expressionMinus; } diff --git a/poincare/src/float.cpp b/poincare/src/float.cpp index ddd5f093e..25a57a4f1 100644 --- a/poincare/src/float.cpp +++ b/poincare/src/float.cpp @@ -53,11 +53,11 @@ Expression * Float::clone() const { return new Float(m_float); } -float Float::approximate(Context& context) const { +float Float::approximate(Context& context, AngleUnit angleUnit) const { return m_float; } -Expression * Float::evaluate(Context& context) const { +Expression * Float::evaluate(Context& context, AngleUnit angleUnit) const { return clone(); } diff --git a/poincare/src/fraction.cpp b/poincare/src/fraction.cpp index 00a0373d8..2e26a68ad 100644 --- a/poincare/src/fraction.cpp +++ b/poincare/src/fraction.cpp @@ -17,25 +17,25 @@ ExpressionLayout * Fraction::createLayout(DisplayMode displayMode) const { return new FractionLayout(m_operands[0]->createLayout(displayMode), m_operands[1]->createLayout(displayMode)); } -float Fraction::approximate(Context& context) const { +float Fraction::approximate(Context& context, AngleUnit angleUnit) const { // TODO: handle division by zero - return m_operands[0]->approximate(context)/m_operands[1]->approximate(context); + return m_operands[0]->approximate(context, angleUnit)/m_operands[1]->approximate(context, angleUnit); } Expression::Type Fraction::type() const { return Type::Fraction; } -Expression * Fraction::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context) const { +Expression * Fraction::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const { Expression * operands[m->numberOfRows() * m->numberOfColumns()]; for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) { - operands[i] = new Float(m->operand(i)->approximate(context)/a->approximate(context)); + operands[i] = new Float(m->operand(i)->approximate(context, angleUnit)/a->approximate(context, angleUnit)); } Expression * result = new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false); return result; } -Expression * Fraction::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context) const { +Expression * Fraction::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const { if (m->numberOfColumns() != n->numberOfColumns()) { return nullptr; } diff --git a/poincare/src/function.cpp b/poincare/src/function.cpp index 64666ee7f..1f5b81afd 100644 --- a/poincare/src/function.cpp +++ b/poincare/src/function.cpp @@ -89,6 +89,6 @@ int Function::numberOfOperands() const { return m_numberOfArguments; } -Expression * Function::evaluate(Context& context) const { - return new Float(approximate(context)); +Expression * Function::evaluate(Context& context, AngleUnit angleUnit) const { + return new Float(approximate(context, angleUnit)); } diff --git a/poincare/src/global_context.cpp b/poincare/src/global_context.cpp index 999327d34..979771c33 100644 --- a/poincare/src/global_context.cpp +++ b/poincare/src/global_context.cpp @@ -41,5 +41,6 @@ const Expression * GlobalContext::expressionForSymbol(const Symbol * symbol) { void GlobalContext::setExpressionForSymbolName(Expression * expression, const Symbol * symbol) { int index = symbolIndex(symbol); + assert(expression->type() == Expression::Type::Float); m_expressions[index] = expression; } diff --git a/poincare/src/integer.cpp b/poincare/src/integer.cpp index ffa6be176..0064d4aca 100644 --- a/poincare/src/integer.cpp +++ b/poincare/src/integer.cpp @@ -257,7 +257,7 @@ Expression * Integer::clone() const { return clone; } -float Integer::approximate(Context& context) const { +float Integer::approximate(Context& context, AngleUnit angleUnit) const { union { uint32_t uint_result; float float_result; @@ -308,8 +308,8 @@ float Integer::approximate(Context& context) const { return float_result; } -Expression * Integer::evaluate(Context& context) const { - return new Float(approximate(context)); +Expression * Integer::evaluate(Context& context, AngleUnit angleUnit) const { + return new Float(approximate(context, angleUnit)); } Expression::Type Integer::type() const { diff --git a/poincare/src/integral.cpp b/poincare/src/integral.cpp index ad99cf7e6..228c130b1 100644 --- a/poincare/src/integral.cpp +++ b/poincare/src/integral.cpp @@ -30,14 +30,14 @@ Expression * Integral::cloneWithDifferentOperands(Expression** newOperands, return i; } -float Integral::approximate(Context& context) const { +float Integral::approximate(Context& context, AngleUnit angleUnit) const { VariableContext xContext = VariableContext('x', &context); - float a = m_args[1]->approximate(context); - float b = m_args[2]->approximate(context); + float a = m_args[1]->approximate(context, angleUnit); + float b = m_args[2]->approximate(context, angleUnit); #ifdef LAGRANGE_METHOD - return lagrangeGaussQuadrature(a, b, xContext); + return lagrangeGaussQuadrature(a, b, xContext, angleUnit); #else - return adaptiveQuadrature(a, b, 0.1, k_maxNumberOfIterations,xContext); + return adaptiveQuadrature(a, b, 0.1, k_maxNumberOfIterations, xContext, angleUnit); #endif } @@ -48,16 +48,16 @@ ExpressionLayout * Integral::createLayout(DisplayMode displayMode) const { return new IntegralLayout(m_args[1]->createLayout(displayMode), m_args[2]->createLayout(displayMode), new HorizontalLayout(childrenLayouts, 2)); } -float Integral::functionValueAtAbscissa(float x, VariableContext xContext) const { +float Integral::functionValueAtAbscissa(float x, VariableContext xContext, AngleUnit angleUnit) const { Float e = Float(x); Symbol xSymbol = Symbol('x'); xContext.setExpressionForSymbolName(&e, &xSymbol); - return m_args[0]->approximate(xContext); + return m_args[0]->approximate(xContext, angleUnit); } #ifdef LAGRANGE_METHOD -float Integral::lagrangeGaussQuadrature(float a, float b, VariableContext xContext) const { +float Integral::lagrangeGaussQuadrature(float a, float b, VariableContext xContext, AngleUnit angleUnit) const { /* We here use Gauss-Legendre quadrature with n = 5 * Gauss-Legendre abscissae and weights taken from * http://www.holoborodko.com/pavel/numerical-methods/numerical-integration/*/ @@ -71,7 +71,7 @@ float Integral::lagrangeGaussQuadrature(float a, float b, VariableContext xConte float result = 0.0f; for (int j = 0; j < 10; j++) { float dx = xr * x[j]; - result += w[j]*(functionValueAtAbscissa(xm+dx, xContext) + functionValueAtAbscissa(xm-dx, xContext)); + result += w[j]*(functionValueAtAbscissa(xm+dx, xContext, angleUnit) + functionValueAtAbscissa(xm-dx, xContext, angleUnit)); } result *= xr; return result; @@ -79,7 +79,7 @@ float Integral::lagrangeGaussQuadrature(float a, float b, VariableContext xConte #else -Integral::DetailedResult Integral::kronrodGaussQuadrature(float a, float b, VariableContext xContext) const { +Integral::DetailedResult Integral::kronrodGaussQuadrature(float a, float b, VariableContext xContext, AngleUnit angleUnit) const { /* We here use Kronrod-Legendre quadrature with n = 21 * The abscissa and weights are taken from QUADPACK library. */ const static float wg[5]= {0.066671344308688137593568809893332f, 0.149451349150580593145776339657697f, @@ -100,14 +100,14 @@ Integral::DetailedResult Integral::kronrodGaussQuadrature(float a, float b, Vari float dhlgth = fabsf(hlgth); float resg =0.0f; - float fc = functionValueAtAbscissa(centr, xContext); + float fc = functionValueAtAbscissa(centr, xContext, angleUnit); float resk = wgk[10]*fc; float resabs = fabsf(resk); for (int j = 0; j < 5; j++) { int jtw = 2*j+1; float absc = hlgth*xgk[jtw]; - float fval1 = functionValueAtAbscissa(centr-absc, xContext); - float fval2 = functionValueAtAbscissa(centr+absc, xContext); + float fval1 = functionValueAtAbscissa(centr-absc, xContext, angleUnit); + float fval2 = functionValueAtAbscissa(centr+absc, xContext, angleUnit); fv1[jtw] = fval1; fv2[jtw] = fval2; float fsum = fval1+fval2; @@ -118,8 +118,8 @@ Integral::DetailedResult Integral::kronrodGaussQuadrature(float a, float b, Vari for (int j = 0; j < 5; j++) { int jtwm1 = 2*j; float absc = hlgth*xgk[jtwm1]; - float fval1 = functionValueAtAbscissa(centr-absc, xContext); - float fval2 = functionValueAtAbscissa(centr+absc, xContext); + float fval1 = functionValueAtAbscissa(centr-absc, xContext, angleUnit); + float fval2 = functionValueAtAbscissa(centr+absc, xContext, angleUnit); fv1[jtwm1] = fval1; fv2[jtwm1] = fval2; float fsum = fval1+fval2; @@ -147,12 +147,12 @@ Integral::DetailedResult Integral::kronrodGaussQuadrature(float a, float b, Vari return result; } -float Integral::adaptiveQuadrature(float a, float b, float eps, int numberOfIterations, VariableContext xContext) const { - DetailedResult quadKG = kronrodGaussQuadrature(a, b, xContext); +float Integral::adaptiveQuadrature(float a, float b, float eps, int numberOfIterations, VariableContext xContext, AngleUnit angleUnit) const { + DetailedResult quadKG = kronrodGaussQuadrature(a, b, xContext, angleUnit); float result = quadKG.integral; if (numberOfIterations < k_maxNumberOfIterations && quadKG.absoluteError > eps) { float m = (a+b)/2.0f; - result = adaptiveQuadrature(a, m, eps/2.0f, numberOfIterations+1, xContext) + adaptiveQuadrature(m, b, eps/2.0f, numberOfIterations+1, xContext); + result = adaptiveQuadrature(a, m, eps/2.0f, numberOfIterations+1, xContext, angleUnit) + adaptiveQuadrature(m, b, eps/2.0f, numberOfIterations+1, xContext, angleUnit); } if (quadKG.absoluteError > eps) { return NAN; diff --git a/poincare/src/logarithm.cpp b/poincare/src/logarithm.cpp index 55bb812c8..6b87433ce 100644 --- a/poincare/src/logarithm.cpp +++ b/poincare/src/logarithm.cpp @@ -27,11 +27,11 @@ Expression * Logarithm::cloneWithDifferentOperands(Expression** newOperands, return l; } -float Logarithm::approximate(Context& context) const { +float Logarithm::approximate(Context& context, AngleUnit angleUnit) const { if (m_numberOfArguments == 1) { - return log10f(m_args[0]->approximate(context)); + return log10f(m_args[0]->approximate(context, angleUnit)); } - return log10f(m_args[1]->approximate(context))/log10f(m_args[0]->approximate(context)); + return log10f(m_args[1]->approximate(context, angleUnit))/log10f(m_args[0]->approximate(context, angleUnit)); } ExpressionLayout * Logarithm::createLayout(DisplayMode displayMode) const { diff --git a/poincare/src/matrix.cpp b/poincare/src/matrix.cpp index fc33c83fd..94c592590 100644 --- a/poincare/src/matrix.cpp +++ b/poincare/src/matrix.cpp @@ -49,14 +49,14 @@ ExpressionLayout * Matrix::createLayout(DisplayMode displayMode) const { return new MatrixLayout(childrenLayouts, numberOfRows(), numberOfColumns()); } -float Matrix::approximate(Context& context) const { +float Matrix::approximate(Context& context, AngleUnit angleUnit) const { return NAN; } -Expression * Matrix::evaluate(Context& context) const { +Expression * Matrix::evaluate(Context& context, AngleUnit angleUnit) const { Expression * operands[numberOfOperands()]; for (int i = 0; i < numberOfOperands(); i++) { - operands[i] = new Float(operand(i)->approximate(context)); + operands[i] = new Float(operand(i)->approximate(context, angleUnit)); } return new Matrix(new MatrixData(operands, numberOfOperands(), numberOfColumns(), numberOfRows(), false)); } diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 0d7a9f285..b8e703636 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -20,8 +20,8 @@ ExpressionLayout * Multiplication::createLayout(DisplayMode displayMode) const { return new HorizontalLayout(children_layouts, 3); } -float Multiplication::approximate(Context& context) const { - return m_operands[0]->approximate(context)*m_operands[1]->approximate(context);; +float Multiplication::approximate(Context& context, AngleUnit angleUnit) const { + return m_operands[0]->approximate(context, angleUnit)*m_operands[1]->approximate(context, angleUnit);; } Expression * Multiplication::cloneWithDifferentOperands(Expression** newOperands, @@ -31,19 +31,19 @@ Expression * Multiplication::cloneWithDifferentOperands(Expression** newOperands return new Multiplication(newOperands, cloneOperands); } -Expression * Multiplication::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context) const { +Expression * Multiplication::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const { Expression * operands[m->numberOfRows() * m->numberOfColumns()]; for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) { - operands[i] = new Float(m->operand(i)->approximate(context)*a->approximate(context)); + operands[i] = new Float(m->operand(i)->approximate(context, angleUnit)*a->approximate(context, angleUnit)); } return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false); } -Expression * Multiplication::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context) const { - return evaluateOnMatrixAndFloat(m, a, context); +Expression * Multiplication::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const { + return evaluateOnMatrixAndFloat(m, a, context, angleUnit); } -Expression * Multiplication::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context) const { +Expression * Multiplication::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const { if (m->numberOfColumns() != n->numberOfRows()) { return nullptr; } @@ -52,7 +52,7 @@ Expression * Multiplication::evaluateOnMatrices(Matrix * m, Matrix * n, Context& for (int j = 0; j < n->numberOfColumns(); j++) { float f = 0.0f; for (int k = 0; k < m->numberOfColumns(); k++) { - f += m->operand(i*m->numberOfColumns()+k)->approximate(context) * n->operand(k*n->numberOfColumns()+j)->approximate(context); + f += m->operand(i*m->numberOfColumns()+k)->approximate(context, angleUnit) * n->operand(k*n->numberOfColumns()+j)->approximate(context, angleUnit); } operands[i*n->numberOfColumns()+j] = new Float(f); } diff --git a/poincare/src/naperian_logarithm.cpp b/poincare/src/naperian_logarithm.cpp index 632df69c4..22f7fb6c2 100644 --- a/poincare/src/naperian_logarithm.cpp +++ b/poincare/src/naperian_logarithm.cpp @@ -26,6 +26,6 @@ Expression * NaperianLogarithm::cloneWithDifferentOperands(Expression** newOpera return l; } -float NaperianLogarithm::approximate(Context& context) const { - return log10f(m_args[0]->approximate(context))/log10f(M_E); +float NaperianLogarithm::approximate(Context& context, AngleUnit angleUnit) const { + return log10f(m_args[0]->approximate(context, angleUnit))/log10f(M_E); } diff --git a/poincare/src/nth_root.cpp b/poincare/src/nth_root.cpp index 759f6c85d..033b4fa55 100644 --- a/poincare/src/nth_root.cpp +++ b/poincare/src/nth_root.cpp @@ -24,8 +24,8 @@ Expression * NthRoot::cloneWithDifferentOperands(Expression** newOperands, return r; } -float NthRoot::approximate(Context& context) const { - return powf(m_args[0]->approximate(context), 1.0f/m_args[1]->approximate(context)); +float NthRoot::approximate(Context& context, AngleUnit angleUnit) const { + return powf(m_args[0]->approximate(context, angleUnit), 1.0f/m_args[1]->approximate(context, angleUnit)); } ExpressionLayout * NthRoot::createLayout(DisplayMode displayMode) const { diff --git a/poincare/src/opposite.cpp b/poincare/src/opposite.cpp index fd1f355d1..b5173d714 100644 --- a/poincare/src/opposite.cpp +++ b/poincare/src/opposite.cpp @@ -33,17 +33,17 @@ Expression * Opposite::clone() const { return this->cloneWithDifferentOperands((Expression**)&m_operand, 1, true); } -Expression * Opposite::evaluate(Context& context) const { - Expression * operandEvalutation = m_operand->evaluate(context); +Expression * Opposite::evaluate(Context& context, AngleUnit angleUnit) const { + Expression * operandEvalutation = m_operand->evaluate(context, angleUnit); if (operandEvalutation == nullptr) { return nullptr; } Expression * result = nullptr; if (operandEvalutation->type() == Type::Float) { - result = new Float(this->approximate(context)); + result = new Float(this->approximate(context, angleUnit)); } if (operandEvalutation->type() == Type::Matrix) { - result = evaluateOnMatrix((Matrix *)operandEvalutation, context); + result = evaluateOnMatrix((Matrix *)operandEvalutation, context, angleUnit); } delete operandEvalutation; return result; @@ -57,8 +57,8 @@ ExpressionLayout * Opposite::createLayout(DisplayMode displayMode) const { return new HorizontalLayout(children_layouts, 2); } -float Opposite::approximate(Context& context) const { - return -m_operand->approximate(context); +float Opposite::approximate(Context& context, AngleUnit angleUnit) const { + return -m_operand->approximate(context, angleUnit); } Expression::Type Opposite::type() const { @@ -72,10 +72,10 @@ Expression * Opposite::cloneWithDifferentOperands(Expression** newOperands, return new Opposite(newOperands[0], cloneOperands); } -Expression * Opposite::evaluateOnMatrix(Matrix * m, Context& context) const { +Expression * Opposite::evaluateOnMatrix(Matrix * m, Context& context, AngleUnit angleUnit) const { Expression * operands[m->numberOfRows() * m->numberOfColumns()]; for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) { - operands[i] = new Float(- m->operand(i)->approximate(context)); + operands[i] = new Float(- m->operand(i)->approximate(context, angleUnit)); } return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false); } diff --git a/poincare/src/parenthesis.cpp b/poincare/src/parenthesis.cpp index 1bd678e05..28998820e 100644 --- a/poincare/src/parenthesis.cpp +++ b/poincare/src/parenthesis.cpp @@ -35,12 +35,12 @@ ExpressionLayout * Parenthesis::createLayout(DisplayMode displayMode) const { return new ParenthesisLayout(m_operand->createLayout(displayMode)); } -float Parenthesis::approximate(Context& context) const { - return m_operand->approximate(context); +float Parenthesis::approximate(Context& context, AngleUnit angleUnit) const { + return m_operand->approximate(context, angleUnit); } -Expression * Parenthesis::evaluate(Context& context) const { - return m_operand->evaluate(context); +Expression * Parenthesis::evaluate(Context& context, AngleUnit angleUnit) const { + return m_operand->evaluate(context, angleUnit); } Expression::Type Parenthesis::type() const { diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 2beb35070..a6b30e16f 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -6,11 +6,11 @@ extern "C" { #include #include "layout/baseline_relative_layout.h" -float Power::approximate(Context& context) const { - return powf(m_operands[0]->approximate(context), m_operands[1]->approximate(context)); +float Power::approximate(Context& context, AngleUnit angleUnit) const { + return powf(m_operands[0]->approximate(context, angleUnit), m_operands[1]->approximate(context, angleUnit)); } -Expression * Power::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context) const { +Expression * Power::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const { if (m_operands[1]->type() != Expression::Type::Integer) { return nullptr; } @@ -18,14 +18,14 @@ Expression * Power::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& con return nullptr; } // TODO: return identity matrix if i == 0 - int power = a->approximate(context); + int power = a->approximate(context, angleUnit); Expression * result = new Float(1); for (int k = 0; k < power; k++) { Expression * operands[2]; operands[0] = result; operands[1] = m; Expression * multiplication = new Multiplication(operands, true); - Expression * newResult = multiplication->evaluate(context); + Expression * newResult = multiplication->evaluate(context, angleUnit); delete result; result = newResult; delete multiplication; diff --git a/poincare/src/product.cpp b/poincare/src/product.cpp index fb4f7dc79..efee469d4 100644 --- a/poincare/src/product.cpp +++ b/poincare/src/product.cpp @@ -28,16 +28,16 @@ Expression * Product::cloneWithDifferentOperands(Expression** newOperands, return p; } -float Product::approximate(Context& context) const { +float Product::approximate(Context& context, AngleUnit angleUnit) const { VariableContext nContext = VariableContext('n', &context); Symbol nSymbol = Symbol('n'); - int start = m_args[1]->approximate(context); - int end = m_args[2]->approximate(context); + int start = m_args[1]->approximate(context, angleUnit); + int end = m_args[2]->approximate(context, angleUnit); float result = 1.0f; for (int i = start; i <= end; i++) { Float iExpression = Float(i); nContext.setExpressionForSymbolName(&iExpression, &nSymbol); - result = result*m_args[0]->approximate(nContext); + result = result*m_args[0]->approximate(nContext, angleUnit); } return result; } diff --git a/poincare/src/sine.cpp b/poincare/src/sine.cpp index 2975d2e82..b82ca0f04 100644 --- a/poincare/src/sine.cpp +++ b/poincare/src/sine.cpp @@ -23,6 +23,9 @@ Expression::Type Sine::type() const { return Expression::Type::Sine; } -float Sine::approximate(Context& context) const { - return sinf(m_args[0]->approximate(context)); +float Sine::approximate(Context& context, AngleUnit angleUnit) const { + if (angleUnit == AngleUnit::Degree) { + return sinf(m_args[0]->approximate(context, angleUnit)*M_PI/180.0f); + } + return sinf(m_args[0]->approximate(context, angleUnit)); } diff --git a/poincare/src/square_root.cpp b/poincare/src/square_root.cpp index ed07983e9..aefb69cd7 100644 --- a/poincare/src/square_root.cpp +++ b/poincare/src/square_root.cpp @@ -24,8 +24,8 @@ Expression * SquareRoot::cloneWithDifferentOperands(Expression** newOperands, return sr; } -float SquareRoot::approximate(Context& context) const { - return powf(m_args[0]->approximate(context), 1.0f/2.0f); +float SquareRoot::approximate(Context& context, AngleUnit angleUnit) const { + return powf(m_args[0]->approximate(context, angleUnit), 1.0f/2.0f); } ExpressionLayout * SquareRoot::createLayout(DisplayMode displayMode) const { diff --git a/poincare/src/subtraction.cpp b/poincare/src/subtraction.cpp index a7f6a3e73..5c799bca1 100644 --- a/poincare/src/subtraction.cpp +++ b/poincare/src/subtraction.cpp @@ -15,8 +15,8 @@ Expression * Subtraction::cloneWithDifferentOperands(Expression** newOperands, return new Subtraction(newOperands, cloneOperands); } -float Subtraction::approximate(Context& context) const { - return m_operands[0]->approximate(context) - m_operands[1]->approximate(context); +float Subtraction::approximate(Context& context, AngleUnit angleUnit) const { + return m_operands[0]->approximate(context, angleUnit) - m_operands[1]->approximate(context, angleUnit); } Expression::Type Subtraction::type() const { @@ -32,32 +32,32 @@ ExpressionLayout * Subtraction::createLayout(DisplayMode displayMode) const { return new HorizontalLayout(children_layouts, 3); } -Expression * Subtraction::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context) const { +Expression * Subtraction::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const { Expression * operands[m->numberOfRows() * m->numberOfColumns()]; for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) { - operands[i] = new Float(m->operand(i)->approximate(context) - a->approximate(context)); + operands[i] = new Float(m->operand(i)->approximate(context, angleUnit) - a->approximate(context, angleUnit)); } return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false); } -Expression * Subtraction::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context) const { +Expression * Subtraction::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const { Expression * operands[m->numberOfRows() * m->numberOfColumns()]; for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) { - operands[i] = new Float(a->approximate(context) - m->operand(i)->approximate(context)); + operands[i] = new Float(a->approximate(context, angleUnit) - m->operand(i)->approximate(context, angleUnit)); } return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false); } -Expression * Subtraction::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context) const { +Expression * Subtraction::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const { if (m->numberOfColumns() != n->numberOfColumns() || m->numberOfRows() != n->numberOfRows()) { return nullptr; } Expression * operands[m->numberOfRows() * m->numberOfColumns()]; for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) { - if (!m->operand(i)->approximate(context) || !n->operand(i)->approximate(context)) { + if (!m->operand(i)->approximate(context, angleUnit) || !n->operand(i)->approximate(context, angleUnit)) { return nullptr; } - operands[i] = new Float(m->operand(i)->approximate(context) - n->operand(i)->approximate(context)); + operands[i] = new Float(m->operand(i)->approximate(context, angleUnit) - n->operand(i)->approximate(context, angleUnit)); } return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false); } diff --git a/poincare/src/sum.cpp b/poincare/src/sum.cpp index 49f005cbe..d0e22bade 100644 --- a/poincare/src/sum.cpp +++ b/poincare/src/sum.cpp @@ -28,16 +28,16 @@ Expression * Sum::cloneWithDifferentOperands(Expression** newOperands, return s; } -float Sum::approximate(Context& context) const { +float Sum::approximate(Context& context, AngleUnit angleUnit) const { VariableContext nContext = VariableContext('n', &context); Symbol nSymbol = Symbol('n'); - int start = m_args[1]->approximate(context); - int end = m_args[2]->approximate(context); + int start = m_args[1]->approximate(context, angleUnit); + int end = m_args[2]->approximate(context, angleUnit); float result = 0.0f; for (int i = start; i <= end; i++) { Float iExpression = Float(i); nContext.setExpressionForSymbolName(&iExpression, &nSymbol); - result += m_args[0]->approximate(nContext); + result += m_args[0]->approximate(nContext, angleUnit); } return result; } diff --git a/poincare/src/symbol.cpp b/poincare/src/symbol.cpp index 71bd034f2..fa26ff66d 100644 --- a/poincare/src/symbol.cpp +++ b/poincare/src/symbol.cpp @@ -11,16 +11,16 @@ Symbol::Symbol(char name) : { } -float Symbol::approximate(Context& context) const { +float Symbol::approximate(Context& context, AngleUnit angleUnit) const { if (context.expressionForSymbol(this)) { - return context.expressionForSymbol(this)->approximate(context); + return context.expressionForSymbol(this)->approximate(context, angleUnit); } // TODO: decide with Leo what we should return return NAN; } -Expression * Symbol::evaluate(Context& context) const { - return context.expressionForSymbol(this)->evaluate(context); +Expression * Symbol::evaluate(Context& context, AngleUnit angleUnit) const { + return context.expressionForSymbol(this)->evaluate(context, angleUnit); } Expression::Type Symbol::type() const { diff --git a/poincare/src/tangent.cpp b/poincare/src/tangent.cpp index 7495c3161..4ba1e12ec 100644 --- a/poincare/src/tangent.cpp +++ b/poincare/src/tangent.cpp @@ -23,6 +23,9 @@ Expression::Type Tangent::type() const { return Expression::Type::Tangent; } -float Tangent::approximate(Context& context) const { - return tanf(m_args[0]->approximate(context)); +float Tangent::approximate(Context& context, AngleUnit angleUnit) const { + if (angleUnit == AngleUnit::Degree) { + return tanf(m_args[0]->approximate(context, angleUnit)*M_PI/180.0f); + } + return tanf(m_args[0]->approximate(context, angleUnit)); } diff --git a/poincare/src/variable_context.cpp b/poincare/src/variable_context.cpp index ba0d5b7c0..c5c58996b 100644 --- a/poincare/src/variable_context.cpp +++ b/poincare/src/variable_context.cpp @@ -9,6 +9,8 @@ VariableContext::VariableContext(char name, ::Context * parentContext) : void VariableContext::setExpressionForSymbolName(Expression * expression, const Symbol * symbol) { if (symbol->name() == m_name) { + /* WARNING: we here assume that the expression does not content any function + * whose evaluation depends on the angle unit */ m_value = Float(expression->approximate(*m_parentContext)); } else { m_parentContext->setExpressionForSymbolName(expression, symbol);