diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 6a552fd1f..ed77f3044 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -159,6 +159,7 @@ public: static Expression ParseAndSimplify(const char * text, Context & context, Preferences::AngleUnit angleUnit); Expression simplify(Context & context, Preferences::AngleUnit angleUnit); Expression deepReduce(Context & context, Preferences::AngleUnit angleUnit); + void reduceChildren(Context & context, Preferences::AngleUnit angleUnit); /* Approximation Helper */ template static U epsilon(); diff --git a/poincare/src/confidence_interval.cpp b/poincare/src/confidence_interval.cpp index e2d413afe..9ea42baef 100644 --- a/poincare/src/confidence_interval.cpp +++ b/poincare/src/confidence_interval.cpp @@ -82,8 +82,8 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Ang matrix.addChildAtIndexInPlace(Addition(r0, sqr), 1, 1); matrix.setDimensions(1, 2); replaceWithInPlace(matrix); - Expression result = matrix.deepReduce(context, angleUnit); - return result; + matrix.reduceChildren(context, angleUnit); + return matrix; } } diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 065a3bf90..6a9c1d3b1 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -106,6 +106,7 @@ bool Expression::DependsOnVariables(const Expression e, Context & context) { } bool Expression::getLinearCoefficients(char * variables, Expression coefficients[], Expression constant[], Context & context, Preferences::AngleUnit angleUnit) const { + assert(!recursivelyMatches(IsMatrix, context)); char * x = variables; while (*x != 0) { int degree = polynomialDegree(*x); @@ -271,14 +272,15 @@ Expression Expression::simplify(Context & context, Preferences::AngleUnit angleU } Expression Expression::deepReduce(Context & context, Preferences::AngleUnit angleUnit) { - /* assert(!recursivelyMatches(IsMatrix, context)); - * We could assert that no matrix is involved but we sometimes call deepReduce - * with a matrix at root to avoid calling deepReduce on all matrix children. - * (Matrix::rowCanonize for instance) */ + assert(!IsMatrix(*this, context)); + reduceChildren(context, angleUnit); + return shallowReduce(context, angleUnit); +} + +void Expression::reduceChildren(Context & context, Preferences::AngleUnit angleUnit) { for (int i = 0; i < numberOfChildren(); i++) { childAtIndex(i).deepReduce(context, angleUnit); } - return shallowReduce(context, angleUnit); } Expression Expression::deepBeautify(Context & context, Preferences::AngleUnit angleUnit) { diff --git a/poincare/src/matrix.cpp b/poincare/src/matrix.cpp index 0ff223bc5..9bec5481b 100644 --- a/poincare/src/matrix.cpp +++ b/poincare/src/matrix.cpp @@ -160,16 +160,11 @@ int Matrix::ArrayInverse(T * array, int numberOfRows, int numberOfColumns) { } Matrix Matrix::rowCanonize(Context & context, Preferences::AngleUnit angleUnit, Multiplication determinant) { - // The matrix has to be reduced to be able to spot 0 inside it - Expression reduced = deepReduce(context, angleUnit); - // The MatrixNode should change only if one of the child is Undefined - if (reduced.type() != ExpressionNode::Type::Matrix) { - return Matrix(); - } - Matrix matrix = static_cast(reduced); + // The matrix children have to be reduced to be able to spot 0 + reduceChildren(context, angleUnit); - int m = matrix.numberOfRows(); - int n = matrix.numberOfColumns(); + int m = numberOfRows(); + int n = numberOfColumns(); int h = 0; // row pivot int k = 0; // column pivot @@ -177,7 +172,7 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::AngleUnit angleUnit, while (h < m && k < n) { // Find the first non-null pivot int iPivot = h; - while (iPivot < m && matrix.matrixChild(iPivot, k).isRationalZero()) { + while (iPivot < m && matrixChild(iPivot, k).isRationalZero()) { iPivot++; } if (iPivot == m) { @@ -189,7 +184,7 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::AngleUnit angleUnit, // Swap row h and iPivot if (iPivot != h) { for (int col = h; col < n; col++) { - matrix.swapChildrenInPlace(iPivot*n+col, h*n+col); + swapChildrenInPlace(iPivot*n+col, h*n+col); } // Update determinant: det *= -1 if (!determinant.isUninitialized()) { determinant.addChildAtIndexInPlace(Rational(-1), 0, determinant.numberOfChildren()); } @@ -201,10 +196,10 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::AngleUnit angleUnit, for (int j = k+1; j < n; j++) { Expression opHJ = matrixChild(h, j); Expression newOpHJ = Division(opHJ, divisor.clone()); - matrix.replaceChildAtIndexInPlace(h*n+j, newOpHJ); + replaceChildAtIndexInPlace(h*n+j, newOpHJ); newOpHJ = newOpHJ.shallowReduce(context, angleUnit); } - matrix.replaceChildInPlace(divisor, Rational(1)); + replaceChildInPlace(divisor, Rational(1)); /* Set to 0 all M[i][j] i != h, j > k by linear combination */ for (int i = 0; i < m; i++) { @@ -213,17 +208,17 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::AngleUnit angleUnit, for (int j = k+1; j < n; j++) { Expression opIJ = matrixChild(i, j); Expression newOpIJ = Subtraction(opIJ, Multiplication(matrixChild(h, j).clone(), factor.clone())); - matrix.replaceChildAtIndexInPlace(i*n+j, newOpIJ); + replaceChildAtIndexInPlace(i*n+j, newOpIJ); newOpIJ.childAtIndex(1).shallowReduce(context, angleUnit); newOpIJ = newOpIJ.shallowReduce(context, angleUnit); } - matrix.replaceChildAtIndexInPlace(i*n+k, Rational(0)); + replaceChildAtIndexInPlace(i*n+k, Rational(0)); } h++; k++; } } - return matrix; + return *this; } template diff --git a/poincare/src/prediction_interval.cpp b/poincare/src/prediction_interval.cpp index 979c75742..1d9c1fb52 100644 --- a/poincare/src/prediction_interval.cpp +++ b/poincare/src/prediction_interval.cpp @@ -93,7 +93,8 @@ Expression PredictionInterval::shallowReduce(Context & context, Preferences::Ang matrix.addChildAtIndexInPlace(Addition(r0.clone(), m), 1, 1); matrix.setDimensions(1, 2); replaceWithInPlace(matrix); - return matrix.deepReduce(context, angleUnit); + matrix.reduceChildren(context, angleUnit); + return matrix; } }