From 768539d1e8eee28a2a0d6478eadae751d2423762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 27 Aug 2018 12:11:06 +0200 Subject: [PATCH] [poincare] Conjugate --- poincare/Makefile | 1 + poincare/include/poincare.h | 1 + poincare/include/poincare/conjugate.h | 48 +++++++++++++++++++-------- poincare/src/conjugate.cpp | 46 ++++++++++++++----------- poincare/src/expression_lexer.l | 2 +- poincare/test/function.cpp | 10 +++--- 6 files changed, 70 insertions(+), 38 deletions(-) diff --git a/poincare/Makefile b/poincare/Makefile index a6a767543..71fdfd45e 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -46,6 +46,7 @@ objs += $(addprefix poincare/src/,\ complex.o\ complex_argument.o\ confidence_interval.o\ + conjugate.o\ cosine.o\ decimal.o\ derivative.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 794cd5725..5f6fd5277 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -114,6 +114,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/conjugate.h b/poincare/include/poincare/conjugate.h index 265b3eeee..8afc697b3 100644 --- a/poincare/include/poincare/conjugate.h +++ b/poincare/include/poincare/conjugate.h @@ -1,26 +1,36 @@ #ifndef POINCARE_CONJUGATE_H #define POINCARE_CONJUGATE_H -#include #include -#include +#include namespace Poincare { -class Conjugate : public StaticHierarchy<1> { - using StaticHierarchy<1>::StaticHierarchy; +class ConjugateNode : public ExpressionNode { public: - Type type() const override; -private: - /* Layout */ - LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; - int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "conj"); + // Allocation Failure + static ConjugateNode * FailedAllocationStaticNode(); + ConjugateNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); } + + // TreeNode + size_t size() const override { return sizeof(ConjugateNode); } + int numberOfChildren() const override { return 1; } +#if POINCARE_TREE_LOG + virtual void logNodeName(std::ostream & stream) const override { + stream << "Conjugate"; } - /* Simplification */ +#endif + + // Properties + Type type() const override { return Type::Conjugate; } +private: + // Layout + LayoutReference createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; + int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; + // Simplification Expression shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const override; - /* Evaluation */ - template static std::complex computeOnComplex(const std::complex c, Preferences::AngleUnit angleUnit); + // Evaluation + template static Complex computeOnComplex(const std::complex c, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, angleUnit,computeOnComplex); } @@ -29,6 +39,18 @@ private: } }; +class Conjugate : public Expression { +public: + Conjugate() : Expression(TreePool::sharedPool()->createTreeNode()) {} + Conjugate(const ConjugateNode * n) : Expression(n) {} + Conjugate(Expression operand) : Conjugate() { + replaceChildAtIndexInPlace(0, operand); + } + + Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit) const; +}; + + } #endif diff --git a/poincare/src/conjugate.cpp b/poincare/src/conjugate.cpp index 0f4a4d2c3..17aedab1b 100644 --- a/poincare/src/conjugate.cpp +++ b/poincare/src/conjugate.cpp @@ -1,44 +1,50 @@ #include -#include #include +#include +#include #include #include namespace Poincare { -ExpressionNode::Type Conjugate::type() const { - return Type::Conjugate; +ConjugateNode * ConjugateNode::FailedAllocationStaticNode() { + static AllocationFailureExpressionNode failure; + TreePool::sharedPool()->registerStaticNodeIfRequired(&failure); + return &failure; } -Expression * Conjugate::clone() const { - Conjugate * a = new Conjugate(m_operands, true); - return a; -} - -LayoutRef Conjugate::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { +LayoutRef ConjugateNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return ConjugateLayoutRef(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits)); } +int ConjugateNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "conj"); +} + +Expression ConjugateNode::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const { + return Conjugate(this).shallowReduce(context, angleUnit); +} + +template +Complex ConjugateNode::computeOnComplex(const std::complex c, Preferences::AngleUnit angleUnit) { + return Complex(std::conj(c)); +} + Expression Conjugate::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const { Expression e = Expression::defaultShallowReduce(context, angleUnit); if (e.isUndefinedOrAllocationFailure()) { return e; } - Expression * op = childAtIndex(0); + Expression c = childAtIndex(0); #if MATRIX_EXACT_REDUCING - if (op->type() == Type::Matrix) { - return SimplificationHelper::Map(this, context, angleUnit); + if (c.type() == ExpressionNode::Type::Matrix) { + return SimplificationHelper::Map(*this, context, angleUnit); } #endif - if (op->type() == Type::Rational) { - return replaceWith(op, true); + if (c.type() == ExpressionNode::Type::Rational) { + return c; } - return this; -} - -template -std::complex Conjugate::computeOnComplex(const std::complex c, Preferences::AngleUnit angleUnit) { - return std::conj(c); + return *this; } } diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index 25b65602e..dba2a1768 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -126,8 +126,8 @@ confidence { poincare_expression_yylval.expression = ConfidenceInterval(); retur /*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; } */ +conj { poincare_expression_yylval.expression = Conjugate(); return FUNCTION; } cos { poincare_expression_yylval.expression = Cosine(); return FUNCTION; } cosh { poincare_expression_yylval.expression = HyperbolicCosine(); return FUNCTION; } /*factor { poincare_expression_yylval.expression = new Factor(); return FUNCTION; } diff --git a/poincare/test/function.cpp b/poincare/test/function.cpp index 2a83d177a..c5f6b31c9 100644 --- a/poincare/test/function.cpp +++ b/poincare/test/function.cpp @@ -28,8 +28,8 @@ QUIZ_CASE(poincare_parse_function) { #endif #endif assert_parsed_expression_type("confidence(0.1, 100)", ExpressionNode::Type::ConfidenceInterval); -#if 0 assert_parsed_expression_type("conj(2)", ExpressionNode::Type::Conjugate); +#if 0 assert_parsed_expression_type("factor(23/42)", ExpressionNode::Type::Factor); assert_parsed_expression_type("floor(2.3)", ExpressionNode::Type::Floor); assert_parsed_expression_type("frac(2.3)", ExpressionNode::Type::FracPart); @@ -152,15 +152,17 @@ QUIZ_CASE(poincare_function_evaluate) { assert_parsed_expression_evaluates_to("confidence(0.1, 100)", "[[0,0.2]]"); assert_parsed_expression_evaluates_to("confidence(0.1, 100)", "[[0,0.2]]"); -#if 0 +#if 0 #if MATRICES_ARE_DEFINED assert_parsed_expression_evaluates_to("dim([[1,2,3][4,5,-6]])", "[[2,3]]"); assert_parsed_expression_evaluates_to("dim([[1,2,3][4,5,-6]])", "[[2,3]]"); +#endif #endif assert_parsed_expression_evaluates_to("conj(3+2*I)", "3-2*I"); assert_parsed_expression_evaluates_to("conj(3+2*I)", "3-2*I"); +#if 0 #if MATRICES_ARE_DEFINED assert_parsed_expression_evaluates_to("inverse([[1,2,3][4,5,-6][7,8,9]])", "[[-1.2917,-0.083333,0.375][1.0833,0.16667,-0.25][0.041667,-0.083333,0.041667]]", Degree, Cartesian, 5); // inverse is not precise enough to display 7 significative digits @@ -242,9 +244,9 @@ QUIZ_CASE(poincare_function_simplify) { assert_parsed_expression_simplify_to("binomial(20,3)", "1140"); assert_parsed_expression_simplify_to("binomial(20,10)", "184756"); assert_parsed_expression_simplify_to("ceil(-1.3)", "-1"); -#if 0 assert_parsed_expression_simplify_to("conj(1/2)", "1/2"); - assert_parsed_expression_simplify_to("quo(19,3)", "6"); +#if 0 + assert_parsed_expression_simplify_to("quo(19,3)", "6"); assert_parsed_expression_simplify_to("quo(19,0)", "undef"); assert_parsed_expression_simplify_to("quo(-19,3)", "-7"); assert_parsed_expression_simplify_to("rem(19,3)", "1");