diff --git a/poincare/include/poincare/unit.h b/poincare/include/poincare/unit.h index a7a21a67a..b340234e1 100644 --- a/poincare/include/poincare/unit.h +++ b/poincare/include/poincare/unit.h @@ -89,6 +89,7 @@ public: size_t supportSize; T norm; }; + Metrics metrics() const; const T coefficientAtIndex(size_t i) const { assert(i < NumberOfBaseUnits); return *(reinterpret_cast(this) + i); diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 4e732b67d..dadef4123 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -302,20 +302,6 @@ Expression Multiplication::shallowReduce(ExpressionNode::ReductionContext reduct return privateShallowReduce(reductionContext, true, true); } -static Unit::Dimension::Vector::Metrics ExponentsMetrics(const Unit::Dimension::Vector &exponents) { - size_t supportSize = 0; - Integer norm(0); - for (size_t i = 0; i < Unit::NumberOfBaseUnits; i++) { - Integer unsignedExponent = exponents.coefficientAtIndex(i); - unsignedExponent.setNegative(false); - if (!unsignedExponent.isZero()) { - supportSize++; - norm = Integer::Addition(norm, unsignedExponent); - } - } - return {.supportSize = supportSize, .norm = norm}; -} - static Unit::Dimension::Vector ExponentsOfBaseUnits(const Expression units) { Unit::Dimension::Vector exponents; // Make sure the provided Expression is a Multiplication @@ -361,7 +347,7 @@ static bool CanSimplifyUnitProduct( for (size_t i = 0; i < Unit::NumberOfBaseUnits; i++) { simplifiedExponents.setCoefficientAtIndex(i, operationOnExponents(unitsExponents.coefficientAtIndex(i), entryUnitExponents.coefficientAtIndex(i))); } - Unit::Dimension::Vector::Metrics simplifiedMetrics = ExponentsMetrics(simplifiedExponents); + Unit::Dimension::Vector::Metrics simplifiedMetrics = simplifiedExponents.metrics(); bool isSimpler = simplifiedMetrics.supportSize < bestRemainderMetrics.supportSize || (simplifiedMetrics.supportSize == bestRemainderMetrics.supportSize && Integer::Addition(simplifiedMetrics.norm, entryUnitNorm).isLowerThan(Integer::Addition(bestRemainderMetrics.norm, bestUnitNorm))); @@ -406,7 +392,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu */ Multiplication unitsAccu = Multiplication::Builder(); Unit::Dimension::Vector unitsExponents = ExponentsOfBaseUnits(units); - Unit::Dimension::Vector::Metrics unitsMetrics = ExponentsMetrics(unitsExponents); + Unit::Dimension::Vector::Metrics unitsMetrics = unitsExponents.metrics(); Unit::Dimension::Vector bestRemainderExponents; while (unitsMetrics.supportSize > 1) { Expression bestUnit; @@ -415,7 +401,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu for (const Unit::Dimension * dim = Unit::DimensionTable + Unit::NumberOfBaseUnits; dim < Unit::DimensionTableUpperBound; dim++) { Unit entryUnit = Unit::Builder(dim, dim->stdRepresentative(), dim->stdRepresentativePrefix()); Unit::Dimension::Vector entryUnitExponents = ExponentsOfBaseUnits(entryUnit.clone().shallowReduce(reductionContext)); - Integer entryUnitNorm = ExponentsMetrics(entryUnitExponents).norm; + Integer entryUnitNorm = entryUnitExponents.metrics().norm; CanSimplifyUnitProduct( unitsExponents, entryUnitExponents, entryUnitNorm, entryUnit, Integer::Subtraction, diff --git a/poincare/src/unit.cpp b/poincare/src/unit.cpp index c94c3abc6..25c8f0d04 100644 --- a/poincare/src/unit.cpp +++ b/poincare/src/unit.cpp @@ -75,6 +75,22 @@ const UnitNode::Prefix * UnitNode::Representative::bestPrefixForValue(double & v return bestPre; } +template<> +Unit::Dimension::Vector::Metrics UnitNode::Dimension::Vector::metrics() const { + size_t supportSize = 0; + Integer norm(0); + for (const Integer * i = reinterpret_cast(this); i < reinterpret_cast(this) + NumberOfBaseUnits; i++) { + Integer coefficient = *i; + if (coefficient.isZero()) { + continue; + } + supportSize++; + coefficient.setNegative(false); + norm = Integer::Addition(norm, coefficient); + } + return {.supportSize = supportSize, .norm = norm}; +} + bool UnitNode::Dimension::canParse(const char * symbol, size_t length, const Representative * * representative, const Prefix * * prefix) const {