[poincare] Implemment getUnit

This commit is contained in:
Léa Saviot
2020-02-05 12:13:47 +01:00
parent 94334169f0
commit d5b07f1f90
23 changed files with 84 additions and 1 deletions

View File

@@ -33,6 +33,7 @@ public:
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
}
Expression getUnit() const override;
// Layout
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;

View File

@@ -35,6 +35,7 @@ public:
template<typename T> static MatrixComplex<T> computeOnComplexAndMatrix(const std::complex<T> c, const MatrixComplex<T> m, Preferences::ComplexFormat complexFormat) {
return MatrixComplex<T>::Undefined();
}
Expression getUnit() const override;
// Simplification
LayoutShape leftLayoutShape() const override {

View File

@@ -25,6 +25,7 @@ public:
// Properties
Type type() const override { return Type::Division; }
int polynomialDegree(Context * context, const char * symbolName) const override;
Expression getUnit() const override { assert(false); return ExpressionNode::getUnit(); }
// Approximation
virtual Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {

View File

@@ -22,6 +22,7 @@ public:
// Properties
Type type() const override { return Type::EmptyExpression; }
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
Expression getUnit() const override { assert(false); return ExpressionNode::getUnit(); }
// Simplification
LayoutShape leftLayoutShape() const override {

View File

@@ -198,6 +198,10 @@ public:
int getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation) const;
Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { return node()->replaceSymbolWithExpression(symbol, expression); }
/* Units */
Expression getUnit() const { return node()->getUnit(); }
bool hasUnit() const;
/* Complex */
static bool EncounteredComplex();
static void SetEncounteredComplex(bool encounterComplex);

View File

@@ -177,6 +177,8 @@ public:
virtual float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const;
bool isOfType(Type * types, int length) const;
virtual Expression getUnit() const; // Only reduced nodes should answer
/* Simplification */
/* SimplificationOrder returns:
* 1 if e1 > e2

View File

@@ -28,6 +28,9 @@ public:
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const override;
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
/* getUnit() is ExpressionNode::getUnit ->
* as the function is reduced, it would have been replaced if it had a
* definition. It thus has no definition, so no unit. */
private:
char m_name[0]; // MUST be the last member variable

View File

@@ -25,6 +25,7 @@ public:
int polynomialDegree(Context * context, const char * symbolName) const override;
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override;
Expression getUnit() const override;
// Approximation
template<typename T> static Complex<T> compute(const std::complex<T> c, const std::complex<T> d, Preferences::ComplexFormat complexFormat) { return Complex<T>::Builder(c*d); }
@@ -77,6 +78,7 @@ public:
// Properties
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const;
Expression getUnit() const;
// Approximation
template<typename T> static void computeOnArrays(T * m, T * n, T * result, int mNumberOfColumns, int mNumberOfRows, int nNumberOfColumns);
// Simplification

View File

@@ -20,6 +20,7 @@ public:
#endif
private:
Expression getUnit() const override { assert(false); return ExpressionNode::getUnit(); }
// Layout
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;

View File

@@ -21,6 +21,7 @@ public:
// Properties
Type type() const override { return Type::Parenthesis; }
int polynomialDegree(Context * context, const char * symbolName) const override;
Expression getUnit() const override { assert(false); return ExpressionNode::getUnit(); }
// Layout
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;

View File

@@ -29,6 +29,7 @@ public:
Sign sign(Context * context) const override;
Expression setSign(Sign s, ReductionContext reductionContext) override;
bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override;
Expression getUnit() const override;
int polynomialDegree(Context * context, const char * symbolName) const override;
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
@@ -76,6 +77,7 @@ public:
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const;
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
Expression getUnit() const;
private:
constexpr static int k_maxExactPowerMatrix = 100;

View File

@@ -24,6 +24,7 @@ public:
Type type() const override { return Type::Subtraction; }
int polynomialDegree(Context * context, const char * symbolName) const override;
bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override;
Expression getUnit() const override { assert(false); return ExpressionNode::getUnit(); }
// Approximation
template<typename T> static Complex<T> compute(const std::complex<T> c, const std::complex<T> d, Preferences::ComplexFormat complexFormat) { return Complex<T>::Builder(c - d); }

View File

@@ -26,6 +26,8 @@ public:
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const override;
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
/* getUnit returns Undefined, because the symbol would have
* already been replaced if it should have been.*/
/* Layout */
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;

View File

@@ -112,6 +112,7 @@ public:
// Expression Properties
Type type() const override { return Type::Unit; }
Sign sign(Context * context) const override;
Expression getUnit() const override;
/* Layout */
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
@@ -509,6 +510,7 @@ public:
Unit(const UnitNode * node) : Expression(node) {}
static Unit Builder(const Dimension * dimension, const Representative * representative, const Prefix * prefix);
Expression getUnit() const { return clone(); }
// Simplification
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);

View File

@@ -20,6 +20,7 @@ public:
Type type() const override { return Type::UnitConvert; }
private:
Expression getUnit() const override { assert(false); return ExpressionNode::getUnit(); }
// Simplification
Expression shallowReduce(ReductionContext reductionContext) override;
// Evalutation

View File

@@ -19,6 +19,10 @@ Expression AbsoluteValueNode::setSign(Sign s, ReductionContext reductionContext)
return AbsoluteValue(this);
}
Expression AbsoluteValueNode::getUnit() const {
return childAtIndex(0)->getUnit();
}
Layout AbsoluteValueNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return AbsoluteValueLayout::Builder(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
}

View File

@@ -29,6 +29,11 @@ int AdditionNode::getPolynomialCoefficients(Context * context, const char * symb
return Addition(this).getPolynomialCoefficients(context, symbolName, coefficients, symbolicComputation);
}
Expression AdditionNode::getUnit() const {
// The expression is reduced, so we can just ask the unit of the first child
return childAtIndex(0)->getUnit();
}
// Layout
Layout AdditionNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {

View File

@@ -453,6 +453,12 @@ int Expression::getPolynomialReducedCoefficients(const char * symbolName, Expres
return degree;
}
/* Units */
bool Expression::hasUnit() const {
return !getUnit().isUndefined();
}
/* Complex */
bool Expression::EncounteredComplex() {

View File

@@ -124,6 +124,10 @@ bool ExpressionNode::isOfType(Type * types, int length) const {
return false;
}
Expression ExpressionNode::getUnit() const {
return Undefined::Builder();
}
void ExpressionNode::setChildrenInPlace(Expression other) {
Expression(this).defaultSetChildrenInPlace(other);
}

View File

@@ -62,6 +62,10 @@ bool MultiplicationNode::childAtIndexNeedsUserParentheses(const Expression & chi
return child.isOfType(types, 2);
}
Expression MultiplicationNode::getUnit() const {
return Multiplication(this).getUnit();
}
template<typename T>
MatrixComplex<T> MultiplicationNode::computeOnMatrices(const MatrixComplex<T> m, const MatrixComplex<T> n, Preferences::ComplexFormat complexFormat) {
if (m.numberOfColumns() != n.numberOfRows()) {
@@ -252,6 +256,26 @@ int Multiplication::getPolynomialCoefficients(Context * context, const char * sy
return deg;
}
Expression Multiplication::getUnit() const {
const int childrenCount = numberOfChildren();
if (childrenCount == 1) {
return childAtIndex(0).getUnit();
}
Multiplication result = Multiplication::Builder();
int resultChildrenCount = 0;
for (int i = 0; i < childrenCount; i++) {
Expression currentUnit = childAtIndex(i).getUnit();
if (!currentUnit.isUndefined()) {
result.addChildAtIndexInPlace(currentUnit, resultChildrenCount, resultChildrenCount);
resultChildrenCount++;
}
}
if (resultChildrenCount == 0) {
return Undefined::Builder();
}
return std::move(result);
}
template<typename T>
void Multiplication::computeOnArrays(T * m, T * n, T * result, int mNumberOfColumns, int mNumberOfRows, int nNumberOfColumns) {
for (int i = 0; i < mNumberOfRows; i++) {

View File

@@ -82,6 +82,10 @@ int PowerNode::polynomialDegree(Context * context, const char * symbolName) cons
return -1;
}
Expression PowerNode::getUnit() const {
return Power(this).getUnit();
}
int PowerNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const {
return Power(this).getPolynomialCoefficients(context, symbolName, coefficients);
}
@@ -912,6 +916,13 @@ Expression Power::shallowBeautify(ExpressionNode::ReductionContext reductionCont
return *this;
}
Expression Power::getUnit() const {
if (childAtIndex(0).type() == ExpressionNode::Type::Unit) {
return clone();
}
return Power::Builder(childAtIndex(0).getUnit(), childAtIndex(1).clone());
}
// Private
// Simplification

View File

@@ -98,6 +98,10 @@ ExpressionNode::Sign UnitNode::sign(Context * context) const {
return Sign::Positive;
}
Expression UnitNode::getUnit() const {
return Unit(this).getUnit();
}
int UnitNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const {
if (!ascending) {
return e->simplificationOrderSameType(this, true, canBeInterrupted);

View File

@@ -33,7 +33,7 @@ Expression UnitConvert::shallowReduce(ExpressionNode::ReductionContext reduction
}
}
// Find the unit
ReductionContext unitReductionContext = ReductionContext(
ExpressionNode::ReductionContext unitReductionContext = ExpressionNode::ReductionContext(
reductionContext.context(),
reductionContext.complexFormat(),
reductionContext.angleUnit(),