From a6648f6e1509076eedde27f016b0d151c248e37a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 9 Mar 2017 15:19:28 +0100 Subject: [PATCH 1/3] [poincare] fix typo Change-Id: Ic95a040012f5392879304601282fb3e496f5e32c --- poincare/src/matrix_inverse.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poincare/src/matrix_inverse.cpp b/poincare/src/matrix_inverse.cpp index 2090dfef6..0547d1fbb 100644 --- a/poincare/src/matrix_inverse.cpp +++ b/poincare/src/matrix_inverse.cpp @@ -38,7 +38,7 @@ Expression * MatrixInverse::privateEvaluate(Context& context, AngleUnit angleUni assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex); if (evaluation->type() == Type::Complex) { Expression * arguments[2]; - arguments[0] = new Complex(Complex::Float(2.0f)); + arguments[0] = new Complex(Complex::Float(1.0f)); arguments[1] = evaluation; Expression * result = new Fraction(arguments, true); delete arguments[0]; From 18265e2111dc17b529db4a5c2d0572ef03687bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 9 Mar 2017 15:28:30 +0100 Subject: [PATCH 2/3] [poincare] Parse trace(matrix) and dim(matrix) Change-Id: I8de073595d23c78bbea440d485d2d0d0c576fe13 --- poincare/Makefile | 2 + poincare/include/poincare.h | 4 +- poincare/include/poincare/expression.h | 2 + poincare/include/poincare/matrix.h | 2 + poincare/include/poincare/matrix_dimension.h | 22 +++++++++ poincare/include/poincare/matrix_trace.h | 21 +++++++++ poincare/src/expression_lexer.l | 2 + poincare/src/matrix.cpp | 19 ++++++++ poincare/src/matrix_dimension.cpp | 47 ++++++++++++++++++++ poincare/src/matrix_trace.cpp | 43 ++++++++++++++++++ 10 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 poincare/include/poincare/matrix_dimension.h create mode 100644 poincare/include/poincare/matrix_trace.h create mode 100644 poincare/src/matrix_dimension.cpp create mode 100644 poincare/src/matrix_trace.cpp diff --git a/poincare/Makefile b/poincare/Makefile index 8d666d12c..88f7d7512 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -34,7 +34,9 @@ objs += $(addprefix poincare/src/,\ logarithm.o\ matrix.o\ matrix_data.o\ + matrix_dimension.o\ matrix_inverse.o\ + matrix_trace.o\ matrix_transpose.o\ multiplication.o\ naperian_logarithm.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 80351bb1e..54eb9501c 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -24,12 +24,12 @@ #include #include #include -#include #include #include #include -#include +#include #include +#include #include #include #include diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 53cc072ff..ebb068970 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -33,7 +33,9 @@ public: Logarithm, LeastCommonMultiple, Matrix, + MatrixDimension, MatrixInverse, + MatrixTrace, MatrixTranspose, Multiplication, NaperianLogarithm, diff --git a/poincare/include/poincare/matrix.h b/poincare/include/poincare/matrix.h index b71b4b4c0..99c26a84e 100644 --- a/poincare/include/poincare/matrix.h +++ b/poincare/include/poincare/matrix.h @@ -23,6 +23,8 @@ public: /* If the buffer is too small, the function fills the buffer until reaching * buffer size */ int writeTextInBuffer(char * buffer, int bufferSize) override; + Expression * createDimensionMatrix(Context& context, AngleUnit angleUnit) const; + float trace(Context& context, AngleUnit angleUnit) const; float determinant(Context& context, AngleUnit angleUnit) const; Expression * createInverse(Context& context, AngleUnit angleUnit) const; Expression * createTranspose(Context& context, AngleUnit angleUnit) const; diff --git a/poincare/include/poincare/matrix_dimension.h b/poincare/include/poincare/matrix_dimension.h new file mode 100644 index 000000000..f90a1f630 --- /dev/null +++ b/poincare/include/poincare/matrix_dimension.h @@ -0,0 +1,22 @@ +#ifndef POINCARE_MATRIX_DIMENSION_H +#define POINCARE_MATRIX_DIMENSION_H + +#include + +namespace Poincare { + +class MatrixDimension : public Function { +public: + MatrixDimension(); + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; +private: + float privateApproximate(Context & context, AngleUnit angleUnit) const override; + Expression * privateEvaluate(Context& context, AngleUnit angleUnit) const override; +}; + +} + +#endif + diff --git a/poincare/include/poincare/matrix_trace.h b/poincare/include/poincare/matrix_trace.h new file mode 100644 index 000000000..fc3fd1b3d --- /dev/null +++ b/poincare/include/poincare/matrix_trace.h @@ -0,0 +1,21 @@ +#ifndef POINCARE_MATRIX_TRACE_H +#define POINCARE_MATRIX_TRACE_H + +#include + +namespace Poincare { + +class MatrixTrace : public Function { +public: + MatrixTrace(); + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; +private: + float privateApproximate(Context & context, AngleUnit angleUnit) const override; +}; + +} + +#endif + diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index b7e3005e7..b03e4620e 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -94,6 +94,7 @@ ans { poincare_expression_yylval.character = Symbol::SpecialSymbols::Ans; return arg { poincare_expression_yylval.expression = new ComplexArgument(); return FUNCTION; } binomial { poincare_expression_yylval.expression = new BinomialCoefficient(); return FUNCTION; } diff { poincare_expression_yylval.expression = new Derivative(); return FUNCTION; } +dim { poincare_expression_yylval.expression = new MatrixDimension(); return FUNCTION; } det { poincare_expression_yylval.expression = new Determinant(); return FUNCTION; } conj { poincare_expression_yylval.expression = new Conjugate(); return FUNCTION; } cos { poincare_expression_yylval.expression = new Cosine(); return FUNCTION; } @@ -116,6 +117,7 @@ sinh { poincare_expression_yylval.expression = new HyperbolicSine(); return FUNC sum { poincare_expression_yylval.expression = new Sum(); return FUNCTION; } tan { poincare_expression_yylval.expression = new Tangent(); return FUNCTION; } tanh { poincare_expression_yylval.expression = new HyperbolicTangent(); return FUNCTION; } +trace { poincare_expression_yylval.expression = new MatrixTrace(); return FUNCTION; } transpose { poincare_expression_yylval.expression = new MatrixTranspose(); return FUNCTION; } \x89 { poincare_expression_yylval.character = yytext[0]; return SYMBOL; } \x8c { return EE; } diff --git a/poincare/src/matrix.cpp b/poincare/src/matrix.cpp index acc7dfd44..97ab0ac93 100644 --- a/poincare/src/matrix.cpp +++ b/poincare/src/matrix.cpp @@ -143,6 +143,25 @@ int Matrix::writeTextInBuffer(char * buffer, int bufferSize) { return currentChar; } +Expression * Matrix::createDimensionMatrix(Context& context, AngleUnit angleUnit) const { + Expression * operands[2]; + operands[0] = new Complex(Complex::Float(numberOfRows())); + operands[1] = new Complex(Complex::Float(numberOfColumns())); + return new Matrix(new MatrixData(operands, 2, 2, 1, false)); +} + +float Matrix::trace(Context& context, AngleUnit angleUnit) const { + if (numberOfColumns() != numberOfRows()) { + return NAN; + } + int dim = numberOfRows(); + float trace = 0.0f; + for (int i = 0; i < dim; i++) { + trace += m_matrixData->operands()[i*dim+i]->approximate(context, angleUnit); + } + return trace; +} + float Matrix::determinant(Context& context, AngleUnit angleUnit) const { if (numberOfColumns() != numberOfRows()) { return NAN; diff --git a/poincare/src/matrix_dimension.cpp b/poincare/src/matrix_dimension.cpp new file mode 100644 index 000000000..7c42f0024 --- /dev/null +++ b/poincare/src/matrix_dimension.cpp @@ -0,0 +1,47 @@ +#include +#include +extern "C" { +#include +#include +} + +namespace Poincare { + +MatrixDimension::MatrixDimension() : + Function("dimension") +{ +} + +Expression::Type MatrixDimension::type() const { + return Type::MatrixDimension; +} + +Expression * MatrixDimension::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + MatrixDimension * md = new MatrixDimension(); + md->setArgument(newOperands, numberOfOperands, cloneOperands); + return md; +} + +float MatrixDimension::privateApproximate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + return NAN; +} + +Expression * MatrixDimension::privateEvaluate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + Expression * evaluation = m_args[0]->evaluate(context, angleUnit); + assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex); + if (evaluation->type() == Type::Complex) { + delete evaluation; + return nullptr; + } + Expression * dimension = ((Matrix *)evaluation)->createDimensionMatrix(context, angleUnit); + delete evaluation; + return dimension; +} + +} + diff --git a/poincare/src/matrix_trace.cpp b/poincare/src/matrix_trace.cpp new file mode 100644 index 000000000..9ad86643b --- /dev/null +++ b/poincare/src/matrix_trace.cpp @@ -0,0 +1,43 @@ +#include +#include +extern "C" { +#include +#include +} + +namespace Poincare { + +MatrixTrace::MatrixTrace() : + Function("trace") +{ +} + +Expression::Type MatrixTrace::type() const { + return Type::MatrixTrace; +} + +Expression * MatrixTrace::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + MatrixTrace * t = new MatrixTrace(); + t->setArgument(newOperands, numberOfOperands, cloneOperands); + return t; +} + +float MatrixTrace::privateApproximate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + Expression * evaluation = m_args[0]->evaluate(context, angleUnit); + assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex); + if (evaluation->type() == Type::Complex) { + float result = evaluation->approximate(context, angleUnit); + delete evaluation; + return result; + } + float trace = ((Matrix *)evaluation)->trace(context, angleUnit); + delete evaluation; + return trace; +} + +} + From 8e5e5d97ca828f6aaea941c8440ef893a8f90012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 9 Mar 2017 15:59:49 +0100 Subject: [PATCH 3/3] [poincare] Parse approximation functions (floor, ceil, frac, round) Change-Id: I54fed14f1effe2cf793ced0111db781c0c3ab06c --- poincare/Makefile | 4 +++ poincare/include/poincare.h | 4 +++ poincare/include/poincare/ceiling.h | 22 ++++++++++++++ poincare/include/poincare/expression.h | 4 +++ poincare/include/poincare/floor.h | 22 ++++++++++++++ poincare/include/poincare/frac_part.h | 22 ++++++++++++++ poincare/include/poincare/round.h | 22 ++++++++++++++ poincare/src/ceiling.cpp | 36 ++++++++++++++++++++++ poincare/src/expression_lexer.l | 4 +++ poincare/src/floor.cpp | 36 ++++++++++++++++++++++ poincare/src/frac_part.cpp | 36 ++++++++++++++++++++++ poincare/src/round.cpp | 41 ++++++++++++++++++++++++++ 12 files changed, 253 insertions(+) create mode 100644 poincare/include/poincare/ceiling.h create mode 100644 poincare/include/poincare/floor.h create mode 100644 poincare/include/poincare/frac_part.h create mode 100644 poincare/include/poincare/round.h create mode 100644 poincare/src/ceiling.cpp create mode 100644 poincare/src/floor.cpp create mode 100644 poincare/src/frac_part.cpp create mode 100644 poincare/src/round.cpp diff --git a/poincare/Makefile b/poincare/Makefile index 88f7d7512..4becc0aef 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -7,6 +7,7 @@ objs += $(addprefix poincare/src/,\ addition.o\ binary_operation.o\ binomial_coefficient.o\ + ceiling.o\ complex.o\ complex_argument.o\ conjugate.o\ @@ -18,6 +19,8 @@ objs += $(addprefix poincare/src/,\ expression.o\ expression_lexer.o\ expression_parser.o\ + floor.o\ + frac_part.o\ fraction.o\ function.o\ global_context.o\ @@ -48,6 +51,7 @@ objs += $(addprefix poincare/src/,\ preferences.o\ product.o\ reel_part.o\ + round.o\ sine.o\ square_root.o\ subtraction.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 54eb9501c..861760a73 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -14,6 +15,8 @@ #include #include #include +#include +#include #include #include #include @@ -41,6 +44,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/ceiling.h b/poincare/include/poincare/ceiling.h new file mode 100644 index 000000000..e09f04eec --- /dev/null +++ b/poincare/include/poincare/ceiling.h @@ -0,0 +1,22 @@ +#ifndef POINCARE_CEILING_H +#define POINCARE_CEILING_H + +#include + +namespace Poincare { + +class Ceiling : public Function { +public: + Ceiling(); + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; +private: + float privateApproximate(Context & context, AngleUnit angleUnit) const override; +}; + +} + +#endif + + diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index ebb068970..b00877d41 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -14,6 +14,7 @@ public: AbsoluteValue, Addition, BinomialCoefficient, + Ceiling, Complex, ComplexArgument, Conjugate, @@ -23,6 +24,8 @@ public: DivisionQuotient, DivisionRemainder, Float, + Floor, + FracPart, GreatCommonDivisor, HyperbolicCosine, HyperbolicSine, @@ -47,6 +50,7 @@ public: Power, Product, ReelPart, + Round, Sine, SquareRoot, Sum, diff --git a/poincare/include/poincare/floor.h b/poincare/include/poincare/floor.h new file mode 100644 index 000000000..da82e8a42 --- /dev/null +++ b/poincare/include/poincare/floor.h @@ -0,0 +1,22 @@ +#ifndef POINCARE_FLOOR_H +#define POINCARE_FLOOR_H + +#include + +namespace Poincare { + +class Floor : public Function { +public: + Floor(); + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; +private: + float privateApproximate(Context & context, AngleUnit angleUnit) const override; +}; + +} + +#endif + + diff --git a/poincare/include/poincare/frac_part.h b/poincare/include/poincare/frac_part.h new file mode 100644 index 000000000..d83a51336 --- /dev/null +++ b/poincare/include/poincare/frac_part.h @@ -0,0 +1,22 @@ +#ifndef POINCARE_FRAC_PART_H +#define POINCARE_FRAC_PART_H + +#include + +namespace Poincare { + +class FracPart : public Function { +public: + FracPart(); + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; +private: + float privateApproximate(Context & context, AngleUnit angleUnit) const override; +}; + +} + +#endif + + diff --git a/poincare/include/poincare/round.h b/poincare/include/poincare/round.h new file mode 100644 index 000000000..85e1bd0e1 --- /dev/null +++ b/poincare/include/poincare/round.h @@ -0,0 +1,22 @@ +#ifndef POINCARE_ROUND_H +#define POINCARE_ROUND_H + +#include + +namespace Poincare { + +class Round : public Function { +public: + Round(); + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; +private: + float privateApproximate(Context & context, AngleUnit angleUnit) const override; +}; + +} + +#endif + + diff --git a/poincare/src/ceiling.cpp b/poincare/src/ceiling.cpp new file mode 100644 index 000000000..555e6064a --- /dev/null +++ b/poincare/src/ceiling.cpp @@ -0,0 +1,36 @@ +#include + +extern "C" { +#include +#include +} + +namespace Poincare { + +Ceiling::Ceiling() : + Function("ceil") +{ +} + +Expression::Type Ceiling::type() const { + return Type::Ceiling; +} + +Expression * Ceiling::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + Ceiling * c = new Ceiling(); + c->setArgument(newOperands, numberOfOperands, cloneOperands); + return c; +} + +float Ceiling::privateApproximate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + float f = m_args[0]->approximate(context, angleUnit); + return ceilf(f); +} + +} + + diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index b03e4620e..e009d9324 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -93,12 +93,15 @@ abs { poincare_expression_yylval.expression = new AbsoluteValue(); return FUNCTI ans { poincare_expression_yylval.character = Symbol::SpecialSymbols::Ans; return SYMBOL; } arg { poincare_expression_yylval.expression = new ComplexArgument(); return FUNCTION; } binomial { poincare_expression_yylval.expression = new BinomialCoefficient(); return FUNCTION; } +ceil { poincare_expression_yylval.expression = new Ceiling(); return FUNCTION; } diff { poincare_expression_yylval.expression = new Derivative(); return FUNCTION; } dim { poincare_expression_yylval.expression = new MatrixDimension(); return FUNCTION; } det { poincare_expression_yylval.expression = new Determinant(); return FUNCTION; } conj { poincare_expression_yylval.expression = new Conjugate(); return FUNCTION; } cos { poincare_expression_yylval.expression = new Cosine(); return FUNCTION; } cosh { poincare_expression_yylval.expression = new HyperbolicCosine(); return FUNCTION; } +floor { poincare_expression_yylval.expression = new Floor(); return FUNCTION; } +frac { poincare_expression_yylval.expression = new FracPart(); return FUNCTION; } gcd { poincare_expression_yylval.expression = new GreatCommonDivisor(); return FUNCTION; } im { poincare_expression_yylval.expression = new ImaginaryPart(); return FUNCTION; } int { poincare_expression_yylval.expression = new Integral(); return FUNCTION; } @@ -112,6 +115,7 @@ quo { poincare_expression_yylval.expression = new DivisionQuotient(); return FUN re { poincare_expression_yylval.expression = new ReelPart(); return FUNCTION; } rem { poincare_expression_yylval.expression = new DivisionRemainder(); return FUNCTION; } root { poincare_expression_yylval.expression = new NthRoot(); return FUNCTION; } +round { poincare_expression_yylval.expression = new Round(); return FUNCTION; } sin { poincare_expression_yylval.expression = new Sine(); return FUNCTION; } sinh { poincare_expression_yylval.expression = new HyperbolicSine(); return FUNCTION; } sum { poincare_expression_yylval.expression = new Sum(); return FUNCTION; } diff --git a/poincare/src/floor.cpp b/poincare/src/floor.cpp new file mode 100644 index 000000000..c9abe1cc0 --- /dev/null +++ b/poincare/src/floor.cpp @@ -0,0 +1,36 @@ +#include + +extern "C" { +#include +#include +} + +namespace Poincare { + +Floor::Floor() : + Function("floor") +{ +} + +Expression::Type Floor::type() const { + return Type::Floor; +} + +Expression * Floor::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + Floor * f = new Floor(); + f->setArgument(newOperands, numberOfOperands, cloneOperands); + return f; +} + +float Floor::privateApproximate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + float f = m_args[0]->approximate(context, angleUnit); + return floorf(f); +} + +} + + diff --git a/poincare/src/frac_part.cpp b/poincare/src/frac_part.cpp new file mode 100644 index 000000000..2648176a4 --- /dev/null +++ b/poincare/src/frac_part.cpp @@ -0,0 +1,36 @@ +#include + +extern "C" { +#include +#include +} + +namespace Poincare { + +FracPart::FracPart() : + Function("frac") +{ +} + +Expression::Type FracPart::type() const { + return Type::FracPart; +} + +Expression * FracPart::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + FracPart * fp = new FracPart(); + fp->setArgument(newOperands, numberOfOperands, cloneOperands); + return fp; +} + +float FracPart::privateApproximate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + float f = m_args[0]->approximate(context, angleUnit); + return f-floorf(f); +} + +} + + diff --git a/poincare/src/round.cpp b/poincare/src/round.cpp new file mode 100644 index 000000000..09154fc4b --- /dev/null +++ b/poincare/src/round.cpp @@ -0,0 +1,41 @@ +#include + +extern "C" { +#include +#include +} + +namespace Poincare { + +Round::Round() : + Function("round") +{ +} + +Expression::Type Round::type() const { + return Type::Round; +} + +Expression * Round::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + Round * r = new Round(); + r->setArgument(newOperands, numberOfOperands, cloneOperands); + return r; +} + +float Round::privateApproximate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + float f1 = m_args[0]->approximate(context, angleUnit); + float f2 = m_args[1]->approximate(context, angleUnit); + if (isnan(f2) || f2 != (int)f2) { + return NAN; + } + float err = powf(10.0f, (int)f2); + return roundf(f1*err)/err; +} + +} + +