mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-25 16:50:50 +01:00
[poincare] Rather check for undefined operand in shallowReduce instead
of in deepReduce Change-Id: I6db09297c75867178d83f27909f915b53ec161c9
This commit is contained in:
@@ -14,17 +14,68 @@ class Evaluation;
|
||||
class Rational;
|
||||
|
||||
class Expression {
|
||||
friend class Division;
|
||||
friend class Logarithm;
|
||||
friend class Opposite;
|
||||
friend class NaperianLogarithm;
|
||||
friend class Subtraction;
|
||||
friend class Addition;
|
||||
friend class Undefined;
|
||||
friend class Rational;
|
||||
friend class Decimal;
|
||||
friend class Multiplication;
|
||||
friend class Power;
|
||||
friend class Trigonometry;
|
||||
friend class Addition;
|
||||
friend class Factorial;
|
||||
friend class Division;
|
||||
friend class Store;
|
||||
friend class Sine;
|
||||
friend class Cosine;
|
||||
friend class Tangent;
|
||||
friend class AbsoluteValue;
|
||||
friend class ArcCosine;
|
||||
friend class ArcSine;
|
||||
friend class ArcTangent;
|
||||
friend class BinomialCoefficient;
|
||||
friend class Ceiling;
|
||||
friend class ComplexArgument;
|
||||
friend class ConfidenceInterval;
|
||||
friend class Conjugate;
|
||||
friend class Derivative;
|
||||
friend class Determinant;
|
||||
friend class DivisionQuotient;
|
||||
friend class DivisionRemainder;
|
||||
friend class Floor;
|
||||
friend class FracPart;
|
||||
friend class GreatCommonDivisor;
|
||||
friend class HyperbolicArcCosine;
|
||||
friend class HyperbolicArcSine;
|
||||
friend class HyperbolicArcTangent;
|
||||
friend class HyperbolicCosine;
|
||||
friend class HyperbolicSine;
|
||||
friend class HyperbolicTangent;
|
||||
friend class ImaginaryPart;
|
||||
friend class Integral;
|
||||
friend class LeastCommonMultiple;
|
||||
friend class Logarithm;
|
||||
friend class MatrixDimension;
|
||||
friend class MatrixInverse;
|
||||
friend class MatrixTrace;
|
||||
friend class MatrixTranspose;
|
||||
friend class NaperianLogarithm;
|
||||
friend class NthRoot;
|
||||
friend class Opposite;
|
||||
friend class Parenthesis;
|
||||
friend class PermuteCoefficient;
|
||||
friend class PredictionInterval;
|
||||
friend class Product;
|
||||
friend class RealPart;
|
||||
friend class Round;
|
||||
friend class SquareRoot;
|
||||
friend class Subtraction;
|
||||
friend class Sum;
|
||||
friend class Symbol;
|
||||
friend class Matrix;
|
||||
friend class SimplificationRoot;
|
||||
friend class Sequence;
|
||||
friend class Trigonometry;
|
||||
friend class EvaluationEngine;
|
||||
friend class SimplificationEngine;
|
||||
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
Undefined = 0,
|
||||
@@ -200,7 +251,7 @@ private:
|
||||
Expression * deepBeautify(Context & context, AngleUnit angleUnit);
|
||||
Expression * deepReduce(Context & context, AngleUnit angleUnit);
|
||||
// TODO: should be virtual pure
|
||||
virtual Expression * shallowReduce(Context & context, AngleUnit angleUnit) { return this; };
|
||||
virtual Expression * shallowReduce(Context & context, AngleUnit angleUnit);
|
||||
virtual Expression * shallowBeautify(Context & context, AngleUnit angleUnit) { return this; };
|
||||
|
||||
// Private methods used in simplification process
|
||||
|
||||
@@ -30,6 +30,10 @@ ExpressionLayout * AbsoluteValue::privateCreateLayout(FloatDisplayMode floatDisp
|
||||
}
|
||||
|
||||
Expression * AbsoluteValue::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
if (operand(0)->sign() == Sign::Positive) {
|
||||
return replaceWith(editableOperand(0), true);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@ Expression * Addition::clone() const {
|
||||
/* Simplication */
|
||||
|
||||
Expression * Addition::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
/* Step 1: Addition is associative, so let's start by merging children which
|
||||
* also are additions themselves. */
|
||||
int i = 0;
|
||||
|
||||
@@ -17,6 +17,10 @@ Expression * ArcCosine::clone() const {
|
||||
}
|
||||
|
||||
Expression * ArcCosine::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@ Expression * ArcSine::clone() const {
|
||||
}
|
||||
|
||||
Expression * ArcSine::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@ Expression * ArcTangent::clone() const {
|
||||
}
|
||||
|
||||
Expression * ArcTangent::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ Expression * Cosine::clone() const {
|
||||
}
|
||||
|
||||
Expression * Cosine::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
return Trigonometry::shallowReduceDirectFunction(this, context, angleUnit);
|
||||
}
|
||||
|
||||
|
||||
@@ -154,6 +154,10 @@ ExpressionLayout * Decimal::privateCreateLayout(FloatDisplayMode floatDisplayMod
|
||||
}
|
||||
|
||||
Expression * Decimal::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
int numberOfDigits = numberOfDigitsInMantissa();
|
||||
Integer numerator = m_mantissa;
|
||||
Integer denominator = Integer(1);
|
||||
|
||||
@@ -23,6 +23,10 @@ Expression * Division::clone() const {
|
||||
}
|
||||
|
||||
Expression * Division::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
Power * p = new Power(operand(1), new Rational(-1), false);
|
||||
Multiplication * m = new Multiplication(operand(0), p, false);
|
||||
detachOperands();
|
||||
|
||||
@@ -141,11 +141,18 @@ void Expression::Reduce(Expression ** expressionAddress, Context & context, Angl
|
||||
Expression * Expression::deepReduce(Context & context, AngleUnit angleUnit) {
|
||||
assert(parent() != nullptr);
|
||||
for (int i = 0; i < numberOfOperands(); i++) {
|
||||
if ((editableOperand(i))->deepReduce(context, angleUnit)->type() == Type::Undefined && this->type() != Type::SimplificationRoot) {
|
||||
editableOperand(i)->deepReduce(context, angleUnit);
|
||||
}
|
||||
return shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
Expression * Expression::shallowReduce(Context & context, AngleUnit angleUnit) {
|
||||
for (int i = 0; i < numberOfOperands(); i++) {
|
||||
if (editableOperand(i)->type() == Type::Undefined && this->type() != Type::SimplificationRoot) {
|
||||
return replaceWith(new Undefined(), true);
|
||||
}
|
||||
}
|
||||
return shallowReduce(context, angleUnit);
|
||||
return this;
|
||||
}
|
||||
|
||||
Expression * Expression::deepBeautify(Context & context, AngleUnit angleUnit) {
|
||||
|
||||
@@ -27,6 +27,10 @@ Expression * Factorial::clone() const {
|
||||
}
|
||||
|
||||
Expression * Factorial::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
if (operand(0)->type() == Type::Rational) {
|
||||
Rational * r = static_cast<Rational *>(editableOperand(0));
|
||||
if (!r->denominator().isOne()) {
|
||||
|
||||
@@ -38,6 +38,10 @@ Complex<T> Logarithm::computeOnComplex(const Complex<T> c, AngleUnit angleUnit)
|
||||
}
|
||||
|
||||
Expression * Logarithm::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
if (operand(0)->sign() == Sign::Negative || (numberOfOperands() == 2 && operand(1)->sign() == Sign::Negative)) {
|
||||
return replaceWith(new Undefined(), true);
|
||||
}
|
||||
|
||||
@@ -113,6 +113,10 @@ static inline const Expression * Base(const Expression * e) {
|
||||
}
|
||||
|
||||
Expression * Multiplication::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
/* Step 1: Multiplication is associative, so let's start by merging children
|
||||
* which also are multiplications themselves. */
|
||||
int i = 0;
|
||||
|
||||
@@ -23,6 +23,10 @@ Expression * NaperianLogarithm::clone() const {
|
||||
}
|
||||
|
||||
Expression * NaperianLogarithm::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
const Expression * logOperands[2] = {operand(0)->clone(), new Symbol(Ion::Charset::Exponential)};
|
||||
Logarithm * l = new Logarithm(logOperands, 2, false);
|
||||
replaceWith(l, true);
|
||||
|
||||
@@ -20,6 +20,10 @@ Expression * NthRoot::clone() const {
|
||||
}
|
||||
|
||||
Expression * NthRoot::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
Power * invIndex = new Power(operand(1), new Rational(-1), false);
|
||||
Power * p = new Power(operand(0), invIndex, false);
|
||||
detachOperands();
|
||||
|
||||
@@ -29,6 +29,10 @@ Complex<T> Opposite::compute(const Complex<T> c, AngleUnit angleUnit) {
|
||||
}
|
||||
|
||||
Expression * Opposite::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
const Expression * op = operand(0);
|
||||
detachOperand(op);
|
||||
Multiplication * m = new Multiplication(new Rational(-1), op, false);
|
||||
|
||||
@@ -24,6 +24,10 @@ ExpressionLayout * Parenthesis::privateCreateLayout(FloatDisplayMode floatDispla
|
||||
}
|
||||
|
||||
Expression * Parenthesis::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
return replaceWith(editableOperand(0), true);
|
||||
}
|
||||
|
||||
|
||||
@@ -136,6 +136,10 @@ int Power::simplificationOrderGreaterType(const Expression * e) const {
|
||||
}
|
||||
|
||||
Expression * Power::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
@@ -22,6 +22,10 @@ Expression * Sine::clone() const {
|
||||
}
|
||||
|
||||
Expression * Sine::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
return Trigonometry::shallowReduceDirectFunction(this, context, angleUnit);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,10 @@ Complex<T> SquareRoot::computeOnComplex(const Complex<T> c, AngleUnit angleUnit)
|
||||
}
|
||||
|
||||
Expression * SquareRoot::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
Power * p = new Power(operand(0), new Rational(1, 2), false);
|
||||
detachOperands();
|
||||
replaceWith(p, true);
|
||||
|
||||
@@ -29,6 +29,10 @@ Complex<T> Subtraction::compute(const Complex<T> c, const Complex<T> d) {
|
||||
}
|
||||
|
||||
Expression * Subtraction::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
Multiplication * m = new Multiplication(new Rational(-1), operand(1), false);
|
||||
Addition * a = new Addition(operand(0), m, false);
|
||||
detachOperands();
|
||||
|
||||
@@ -23,6 +23,10 @@ Expression * Tangent::clone() const {
|
||||
}
|
||||
|
||||
Expression * Tangent::shallowReduce(Context& context, AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
}
|
||||
Expression * newExpression = Trigonometry::shallowReduceDirectFunction(this, context, angleUnit);
|
||||
if (newExpression->type() == Type::Tangent) {
|
||||
const Expression * op[1] = {newExpression->operand(0)};
|
||||
|
||||
Reference in New Issue
Block a user