diff --git a/apps/math_toolbox.cpp b/apps/math_toolbox.cpp index f53eb4f9d..6b23bd5bb 100644 --- a/apps/math_toolbox.cpp +++ b/apps/math_toolbox.cpp @@ -9,7 +9,7 @@ const ToolboxNode calculChildren[4] = {ToolboxNode("diff(,)", "Nombre derive"), ToolboxNode("int(,,)", "Integrale"), ToolboxNode("sum(,,)", "Somme"), ToolboxNode("product(,,)", "Produit")}; const ToolboxNode complexChildren[5] = {ToolboxNode("abs()", "Module"), ToolboxNode("arg()", "Argument"), ToolboxNode("re()", "Partie reelle"), ToolboxNode("im()", "Partie imaginaire"), ToolboxNode("conj()", "Conjugue")}; -const ToolboxNode probabilityChildren[4] = {ToolboxNode("binomial()", "Combinaison"), ToolboxNode("permute(,)", "Arrangement"), ToolboxNode("random(,)", "Nombre aleatoire"), ToolboxNode("gamma()", "Fonction gamma")}; +const ToolboxNode probabilityChildren[2] = {ToolboxNode("binomial(,)", "Combinaison"), ToolboxNode("permute(,)", "Arrangement")}; const ToolboxNode arithmeticChildren[4] = {ToolboxNode("gcd()", "PGCD"), ToolboxNode("lcm()", "PPCM"), ToolboxNode("rem()", "Reste division euclidienne"), ToolboxNode("quo()","Quotien division euclidienne")}; const ToolboxNode matricesChildren[5] = {ToolboxNode("inverse()", "Inverse"), ToolboxNode("det()", "Determinant"), ToolboxNode("transpose()", "Transposee"), ToolboxNode("trace()", "Trace"), ToolboxNode("dim()", "Taille")}; const ToolboxNode listesChildren[5] = {ToolboxNode("sort<()", "Tri croissant"), ToolboxNode("sort>()", "Tri decroissant"), ToolboxNode("max()", "Maximum"), ToolboxNode("min()", "Minimum"), ToolboxNode("dim()", "Taille")}; @@ -18,7 +18,7 @@ const ToolboxNode trigonometryChildren[6] = {ToolboxNode("cosh()", "cosh"), Tool const ToolboxNode menu[11] = {ToolboxNode("abs()", "Valeur absolue"), ToolboxNode("root(,)", "Racine k-ieme"), ToolboxNode("log(,)", "Logarithme base a"), ToolboxNode("Calcul", nullptr, calculChildren, 4), ToolboxNode("Nombre complexe", nullptr, complexChildren, 5), - ToolboxNode("Probabilite", nullptr, probabilityChildren, 4), ToolboxNode("Arithmetique", nullptr, arithmeticChildren, 4), + ToolboxNode("Probabilite", nullptr, probabilityChildren, 2), ToolboxNode("Arithmetique", nullptr, arithmeticChildren, 4), ToolboxNode("Matrice", nullptr, matricesChildren, 5), ToolboxNode("Liste", nullptr, listesChildren, 5), ToolboxNode("Approximation", nullptr, approximationChildren, 4), ToolboxNode("Trigonometrie", nullptr, trigonometryChildren, 6)}; const ToolboxNode toolboxModel = ToolboxNode("Toolbox", nullptr, menu, 11); diff --git a/poincare/Makefile b/poincare/Makefile index 5363ada5e..a2a87fb38 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -6,9 +6,10 @@ objs += $(addprefix poincare/src/,\ absolute_value.o\ addition.o\ binary_operation.o\ - cosine.o\ complex.o\ complex_argument.o\ + conjugate.o\ + cosine.o\ derivative.o\ determinant.o\ expression.o\ @@ -50,6 +51,7 @@ objs += $(addprefix poincare/src/layout/,\ absolute_value_layout.o\ baseline_relative_layout.o\ condensed_sum_layout.o\ + conjugate_layout.o\ expression_layout.o\ fraction_layout.o\ horizontal_layout.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 45a869324..ba1302608 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/complex.h b/poincare/include/poincare/complex.h index 07c81281d..f81057ec9 100644 --- a/poincare/include/poincare/complex.h +++ b/poincare/include/poincare/complex.h @@ -22,6 +22,7 @@ public: float b(); float r() const; float th() const; + Complex * createConjugate(); /* The parameter 'DisplayMode' refers to the way to display float 'scientific' * or 'auto'. The scientific mode returns float with style -1.2E2 whereas * the auto mode tries to return 'natural' float like (0.021) and switches diff --git a/poincare/include/poincare/conjugate.h b/poincare/include/poincare/conjugate.h new file mode 100644 index 000000000..9de194f45 --- /dev/null +++ b/poincare/include/poincare/conjugate.h @@ -0,0 +1,23 @@ +#ifndef POINCARE_CONJUGATE_H +#define POINCARE_CONJUGATE_H + +#include + +namespace Poincare { + +class Conjugate : public Function { +public: + Conjugate(); + 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; + ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override; +}; + +} + +#endif + diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 545059006..493a89dd5 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -15,6 +15,7 @@ public: Addition, Complex, ComplexArgument, + Conjugate, Cosine, Derivative, Determinant, diff --git a/poincare/src/complex.cpp b/poincare/src/complex.cpp index 348246bc0..fb74ea74b 100644 --- a/poincare/src/complex.cpp +++ b/poincare/src/complex.cpp @@ -137,6 +137,10 @@ float Complex::th() const { return result; } +Complex * Complex::createConjugate() { + return new Complex(Complex::Cartesian(m_a, -m_b)); +} + int Complex::convertFloatToText(float f, char * buffer, int bufferSize, int numberOfSignificantDigits, FloatDisplayMode mode) { if (mode == FloatDisplayMode::Default) { diff --git a/poincare/src/conjugate.cpp b/poincare/src/conjugate.cpp new file mode 100644 index 000000000..e669441f5 --- /dev/null +++ b/poincare/src/conjugate.cpp @@ -0,0 +1,55 @@ +#include +#include +#include "layout/conjugate_layout.h" + +extern "C" { +#include +#include +} + +namespace Poincare { + +Conjugate::Conjugate() : + Function("conj") +{ +} + +Expression::Type Conjugate::type() const { + return Type::Conjugate; +} + +Expression * Conjugate::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + Conjugate * c = new Conjugate(); + c->setArgument(newOperands, numberOfOperands, cloneOperands); + return c; +} + +float Conjugate::privateApproximate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + return m_args[0]->approximate(context, angleUnit); +} + +Expression * Conjugate::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::Matrix) { + delete evaluation; + return new Complex(Complex::Float(NAN)); + } + Expression * result = ((Complex *)evaluation)->createConjugate(); + delete evaluation; + return result; +} + +ExpressionLayout * Conjugate::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const { + assert(floatDisplayMode != FloatDisplayMode::Default); + assert(complexFormat != ComplexFormat::Default); + return new ConjugateLayout(m_args[0]->createLayout(floatDisplayMode, complexFormat)); +} + +} + diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index 1e3b85c0f..544100b91 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; } diff { poincare_expression_yylval.expression = new Derivative(); 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; } im { poincare_expression_yylval.expression = new ImaginaryPart(); return FUNCTION; } diff --git a/poincare/src/layout/conjugate_layout.cpp b/poincare/src/layout/conjugate_layout.cpp new file mode 100644 index 000000000..ca0aa4cef --- /dev/null +++ b/poincare/src/layout/conjugate_layout.cpp @@ -0,0 +1,42 @@ +#include "conjugate_layout.h" +extern "C" { +#include +#include +} + +namespace Poincare { + +ConjugateLayout::ConjugateLayout(ExpressionLayout * operandLayout) : + ExpressionLayout(), + m_operandLayout(operandLayout) +{ + m_operandLayout->setParent(this); + m_baseline = m_operandLayout->baseline()+k_overlineWidth+k_overlineMargin; +} + +ConjugateLayout::~ConjugateLayout() { + delete m_operandLayout; +} + +void ConjugateLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) { + ctx->fillRect(KDRect(p.x(), p.y(), m_operandLayout->size().width(), k_overlineWidth), expressionColor); +} + +KDSize ConjugateLayout::computeSize() { + KDSize operandSize = m_operandLayout->size(); + return KDSize(operandSize.width(), operandSize.height()+k_overlineWidth+k_overlineMargin); +} + +ExpressionLayout * ConjugateLayout::child(uint16_t index) { + if (index == 0) { + return m_operandLayout; + } + return nullptr; +} + +KDPoint ConjugateLayout::positionOfChild(ExpressionLayout * child) { + return KDPoint(0, k_overlineWidth+k_overlineMargin); +} + +} + diff --git a/poincare/src/layout/conjugate_layout.h b/poincare/src/layout/conjugate_layout.h new file mode 100644 index 000000000..59ff5bd6f --- /dev/null +++ b/poincare/src/layout/conjugate_layout.h @@ -0,0 +1,27 @@ +#ifndef POINCARE_CONJUGATE_LAYOUT_H +#define POINCARE_CONJUGATE_LAYOUT_H + +#include +#include + +namespace Poincare { + +class ConjugateLayout : public ExpressionLayout { +public: + ConjugateLayout(ExpressionLayout * operandLayout); + ~ConjugateLayout(); +protected: + void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override; + KDSize computeSize() override; + ExpressionLayout * child(uint16_t index) override; + KDPoint positionOfChild(ExpressionLayout * child) override; +private: + constexpr static KDCoordinate k_overlineWidth = 1; + constexpr static KDCoordinate k_overlineMargin = 3; + ExpressionLayout * m_operandLayout; +}; + +} + +#endif +