From 37dd3db06ef5fe9438beebfdb231ffed334e4950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 17 Nov 2017 12:05:32 +0100 Subject: [PATCH] [poincare] Do not simplify expressions with matrix Change-Id: I0b4c5fabf3e0669c50ecefc95a2896e945b8c5d9 --- .../include/poincare/simplification_engine.h | 4 ++ poincare/src/absolute_value.cpp | 2 + poincare/src/addition.cpp | 2 + poincare/src/arc_cosine.cpp | 2 + poincare/src/arc_sine.cpp | 2 + poincare/src/arc_tangent.cpp | 2 + poincare/src/binomial_coefficient.cpp | 2 + poincare/src/ceiling.cpp | 2 + poincare/src/complex_argument.cpp | 2 + poincare/src/confidence_interval.cpp | 2 + poincare/src/conjugate.cpp | 2 + poincare/src/cosine.cpp | 2 + poincare/src/derivative.cpp | 2 + poincare/src/determinant.cpp | 4 ++ poincare/src/division_quotient.cpp | 2 + poincare/src/division_remainder.cpp | 2 + poincare/src/expression.cpp | 6 +++ poincare/src/factorial.cpp | 2 + poincare/src/floor.cpp | 2 + poincare/src/frac_part.cpp | 2 + poincare/src/great_common_divisor.cpp | 2 + poincare/src/hyperbolic_arc_cosine.cpp | 2 + poincare/src/hyperbolic_arc_sine.cpp | 2 + poincare/src/hyperbolic_arc_tangent.cpp | 2 + poincare/src/hyperbolic_cosine.cpp | 2 + poincare/src/hyperbolic_sine.cpp | 2 + poincare/src/hyperbolic_tangent.cpp | 2 + poincare/src/imaginary_part.cpp | 2 + poincare/src/integral.cpp | 2 + poincare/src/least_common_multiple.cpp | 2 + poincare/src/logarithm.cpp | 2 + poincare/src/matrix_dimension.cpp | 5 ++ poincare/src/matrix_inverse.cpp | 5 ++ poincare/src/matrix_trace.cpp | 4 ++ poincare/src/matrix_transpose.cpp | 4 ++ poincare/src/multiplication.cpp | 4 +- poincare/src/naperian_logarithm.cpp | 2 + poincare/src/nth_root.cpp | 2 + poincare/src/opposite.cpp | 2 + poincare/src/permute_coefficient.cpp | 2 + poincare/src/power.cpp | 2 + poincare/src/prediction_interval.cpp | 2 + poincare/src/real_part.cpp | 2 + poincare/src/round.cpp | 2 + poincare/src/simplification_engine.cpp | 4 ++ poincare/src/sine.cpp | 2 + poincare/src/square_root.cpp | 2 + poincare/src/tangent.cpp | 2 + poincare/test/simplify_easy.cpp | 48 ++++++++++++------- 49 files changed, 149 insertions(+), 17 deletions(-) diff --git a/poincare/include/poincare/simplification_engine.h b/poincare/include/poincare/simplification_engine.h index 11c1f6bb7..95d22c72d 100644 --- a/poincare/include/poincare/simplification_engine.h +++ b/poincare/include/poincare/simplification_engine.h @@ -1,6 +1,8 @@ #ifndef POINCARE_SIMPLIFICATION_ENGINE_H #define POINCARE_SIMPLIFICATION_ENGINE_H +#if MATRIX_EXACT_REDUCING + #include namespace Poincare { @@ -14,3 +16,5 @@ public: } #endif + +#endif diff --git a/poincare/src/absolute_value.cpp b/poincare/src/absolute_value.cpp index 55b436534..62bbe0000 100644 --- a/poincare/src/absolute_value.cpp +++ b/poincare/src/absolute_value.cpp @@ -36,9 +36,11 @@ Expression * AbsoluteValue::shallowReduce(Context& context, AngleUnit angleUnit) return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif if (op->sign() == Sign::Positive) { return replaceWith(op, true); } diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 076617900..76dc319b0 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -46,6 +46,7 @@ Expression * Addition::shallowReduce(Context& context, AngleUnit angleUnit) { // Step 2: Sort the operands sortOperands(Expression::SimplificationOrder); +#if MATRIX_EXACT_REDUCING /* Step 2bis: get rid of matrix */ int n = 1; int m = 1; @@ -92,6 +93,7 @@ Expression * Addition::shallowReduce(Context& context, AngleUnit angleUnit) { } return replaceWith(resultMatrix, true)->shallowReduce(context, angleUnit); } +#endif /* Step 3: Factorize like terms. Thanks to the simplification order, those are * next to each other at this point. */ diff --git a/poincare/src/arc_cosine.cpp b/poincare/src/arc_cosine.cpp index 63b347569..13fc28d2e 100644 --- a/poincare/src/arc_cosine.cpp +++ b/poincare/src/arc_cosine.cpp @@ -22,9 +22,11 @@ Expression * ArcCosine::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING if (operand(0)->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit); } diff --git a/poincare/src/arc_sine.cpp b/poincare/src/arc_sine.cpp index 4117abef7..a593e92f1 100644 --- a/poincare/src/arc_sine.cpp +++ b/poincare/src/arc_sine.cpp @@ -22,9 +22,11 @@ Expression * ArcSine::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING if (operand(0)->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit); } diff --git a/poincare/src/arc_tangent.cpp b/poincare/src/arc_tangent.cpp index 676246bc4..7d5fd6d96 100644 --- a/poincare/src/arc_tangent.cpp +++ b/poincare/src/arc_tangent.cpp @@ -22,9 +22,11 @@ Expression * ArcTangent::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING if (operand(0)->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit); } diff --git a/poincare/src/binomial_coefficient.cpp b/poincare/src/binomial_coefficient.cpp index 3531bcd3e..4b5ec7151 100644 --- a/poincare/src/binomial_coefficient.cpp +++ b/poincare/src/binomial_coefficient.cpp @@ -29,9 +29,11 @@ Expression * BinomialCoefficient::shallowReduce(Context& context, AngleUnit angl } Expression * op0 = editableOperand(0); Expression * op1 = editableOperand(1); +#if MATRIX_EXACT_REDUCING if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif if (op0->type() == Type::Rational) { Rational * r0 = static_cast(op0); if (!r0->denominator().isOne() || r0->numerator().isNegative()) { diff --git a/poincare/src/ceiling.cpp b/poincare/src/ceiling.cpp index 28b3bbd3c..629c2a5bc 100644 --- a/poincare/src/ceiling.cpp +++ b/poincare/src/ceiling.cpp @@ -25,9 +25,11 @@ Expression * Ceiling::shallowReduce(Context& context, AngleUnit angleUnit) { return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif if (op->type() == Type::Symbol) { Symbol * s = static_cast(op); if (s->name() == Ion::Charset::SmallPi) { diff --git a/poincare/src/complex_argument.cpp b/poincare/src/complex_argument.cpp index d2de2a55a..99d0c4d4f 100644 --- a/poincare/src/complex_argument.cpp +++ b/poincare/src/complex_argument.cpp @@ -22,10 +22,12 @@ Expression * ComplexArgument::shallowReduce(Context& context, AngleUnit angleUni if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return this; } diff --git a/poincare/src/confidence_interval.cpp b/poincare/src/confidence_interval.cpp index e57364552..da8d00913 100644 --- a/poincare/src/confidence_interval.cpp +++ b/poincare/src/confidence_interval.cpp @@ -28,9 +28,11 @@ Expression * ConfidenceInterval::shallowReduce(Context& context, AngleUnit angle } Expression * op0 = editableOperand(0); Expression * op1 = editableOperand(1); +#if MATRIX_EXACT_REDUCING if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif if (op0->type() == Type::Rational) { Rational * r0 = static_cast(op0); if (r0->numerator().isNegative() || Integer::NaturalOrder(r0->numerator(), r0->denominator()) > 0) { diff --git a/poincare/src/conjugate.cpp b/poincare/src/conjugate.cpp index ffcddc39d..0944df809 100644 --- a/poincare/src/conjugate.cpp +++ b/poincare/src/conjugate.cpp @@ -31,9 +31,11 @@ Expression * Conjugate::shallowReduce(Context& context, AngleUnit angleUnit) { return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif if (op->type() == Type::Rational) { return replaceWith(op, true); } diff --git a/poincare/src/cosine.cpp b/poincare/src/cosine.cpp index e68ed1edc..38ce65d52 100644 --- a/poincare/src/cosine.cpp +++ b/poincare/src/cosine.cpp @@ -27,10 +27,12 @@ Expression * Cosine::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return Trigonometry::shallowReduceDirectFunction(this, context, angleUnit); } diff --git a/poincare/src/derivative.cpp b/poincare/src/derivative.cpp index 4694b1646..141146620 100644 --- a/poincare/src/derivative.cpp +++ b/poincare/src/derivative.cpp @@ -25,9 +25,11 @@ Expression * Derivative::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING if (operand(0)->type() == Type::Matrix || operand(1)->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif // TODO: to be implemented diff(+) -> +diff() etc return this; } diff --git a/poincare/src/determinant.cpp b/poincare/src/determinant.cpp index 8a907a790..cf19a054a 100644 --- a/poincare/src/determinant.cpp +++ b/poincare/src/determinant.cpp @@ -22,10 +22,14 @@ Expression * Determinant::shallowReduce(Context& context, AngleUnit angleUnit) { return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (!op->recursivelyMatches(Expression::IsMatrix)) { return replaceWith(op, true); } return this; +#else + return replaceWith(op, true); +#endif } // TODO: handle this exactly in shallowReduce for small dimensions. diff --git a/poincare/src/division_quotient.cpp b/poincare/src/division_quotient.cpp index 394be25fa..7f36ba10e 100644 --- a/poincare/src/division_quotient.cpp +++ b/poincare/src/division_quotient.cpp @@ -25,9 +25,11 @@ Expression * DivisionQuotient::shallowReduce(Context& context, AngleUnit angleUn } Expression * op0 = editableOperand(0); Expression * op1 = editableOperand(1); +#if MATRIX_EXACT_REDUCING if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif if (op0->type() == Type::Rational) { Rational * r0 = static_cast(op0); if (!r0->denominator().isOne()) { diff --git a/poincare/src/division_remainder.cpp b/poincare/src/division_remainder.cpp index ffba4c311..02caf8997 100644 --- a/poincare/src/division_remainder.cpp +++ b/poincare/src/division_remainder.cpp @@ -25,9 +25,11 @@ Expression * DivisionRemainder::shallowReduce(Context& context, AngleUnit angleU } Expression * op0 = editableOperand(0); Expression * op1 = editableOperand(1); +#if MATRIX_EXACT_REDUCING if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif if (op0->type() == Type::Rational) { Rational * r0 = static_cast(op0); if (!r0->denominator().isOne()) { diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 9735cc2cf..02bf5a816 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -131,6 +131,12 @@ void Expression::Simplify(Expression ** expressionAddress, Context & context, An if (angleUnit == AngleUnit::Default) { angleUnit = Preferences::sharedPreferences()->angleUnit(); } +#if MATRIX_EXACT_REDUCING +#else + if ((*expressionAddress)->recursivelyMatches(IsMatrix)) { + return; + } +#endif SimplificationRoot root(*expressionAddress); root.editableOperand(0)->deepReduce(context, angleUnit); root.editableOperand(0)->deepBeautify(context, angleUnit); diff --git a/poincare/src/factorial.cpp b/poincare/src/factorial.cpp index 6fced1e5c..3139a16fb 100644 --- a/poincare/src/factorial.cpp +++ b/poincare/src/factorial.cpp @@ -32,9 +32,11 @@ Expression * Factorial::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING if (operand(0)->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif if (operand(0)->type() == Type::Rational) { Rational * r = static_cast(editableOperand(0)); if (!r->denominator().isOne()) { diff --git a/poincare/src/floor.cpp b/poincare/src/floor.cpp index 48c45a823..ac2efea9a 100644 --- a/poincare/src/floor.cpp +++ b/poincare/src/floor.cpp @@ -25,9 +25,11 @@ Expression * Floor::shallowReduce(Context& context, AngleUnit angleUnit) { return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif if (op->type() == Type::Symbol) { Symbol * s = static_cast(op); if (s->name() == Ion::Charset::SmallPi) { diff --git a/poincare/src/frac_part.cpp b/poincare/src/frac_part.cpp index f35d7c1ca..0231b4e75 100644 --- a/poincare/src/frac_part.cpp +++ b/poincare/src/frac_part.cpp @@ -23,9 +23,11 @@ Expression * FracPart::shallowReduce(Context& context, AngleUnit angleUnit) { return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif if (op->type() != Type::Rational) { return this; } diff --git a/poincare/src/great_common_divisor.cpp b/poincare/src/great_common_divisor.cpp index 64eb1191b..46e8dd079 100644 --- a/poincare/src/great_common_divisor.cpp +++ b/poincare/src/great_common_divisor.cpp @@ -27,9 +27,11 @@ Expression * GreatCommonDivisor::shallowReduce(Context& context, AngleUnit angle } Expression * op0 = editableOperand(0); Expression * op1 = editableOperand(1); +#if MATRIX_EXACT_REDUCING if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif if (op0->type() == Type::Rational) { Rational * r0 = static_cast(op0); if (!r0->denominator().isOne()) { diff --git a/poincare/src/hyperbolic_arc_cosine.cpp b/poincare/src/hyperbolic_arc_cosine.cpp index 2b5cd903f..0d5fbb7c3 100644 --- a/poincare/src/hyperbolic_arc_cosine.cpp +++ b/poincare/src/hyperbolic_arc_cosine.cpp @@ -21,10 +21,12 @@ Expression * HyperbolicArcCosine::shallowReduce(Context& context, AngleUnit angl if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return this; } diff --git a/poincare/src/hyperbolic_arc_sine.cpp b/poincare/src/hyperbolic_arc_sine.cpp index a6a6c403f..6f68f1f21 100644 --- a/poincare/src/hyperbolic_arc_sine.cpp +++ b/poincare/src/hyperbolic_arc_sine.cpp @@ -21,10 +21,12 @@ Expression * HyperbolicArcSine::shallowReduce(Context& context, AngleUnit angleU if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return this; } diff --git a/poincare/src/hyperbolic_arc_tangent.cpp b/poincare/src/hyperbolic_arc_tangent.cpp index 3035f1b90..6717cedb0 100644 --- a/poincare/src/hyperbolic_arc_tangent.cpp +++ b/poincare/src/hyperbolic_arc_tangent.cpp @@ -21,10 +21,12 @@ Expression * HyperbolicArcTangent::shallowReduce(Context& context, AngleUnit ang if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return this; } diff --git a/poincare/src/hyperbolic_cosine.cpp b/poincare/src/hyperbolic_cosine.cpp index dfe66192a..a0e7d7c5e 100644 --- a/poincare/src/hyperbolic_cosine.cpp +++ b/poincare/src/hyperbolic_cosine.cpp @@ -26,10 +26,12 @@ Expression * HyperbolicCosine::shallowReduce(Context& context, AngleUnit angleUn if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return this; } diff --git a/poincare/src/hyperbolic_sine.cpp b/poincare/src/hyperbolic_sine.cpp index fd275a122..1b5ce48c9 100644 --- a/poincare/src/hyperbolic_sine.cpp +++ b/poincare/src/hyperbolic_sine.cpp @@ -26,10 +26,12 @@ Expression * HyperbolicSine::shallowReduce(Context& context, AngleUnit angleUnit if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return this; } diff --git a/poincare/src/hyperbolic_tangent.cpp b/poincare/src/hyperbolic_tangent.cpp index 9034a4532..96ccbb6ae 100644 --- a/poincare/src/hyperbolic_tangent.cpp +++ b/poincare/src/hyperbolic_tangent.cpp @@ -25,10 +25,12 @@ Expression * HyperbolicTangent::shallowReduce(Context& context, AngleUnit angleU if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return this; } diff --git a/poincare/src/imaginary_part.cpp b/poincare/src/imaginary_part.cpp index 02a32cedc..506141ef3 100644 --- a/poincare/src/imaginary_part.cpp +++ b/poincare/src/imaginary_part.cpp @@ -25,9 +25,11 @@ Expression * ImaginaryPart::shallowReduce(Context& context, AngleUnit angleUnit) return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif if (op->type() == Type::Rational) { return replaceWith(new Rational(0), true); } diff --git a/poincare/src/integral.cpp b/poincare/src/integral.cpp index 61b518c71..813530d61 100644 --- a/poincare/src/integral.cpp +++ b/poincare/src/integral.cpp @@ -28,9 +28,11 @@ Expression * Integral::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING if (operand(0)->type() == Type::Matrix || operand(1)->type() == Type::Matrix || operand(2)->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif return this; } diff --git a/poincare/src/least_common_multiple.cpp b/poincare/src/least_common_multiple.cpp index 60ef0c29e..4ebadd4d7 100644 --- a/poincare/src/least_common_multiple.cpp +++ b/poincare/src/least_common_multiple.cpp @@ -27,9 +27,11 @@ Expression * LeastCommonMultiple::shallowReduce(Context& context, AngleUnit angl } Expression * op0 = editableOperand(0); Expression * op1 = editableOperand(1); +#if MATRIX_EXACT_REDUCING if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif if (op0->type() == Type::Rational) { Rational * r0 = static_cast(op0); if (!r0->denominator().isOne()) { diff --git a/poincare/src/logarithm.cpp b/poincare/src/logarithm.cpp index 9d87fe703..8429e7477 100644 --- a/poincare/src/logarithm.cpp +++ b/poincare/src/logarithm.cpp @@ -45,12 +45,14 @@ Expression * Logarithm::shallowReduce(Context& context, AngleUnit angleUnit) { return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (numberOfOperands() == 1 && op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } if (numberOfOperands() == 2 && (op->type() == Type::Matrix || operand(1)->type() == Type::Matrix)) { return replaceWith(new Undefined(), true); } +#endif if (op->sign() == Sign::Negative || (numberOfOperands() == 2 && operand(1)->sign() == Sign::Negative)) { return replaceWith(new Undefined(), true); } diff --git a/poincare/src/matrix_dimension.cpp b/poincare/src/matrix_dimension.cpp index 076a695c4..61c825874 100644 --- a/poincare/src/matrix_dimension.cpp +++ b/poincare/src/matrix_dimension.cpp @@ -21,6 +21,7 @@ Expression * MatrixDimension::shallowReduce(Context& context, AngleUnit angleUni if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { Matrix * m = static_cast(op); @@ -32,6 +33,10 @@ Expression * MatrixDimension::shallowReduce(Context& context, AngleUnit angleUni return replaceWith(new Matrix(newOperands, 1, 2, false), true); } return this; +#else + const Expression * newOperands[2] = {new Rational(1), new Rational(1)}; + return replaceWith(new Matrix(newOperands, 1, 2, false), true); +#endif } template diff --git a/poincare/src/matrix_inverse.cpp b/poincare/src/matrix_inverse.cpp index 2a450e320..1d5271be5 100644 --- a/poincare/src/matrix_inverse.cpp +++ b/poincare/src/matrix_inverse.cpp @@ -26,6 +26,7 @@ Expression * MatrixInverse::shallowReduce(Context& context, AngleUnit angleUnit) return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (!op->recursivelyMatches(Expression::IsMatrix)) { detachOperand(op); return replaceWith(new Power(op, new Rational(-1), false), true)->shallowReduce(context, angleUnit); @@ -37,6 +38,10 @@ Expression * MatrixInverse::shallowReduce(Context& context, AngleUnit angleUnit) } } return this; +#else + detachOperand(op); + return replaceWith(new Power(op, new Rational(-1), false), true)->shallowReduce(context, angleUnit); +#endif } // TODO: handle this exactly in shallowReduce for small dimensions. diff --git a/poincare/src/matrix_trace.cpp b/poincare/src/matrix_trace.cpp index d7c3c207a..4ae4ebfab 100644 --- a/poincare/src/matrix_trace.cpp +++ b/poincare/src/matrix_trace.cpp @@ -24,6 +24,7 @@ Expression * MatrixTrace::shallowReduce(Context& context, AngleUnit angleUnit) { return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (op->type() == Type::Matrix) { Matrix * m = static_cast(op); if (m->numberOfRows() != m->numberOfColumns()) { @@ -42,6 +43,9 @@ Expression * MatrixTrace::shallowReduce(Context& context, AngleUnit angleUnit) { return replaceWith(op, true); } return this; +#else + return replaceWith(op, true); +#endif } template diff --git a/poincare/src/matrix_transpose.cpp b/poincare/src/matrix_transpose.cpp index f2da1314c..59bb4ec3f 100644 --- a/poincare/src/matrix_transpose.cpp +++ b/poincare/src/matrix_transpose.cpp @@ -24,6 +24,7 @@ Expression * MatrixTranspose::shallowReduce(Context& context, AngleUnit angleUni return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (op->type() == Type::Matrix) { Matrix * transpose = static_cast(op)->createTranspose(); return replaceWith(transpose, true); @@ -32,6 +33,9 @@ Expression * MatrixTranspose::shallowReduce(Context& context, AngleUnit angleUni return replaceWith(op, true); } return this; +#else + return replaceWith(op, true); +#endif } template diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index e951c0be2..ff2df4a23 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -127,7 +127,7 @@ Expression * Multiplication::shallowReduce(Context& context, AngleUnit angleUnit while (i < initialNumberOfOperands) { Expression * o = editableOperand(i); if (o->type() == Type::Multiplication) { - mergeOperands(static_cast(o)); + mergeOperands(static_cast(o)); // TODO: ensure that matrix operands are not swapped to implement MATRIX_EXACT_REDUCING continue; } i++; @@ -144,6 +144,7 @@ Expression * Multiplication::shallowReduce(Context& context, AngleUnit angleUnit // Step 3: Sort the operands sortOperands(SimplificationOrder); +#if MATRIX_EXACT_REDUCING /* Step 3bis: get rid of matrix */ int n = 1; int m = 1; @@ -215,6 +216,7 @@ Expression * Multiplication::shallowReduce(Context& context, AngleUnit angleUnit } return replaceWith(resultMatrix, true)->shallowReduce(context, angleUnit); } +#endif /* Step 4: Gather like terms. For example, turn pi^2*pi^3 into pi^5. Thanks to * the simplification order, such terms are guaranteed to be next to each diff --git a/poincare/src/naperian_logarithm.cpp b/poincare/src/naperian_logarithm.cpp index 7413e1836..6b23eb695 100644 --- a/poincare/src/naperian_logarithm.cpp +++ b/poincare/src/naperian_logarithm.cpp @@ -28,9 +28,11 @@ Expression * NaperianLogarithm::shallowReduce(Context& context, AngleUnit angleU if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING if (operand(0)->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif const Expression * logOperands[2] = {operand(0)->clone(), new Symbol(Ion::Charset::Exponential)}; Logarithm * l = new Logarithm(logOperands, 2, false); replaceWith(l, true); diff --git a/poincare/src/nth_root.cpp b/poincare/src/nth_root.cpp index ef0a8b6c7..030dc13ff 100644 --- a/poincare/src/nth_root.cpp +++ b/poincare/src/nth_root.cpp @@ -25,9 +25,11 @@ Expression * NthRoot::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING if (operand(0)->type() == Type::Matrix || operand(1)->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif Power * invIndex = new Power(operand(1), new Rational(-1), false); Power * p = new Power(operand(0), invIndex, false); detachOperands(); diff --git a/poincare/src/opposite.cpp b/poincare/src/opposite.cpp index 7b05bab95..aad66e0cf 100644 --- a/poincare/src/opposite.cpp +++ b/poincare/src/opposite.cpp @@ -34,9 +34,11 @@ Expression * Opposite::shallowReduce(Context& context, AngleUnit angleUnit) { return e; } const Expression * op = operand(0); +#if MATRIX_EXACT_REDUCING if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif detachOperand(op); Multiplication * m = new Multiplication(new Rational(-1), op, false); replaceWith(m, true); diff --git a/poincare/src/permute_coefficient.cpp b/poincare/src/permute_coefficient.cpp index a8645c328..b0d887463 100644 --- a/poincare/src/permute_coefficient.cpp +++ b/poincare/src/permute_coefficient.cpp @@ -25,9 +25,11 @@ Expression * PermuteCoefficient::shallowReduce(Context& context, AngleUnit angle } Expression * op0 = editableOperand(0); Expression * op1 = editableOperand(1); +#if MATRIX_EXACT_REDUCING if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif if (op0->type() == Type::Rational) { Rational * r0 = static_cast(op0); if (!r0->denominator().isOne() || r0->numerator().isNegative()) { diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 669d10503..0c8b06f14 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -138,6 +138,7 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING /* Step 0: get rid of matrix */ if (operand(1)->type() == Type::Matrix) { return replaceWith(new Undefined(), true); @@ -175,6 +176,7 @@ Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) { replaceWith(result, true); return result->shallowReduce(context, angleUnit); } +#endif /* Step 0: We look for square root and sum of square roots (two terms maximum * so far) at the denominator and move them to the numerator. */ diff --git a/poincare/src/prediction_interval.cpp b/poincare/src/prediction_interval.cpp index 2cff832c5..37ac1d43d 100644 --- a/poincare/src/prediction_interval.cpp +++ b/poincare/src/prediction_interval.cpp @@ -29,9 +29,11 @@ Expression * PredictionInterval::shallowReduce(Context& context, AngleUnit angle } Expression * op0 = editableOperand(0); Expression * op1 = editableOperand(1); +#if MATRIX_EXACT_REDUCING if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif if (op0->type() == Type::Rational) { Rational * r0 = static_cast(op0); if (r0->numerator().isNegative() || Integer::NaturalOrder(r0->numerator(), r0->denominator()) > 0) { diff --git a/poincare/src/real_part.cpp b/poincare/src/real_part.cpp index 010bcfe03..aa8d4904f 100644 --- a/poincare/src/real_part.cpp +++ b/poincare/src/real_part.cpp @@ -23,9 +23,11 @@ Expression * RealPart::shallowReduce(Context& context, AngleUnit angleUnit) { return e; } Expression * op = editableOperand(0); +#if MATRIX_EXACT_REDUCING if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif if (op->type() == Type::Rational) { return replaceWith(op, true); } diff --git a/poincare/src/round.cpp b/poincare/src/round.cpp index 7b8083b30..4a93fa0d9 100644 --- a/poincare/src/round.cpp +++ b/poincare/src/round.cpp @@ -22,9 +22,11 @@ Expression * Round::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING if (operand(0)->type() == Type::Matrix || operand(1)->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } +#endif return this; // TODO: implement for rationals! } diff --git a/poincare/src/simplification_engine.cpp b/poincare/src/simplification_engine.cpp index f11d4250d..b4e33d4d5 100644 --- a/poincare/src/simplification_engine.cpp +++ b/poincare/src/simplification_engine.cpp @@ -1,5 +1,7 @@ #include +#if MATRIX_EXACT_REDUCING + namespace Poincare { Expression * SimplificationEngine::map(Expression * e, Context & context, Expression::AngleUnit angleUnit) { @@ -16,3 +18,5 @@ Expression * SimplificationEngine::map(Expression * e, Context & context, Expres } } + +#endif diff --git a/poincare/src/sine.cpp b/poincare/src/sine.cpp index e65252b11..5b45acd0e 100644 --- a/poincare/src/sine.cpp +++ b/poincare/src/sine.cpp @@ -27,10 +27,12 @@ Expression * Sine::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif return Trigonometry::shallowReduceDirectFunction(this, context, angleUnit); } diff --git a/poincare/src/square_root.cpp b/poincare/src/square_root.cpp index e1d79c53e..5d67ad83a 100644 --- a/poincare/src/square_root.cpp +++ b/poincare/src/square_root.cpp @@ -38,9 +38,11 @@ Expression * SquareRoot::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING if (operand(0)->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif Power * p = new Power(operand(0), new Rational(1, 2), false); detachOperands(); replaceWith(p, true); diff --git a/poincare/src/tangent.cpp b/poincare/src/tangent.cpp index f0d0a33a9..8176a0313 100644 --- a/poincare/src/tangent.cpp +++ b/poincare/src/tangent.cpp @@ -28,10 +28,12 @@ Expression * Tangent::shallowReduce(Context& context, AngleUnit angleUnit) { if (e != this) { return e; } +#if MATRIX_EXACT_REDUCING Expression * op = editableOperand(0); if (op->type() == Type::Matrix) { return SimplificationEngine::map(this, context, angleUnit); } +#endif Expression * newExpression = Trigonometry::shallowReduceDirectFunction(this, context, angleUnit); if (newExpression->type() == Type::Tangent) { const Expression * op[1] = {newExpression->operand(0)}; diff --git a/poincare/test/simplify_easy.cpp b/poincare/test/simplify_easy.cpp index bd87ed7a3..b1dc8dae9 100644 --- a/poincare/test/simplify_easy.cpp +++ b/poincare/test/simplify_easy.cpp @@ -35,6 +35,7 @@ void assert_parsed_expression_simplify_to(const char * expression, const char * QUIZ_CASE(poincare_simplify_easy) { //assert_parsed_expression_simplify_to("(((R(6)-R(2))/4)/((R(6)+R(2))/4))+1", "((1/2)*R(6))/((R(6)+R(2))/4)"); // Addition Matrix +#if MATRIX_EXACT_REDUCING assert_parsed_expression_simplify_to("1+[[1,2,3][4,5,6]]", "[[2,3,4][5,6,7]]"); assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]+1", "[[2,3,4][5,6,7]]"); assert_parsed_expression_simplify_to("[[1,2][3,4]]+[[1,2,3][4,5,6]]", "undef"); @@ -42,6 +43,10 @@ QUIZ_CASE(poincare_simplify_easy) { assert_parsed_expression_simplify_to("2+[[1,2,3][4,5,6]]+[[1,2,3][4,5,6]]", "[[4,6,8][10,12,14]]"); assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]+cos(2)+[[1,2,3][4,5,6]]", "[[2+cos(2),4+cos(2),6+cos(2)][8+cos(2),10+cos(2),12+cos(2)]]"); assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]+10+[[1,2,3][4,5,6]]+R(2)", "[[12+R(2),14+R(2),16+R(2)][18+R(2),20+R(2),22+R(2)]]"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-1)+3", "inverse([[1,2][3,4]])+3"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)+3", "inverse([[37,54][81,118]])+3"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)+[[1,2][3,4]]", "inverse([[37,54][81,118]])+[[1,2][3,4]]"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)+[[1,2][3,4]]+4+R(2)", "inverse([[37,54][81,118]])+[[5+R(2),6+R(2)][7+R(2),8+R(2)]]"); // Multiplication Matrix assert_parsed_expression_simplify_to("2*[[1,2,3][4,5,6]]", "[[2,4,6][8,10,12]]"); @@ -49,13 +54,14 @@ QUIZ_CASE(poincare_simplify_easy) { assert_parsed_expression_simplify_to("[[1,2][3,4]]*[[1,2,3][4,5,6]]", "[[9, 12, 15][19, 26, 33]]"); assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]*[[1,2][2,3][5,6]]", "[[20, 26][44, 59]]"); assert_parsed_expression_simplify_to("[[1,2,3,4][4,5,6,5]]*[[1,2][2,3][5,6]]", "undef"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)*[[1,2][3,4]]", "[[1,2][3,4]]^(-3)*[[1,2][3,4]]"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)*[[1,2,3][3,4,5]]*[[1,2][3,2][4,5]]*4", "[[37,54][81,118]]^(-1)*[[76,84][140,156]]"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)*[[1,2][3,4]]", "[[1,2][3,4]]^(-3)*[[1,2][3,4]]"); // Power Matrix assert_parsed_expression_simplify_to("[[1,2,3][4,5,6][7,8,9]]^3", "[[468,576,684][1062,1305,1548][1656,2034,2412]]"); assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]^(-1)", "undef"); assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-1)", "[[1,2][3,4]]^(-1)"); // TODO: Implement matrix inverse for dim < 3 - assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-1)+3", "inverse([[1,2][3,4]])+3"); - assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)+3", "inverse([[37,54][81,118]])+3"); // Function on matrix assert_parsed_expression_simplify_to("abs([[1,-2][3,4]])", "[[1,2][3,4]]"); @@ -64,8 +70,6 @@ QUIZ_CASE(poincare_simplify_easy) { assert_parsed_expression_simplify_to("atan([[R(3),1][1/R(3),-1]])", "[[P/3,P/4][P/6,-P/4]]"); assert_parsed_expression_simplify_to("acos([[1/R(2),1/2][1,-1]])", "[[P/4,P/3][0,P]]"); assert_parsed_expression_simplify_to("binomial([[1,-2][3,4]], 2)", "undef"); - 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/R(2),1/2][1,-1.3]])", "[[ceil(R(2)/2),1][1,-1]]"); assert_parsed_expression_simplify_to("confidence(1/3, 25)", "[[2/15,8/15]]"); assert_parsed_expression_simplify_to("confidence(45, 25)", "undef"); @@ -77,18 +81,11 @@ QUIZ_CASE(poincare_simplify_easy) { assert_parsed_expression_simplify_to("det([[2,2][3,4]])", "det([[2,2][3,4]])"); assert_parsed_expression_simplify_to("det([[2,2][3,3]])", "det([[2,2][3,3]])"); assert_parsed_expression_simplify_to("quo([[2,2][3,3]],2)", "undef"); - assert_parsed_expression_simplify_to("quo(19,3)", "6"); - assert_parsed_expression_simplify_to("quo(-19,3)", "-7"); assert_parsed_expression_simplify_to("rem([[2,2][3,3]],2)", "undef"); - assert_parsed_expression_simplify_to("rem(19,3)", "1"); - assert_parsed_expression_simplify_to("rem(-19,3)", "2"); - assert_parsed_expression_simplify_to("99!", "933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000"); assert_parsed_expression_simplify_to("[[1,2][3,4]]!", "[[1,2][6,24]]"); assert_parsed_expression_simplify_to("floor([[1/R(2),1/2][1,-1.3]])", "[[floor(R(2)/2),0][1,-2]]"); assert_parsed_expression_simplify_to("frac([[1/R(2),1/2][1,-1.3]])", "[[frac(R(2)/2),1/2][0,0.7]]"); assert_parsed_expression_simplify_to("gcd([[1/R(2),1/2][1,-1.3]], [[1]])", "undef"); - assert_parsed_expression_simplify_to("gcd(123,278)", "1"); - assert_parsed_expression_simplify_to("gcd(11,121)", "11"); assert_parsed_expression_simplify_to("asinh([[1/R(2),1/2][1,-1]])", "[[asinh(1/R(2)),asinh(1/2)][asinh(1),asinh(-1)]]"); assert_parsed_expression_simplify_to("atanh([[R(3),1][1/R(3),-1]])", "[[atanh(R(3)),atanh(1)][atanh(1/R(3)),atanh(-1)]]"); assert_parsed_expression_simplify_to("acosh([[1/R(2),1/2][1,-1]])", "[[acosh(1/R(2)),acosh(1/2)][acosh(1),acosh(-1)]]"); @@ -98,8 +95,6 @@ QUIZ_CASE(poincare_simplify_easy) { assert_parsed_expression_simplify_to("im([[1/R(2),1/2][1,-1]])", "[[im(1/R(2)),0][0,0]]"); assert_parsed_expression_simplify_to("int([[P/3,0][P/7,P/2]],3,2)", "undef"); assert_parsed_expression_simplify_to("lcm(2, [[1]])", "undef"); - assert_parsed_expression_simplify_to("lcm(123,278)", "34194"); - assert_parsed_expression_simplify_to("lcm(11,121)", "121"); assert_parsed_expression_simplify_to("log([[R(2),1/2][1,3]])", "[[(1/2)*log(2),-log(2)][0,log(3)]]"); assert_parsed_expression_simplify_to("log([[1/R(2),1/2][1,-3]])", "undef"); assert_parsed_expression_simplify_to("log([[1/R(2),1/2][1,-3]],3)", "undef"); @@ -117,8 +112,6 @@ QUIZ_CASE(poincare_simplify_easy) { assert_parsed_expression_simplify_to("root(4,3)", "4^(1/3)"); assert_parsed_expression_simplify_to("-[[1/R(2),1/2,3][2,1,-3]]", "[[-1/R(2),-1/2,-3][-2,-1,3]]"); assert_parsed_expression_simplify_to("permute([[1,-2][3,4]], 2)", "undef"); - assert_parsed_expression_simplify_to("permute(102,4)", "101989800"); - assert_parsed_expression_simplify_to("permute(20,-10)", "undef"); assert_parsed_expression_simplify_to("prediction95(1/3, 25)", "[[1/3-49R(2)/375,1/3+49R(2)/375]]"); assert_parsed_expression_simplify_to("prediction95(45, 25)", "undef"); assert_parsed_expression_simplify_to("prediction95(1/3, -34)", "undef"); @@ -129,12 +122,35 @@ QUIZ_CASE(poincare_simplify_easy) { assert_parsed_expression_simplify_to("sin([[P/3,0][P/7,P/2]])", "[[R(3)/2,0][sin(P/7),1]]"); assert_parsed_expression_simplify_to("R([[4,2][P/7,1]])", "[[2,R(2)][R(P/7),1]]"); assert_parsed_expression_simplify_to("tan([[P/3,0][P/7,P/6]])", "[[R(3),0][tan(P/7),R(3)/3]]"); - +#else + assert_parsed_expression_simplify_to("R([[4,2][P/7,1]])", "R([[4,2][P/7,1]])"); +#endif /* Complex */ assert_parsed_expression_simplify_to("I", "I"); assert_parsed_expression_simplify_to("R(-33)", "R(33)*I"); assert_parsed_expression_simplify_to("I^(3/5)", "X^(IP3/10)"); + //Functions + 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"); + assert_parsed_expression_simplify_to("conj(1/2)", "1/2"); + assert_parsed_expression_simplify_to("quo(19,3)", "6"); + assert_parsed_expression_simplify_to("quo(-19,3)", "-7"); + assert_parsed_expression_simplify_to("rem(19,3)", "1"); + assert_parsed_expression_simplify_to("rem(-19,3)", "2"); + assert_parsed_expression_simplify_to("99!", "933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000"); + assert_parsed_expression_simplify_to("floor(-1.3)", "-2"); + assert_parsed_expression_simplify_to("frac(-1.3)", "0.7"); + assert_parsed_expression_simplify_to("gcd(123,278)", "1"); + assert_parsed_expression_simplify_to("gcd(11,121)", "11"); + assert_parsed_expression_simplify_to("lcm(123,278)", "34194"); + assert_parsed_expression_simplify_to("lcm(11,121)", "121"); + assert_parsed_expression_simplify_to("root(4,3)", "4^(1/3)"); + assert_parsed_expression_simplify_to("permute(102,4)", "101989800"); + assert_parsed_expression_simplify_to("permute(20,-10)", "undef"); + assert_parsed_expression_simplify_to("re(1/2)", "1/2"); + assert_parsed_expression_simplify_to("1*tan(2)*tan(5)", "tan(2)*tan(5)"); assert_parsed_expression_simplify_to("P+(3R(2)-2R(3))/25", "(3R(2)-2R(3)+25P)/25"); assert_parsed_expression_simplify_to("-1/3", "-1/3");