mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
[poincare] Add watthour representation to classic unit conversion
This commit is contained in:
@@ -121,6 +121,7 @@ public:
|
||||
bool isThree() const { return (numberOfDigits() == 1 && digit(0) == 3 && !m_negative); };
|
||||
bool isTen() const { return (numberOfDigits() == 1 && digit(0) == 10 && !m_negative); };
|
||||
bool isMinusOne() const { return (numberOfDigits() == 1 && digit(0) == 1 && m_negative); };
|
||||
bool isMinusTwo() const { return (numberOfDigits() == 1 && digit(0) == 2 && m_negative); };
|
||||
bool isZero() const { return (numberOfDigits() == 0); };
|
||||
bool isEven() const { return ((digit(0) & 1) == 0); }
|
||||
|
||||
|
||||
@@ -45,8 +45,10 @@ public:
|
||||
// Basic test
|
||||
bool isZero() const { return unsignedNumerator().isZero(); }
|
||||
bool isOne() const { return signedNumerator().isOne() && isInteger(); }
|
||||
bool isTwo() const { return signedNumerator().isTwo() && isInteger(); }
|
||||
bool isThree() const { return signedNumerator().isThree() && isInteger(); }
|
||||
bool isMinusOne() const { return signedNumerator().isMinusOne() && isInteger(); }
|
||||
bool isMinusTwo() const { return signedNumerator().isMinusTwo() && isInteger(); }
|
||||
bool isHalf() const { return signedNumerator().isOne() && denominator().isTwo(); }
|
||||
bool isMinusHalf() const { return signedNumerator().isMinusOne() && denominator().isTwo(); }
|
||||
bool isTen() const { return signedNumerator().isTen() && isInteger(); }
|
||||
@@ -90,8 +92,10 @@ public:
|
||||
bool isNegative() const { return node()->isNegative(); }
|
||||
bool isZero() const { return node()->isZero(); }
|
||||
bool isOne() const { return node()->isOne(); }
|
||||
bool isTwo() const { return node()->isTwo(); }
|
||||
bool isThree() const { return node()->isThree(); }
|
||||
bool isMinusOne() const { return node()->isMinusOne(); }
|
||||
bool isMinusTwo() const { return node()->isMinusTwo(); }
|
||||
bool isHalf() const { return node()->isHalf(); }
|
||||
bool isMinusHalf() const { return node()->isMinusHalf(); }
|
||||
bool isTen() const { return node()->isTen(); }
|
||||
|
||||
@@ -415,10 +415,13 @@ public:
|
||||
NegativePrefixes),
|
||||
};
|
||||
// TODO: find a better way to find defines these pointers
|
||||
static_assert(sizeof(TimeRepresentatives)/sizeof(Representative) == 7, "The Unit::SecondRepresentative, Unit::HourRepresentative might require to be fixed if the TimeRepresentatives table was changed.");
|
||||
static const Representative constexpr * SecondRepresentative = &TimeRepresentatives[0];
|
||||
static const Representative constexpr * HourRepresentative = &TimeRepresentatives[2];
|
||||
static const Representative constexpr * MeterRepresentative = &DistanceRepresentatives[0];
|
||||
static const Representative constexpr * KilogramRepresentative = &MassRepresentatives[0];
|
||||
static const Representative constexpr * LiterRepresentative = &VolumeRepresentatives[0];
|
||||
static const Representative constexpr * WattRepresentative = &PowerRepresentatives[0];
|
||||
static constexpr const Dimension DimensionTable[] = {
|
||||
/* The current table is sorted from most to least simple units.
|
||||
* The order determines the behavior of simplification.
|
||||
@@ -724,8 +727,11 @@ public:
|
||||
),
|
||||
};
|
||||
// TODO: find a better way to find defines these pointers
|
||||
static_assert(sizeof(DimensionTable)/sizeof(Dimension) == 23, "The Unit::TimeDimension, Unit::DistanceDimension and so on might require to be fixed if the Dimension table was changed.");
|
||||
static const Dimension constexpr * TimeDimension = &DimensionTable[0] ;
|
||||
static const Dimension constexpr * DistanceDimension = &DimensionTable[1];
|
||||
static const Dimension constexpr * MassDimension = &DimensionTable[2];
|
||||
static const Dimension constexpr * PowerDimension = &DimensionTable[11];
|
||||
static const Dimension constexpr * VolumeDimension = &DimensionTable[sizeof(DimensionTable)/sizeof(Dimension)-1];
|
||||
|
||||
static constexpr const Unit::Dimension * DimensionTableUpperBound =
|
||||
@@ -738,11 +744,14 @@ public:
|
||||
static Unit Kilometer() { return Builder(DistanceDimension, MeterRepresentative, &KiloPrefix); }
|
||||
static Unit Hour() { return Builder(TimeDimension, HourRepresentative, &EmptyPrefix); }
|
||||
static Unit Liter() { return Builder(VolumeDimension, LiterRepresentative, &EmptyPrefix); }
|
||||
static Unit Watt() { return Builder(PowerDimension, WattRepresentative, &EmptyPrefix); }
|
||||
|
||||
static bool IsISSpeed(Expression & e);
|
||||
static bool IsISVolume(Expression & e);
|
||||
static bool IsISEnergy(Expression & e);
|
||||
bool isMeter() const;
|
||||
bool isSecond() const;
|
||||
bool isKilogram() const;
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
@@ -750,6 +759,7 @@ public:
|
||||
|
||||
static constexpr double MeterPerSecondToKilometerPerHourFactor = 60.0*60.0/1000.0;
|
||||
static constexpr double CubicMeterToLiterFactor = 10.0*10.0*10.0;
|
||||
static constexpr double JouleToWatthourFactor = 1.0/3600.0;
|
||||
private:
|
||||
UnitNode * node() const { return static_cast<UnitNode *>(Expression::node()); }
|
||||
Expression removeUnit(Expression * unit);
|
||||
|
||||
@@ -480,6 +480,15 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
units = Unit::Liter();
|
||||
static_cast<Unit&>(units).chooseBestMultipleForValue(value, 1, reductionContext);
|
||||
}
|
||||
if (Unit::IsISEnergy(units)) {
|
||||
value *= Unit::JouleToWatthourFactor;
|
||||
Unit w = Unit::Watt();
|
||||
units = Multiplication::Builder(
|
||||
w,
|
||||
Unit::Hour()
|
||||
);
|
||||
w.chooseBestMultipleForValue(value, 1, reductionContext);
|
||||
}
|
||||
// TODO: what to do if no classic conversion?
|
||||
}
|
||||
if (result.isUninitialized()) {
|
||||
|
||||
@@ -361,6 +361,11 @@ bool Unit::isMeter() const {
|
||||
return node()->dimension() == DistanceDimension && node()->representative() == MeterRepresentative && node()->prefix() == &EmptyPrefix;
|
||||
}
|
||||
|
||||
|
||||
bool Unit::isKilogram() const {
|
||||
return node()->dimension() == MassDimension && node()->representative() == KilogramRepresentative && node()->prefix() == &KiloPrefix;
|
||||
}
|
||||
|
||||
bool Unit::IsISSpeed(Expression & e) {
|
||||
// Form m*s^-1
|
||||
return e.type() == ExpressionNode::Type::Multiplication && e.numberOfChildren() == 2 &&
|
||||
@@ -377,6 +382,18 @@ bool Unit::IsISVolume(Expression & e) {
|
||||
e.childAtIndex(1).type() == ExpressionNode::Type::Rational && e.childAtIndex(1).convert<const Rational>().isThree();
|
||||
}
|
||||
|
||||
bool Unit::IsISEnergy(Expression & e) {
|
||||
// Form _kg*_m^2*_s^-2
|
||||
return e.type() == ExpressionNode::Type::Multiplication && e.numberOfChildren() == 3 &&
|
||||
e.childAtIndex(0).type() == ExpressionNode::Type::Unit && e.childAtIndex(0).convert<Unit>().isKilogram() &&
|
||||
e.childAtIndex(1).type() == ExpressionNode::Type::Power &&
|
||||
e.childAtIndex(1).childAtIndex(0).type() == ExpressionNode::Type::Unit && e.childAtIndex(1).childAtIndex(0).convert<Unit>().isMeter();
|
||||
e.childAtIndex(1).childAtIndex(1).type() == ExpressionNode::Type::Rational && e.childAtIndex(1).childAtIndex(1).convert<const Rational>().isTwo() &&
|
||||
e.childAtIndex(2).type() == ExpressionNode::Type::Power &&
|
||||
e.childAtIndex(2).childAtIndex(0).type() == ExpressionNode::Type::Unit && e.childAtIndex(1).childAtIndex(0).convert<Unit>().isSecond();
|
||||
e.childAtIndex(2).childAtIndex(1).type() == ExpressionNode::Type::Rational && e.childAtIndex(1).childAtIndex(1).convert<const Rational>().isMinusTwo();
|
||||
}
|
||||
|
||||
template Evaluation<float> UnitNode::templatedApproximate<float>(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template Evaluation<double> UnitNode::templatedApproximate<double>(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
|
||||
@@ -1287,6 +1287,7 @@ QUIZ_CASE(poincare_simplification_unit_conversion) {
|
||||
assert_parsed_expression_simplify_to("10_m/_h", "0.01×_km×_h^\x12-1\x13", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, ClassicUnitConversion);
|
||||
assert_parsed_expression_simplify_to("0.2_m^3", "200×_L", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, ClassicUnitConversion);
|
||||
assert_parsed_expression_simplify_to("0.000012_m^3", "1.2×_cL", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, ClassicUnitConversion);
|
||||
assert_parsed_expression_simplify_to("3600_J", "1×_W×_h", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, ClassicUnitConversion);
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_simplification_user_function) {
|
||||
|
||||
Reference in New Issue
Block a user