mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Make code more object oriented
Turn ExponentsOfBaseUnits function into a method of the Unit::Dimension::Vector class
This commit is contained in:
committed by
Émilie Feral
parent
e2cdf78605
commit
b6d07cbd90
@@ -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<const T*>(this) + i);
|
||||
|
||||
@@ -302,20 +302,6 @@ Expression Multiplication::shallowReduce(ExpressionNode::ReductionContext reduct
|
||||
return privateShallowReduce(reductionContext, true, true);
|
||||
}
|
||||
|
||||
static Unit::Dimension::Vector<Integer>::Metrics ExponentsMetrics(const Unit::Dimension::Vector<Integer> &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<Integer> ExponentsOfBaseUnits(const Expression units) {
|
||||
Unit::Dimension::Vector<Integer> 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<Integer>::Metrics simplifiedMetrics = ExponentsMetrics(simplifiedExponents);
|
||||
Unit::Dimension::Vector<Integer>::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<Integer> unitsExponents = ExponentsOfBaseUnits(units);
|
||||
Unit::Dimension::Vector<Integer>::Metrics unitsMetrics = ExponentsMetrics(unitsExponents);
|
||||
Unit::Dimension::Vector<Integer>::Metrics unitsMetrics = unitsExponents.metrics();
|
||||
Unit::Dimension::Vector<Integer> 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<Integer> entryUnitExponents = ExponentsOfBaseUnits(entryUnit.clone().shallowReduce(reductionContext));
|
||||
Integer entryUnitNorm = ExponentsMetrics(entryUnitExponents).norm;
|
||||
Integer entryUnitNorm = entryUnitExponents.metrics().norm;
|
||||
CanSimplifyUnitProduct(
|
||||
unitsExponents, entryUnitExponents, entryUnitNorm, entryUnit,
|
||||
Integer::Subtraction,
|
||||
|
||||
@@ -75,6 +75,22 @@ const UnitNode::Prefix * UnitNode::Representative::bestPrefixForValue(double & v
|
||||
return bestPre;
|
||||
}
|
||||
|
||||
template<>
|
||||
Unit::Dimension::Vector<Integer>::Metrics UnitNode::Dimension::Vector<Integer>::metrics() const {
|
||||
size_t supportSize = 0;
|
||||
Integer norm(0);
|
||||
for (const Integer * i = reinterpret_cast<const Integer*>(this); i < reinterpret_cast<const Integer*>(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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user