[poincare] Implemented didDerivate for Multiplication

Derivation propagates as expected on multiplications (but not power). Some tests involving diff had to be updated to reflect that behaviour.

Change-Id: Ifa32031bc37a156c18d296757bcdd6ccdb0ea43e
This commit is contained in:
Gabriel Ozouf
2020-05-19 16:05:06 +02:00
committed by Émilie Feral
parent c65687e9f6
commit 6f378ef3ef
7 changed files with 43 additions and 4 deletions

View File

@@ -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<typename T> static MatrixComplex<T> computeOnMatrixAndComplex(const MatrixComplex<T> m, const std::complex<T> 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);

View File

@@ -1,5 +1,6 @@
#include <poincare/addition.h>
#include <poincare/complex_cartesian.h>
#include <poincare/derivative.h>
#include <poincare/layout_helper.h>
#include <poincare/matrix.h>
#include <poincare/multiplication.h>
@@ -8,7 +9,6 @@
#include <poincare/serialization_helper.h>
#include <poincare/subtraction.h>
#include <poincare/undefined.h>
#include <poincare/derivative.h>
#include <assert.h>
#include <utility>

View File

@@ -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;

View File

@@ -1,6 +1,7 @@
#include <poincare/multiplication.h>
#include <poincare/addition.h>
#include <poincare/arithmetic.h>
#include <poincare/derivative.h>
#include <poincare/division.h>
#include <poincare/float.h>
#include <poincare/infinity.h>
@@ -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<Symbol>(),
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();

View File

@@ -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");
}

View File

@@ -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);

View File

@@ -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);