mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[poincare] shallowBeautify can modify the reduction context
UnitConvert must set UnitConversion to None, otherwise the unit asked for in the conversion might get changed after being properly set in UnitConvert::shallowBeautify.
This commit is contained in:
committed by
EmilieNumworks
parent
3a0796d3c5
commit
5df60e946a
@@ -55,7 +55,7 @@ private:
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
|
||||
// Derivation
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
static Addition Builder(Expression e1, Expression e2) { return Addition::Builder({e1, e2}); }
|
||||
// Expression
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
void sortChildrenInPlace(NAryExpressionNode::ExpressionOrder order, Context * context, bool canBeInterrupted) {
|
||||
|
||||
@@ -30,7 +30,7 @@ private:
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override {
|
||||
/* leftLayoutShape is called after beautifying expression. ComplexCartesian
|
||||
* is transformed in another expression at beautifying. */
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce();
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
|
||||
// Common operations (done in-place)
|
||||
Expression squareNorm(ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { assert(!m_negative); return LayoutShape::Decimal; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::Decimal; }
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ protected:
|
||||
Expression makePositiveAnyNegativeNumeralFactor(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression denominator(ExpressionNode::ReductionContext reductionContext) const { return node()->denominator(reductionContext); }
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext) { return node()->shallowReduce(reductionContext); }
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext) { return node()->shallowBeautify(reductionContext); }
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext) { return node()->shallowBeautify(reductionContext); }
|
||||
Expression deepBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
// WARNING: this must be called on reduced expressions
|
||||
Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext);
|
||||
@@ -429,6 +429,10 @@ private:
|
||||
Expression defaultHandleUnitsInChildren(); // Children must be reduced
|
||||
Expression shallowReduceUsingApproximation(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression defaultShallowBeautify() { return *this; }
|
||||
void deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
|
||||
node()->deepBeautifyChildren(reductionContext);
|
||||
}
|
||||
void defaultDeepBeautifyChildren(ExpressionNode::ReductionContext reductionContext);
|
||||
bool defaultDidDerivate() { return false; }
|
||||
Expression defaultUnaryFunctionDifferential() { return *this; }
|
||||
|
||||
|
||||
@@ -284,8 +284,9 @@ public:
|
||||
|
||||
/* Simplification */
|
||||
/*!*/ virtual void deepReduceChildren(ReductionContext reductionContext);
|
||||
/*!*/ virtual void deepBeautifyChildren(ReductionContext reductionContext);
|
||||
/*!*/ virtual Expression shallowReduce(ReductionContext reductionContext);
|
||||
/*!*/ virtual Expression shallowBeautify(ReductionContext reductionContext);
|
||||
/*!*/ virtual Expression shallowBeautify(ReductionContext * reductionContext);
|
||||
/*!*/ virtual bool derivate(ReductionContext, Expression symbol, Expression symbolValue);
|
||||
virtual Expression unaryFunctionDifferential();
|
||||
/* Return a clone of the denominator part of the expression */
|
||||
|
||||
@@ -27,7 +27,7 @@ private:
|
||||
/* Serialization */
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Simplification */
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
|
||||
// Expression
|
||||
Expression shallowReduce(Context * context);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ private:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
|
||||
@@ -26,7 +26,7 @@ private:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
// Simplification
|
||||
void deepReduceChildren(ExpressionNode::ReductionContext reductionContext) override;
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Derivation
|
||||
|
||||
@@ -47,7 +47,7 @@ private:
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
Expression denominator(ExpressionNode::ReductionContext reductionContext) const override;
|
||||
// Derivation
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
// Simplification
|
||||
Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
Expression denominator(ExpressionNode::ReductionContext reductionContext) const;
|
||||
void sortChildrenInPlace(NAryExpressionNode::ExpressionOrder order, Context * context, bool canBeInterrupted) {
|
||||
NAryExpression::sortChildrenInPlace(order, context, false, canBeInterrupted);
|
||||
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
|
||||
// Simplify
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return childAtIndex(0)->leftLayoutShape(); }
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::RightOfPower; }
|
||||
int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext);
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const;
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
|
||||
private:
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
private:
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { assert(!m_negative); return isInteger() ? LayoutShape::Integer : LayoutShape::Fraction; };
|
||||
Expression setSign(Sign s, ReductionContext reductionContext) override;
|
||||
Expression denominator(ReductionContext reductionContext) const override;
|
||||
|
||||
@@ -473,7 +473,7 @@ public:
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::OneLetter; } // TODO
|
||||
|
||||
const Representative * representative() const { return m_representative; }
|
||||
@@ -686,7 +686,7 @@ public:
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify();
|
||||
|
||||
bool isBaseUnit() const { return node()->representative()->isBaseUnit() && node()->prefix() == node()->representative()->basePrefix(); }
|
||||
void chooseBestRepresentativeAndPrefix(double * value, double exponent, ExpressionNode::ReductionContext reductionContext, bool optimizePrefix);
|
||||
|
||||
@@ -23,7 +23,8 @@ private:
|
||||
Expression removeUnit(Expression * unit) override;
|
||||
// Simplification
|
||||
void deepReduceChildren(ExpressionNode::ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
void deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
// Evalutation
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
@@ -38,7 +39,8 @@ public:
|
||||
|
||||
// Expression
|
||||
void deepReduceChildren(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
void deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
private:
|
||||
UnitConvertNode * node() const { return static_cast<UnitConvertNode *>(Expression::node()); }
|
||||
};
|
||||
|
||||
@@ -46,7 +46,7 @@ Expression AdditionNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return Addition(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
Expression AdditionNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression AdditionNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return Addition(this).shallowBeautify(reductionContext);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ int Addition::getPolynomialCoefficients(Context * context, const char * symbolNa
|
||||
return deg;
|
||||
}
|
||||
|
||||
Expression Addition::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
|
||||
Expression Addition::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
|
||||
/* Beautifying AdditionNode essentially consists in adding Subtractions if
|
||||
* needed.
|
||||
* In practice, we want to turn "a+(-1)*b" into "a-b". Or, more precisely, any
|
||||
@@ -98,12 +98,12 @@ Expression Addition::shallowBeautify(ExpressionNode::ReductionContext reductionC
|
||||
/* Sort children in decreasing order:
|
||||
* 1+x+x^2 --> x^2+x+1
|
||||
* 1+R(2) --> R(2)+1 */
|
||||
sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, false, canBeInterrupted); }, reductionContext.context(), true);
|
||||
sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, false, canBeInterrupted); }, reductionContext->context(), true);
|
||||
|
||||
int nbChildren = numberOfChildren();
|
||||
for (int i = 0; i < nbChildren; i++) {
|
||||
// Try to make the child i positive if any negative numeral factor is found
|
||||
Expression subtractant = childAtIndex(i).makePositiveAnyNegativeNumeralFactor(reductionContext);
|
||||
Expression subtractant = childAtIndex(i).makePositiveAnyNegativeNumeralFactor(*reductionContext);
|
||||
if (subtractant.isUninitialized())
|
||||
{
|
||||
// if subtractant is not initialized, it means the child i had no negative numeral factor
|
||||
@@ -130,7 +130,6 @@ Expression Addition::shallowBeautify(ExpressionNode::ReductionContext reductionC
|
||||
}
|
||||
|
||||
Expression result = squashUnaryHierarchyInPlace();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Expression ComplexCartesianNode::shallowReduce(ReductionContext reductionContext
|
||||
return ComplexCartesian(this).shallowReduce();
|
||||
}
|
||||
|
||||
Expression ComplexCartesianNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression ComplexCartesianNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return ComplexCartesian(this).shallowBeautify(reductionContext);
|
||||
}
|
||||
|
||||
@@ -77,11 +77,11 @@ Expression ComplexCartesian::shallowReduce() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Expression ComplexCartesian::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
|
||||
Expression ComplexCartesian::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
|
||||
Expression a = real();
|
||||
Expression b = imag();
|
||||
Expression oppositeA = a.makePositiveAnyNegativeNumeralFactor(reductionContext);
|
||||
Expression oppositeB = b.makePositiveAnyNegativeNumeralFactor(reductionContext);
|
||||
Expression oppositeA = a.makePositiveAnyNegativeNumeralFactor(*reductionContext);
|
||||
Expression oppositeB = b.makePositiveAnyNegativeNumeralFactor(*reductionContext);
|
||||
a = oppositeA.isUninitialized() ? a : oppositeA;
|
||||
b = oppositeB.isUninitialized() ? b : oppositeB;
|
||||
Expression e = Expression::CreateComplexExpression(a, b, Preferences::ComplexFormat::Cartesian,
|
||||
|
||||
@@ -115,7 +115,7 @@ Expression DecimalNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return Decimal(this).shallowReduce();
|
||||
}
|
||||
|
||||
Expression DecimalNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression DecimalNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return Decimal(this).shallowBeautify();
|
||||
}
|
||||
|
||||
|
||||
@@ -388,6 +388,18 @@ Expression Expression::shallowReduceUsingApproximation(ExpressionNode::Reduction
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Expression::defaultDeepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
|
||||
const int nbChildren = numberOfChildren();
|
||||
for (int i = 0; i < nbChildren; i++) {
|
||||
Expression child = childAtIndex(i);
|
||||
child = child.deepBeautify(reductionContext);
|
||||
// We add missing Parentheses after beautifying the parent and child
|
||||
if (node()->childAtIndexNeedsUserParentheses(child, i)) {
|
||||
replaceChildAtIndexInPlace(i, Parenthesis::Builder(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Expression::SimplificationHasBeenInterrupted() {
|
||||
return sSimplificationHasBeenInterrupted;
|
||||
}
|
||||
@@ -656,7 +668,7 @@ void Expression::beautifyAndApproximateScalar(Expression * simplifiedExpression,
|
||||
ecomplexClone.imag().deepBeautify(userReductionContext);
|
||||
*approximateExpression = ecomplexClone.approximate<double>(context, complexFormat, angleUnit);
|
||||
}
|
||||
// Step 2: create the simplied expression with the required complex format
|
||||
// Step 2: create the simplified expression with the required complex format
|
||||
Expression ra = complexFormat == Preferences::ComplexFormat::Polar ?
|
||||
ecomplex.clone().convert<ComplexCartesian>().norm(userReductionContext).shallowReduce(userReductionContext) :
|
||||
ecomplex.real();
|
||||
@@ -833,16 +845,8 @@ Expression Expression::deepReduce(ExpressionNode::ReductionContext reductionCont
|
||||
}
|
||||
|
||||
Expression Expression::deepBeautify(ExpressionNode::ReductionContext reductionContext) {
|
||||
Expression e = shallowBeautify(reductionContext);
|
||||
const int nbChildren = e.numberOfChildren();
|
||||
for (int i = 0; i < nbChildren; i++) {
|
||||
Expression child = e.childAtIndex(i);
|
||||
child = child.deepBeautify(reductionContext);
|
||||
// We add missing Parentheses after beautifying the parent and child
|
||||
if (e.node()->childAtIndexNeedsUserParentheses(child, i)) {
|
||||
e.replaceChildAtIndexInPlace(i, Parenthesis::Builder(child));
|
||||
}
|
||||
}
|
||||
Expression e = shallowBeautify(&reductionContext);
|
||||
e.deepBeautifyChildren(reductionContext);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
@@ -103,11 +103,15 @@ void ExpressionNode::deepReduceChildren(ExpressionNode::ReductionContext reducti
|
||||
Expression(this).defaultDeepReduceChildren(reductionContext);
|
||||
}
|
||||
|
||||
void ExpressionNode::deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
|
||||
Expression(this).defaultDeepBeautifyChildren(reductionContext);
|
||||
}
|
||||
|
||||
Expression ExpressionNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return Expression(this).defaultShallowReduce();
|
||||
}
|
||||
|
||||
Expression ExpressionNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression ExpressionNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return Expression(this).defaultShallowBeautify();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ Expression FactorNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return Factor(this).shallowReduce(reductionContext.context());
|
||||
}
|
||||
|
||||
Expression FactorNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression FactorNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return Factor(this).shallowBeautify(reductionContext);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ Expression Factor::shallowReduce(Context * context) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Expression Factor::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
|
||||
Expression Factor::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
|
||||
Expression c = childAtIndex(0);
|
||||
if (c.type() != ExpressionNode::Type::Rational) {
|
||||
return replaceWithUndefinedInPlace();
|
||||
|
||||
@@ -19,8 +19,8 @@ Expression GreatCommonDivisorNode::shallowReduce(ReductionContext reductionConte
|
||||
return GreatCommonDivisor(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
Expression GreatCommonDivisorNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
return GreatCommonDivisor(this).shallowBeautify(reductionContext.context());
|
||||
Expression GreatCommonDivisorNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return GreatCommonDivisor(this).shallowBeautify(reductionContext->context());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -19,8 +19,8 @@ Expression LeastCommonMultipleNode::shallowReduce(ReductionContext reductionCont
|
||||
return LeastCommonMultiple(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
Expression LeastCommonMultipleNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
return LeastCommonMultiple(this).shallowBeautify(reductionContext.context());
|
||||
Expression LeastCommonMultipleNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return LeastCommonMultiple(this).shallowBeautify(reductionContext->context());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -95,12 +95,12 @@ Expression LogarithmNode<1>::unaryFunctionDifferential() {
|
||||
/**/
|
||||
|
||||
template<>
|
||||
Expression LogarithmNode<1>::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression LogarithmNode<1>::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return CommonLogarithm(this);
|
||||
}
|
||||
|
||||
template<>
|
||||
Expression LogarithmNode<2>::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression LogarithmNode<2>::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return Logarithm(this).shallowBeautify();
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ Expression MultiplicationNode::shallowReduce(ReductionContext reductionContext)
|
||||
return Multiplication(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
Expression MultiplicationNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression MultiplicationNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return Multiplication(this).shallowBeautify(reductionContext);
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ static bool CanSimplifyUnitProduct(
|
||||
return isSimpler;
|
||||
}
|
||||
|
||||
Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
|
||||
Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
|
||||
/* Beautifying a Multiplication consists in several possible operations:
|
||||
* - Add Opposite ((-3)*x -> -(3*x), useful when printing fractions)
|
||||
* - Recognize derived units in the product of units
|
||||
@@ -408,7 +408,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
*/
|
||||
|
||||
// Step 1: Turn -n*A into -(n*A)
|
||||
Expression noNegativeNumeral = makePositiveAnyNegativeNumeralFactor(reductionContext);
|
||||
Expression noNegativeNumeral = makePositiveAnyNegativeNumeralFactor(*reductionContext);
|
||||
// If one negative numeral factor was made positive, we turn the expression in an Opposite
|
||||
if (!noNegativeNumeral.isUninitialized()) {
|
||||
Opposite o = Opposite::Builder();
|
||||
@@ -425,7 +425,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
Expression units;
|
||||
/* removeUnit has to be called on reduced expression but we want to modify
|
||||
* the least the expression so we use the uninvasive reduction context. */
|
||||
self = deepReduce(ExpressionNode::ReductionContext::NonInvasiveReductionContext(reductionContext));
|
||||
self = deepReduce(ExpressionNode::ReductionContext::NonInvasiveReductionContext(*reductionContext));
|
||||
self = removeUnit(&units);
|
||||
|
||||
if (self.isUndefined() || units.isUninitialized()) {
|
||||
@@ -434,7 +434,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
goto replace_by_result;
|
||||
}
|
||||
|
||||
ExpressionNode::UnitConversion unitConversionMode = reductionContext.unitConversion();
|
||||
ExpressionNode::UnitConversion unitConversionMode = reductionContext->unitConversion();
|
||||
if (unitConversionMode == ExpressionNode::UnitConversion::Default) {
|
||||
/* Step 2a: Recognize derived units
|
||||
* - Look up in the table of derived units, the one which itself or its inverse simplifies 'units' the most.
|
||||
@@ -501,7 +501,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
// Apply simplifications
|
||||
if (unitsAccu.numberOfChildren() > 0) {
|
||||
// Divide by derived units
|
||||
units = Division::Builder(units, unitsAccu.clone()).deepReduce(reductionContext);
|
||||
units = Division::Builder(units, unitsAccu.clone()).deepReduce(*reductionContext);
|
||||
Expression newUnits;
|
||||
// Separate units and generated values
|
||||
units = units.removeUnit(&newUnits);
|
||||
@@ -528,7 +528,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
* most relevant.
|
||||
*/
|
||||
|
||||
double value = self.approximateToScalar<double>(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit());
|
||||
double value = self.approximateToScalar<double>(reductionContext->context(), reductionContext->complexFormat(), reductionContext->angleUnit());
|
||||
if (std::isnan(value)) {
|
||||
// If the value is undefined, return "undef" without any unit
|
||||
result = Undefined::Builder();
|
||||
@@ -538,7 +538,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
/* In most cases, unit composition works the same for imperial and
|
||||
* metric units. However, in imperial, we want volumes to be displayed
|
||||
* using volume units instead of cubic length. */
|
||||
const bool forceVolumeRepresentative = reductionContext.unitFormat() == Preferences::UnitFormat::Imperial && UnitNode::Vector<int>::FromBaseUnits(units) == UnitNode::VolumeRepresentative::Default().dimensionVector();
|
||||
const bool forceVolumeRepresentative = reductionContext->unitFormat() == Preferences::UnitFormat::Imperial && UnitNode::Vector<int>::FromBaseUnits(units) == UnitNode::VolumeRepresentative::Default().dimensionVector();
|
||||
const UnitNode::Representative * repr;
|
||||
if (forceVolumeRepresentative) {
|
||||
/* The choice of representative doesn't matter, as it will be tuned to a
|
||||
@@ -546,9 +546,9 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
repr = UnitNode::VolumeRepresentative::Default().representativesOfSameDimension();
|
||||
units = Unit::Builder(repr, UnitNode::Prefix::EmptyPrefix());
|
||||
value /= repr->ratio();
|
||||
Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, reductionContext);
|
||||
Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, *reductionContext);
|
||||
} else {
|
||||
Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, reductionContext);
|
||||
Unit::ChooseBestRepresentativeAndPrefixForValue(units, &value, *reductionContext);
|
||||
}
|
||||
}
|
||||
// Build final Expression
|
||||
@@ -558,7 +558,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
} else {
|
||||
// Step 3: Create a Division if relevant
|
||||
Expression numer, denom;
|
||||
splitIntoNormalForm(numer, denom, reductionContext);
|
||||
splitIntoNormalForm(numer, denom, *reductionContext);
|
||||
if (!numer.isUninitialized()) {
|
||||
result = numer;
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ Expression PowerNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return Power(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
Expression PowerNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression PowerNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return Power(this).shallowBeautify(reductionContext);
|
||||
}
|
||||
|
||||
@@ -985,14 +985,14 @@ Expression Power::shallowReduce(ExpressionNode::ReductionContext reductionContex
|
||||
return *this;
|
||||
}
|
||||
|
||||
Expression Power::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
|
||||
Expression Power::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
|
||||
// Step 1: X^-y -> 1/(X->shallowBeautify)^y
|
||||
Expression p = denominator(reductionContext);
|
||||
Expression p = denominator(*reductionContext);
|
||||
// If the denominator is initialized, the index of the power is of form -y
|
||||
if (!p.isUninitialized()) {
|
||||
Division d = Division::Builder(Rational::Builder(1), p);
|
||||
replaceWithInPlace(d);
|
||||
p.shallowReduce(reductionContext);
|
||||
p.shallowReduce(*reductionContext);
|
||||
return d.shallowBeautify(reductionContext);
|
||||
}
|
||||
// Step 2: Turn a^(1/n) into root(a, n), unless base is a unit
|
||||
|
||||
@@ -141,7 +141,7 @@ Expression RationalNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return Rational(this).shallowReduce();
|
||||
}
|
||||
|
||||
Expression RationalNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression RationalNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return Rational(this).shallowBeautify();
|
||||
}
|
||||
|
||||
|
||||
@@ -701,8 +701,8 @@ Expression UnitNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return Unit(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
Expression UnitNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
return Unit(this).shallowBeautify(reductionContext);
|
||||
Expression UnitNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return Unit(this).shallowBeautify();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -824,7 +824,7 @@ Expression Unit::BuildSplit(double value, const Unit * units, int length, Expres
|
||||
ExpressionNode::ReductionTarget::User,
|
||||
ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition,
|
||||
ExpressionNode::UnitConversion::None);
|
||||
return res.squashUnaryHierarchyInPlace().shallowBeautify(keepUnitsContext);
|
||||
return res.squashUnaryHierarchyInPlace().shallowBeautify(&keepUnitsContext);
|
||||
}
|
||||
|
||||
Expression Unit::ConvertTemperatureUnits(Expression e, Unit unit, ExpressionNode::ReductionContext reductionContext) {
|
||||
@@ -904,7 +904,7 @@ Expression Unit::shallowReduce(ExpressionNode::ReductionContext reductionContext
|
||||
return result;
|
||||
}
|
||||
|
||||
Expression Unit::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
|
||||
Expression Unit::shallowBeautify() {
|
||||
// Force Float(1) in front of an orphan Unit
|
||||
if (parent().isUninitialized() || parent().type() == ExpressionNode::Type::Opposite) {
|
||||
Multiplication m = Multiplication::Builder(Float<double>::Builder(1.));
|
||||
|
||||
@@ -20,7 +20,7 @@ Expression UnitConvertNode::removeUnit(Expression * unit) {
|
||||
childAtIndex(1)->removeUnit(unit);
|
||||
return UnitConvert(this).replaceWithUndefinedInPlace();
|
||||
}
|
||||
Expression UnitConvertNode::shallowBeautify(ReductionContext reductionContext) {
|
||||
Expression UnitConvertNode::shallowBeautify(ReductionContext * reductionContext) {
|
||||
return UnitConvert(this).shallowBeautify(reductionContext);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ void UnitConvertNode::deepReduceChildren(ExpressionNode::ReductionContext reduct
|
||||
UnitConvert(this).deepReduceChildren(reductionContext);
|
||||
}
|
||||
|
||||
void UnitConvertNode::deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
|
||||
UnitConvert(this).deepBeautifyChildren(reductionContext);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> UnitConvertNode::templatedApproximate(ApproximationContext approximationContext) const {
|
||||
/* If we are here, it means that the unit convert node was not shallowReduced.
|
||||
@@ -50,15 +54,27 @@ void UnitConvert::deepReduceChildren(ExpressionNode::ReductionContext reductionC
|
||||
childAtIndex(1).deepReduce(reductionContextKeepUnitAsIs);
|
||||
}
|
||||
|
||||
Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reductionContext) {
|
||||
void UnitConvert::deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
|
||||
ExpressionNode::ReductionContext reductionContextKeepUnitAsIs = ExpressionNode::ReductionContext(
|
||||
reductionContext.context(),
|
||||
reductionContext.complexFormat(),
|
||||
reductionContext.angleUnit(),
|
||||
reductionContext.unitFormat(),
|
||||
reductionContext.target(),
|
||||
reductionContext.symbolicComputation(),
|
||||
ExpressionNode::UnitConversion::None);
|
||||
defaultDeepBeautifyChildren(reductionContextKeepUnitAsIs);
|
||||
}
|
||||
|
||||
Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext * reductionContext) {
|
||||
// Discard cases like 4 -> _m/_km
|
||||
{
|
||||
ExpressionNode::ReductionContext reductionContextWithUnits = ExpressionNode::ReductionContext(
|
||||
reductionContext.context(),
|
||||
reductionContext.complexFormat(),
|
||||
reductionContext.angleUnit(),
|
||||
reductionContext.unitFormat(),
|
||||
reductionContext.target(),
|
||||
reductionContext->context(),
|
||||
reductionContext->complexFormat(),
|
||||
reductionContext->angleUnit(),
|
||||
reductionContext->unitFormat(),
|
||||
reductionContext->target(),
|
||||
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined);
|
||||
Expression unit;
|
||||
Expression childWithoutUnit = childAtIndex(1).clone().deepReduce(reductionContextWithUnits).removeUnit(&unit);
|
||||
@@ -68,14 +84,6 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti
|
||||
}
|
||||
}
|
||||
// Find the unit
|
||||
ExpressionNode::ReductionContext reductionContextWithoutUnits = ExpressionNode::ReductionContext(
|
||||
reductionContext.context(),
|
||||
reductionContext.complexFormat(),
|
||||
reductionContext.angleUnit(),
|
||||
reductionContext.unitFormat(),
|
||||
reductionContext.target(),
|
||||
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined,
|
||||
ExpressionNode::UnitConversion::None);
|
||||
Expression unit;
|
||||
childAtIndex(1).removeUnit(&unit);
|
||||
if (unit.isUninitialized()) {
|
||||
@@ -88,7 +96,7 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti
|
||||
if (unit.type() == ExpressionNode::Type::Unit) {
|
||||
Unit unitRef = static_cast<Unit &>(unit);
|
||||
if (unitRef.representative()->dimensionVector() == Unit::TemperatureRepresentative::Default().dimensionVector()) {
|
||||
Expression result = Unit::ConvertTemperatureUnits(childAtIndex(0), unitRef, reductionContext);
|
||||
Expression result = Unit::ConvertTemperatureUnits(childAtIndex(0), unitRef, *reductionContext);
|
||||
replaceWithInPlace(result);
|
||||
return result;
|
||||
}
|
||||
@@ -96,7 +104,7 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti
|
||||
|
||||
// Divide the left member by the new unit
|
||||
Expression division = Division::Builder(childAtIndex(0), unit.clone());
|
||||
division = division.deepReduce(reductionContext);
|
||||
division = division.deepReduce(*reductionContext);
|
||||
Expression divisionUnit;
|
||||
division = division.removeUnit(&divisionUnit);
|
||||
if (!divisionUnit.isUninitialized()) {
|
||||
@@ -105,8 +113,25 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti
|
||||
}
|
||||
Expression result = Multiplication::Builder(division, unit);
|
||||
replaceWithInPlace(result);
|
||||
ExpressionNode::ReductionContext reductionContextWithoutUnits = ExpressionNode::ReductionContext(
|
||||
reductionContext->context(),
|
||||
reductionContext->complexFormat(),
|
||||
reductionContext->angleUnit(),
|
||||
reductionContext->unitFormat(),
|
||||
reductionContext->target(),
|
||||
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined,
|
||||
ExpressionNode::UnitConversion::None);
|
||||
result = result.shallowReduce(reductionContextWithoutUnits);
|
||||
return result.shallowBeautify(reductionContextWithoutUnits);
|
||||
result = result.shallowBeautify(&reductionContextWithoutUnits);
|
||||
*reductionContext = ExpressionNode::ReductionContext(
|
||||
reductionContext->context(),
|
||||
reductionContext->complexFormat(),
|
||||
reductionContext->angleUnit(),
|
||||
reductionContext->unitFormat(),
|
||||
reductionContext->target(),
|
||||
reductionContext->symbolicComputation(),
|
||||
ExpressionNode::UnitConversion::None);
|
||||
return result;
|
||||
}
|
||||
|
||||
template Evaluation<float> UnitConvertNode::templatedApproximate<float>(ApproximationContext approximationContext) const;
|
||||
|
||||
Reference in New Issue
Block a user