diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index 4b1c41a74..cc6b48a90 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -49,6 +49,8 @@ private: Expression shallowReduce(ReductionContext reductionContext) override; Expression shallowBeautify(ReductionContext reductionContext) override; Expression denominator(ExpressionNode::ReductionContext reductionContext) const override; + // Derivation + bool didDerivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override; // Approximation template static MatrixComplex computeOnMatrixAndComplex(const MatrixComplex m, const std::complex c, Preferences::ComplexFormat complexFormat) { @@ -88,6 +90,8 @@ public: void sortChildrenInPlace(NAryExpressionNode::ExpressionOrder order, Context * context, bool canBeInterrupted) { NAryExpression::sortChildrenInPlace(order, context, false, canBeInterrupted); } + // Derivation + bool didDerivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue); private: // Unit Expression removeUnit(Expression * unit); diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index fd1e9da34..e160ed064 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -8,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/poincare/src/derivative.cpp b/poincare/src/derivative.cpp index c010f2108..e24a7148b 100644 --- a/poincare/src/derivative.cpp +++ b/poincare/src/derivative.cpp @@ -179,6 +179,8 @@ Expression Derivative::shallowReduce(ExpressionNode::ReductionContext reductionC derivand = childAtIndex(0); /* Deep reduces the child, because didDerivate may not preserve its reduced * status. */ + + derivand = derivand.replaceSymbolWithExpression(symbol, symbolValue); derivand = derivand.deepReduce(reductionContext); replaceWithInPlace(derivand); return derivand; diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index a0cc74a7a..027ac8bf3 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -218,6 +219,10 @@ Expression MultiplicationNode::denominator(ReductionContext reductionContext) co return Multiplication(this).denominator(reductionContext); } +bool MultiplicationNode::didDerivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) { + return Multiplication(this).didDerivate(reductionContext, symbol, symbolValue); +} + /* Multiplication */ int Multiplication::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const { @@ -490,6 +495,26 @@ Expression Multiplication::denominator(ExpressionNode::ReductionContext reductio return denom; } +bool Multiplication::didDerivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue) { + Addition resultingAddition = Addition::Builder(); + int numberOfTerms = numberOfChildren(); + assert (numberOfTerms > 0); + Expression childI; + + for (int i = 0; i < numberOfTerms; ++i) { + childI = clone(); + childI.replaceChildAtIndexInPlace(i, Derivative::Builder( + childI.childAtIndex(i), + symbol.clone().convert(), + symbolValue.clone() + )); + resultingAddition.addChildAtIndexInPlace(childI, i, i); + } + + replaceWithInPlace(resultingAddition); + return true; +} + Expression Multiplication::privateShallowReduce(ExpressionNode::ReductionContext reductionContext, bool shouldExpand, bool canBeInterrupted) { { Expression e = Expression::defaultShallowReduce(); diff --git a/poincare/test/derivative.cpp b/poincare/test/derivative.cpp index 19f77e803..21be79100 100644 --- a/poincare/test/derivative.cpp +++ b/poincare/test/derivative.cpp @@ -26,6 +26,14 @@ QUIZ_CASE(poincare_differential_addition) { assert_parses_and_reduces_as("diff(x,x,1)", "1"); assert_parses_and_reduces_as("diff(1+2,x,1)", "0"); assert_parses_and_reduces_as("diff(a,x,1)", "0"); + assert_parses_and_reduces_as("diff(1+x,x,1)", "1"); assert_parses_and_reduces_as("diff(undef,x,1)", "undef"); + + assert_parses_and_reduces_as("diff(x+x,x,4)", "2"); + assert_parses_and_reduces_as("diff(2*x,x,1)", "2"); + assert_parses_and_reduces_as("diff(a*x,x,2)", "a"); + assert_parses_and_reduces_as("diff(a*x+b,x,x)", "a"); + + // assert_parses_and_reduces_as("diff(x*x,x,3)", "3"); } \ No newline at end of file diff --git a/poincare/test/expression_properties.cpp b/poincare/test/expression_properties.cpp index 145e533af..abdc9567d 100644 --- a/poincare/test/expression_properties.cpp +++ b/poincare/test/expression_properties.cpp @@ -216,8 +216,8 @@ QUIZ_CASE(poincare_properties_polynomial_degree) { assert_reduced_expression_polynomial_degree("x+1", 1); assert_reduced_expression_polynomial_degree("cos(2)+1", 0); assert_reduced_expression_polynomial_degree("confidence(0.2,10)+1", -1); - assert_reduced_expression_polynomial_degree("diff(3×x+x,x,2)", -1); - assert_reduced_expression_polynomial_degree("diff(3×x+x,x,x)", -1); + assert_reduced_expression_polynomial_degree("diff(3×x+x,x,2)", 0); + assert_reduced_expression_polynomial_degree("diff(3×x+x,x,x)", 0); assert_reduced_expression_polynomial_degree("diff(3×x+x,x,x)", 0, "a"); assert_reduced_expression_polynomial_degree("(3×x+2)/3", 1); assert_reduced_expression_polynomial_degree("(3×x+2)/x", -1); diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index 64175b73c..efba56df3 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -1140,7 +1140,7 @@ QUIZ_CASE(poincare_simplification_complex_format) { assert_parsed_expression_simplify_to("conj(-2+2×𝐢+𝐢)", "-2-3×𝐢", User, Radian, Cartesian); assert_parsed_expression_simplify_to("cos(12)", "cos(12)", User, Radian, Cartesian); assert_parsed_expression_simplify_to("cos(12+𝐢)", "cos(12+𝐢)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("diff(3×x, x, 3)", "diff(3×x,x,3)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("diff(3×x, x, 3)", "3", User, Radian, Cartesian); assert_parsed_expression_simplify_to("quo(34,x)", "quo(34,x)", User, Radian, Cartesian); assert_parsed_expression_simplify_to("rem(5,3)", "2", User, Radian, Cartesian); assert_parsed_expression_simplify_to("floor(x)", "floor(x)", User, Radian, Cartesian);