From fad375c11c557d59e28036275b2a9347e4a245b9 Mon Sep 17 00:00:00 2001 From: Gabriel Ozouf Date: Wed, 22 Jul 2020 10:01:53 +0200 Subject: [PATCH] [poincare] Add unitFormat to ReductionContext Change-Id: I1d3fcd2f47c973c041e1be84e9a902dd58de3562 --- .../matrix_list_controller.cpp | 6 +- .../unit_list_controller.cpp | 53 +-- apps/calculation/calculation.cpp | 2 +- apps/global_preferences.cpp | 5 - apps/global_preferences.h | 2 +- apps/shared/poincare_helpers.h | 11 +- apps/solver/equation.cpp | 3 +- apps/solver/equation_store.cpp | 14 +- apps/solver/test/helpers.cpp | 4 +- poincare/include/poincare/equal.h | 2 +- poincare/include/poincare/expression.h | 14 +- poincare/include/poincare/expression_node.h | 5 +- poincare/include/poincare/matrix.h | 2 +- poincare/include/poincare/number.h | 2 +- poincare/include/poincare/preferences.h | 3 - poincare/include/poincare/unit.h | 12 +- poincare/src/addition.cpp | 1 + poincare/src/equal.cpp | 4 +- poincare/src/expression.cpp | 38 +- poincare/src/integer.cpp | 2 +- poincare/src/matrix.cpp | 4 +- poincare/src/unit.cpp | 37 +- poincare/src/unit_convert.cpp | 3 + poincare/test/approximation.cpp | 348 +++++++++--------- poincare/test/derivative.cpp | 4 +- poincare/test/expression_properties.cpp | 38 +- poincare/test/helper.cpp | 40 +- poincare/test/helper.h | 17 +- poincare/test/simplification.cpp | 321 ++++++++-------- 29 files changed, 510 insertions(+), 487 deletions(-) diff --git a/apps/calculation/additional_outputs/matrix_list_controller.cpp b/apps/calculation/additional_outputs/matrix_list_controller.cpp index 6ab5e6a6e..eed72ad18 100644 --- a/apps/calculation/additional_outputs/matrix_list_controller.cpp +++ b/apps/calculation/additional_outputs/matrix_list_controller.cpp @@ -1,6 +1,7 @@ #include "matrix_list_controller.h" #include "../app.h" #include "../../shared/poincare_helpers.h" +#include #include #include #include @@ -30,6 +31,7 @@ void MatrixListController::setExpression(Poincare::Expression e) { context, preferences->complexFormat(), preferences->angleUnit(), + GlobalPreferences::sharedGlobalPreferences()->unitFormat(), ExpressionNode::ReductionTarget::SystemForApproximation, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); @@ -78,7 +80,7 @@ Poincare::Layout MatrixListController::getLayoutFromExpression(Expression e, Con Expression approximateExpression; Expression simplifiedExpression; e.simplifyAndApproximate(&simplifiedExpression, &approximateExpression, context, - preferences->complexFormat(), preferences->angleUnit(), + preferences->complexFormat(), preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(), ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); // simplify might have been interrupted, in which case we use approximate if (simplifiedExpression.isUninitialized()) { @@ -100,4 +102,4 @@ I18n::Message MatrixListController::messageAtIndex(int index) { return messages[m_indexMessageMap[index]]; } -} \ No newline at end of file +} diff --git a/apps/calculation/additional_outputs/unit_list_controller.cpp b/apps/calculation/additional_outputs/unit_list_controller.cpp index 111fab656..2ae84d917 100644 --- a/apps/calculation/additional_outputs/unit_list_controller.cpp +++ b/apps/calculation/additional_outputs/unit_list_controller.cpp @@ -12,11 +12,11 @@ using namespace Shared; namespace Calculation { -void storeAndSimplify(Expression e, Expression * dest, bool requireSimplification, bool canChangeUnitPrefix) { +void storeAndSimplify(Expression e, Expression * dest, bool requireSimplification, bool canChangeUnitPrefix, ExpressionNode::ReductionContext reductionContext) { assert(!e.isUninitialized()); *dest = e; if (requireSimplification) { - Shared::PoincareHelpers::Simplify(dest, App::app()->localContext(), ExpressionNode::ReductionTarget::User); + *dest = dest->simplify(reductionContext); } if (canChangeUnitPrefix) { Expression newUnits; @@ -25,17 +25,10 @@ void storeAndSimplify(Expression e, Expression * dest, bool requireSimplificatio * SI units. */ if (!requireSimplification) { // Reduce to be able to removeUnit - PoincareHelpers::Reduce(dest, App::app()->localContext(), ExpressionNode::ReductionTarget::User); + *dest = dest->reduce(reductionContext); } *dest = dest->removeUnit(&newUnits); double value = Shared::PoincareHelpers::ApproximateToScalar(*dest, App::app()->localContext()); - ExpressionNode::ReductionContext reductionContext( - App::app()->localContext(), - Preferences::sharedPreferences()->complexFormat(), - Preferences::sharedPreferences()->angleUnit(), - ExpressionNode::ReductionTarget::User, - ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); - Unit::ChooseBestPrefixForValue(&newUnits, &value, reductionContext); *dest = Multiplication::Builder(Number::FloatNumber(value), newUnits); } } @@ -59,37 +52,51 @@ void UnitListController::setExpression(Poincare::Expression e) { // Reduce to be able to recognize units PoincareHelpers::Reduce(©, App::app()->localContext(), ExpressionNode::ReductionTarget::User); copy = copy.removeUnit(&units); - Preferences::UnitFormat chosenFormat = Preferences::sharedPreferences()->unitFormat(); + Preferences::UnitFormat chosenFormat = GlobalPreferences::sharedGlobalPreferences()->unitFormat(); Preferences::UnitFormat otherFormat = (chosenFormat == Preferences::UnitFormat::Metric) ? Preferences::UnitFormat::Imperial : Preferences::UnitFormat::Metric; + ExpressionNode::ReductionContext chosenFormatContext( + App::app()->localContext(), + Preferences::sharedPreferences()->complexFormat(), + Preferences::sharedPreferences()->angleUnit(), + chosenFormat, + ExpressionNode::ReductionTarget::User, + ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); + ExpressionNode::ReductionContext otherFormatContext( + App::app()->localContext(), + Preferences::sharedPreferences()->complexFormat(), + Preferences::sharedPreferences()->angleUnit(), + otherFormat, + ExpressionNode::ReductionTarget::User, + ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); if (Unit::IsSISpeed(units)) { // 1.a. Turn speed into km/h or mi/h - storeAndSimplify(Unit::StandardSpeedConversion(m_expression.clone(), chosenFormat, App::app()->localContext()), &expressions[numberOfExpressions++], true, false); - storeAndSimplify(Unit::StandardSpeedConversion(m_expression.clone(), otherFormat, App::app()->localContext()), &expressions[numberOfExpressions++], true, false); + storeAndSimplify(Unit::StandardSpeedConversion(m_expression.clone(), chosenFormatContext), &expressions[numberOfExpressions++], true, false, chosenFormatContext); + storeAndSimplify(Unit::StandardSpeedConversion(m_expression.clone(), otherFormatContext), &expressions[numberOfExpressions++], true, false, otherFormatContext); } else if (Unit::IsSIVolume(units)) { // 1.b. Turn volume into L or _gal + _cp + _floz - storeAndSimplify(Unit::StandardVolumeConversion(m_expression.clone(), chosenFormat, App::app()->localContext()), &expressions[numberOfExpressions++], chosenFormat == Preferences::UnitFormat::Metric, chosenFormat == Preferences::UnitFormat::Metric); - storeAndSimplify(Unit::StandardVolumeConversion(m_expression.clone(), otherFormat, App::app()->localContext()), &expressions[numberOfExpressions++], otherFormat == Preferences::UnitFormat::Metric, otherFormat == Preferences::UnitFormat::Metric); + storeAndSimplify(Unit::StandardVolumeConversion(m_expression.clone(), chosenFormatContext), &expressions[numberOfExpressions++], chosenFormat == Preferences::UnitFormat::Metric, chosenFormat == Preferences::UnitFormat::Metric, chosenFormatContext); + storeAndSimplify(Unit::StandardVolumeConversion(m_expression.clone(), otherFormatContext), &expressions[numberOfExpressions++], otherFormat == Preferences::UnitFormat::Metric, otherFormat == Preferences::UnitFormat::Metric, otherFormatContext); } else if (Unit::IsSIEnergy(units)) { // 1.c. Turn energy into Wh - storeAndSimplify(UnitConvert::Builder(m_expression.clone(), Multiplication::Builder(Unit::Watt(), Unit::Hour())), &expressions[numberOfExpressions++], true, true); - storeAndSimplify(UnitConvert::Builder(m_expression.clone(), Unit::ElectronVolt()), &expressions[numberOfExpressions++], true, true); + storeAndSimplify(UnitConvert::Builder(m_expression.clone(), Multiplication::Builder(Unit::Watt(), Unit::Hour())), &expressions[numberOfExpressions++], true, true, chosenFormatContext); + storeAndSimplify(UnitConvert::Builder(m_expression.clone(), Unit::ElectronVolt()), &expressions[numberOfExpressions++], true, true, chosenFormatContext); } else if (Unit::IsSITime(units)) { // 1.d. Turn time into ? year + ? month + ? day + ? h + ? min + ? s double value = Shared::PoincareHelpers::ApproximateToScalar(copy, App::app()->localContext()); expressions[numberOfExpressions++] = Unit::BuildTimeSplit(value, App::app()->localContext()); } else if (Unit::IsSIDistance(units)) { // 1.e. Turn distance into _?m or _mi + _yd + _ft + _in - storeAndSimplify(Unit::StandardDistanceConversion(m_expression.clone(), chosenFormat, App::app()->localContext()), &expressions[numberOfExpressions++], chosenFormat == Preferences::UnitFormat::Metric, chosenFormat == Preferences::UnitFormat::Metric); - storeAndSimplify(Unit::StandardDistanceConversion(m_expression.clone(), otherFormat, App::app()->localContext()), &expressions[numberOfExpressions++], otherFormat == Preferences::UnitFormat::Metric, otherFormat == Preferences::UnitFormat::Metric); + storeAndSimplify(Unit::StandardDistanceConversion(m_expression.clone(), chosenFormatContext), &expressions[numberOfExpressions++], chosenFormat == Preferences::UnitFormat::Metric, chosenFormat == Preferences::UnitFormat::Metric, chosenFormatContext); + storeAndSimplify(Unit::StandardDistanceConversion(m_expression.clone(), otherFormatContext), &expressions[numberOfExpressions++], otherFormat == Preferences::UnitFormat::Metric, otherFormat == Preferences::UnitFormat::Metric, otherFormatContext); } else if (Unit::IsSISurface(units)) { // 1.f. Turn surface into hectares or acres - storeAndSimplify(Unit::StandardSurfaceConversion(m_expression.clone(), chosenFormat, App::app()->localContext()), &expressions[numberOfExpressions++], true, false); - storeAndSimplify(Unit::StandardSurfaceConversion(m_expression.clone(), otherFormat, App::app()->localContext()), &expressions[numberOfExpressions++], true, false); + storeAndSimplify(Unit::StandardSurfaceConversion(m_expression.clone(), chosenFormatContext), &expressions[numberOfExpressions++], true, false, chosenFormatContext); + storeAndSimplify(Unit::StandardSurfaceConversion(m_expression.clone(), otherFormatContext), &expressions[numberOfExpressions++], true, false, otherFormatContext); } else if (Unit::IsSIMass(units)) { // 1.g. Turn mass into _?g and _lb + _oz - storeAndSimplify(Unit::StandardMassConversion(m_expression.clone(), chosenFormat, App::app()->localContext()), &expressions[numberOfExpressions++], chosenFormat == Preferences::UnitFormat::Metric, chosenFormat == Preferences::UnitFormat::Metric); - storeAndSimplify(Unit::StandardMassConversion(m_expression.clone(), otherFormat, App::app()->localContext()), &expressions[numberOfExpressions++], otherFormat == Preferences::UnitFormat::Metric, otherFormat == Preferences::UnitFormat::Metric); + storeAndSimplify(Unit::StandardMassConversion(m_expression.clone(), chosenFormatContext), &expressions[numberOfExpressions++], chosenFormat == Preferences::UnitFormat::Metric, chosenFormat == Preferences::UnitFormat::Metric, chosenFormatContext); + storeAndSimplify(Unit::StandardMassConversion(m_expression.clone(), otherFormatContext), &expressions[numberOfExpressions++], otherFormat == Preferences::UnitFormat::Metric, otherFormat == Preferences::UnitFormat::Metric, otherFormatContext); } // 2. SI units only diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index c51091768..f0c62dddb 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -218,7 +218,7 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual( Preferences * preferences = Preferences::sharedPreferences(); // TODO: complex format should not be needed here (as it is not used to create layouts) Preferences::ComplexFormat complexFormat = Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), m_inputText); - m_equalSign = Expression::ParsedExpressionsAreEqual(exactOutputText(), approximateOutputText(NumberOfSignificantDigits::UserDefined), context, complexFormat, preferences->angleUnit()) ? EqualSign::Equal : EqualSign::Approximation; + m_equalSign = Expression::ParsedExpressionsAreEqual(exactOutputText(), approximateOutputText(NumberOfSignificantDigits::UserDefined), context, complexFormat, preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat()) ? EqualSign::Equal : EqualSign::Approximation; return m_equalSign; } else { /* Do not override m_equalSign in case there is enough room in the pool diff --git a/apps/global_preferences.cpp b/apps/global_preferences.cpp index 5c6c4cd77..c6644f5fd 100644 --- a/apps/global_preferences.cpp +++ b/apps/global_preferences.cpp @@ -5,11 +5,6 @@ GlobalPreferences * GlobalPreferences::sharedGlobalPreferences() { return &globalPreferences; } -void GlobalPreferences::setCountry(I18n::Country country) { - m_country = country; - Poincare::Preferences::sharedPreferences()->setUnitFormat(unitFormat()); -} - GlobalPreferences::ExamMode GlobalPreferences::examMode() const { if (m_examMode == ExamMode::Unknown) { uint8_t mode = Ion::ExamMode::FetchExamMode(); diff --git a/apps/global_preferences.h b/apps/global_preferences.h index b4471d008..c6c20ff8b 100644 --- a/apps/global_preferences.h +++ b/apps/global_preferences.h @@ -15,7 +15,7 @@ public: I18n::Language language() const { return m_language; } void setLanguage(I18n::Language language) { m_language = language; } I18n::Country country() const { return m_country; } - void setCountry(I18n::Country country); + void setCountry(I18n::Country country) { m_country = country; } CountryPreferences::AvailableExamModes availableExamModes() const { return I18n::CountryPreferencesArray[static_cast(m_country)].availableExamModes(); } CountryPreferences::MethodForQuartiles methodForQuartiles() const { return I18n::CountryPreferencesArray[static_cast(m_country)].methodForQuartiles(); } Poincare::Preferences::UnitFormat unitFormat() const { return I18n::CountryPreferencesArray[static_cast(m_country)].unitFormat(); } diff --git a/apps/shared/poincare_helpers.h b/apps/shared/poincare_helpers.h index 774547e17..372c66add 100644 --- a/apps/shared/poincare_helpers.h +++ b/apps/shared/poincare_helpers.h @@ -1,6 +1,7 @@ #ifndef SHARED_POINCARE_HELPERS_H #define SHARED_POINCARE_HELPERS_H +#include #include #include #include @@ -53,33 +54,33 @@ template inline T ApproximateToScalar(const char * text, Poincare::Context * context, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text); - return Poincare::Expression::ApproximateToScalar(text, context, complexFormat, preferences->angleUnit(), symbolicComputation); + return Poincare::Expression::ApproximateToScalar(text, context, complexFormat, preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(), symbolicComputation); } inline Poincare::Expression ParseAndSimplify(const char * text, Poincare::Context * context, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text); - return Poincare::Expression::ParseAndSimplify(text, context, complexFormat, preferences->angleUnit(), symbolicComputation); + return Poincare::Expression::ParseAndSimplify(text, context, complexFormat, preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(), symbolicComputation); } inline void Simplify(Poincare::Expression * e, Poincare::Context * context, Poincare::ExpressionNode::ReductionTarget target, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion unitConversion = Poincare::ExpressionNode::UnitConversion::Default) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), *e, context); - *e = e->simplify(Poincare::ExpressionNode::ReductionContext(context, complexFormat, preferences->angleUnit(), target, symbolicComputation, unitConversion)); + *e = e->simplify(Poincare::ExpressionNode::ReductionContext(context, complexFormat, preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(), target, symbolicComputation, unitConversion)); } inline void Reduce(Poincare::Expression * e, Poincare::Context * context, Poincare::ExpressionNode::ReductionTarget target, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion unitConversion = Poincare::ExpressionNode::UnitConversion::Default) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), *e, context); - *e = e->reduce(Poincare::ExpressionNode::ReductionContext(context, complexFormat, preferences->angleUnit(), target, symbolicComputation, unitConversion)); + *e = e->reduce(Poincare::ExpressionNode::ReductionContext(context, complexFormat, preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(), target, symbolicComputation, unitConversion)); } inline void ParseAndSimplifyAndApproximate(const char * text, Poincare::Expression * simplifiedExpression, Poincare::Expression * approximateExpression, Poincare::Context * context, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text); - Poincare::Expression::ParseAndSimplifyAndApproximate(text, simplifiedExpression, approximateExpression, context, complexFormat, preferences->angleUnit(), symbolicComputation); + Poincare::Expression::ParseAndSimplifyAndApproximate(text, simplifiedExpression, approximateExpression, context, complexFormat, preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(), symbolicComputation); } inline typename Poincare::Coordinate2D NextMinimum(const Poincare::Expression e, const char * symbol, double start, double step, double max, Poincare::Context * context) { diff --git a/apps/solver/equation.cpp b/apps/solver/equation.cpp index 80d2a4cab..a9b14f194 100644 --- a/apps/solver/equation.cpp +++ b/apps/solver/equation.cpp @@ -1,4 +1,5 @@ #include "equation.h" +#include #include #include #include @@ -49,7 +50,7 @@ Expression Equation::Model::standardForm(const Storage::Record * record, Context *returnedExpression = Undefined::Builder(); } else if (expressionRed.type() == ExpressionNode::Type::Equal) { Preferences * preferences = Preferences::sharedPreferences(); - *returnedExpression = static_cast(expressionRed).standardEquation(contextToUse, Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), expressionInputWithoutFunctions, contextToUse), preferences->angleUnit()); + *returnedExpression = static_cast(expressionRed).standardEquation(contextToUse, Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), expressionInputWithoutFunctions, contextToUse), preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat()); } else { assert(expressionRed.type() == ExpressionNode::Type::Rational && static_cast(expressionRed).isOne()); // The equality was reduced which means the equality was always true. diff --git a/apps/solver/equation_store.cpp b/apps/solver/equation_store.cpp index 867a19d7c..8517bef6c 100644 --- a/apps/solver/equation_store.cpp +++ b/apps/solver/equation_store.cpp @@ -180,7 +180,7 @@ EquationStore::Error EquationStore::privateExactSolve(Poincare::Context * contex bool isLinear = true; // Invalid the linear system if one equation is non-linear Preferences * preferences = Preferences::sharedPreferences(); for (int i = 0; i < numberOfDefinedModels(); i++) { - isLinear = isLinear && modelForRecord(definedRecordAtIndex(i))->standardForm(context, replaceFunctionsButNotSymbols).getLinearCoefficients((char *)m_variables, Poincare::SymbolAbstract::k_maxNameSize, coefficients[i], &constants[i], context, updatedComplexFormat(context), preferences->angleUnit(), replaceFunctionsButNotSymbols ? ExpressionNode::SymbolicComputation::ReplaceDefinedFunctionsWithDefinitions : ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition); + isLinear = isLinear && modelForRecord(definedRecordAtIndex(i))->standardForm(context, replaceFunctionsButNotSymbols).getLinearCoefficients((char *)m_variables, Poincare::SymbolAbstract::k_maxNameSize, coefficients[i], &constants[i], context, updatedComplexFormat(context), preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(), replaceFunctionsButNotSymbols ? ExpressionNode::SymbolicComputation::ReplaceDefinedFunctionsWithDefinitions : ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition); if (!isLinear) { // TODO: should we clean pool allocated memory if the system is not linear #if 0 @@ -218,6 +218,7 @@ EquationStore::Error EquationStore::privateExactSolve(Poincare::Context * contex context, updatedComplexFormat(context), preferences->angleUnit(), + GlobalPreferences::sharedGlobalPreferences()->unitFormat(), replaceFunctionsButNotSymbols ? ExpressionNode::SymbolicComputation::ReplaceDefinedFunctionsWithDefinitions : ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition); @@ -259,7 +260,7 @@ EquationStore::Error EquationStore::privateExactSolve(Poincare::Context * contex * solutions. */ m_exactSolutionIdentity[solutionIndex] = forbidExactSolutions || strcmp(exactBuffer, approximateBuffer) == 0; if (!m_exactSolutionIdentity[solutionIndex]) { - m_exactSolutionEquality[solutionIndex] = Expression::ParsedExpressionsAreEqual(exactBuffer, approximateBuffer, context, updatedComplexFormat(context), preferences->angleUnit()); + m_exactSolutionEquality[solutionIndex] = Expression::ParsedExpressionsAreEqual(exactBuffer, approximateBuffer, context, updatedComplexFormat(context), preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat()); } solutionIndex++; } @@ -269,6 +270,7 @@ EquationStore::Error EquationStore::privateExactSolve(Poincare::Context * contex EquationStore::Error EquationStore::resolveLinearSystem(Expression exactSolutions[k_maxNumberOfExactSolutions], Expression exactSolutionsApproximations[k_maxNumberOfExactSolutions], Expression coefficients[k_maxNumberOfEquations][Expression::k_maxNumberOfVariables], Expression constants[k_maxNumberOfEquations], Context * context) { Preferences::AngleUnit angleUnit = Preferences::sharedPreferences()->angleUnit(); + Preferences::UnitFormat unitFormat = GlobalPreferences::sharedGlobalPreferences()->unitFormat(); // n unknown variables int n = 0; while (n < Expression::k_maxNumberOfVariables && m_variables[n][0] != 0) { @@ -286,7 +288,7 @@ EquationStore::Error EquationStore::resolveLinearSystem(Expression exactSolution Ab.setDimensions(m, n+1); // Compute the rank of (AΒ | b) - int rankAb = Ab.rank(context, updatedComplexFormat(context), angleUnit, true); + int rankAb = Ab.rank(context, updatedComplexFormat(context), angleUnit, unitFormat, true); // Initialize the number of solutions m_numberOfSolutions = INT_MAX; @@ -311,7 +313,7 @@ EquationStore::Error EquationStore::resolveLinearSystem(Expression exactSolution m_numberOfSolutions = n; for (int i = 0; i < m_numberOfSolutions; i++) { exactSolutions[i] = Ab.matrixChild(i,n); - exactSolutions[i].simplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit()); + exactSolutions[i].simplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], context, updatedComplexFormat(context), angleUnit, unitFormat); } } } @@ -323,7 +325,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact assert(degree == 2); // Compute delta = b*b-4ac Expression delta = Subtraction::Builder(Power::Builder(coefficients[1].clone(), Rational::Builder(2)), Multiplication::Builder(Rational::Builder(4), coefficients[0].clone(), coefficients[2].clone())); - delta = delta.simplify(ExpressionNode::ReductionContext(context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit(), ExpressionNode::ReductionTarget::SystemForApproximation)); + delta = delta.simplify(ExpressionNode::ReductionContext(context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(), ExpressionNode::ReductionTarget::SystemForApproximation)); if (delta.isUninitialized()) { delta = Poincare::Undefined::Builder(); } @@ -340,7 +342,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact } exactSolutions[m_numberOfSolutions-1] = delta; for (int i = 0; i < m_numberOfSolutions; i++) { - exactSolutions[i].simplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit()); + exactSolutions[i].simplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat()); } return Error::NoError; #if 0 diff --git a/apps/solver/test/helpers.cpp b/apps/solver/test/helpers.cpp index 119e085f6..a5bba40e3 100644 --- a/apps/solver/test/helpers.cpp +++ b/apps/solver/test/helpers.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -147,7 +148,8 @@ void set(const char * variable, const char * value) { buffer, &globalContext, Preferences::sharedPreferences()->complexFormat(), - Preferences::sharedPreferences()->angleUnit() + Preferences::sharedPreferences()->angleUnit(), + GlobalPreferences::sharedGlobalPreferences()->unitFormat() ); } diff --git a/poincare/include/poincare/equal.h b/poincare/include/poincare/equal.h index 6826f35ab..5f39dc772 100644 --- a/poincare/include/poincare/equal.h +++ b/poincare/include/poincare/equal.h @@ -39,7 +39,7 @@ public: static Equal Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } // For the equation A = B, create the reduced expression A-B - Expression standardEquation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Expression standardEquation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat) const; // Expression Expression shallowReduce(); }; diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 4639195aa..e658a926d 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -196,14 +196,14 @@ public: * the variables hold in 'variables'. Otherwise, it fills 'coefficients' with * the coefficients of the variables hold in 'variables' (following the same * order) and 'constant' with the constant of the expression. */ - bool getLinearCoefficients(char * variables, int maxVariableLength, Expression coefficients[], Expression constant[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation) const; + bool getLinearCoefficients(char * variables, int maxVariableLength, Expression coefficients[], Expression constant[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation) const; /* getPolynomialCoefficients fills the table coefficients with the expressions * of the first 3 polynomial coefficients and returns the polynomial degree. * It is supposed to be called on a reduced expression. * coefficients has up to 3 entries. */ static constexpr int k_maxPolynomialDegree = 2; static constexpr int k_maxNumberOfPolynomialCoefficients = k_maxPolynomialDegree+1; - int getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation) const; + int getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation) const; Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { return node()->replaceSymbolWithExpression(symbol, expression); } /* Units */ @@ -226,7 +226,7 @@ public: /* isIdenticalToWithoutParentheses behaves as isIdenticalTo, but without * taking into account parentheses: e^(0) is identical to e^0. */ bool isIdenticalToWithoutParentheses(const Expression e) const; - static bool ParsedExpressionsAreEqual(const char * e0, const char * e1, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); + static bool ParsedExpressionsAreEqual(const char * e0, const char * e1, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat); /* Layout Helper */ Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const; @@ -247,11 +247,11 @@ public: * account the complex format required in the expression they return. * (For instance, in Polar mode, they return an expression of the form * r*e^(i*th) reduced and approximated.) */ - static Expression ParseAndSimplify(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default); + static Expression ParseAndSimplify(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default); Expression simplify(ExpressionNode::ReductionContext reductionContext); - static void ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default); - void simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default); + static void ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default); + void simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default); Expression reduce(ExpressionNode::ReductionContext context); Expression mapOnMatrixFirstChild(ExpressionNode::ReductionContext reductionContext); @@ -267,7 +267,7 @@ public: template static U Epsilon(); template Expression approximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; template U approximateToScalar(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; - template static U ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition); + template static U ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition); template U approximateWithValueForSymbol(const char * symbol, U x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; /* Expression roots/extrema solver */ Coordinate2D nextMinimum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index c08435fc3..e30d627ce 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -158,10 +158,11 @@ public: class ReductionContext { public: - ReductionContext(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, SymbolicComputation symbolicComputation = SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, UnitConversion unitConversion = UnitConversion::Default) : + ReductionContext(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ReductionTarget target, SymbolicComputation symbolicComputation = SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, UnitConversion unitConversion = UnitConversion::Default) : m_context(context), m_complexFormat(complexFormat), m_angleUnit(angleUnit), + m_unitFormat(unitFormat), m_target(target), m_symbolicComputation(symbolicComputation), m_unitConversion(unitConversion) @@ -169,6 +170,7 @@ public: Context * context() { return m_context; } Preferences::ComplexFormat complexFormat() const { return m_complexFormat; } Preferences::AngleUnit angleUnit() const { return m_angleUnit; } + Preferences::UnitFormat unitFormat() const { return m_unitFormat; } ReductionTarget target() const { return m_target; } SymbolicComputation symbolicComputation() const { return m_symbolicComputation; } UnitConversion unitConversion() const { return m_unitConversion; } @@ -176,6 +178,7 @@ public: Context * m_context; Preferences::ComplexFormat m_complexFormat; Preferences::AngleUnit m_angleUnit; + Preferences::UnitFormat m_unitFormat; ReductionTarget m_target; SymbolicComputation m_symbolicComputation; UnitConversion m_unitConversion; diff --git a/poincare/include/poincare/matrix.h b/poincare/include/poincare/matrix.h index 30ea4f5d4..06013fffe 100644 --- a/poincare/include/poincare/matrix.h +++ b/poincare/include/poincare/matrix.h @@ -74,7 +74,7 @@ public: Expression matrixChild(int i, int j) { return childAtIndex(i*numberOfColumns()+j); } /* Operation on matrix */ - int rank(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool inPlace = false); + int rank(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, bool inPlace = false); Expression createTrace(); // Inverse the array in-place. Array has to be given in the form array[row_index][column_index] template static int ArrayInverse(T * array, int numberOfRows, int numberOfColumns); diff --git a/poincare/include/poincare/number.h b/poincare/include/poincare/number.h index ea2b48f2a..7c4f955c2 100644 --- a/poincare/include/poincare/number.h +++ b/poincare/include/poincare/number.h @@ -53,7 +53,7 @@ public: ExpressionNode::Sign sign() const { return Expression::sign(nullptr); } Number setSign(ExpressionNode::Sign s) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); - return Expression::setSign(s, ExpressionNode::ReductionContext(nullptr, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Degree, ExpressionNode::ReductionTarget::User)).convert(); + return Expression::setSign(s, ExpressionNode::ReductionContext(nullptr, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Degree, Preferences::UnitFormat::Metric, ExpressionNode::ReductionTarget::User)).convert(); } bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue); diff --git a/poincare/include/poincare/preferences.h b/poincare/include/poincare/preferences.h index f8354186f..e98a7ac39 100644 --- a/poincare/include/poincare/preferences.h +++ b/poincare/include/poincare/preferences.h @@ -50,8 +50,6 @@ public: void setEditionMode(EditionMode editionMode) { m_editionMode = editionMode; } ComplexFormat complexFormat() const { return m_complexFormat; } void setComplexFormat(Preferences::ComplexFormat complexFormat) { m_complexFormat = complexFormat; } - UnitFormat unitFormat() const { return m_unitFormat; } - void setUnitFormat(UnitFormat unitFormat) { m_unitFormat = unitFormat; } uint8_t numberOfSignificantDigits() const { return m_numberOfSignificantDigits; } void setNumberOfSignificantDigits(uint8_t numberOfSignificantDigits) { m_numberOfSignificantDigits = numberOfSignificantDigits; } private: @@ -59,7 +57,6 @@ private: PrintFloatMode m_displayMode; EditionMode m_editionMode; ComplexFormat m_complexFormat; - UnitFormat m_unitFormat; uint8_t m_numberOfSignificantDigits; }; diff --git a/poincare/include/poincare/unit.h b/poincare/include/poincare/unit.h index fda797f13..9c6f655e4 100644 --- a/poincare/include/poincare/unit.h +++ b/poincare/include/poincare/unit.h @@ -876,7 +876,7 @@ public: static Expression BuildImperialDistanceSplit(double inches, Context * context); static Expression BuildImperialMassSplit(double ounces, Context * context); static Expression BuildImperialVolumeSplit(double fluidOunces, Context * context); - static double ConvertedValueInUnit(Expression e, Unit unit, Context * context); + static double ConvertedValueInUnit(Expression e, Unit unit, ExpressionNode::ReductionContext reductionContext); static bool IsSI(Expression & e); static bool IsSISpeed(Expression & e); @@ -890,11 +890,11 @@ public: bool isSecond() const; bool isKilogram() const; - static Expression StandardSpeedConversion(Expression e, Preferences::UnitFormat format, Context * context); - static Expression StandardDistanceConversion(Expression e, Preferences::UnitFormat format, Context * context); - static Expression StandardVolumeConversion(Expression e, Preferences::UnitFormat format, Context * context); - static Expression StandardMassConversion(Expression e, Preferences::UnitFormat format, Context * context); - static Expression StandardSurfaceConversion(Expression e, Preferences::UnitFormat format, Context * context); + static Expression StandardSpeedConversion(Expression e, ExpressionNode::ReductionContext reductionContext); + static Expression StandardDistanceConversion(Expression e, ExpressionNode::ReductionContext reductionContext); + static Expression StandardVolumeConversion(Expression e, ExpressionNode::ReductionContext reductionContext); + static Expression StandardMassConversion(Expression e, ExpressionNode::ReductionContext reductionContext); + static Expression StandardSurfaceConversion(Expression e, ExpressionNode::ReductionContext reductionContext); // Simplification Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 7f868ab48..070168b28 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -441,6 +441,7 @@ Expression Addition::factorizeOnCommonDenominator(ExpressionNode::ReductionConte reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit(), + reductionContext.unitFormat(), reductionContext.target(), ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition); diff --git a/poincare/src/equal.cpp b/poincare/src/equal.cpp index f5f16e686..6ae1f00cc 100644 --- a/poincare/src/equal.cpp +++ b/poincare/src/equal.cpp @@ -44,13 +44,13 @@ Evaluation EqualNode::templatedApproximate(Context * context, Preferences::Co } -Expression Equal::standardEquation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression Equal::standardEquation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat) const { Expression sub = Subtraction::Builder(childAtIndex(0).clone(), childAtIndex(1).clone()); /* When reducing the equation, we specify the reduction target to be * SystemForAnalysis. This enables to expand Newton multinom to be able to * detect polynom correctly ("(x+2)^2" in this form won't be detected * unless expanded). */ - return sub.reduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForAnalysis)); + return sub.reduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, unitFormat, ExpressionNode::ReductionTarget::SystemForAnalysis)); } Expression Equal::shallowReduce() { diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 21daee9cb..a26abadea 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -214,7 +214,7 @@ bool containsVariables(const Expression e, char * variables, int maxVariableSize return false; } -bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Expression coefficients[], Expression constant[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation) const { +bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Expression coefficients[], Expression constant[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation) const { assert(!recursivelyMatches(IsMatrix, context, symbolicComputation)); // variables is in fact of type char[k_maxNumberOfVariables][maxVariableSize] int index = 0; @@ -229,7 +229,7 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex index = 0; Expression polynomialCoefficients[k_maxNumberOfPolynomialCoefficients]; while (variables[index*maxVariableSize] != 0) { - int degree = equation.getPolynomialReducedCoefficients(&variables[index*maxVariableSize], polynomialCoefficients, context, complexFormat, angleUnit, symbolicComputation); + int degree = equation.getPolynomialReducedCoefficients(&variables[index*maxVariableSize], polynomialCoefficients, context, complexFormat, angleUnit, unitFormat, symbolicComputation); switch (degree) { case 0: coefficients[index] = Rational::Builder(0); @@ -250,7 +250,7 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex equation = polynomialCoefficients[0]; index++; } - constant[0] = Opposite::Builder(equation.clone()).reduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForApproximation, symbolicComputation)); + constant[0] = Opposite::Builder(equation.clone()).reduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, unitFormat, ExpressionNode::ReductionTarget::SystemForApproximation, symbolicComputation)); /* The expression can be linear on all coefficients taken one by one but * non-linear (ex: xy = 2). We delete the results and return false if one of * the coefficients contains a variable. */ @@ -479,11 +479,11 @@ int Expression::defaultGetPolynomialCoefficients(Context * context, const char * return -1; } -int Expression::getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation) const { +int Expression::getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation) const { // Reset interrupting flag because we use deepReduce int degree = getPolynomialCoefficients(context, symbolName, coefficients, symbolicComputation); for (int i = 0; i <= degree; i++) { - coefficients[i] = coefficients[i].reduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForApproximation, symbolicComputation)); + coefficients[i] = coefficients[i].reduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, unitFormat, ExpressionNode::ReductionTarget::SystemForApproximation, symbolicComputation)); } return degree; } @@ -570,9 +570,9 @@ bool Expression::isIdenticalToWithoutParentheses(const Expression e) const { return ExpressionNode::SimplificationOrder(node(), e.node(), true, true, true) == 0; } -bool Expression::ParsedExpressionsAreEqual(const char * e0, const char * e1, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { - Expression exp0 = Expression::ParseAndSimplify(e0, context, complexFormat, angleUnit, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); - Expression exp1 = Expression::ParseAndSimplify(e1, context, complexFormat, angleUnit, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); +bool Expression::ParsedExpressionsAreEqual(const char * e0, const char * e1, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat) { + Expression exp0 = Expression::ParseAndSimplify(e0, context, complexFormat, angleUnit, unitFormat, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); + Expression exp1 = Expression::ParseAndSimplify(e1, context, complexFormat, angleUnit, unitFormat, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); if (exp0.isUninitialized() || exp1.isUninitialized()) { return false; } @@ -589,12 +589,12 @@ int Expression::serialize(char * buffer, int bufferSize, Preferences::PrintFloat /* Simplification */ -Expression Expression::ParseAndSimplify(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation, ExpressionNode::UnitConversion unitConversion) { +Expression Expression::ParseAndSimplify(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation, ExpressionNode::UnitConversion unitConversion) { Expression exp = Parse(text, context, false); if (exp.isUninitialized()) { return Undefined::Builder(); } - exp = exp.simplify(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicComputation, unitConversion)); + exp = exp.simplify(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, unitFormat, ExpressionNode::ReductionTarget::User, symbolicComputation, unitConversion)); /* simplify might have been interrupted, in which case the resulting * expression is uninitialized, so we need to check that. */ if (exp.isUninitialized()) { @@ -603,7 +603,7 @@ Expression Expression::ParseAndSimplify(const char * text, Context * context, Pr return exp; } -void Expression::ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation, ExpressionNode::UnitConversion unitConversion) { +void Expression::ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation, ExpressionNode::UnitConversion unitConversion) { assert(simplifiedExpression); Expression exp = Parse(text, context, false); if (exp.isUninitialized()) { @@ -611,7 +611,7 @@ void Expression::ParseAndSimplifyAndApproximate(const char * text, Expression * *approximateExpression = Undefined::Builder(); return; } - exp.simplifyAndApproximate(simplifiedExpression, approximateExpression, context, complexFormat, angleUnit, symbolicComputation, unitConversion); + exp.simplifyAndApproximate(simplifiedExpression, approximateExpression, context, complexFormat, angleUnit, unitFormat, symbolicComputation, unitConversion); /* simplify might have been interrupted, in which case the resulting * expression is uninitialized, so we need to check that. */ if (simplifiedExpression->isUninitialized()) { @@ -693,15 +693,15 @@ void Expression::beautifyAndApproximateScalar(Expression * simplifiedExpression, } } -void Expression::simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation, ExpressionNode::UnitConversion unitConversion) { +void Expression::simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation, ExpressionNode::UnitConversion unitConversion) { assert(simplifiedExpression); sSimplificationHasBeenInterrupted = false; // Step 1: we reduce the expression - ExpressionNode::ReductionContext userReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicComputation, unitConversion); + ExpressionNode::ReductionContext userReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, unitFormat, ExpressionNode::ReductionTarget::User, symbolicComputation, unitConversion); Expression e = clone().reduce(userReductionContext); if (sSimplificationHasBeenInterrupted) { sSimplificationHasBeenInterrupted = false; - ExpressionNode::ReductionContext systemReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForApproximation, symbolicComputation, unitConversion); + ExpressionNode::ReductionContext systemReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, unitFormat, ExpressionNode::ReductionTarget::SystemForApproximation, symbolicComputation, unitConversion); e = reduce(systemReductionContext); } *simplifiedExpression = Expression(); @@ -868,8 +868,8 @@ U Expression::approximateToScalar(Context * context, Preferences::ComplexFormat } template -U Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation) { - Expression exp = ParseAndSimplify(text, context, complexFormat, angleUnit, symbolicComputation); +U Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation) { + Expression exp = ParseAndSimplify(text, context, complexFormat, angleUnit, unitFormat, symbolicComputation); assert(!exp.isUninitialized()); return exp.approximateToScalar(context, complexFormat, angleUnit); } @@ -1164,8 +1164,8 @@ template Expression Expression::approximate(Context * context, Preferenc template float Expression::approximateToScalar(Context * context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; template double Expression::approximateToScalar(Context * context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; -template float Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation); -template double Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation); +template float Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation); +template double Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation); template Evaluation Expression::approximateToEvaluation(Context * context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; template Evaluation Expression::approximateToEvaluation(Context * context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; diff --git a/poincare/src/integer.cpp b/poincare/src/integer.cpp index 6cbe5b91c..b85150974 100644 --- a/poincare/src/integer.cpp +++ b/poincare/src/integer.cpp @@ -695,7 +695,7 @@ Expression Integer::CreateEuclideanDivision(const Integer & num, const Integer & Expression quo = DivisionQuotient::Reduce(num, denom); Expression rem = DivisionRemainder::Reduce(num, denom); Expression e = Equal::Builder(Rational::Builder(num), Addition::Builder(Multiplication::Builder(Rational::Builder(denom), quo), rem)); - ExpressionNode::ReductionContext defaultReductionContext = ExpressionNode::ReductionContext(nullptr, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Radian, ExpressionNode::ReductionTarget::User, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); + ExpressionNode::ReductionContext defaultReductionContext = ExpressionNode::ReductionContext(nullptr, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Radian, Preferences::UnitFormat::Metric, ExpressionNode::ReductionTarget::User, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); e = e.deepBeautify(defaultReductionContext); return e; } diff --git a/poincare/src/matrix.cpp b/poincare/src/matrix.cpp index 6c7df3815..97417781c 100644 --- a/poincare/src/matrix.cpp +++ b/poincare/src/matrix.cpp @@ -128,9 +128,9 @@ void Matrix::addChildrenAsRowInPlace(TreeHandle t, int i) { setDimensions(previousNumberOfRows + 1, previousNumberOfColumns == 0 ? t.numberOfChildren() : previousNumberOfColumns); } -int Matrix::rank(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool inPlace) { +int Matrix::rank(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, bool inPlace) { Matrix m = inPlace ? *this : clone().convert(); - ExpressionNode::ReductionContext systemReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForApproximation); + ExpressionNode::ReductionContext systemReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, unitFormat, ExpressionNode::ReductionTarget::SystemForApproximation); m = m.rowCanonize(systemReductionContext, nullptr); int rank = m.numberOfRows(); int i = rank-1; diff --git a/poincare/src/unit.cpp b/poincare/src/unit.cpp index de1a31bbd..01c6e103f 100644 --- a/poincare/src/unit.cpp +++ b/poincare/src/unit.cpp @@ -410,7 +410,7 @@ void Unit::chooseBestMultipleForValue(double * value, const float exponent, bool const Representative * startRep = tuneRepresentative ? dim->stdRepresentative() : bestRep; const Representative * endRep = tuneRepresentative ? dim->representativesUpperBound() : bestRep + 1; for (const Representative * rep = startRep; rep < endRep; rep++) { - if (!rep->canOutputInSystem(Preferences::sharedPreferences()->unitFormat())) { + if (!rep->canOutputInSystem(reductionContext.unitFormat())) { continue; } // evaluate quotient @@ -529,12 +529,12 @@ bool Unit::IsSISurface(Expression & e) { e.childAtIndex(1).type() == ExpressionNode::Type::Rational && e.childAtIndex(1).convert().isTwo(); } -double Unit::ConvertedValueInUnit(Expression e, Unit unit, Context * context) { +double Unit::ConvertedValueInUnit(Expression e, Unit unit, ExpressionNode::ReductionContext reductionContext) { Expression conversion = UnitConvert::Builder(e.clone(), unit); Expression newUnit; - conversion = conversion.simplify(ExpressionNode::ReductionContext(context, Preferences::ComplexFormat::Real, Preferences::sharedPreferences()->angleUnit(), ExpressionNode::ReductionTarget::User, ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion::Default)); + conversion = conversion.simplify(reductionContext); conversion = conversion.removeUnit(&newUnit); - return conversion.approximateToScalar(context, Preferences::ComplexFormat::Real, Preferences::sharedPreferences()->angleUnit()); + return conversion.approximateToScalar(reductionContext.context(), Preferences::ComplexFormat::Real, Preferences::sharedPreferences()->angleUnit()); } Expression Unit::BuildSplit(double baseValue, Unit const * units, double const * conversionFactors, const int numberOfUnits, Context * context) { @@ -568,7 +568,7 @@ Expression Unit::BuildSplit(double baseValue, Unit const * units, double const * } } - ExpressionNode::ReductionContext reductionContext(context, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Degree, ExpressionNode::ReductionTarget::User, ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion::None); + ExpressionNode::ReductionContext reductionContext(context, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Degree, Preferences::UnitFormat::Imperial, ExpressionNode::ReductionTarget::User, ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion::None); // Beautify the addition into an subtraction if necessary return a.squashUnaryHierarchyInPlace().shallowBeautify(reductionContext); } @@ -601,7 +601,8 @@ Expression Unit::BuildImperialVolumeSplit(double fluidOunces, Context * context) return BuildSplit(fluidOunces, units, factors, numberOfUnits, context); } -Expression Unit::StandardSpeedConversion(Expression e, Preferences::UnitFormat format, Context * context) { +Expression Unit::StandardSpeedConversion(Expression e, ExpressionNode::ReductionContext reductionContext) { + Preferences::UnitFormat format = reductionContext.unitFormat(); return UnitConvert::Builder(e.clone(), Multiplication::Builder( format == Preferences::UnitFormat::Metric ? Unit::Kilometer() : Unit::Mile(), Power::Builder( @@ -612,34 +613,38 @@ Expression Unit::StandardSpeedConversion(Expression e, Preferences::UnitFormat f ); } -Expression Unit::StandardDistanceConversion(Expression e, Preferences::UnitFormat format, Context * context) { +Expression Unit::StandardDistanceConversion(Expression e, ExpressionNode::ReductionContext reductionContext) { + Preferences::UnitFormat format = reductionContext.unitFormat(); if (format == Preferences::UnitFormat::Metric) { return UnitConvert::Builder(e.clone(), Unit::Meter()); } assert(format == Preferences::UnitFormat::Imperial); - double rawValue = ConvertedValueInUnit(e, Unit::Inch(), context); - return BuildImperialDistanceSplit(rawValue, context); + double rawValue = ConvertedValueInUnit(e, Unit::Inch(), reductionContext); + return BuildImperialDistanceSplit(rawValue, reductionContext.context()); } -Expression Unit::StandardVolumeConversion(Expression e, Preferences::UnitFormat format, Context * context) { +Expression Unit::StandardVolumeConversion(Expression e, ExpressionNode::ReductionContext reductionContext) { + Preferences::UnitFormat format = reductionContext.unitFormat(); if (format == Preferences::UnitFormat::Metric) { return UnitConvert::Builder(e.clone(), Unit::Liter()); } assert(format == Preferences::UnitFormat::Imperial); - double rawValue = ConvertedValueInUnit(e, Unit::FluidOunce(), context); - return BuildImperialVolumeSplit(rawValue, context); + double rawValue = ConvertedValueInUnit(e, Unit::FluidOunce(), reductionContext); + return BuildImperialVolumeSplit(rawValue, reductionContext.context()); } -Expression Unit::StandardMassConversion(Expression e, Preferences::UnitFormat format, Context * context) { +Expression Unit::StandardMassConversion(Expression e, ExpressionNode::ReductionContext reductionContext) { + Preferences::UnitFormat format = reductionContext.unitFormat(); if (format == Preferences::UnitFormat::Metric) { return UnitConvert::Builder(e.clone(), Unit::Gram()); } assert(format == Preferences::UnitFormat::Imperial); - double rawValue = ConvertedValueInUnit(e, Unit::Ounce(), context); - return BuildImperialMassSplit(rawValue, context); + double rawValue = ConvertedValueInUnit(e, Unit::Ounce(), reductionContext); + return BuildImperialMassSplit(rawValue, reductionContext.context()); } -Expression Unit::StandardSurfaceConversion(Expression e, Preferences::UnitFormat format, Context * context) { +Expression Unit::StandardSurfaceConversion(Expression e, ExpressionNode::ReductionContext reductionContext) { + Preferences::UnitFormat format = reductionContext.unitFormat(); if (format == Preferences::UnitFormat::Metric) { return UnitConvert::Builder(e.clone(), Unit::Hectare()); } diff --git a/poincare/src/unit_convert.cpp b/poincare/src/unit_convert.cpp index c8c2acf7c..995798561 100644 --- a/poincare/src/unit_convert.cpp +++ b/poincare/src/unit_convert.cpp @@ -42,6 +42,7 @@ void UnitConvert::deepReduceChildren(ExpressionNode::ReductionContext reductionC reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit(), + reductionContext.unitFormat(), reductionContext.target(), ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined, ExpressionNode::UnitConversion::None); @@ -56,6 +57,7 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit(), + reductionContext.unitFormat(), reductionContext.target(), ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined); Expression unit; @@ -70,6 +72,7 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit(), + reductionContext.unitFormat(), reductionContext.target(), ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined, ExpressionNode::UnitConversion::None); diff --git a/poincare/test/approximation.cpp b/poincare/test/approximation.cpp index ec896ab7f..30b2d57d5 100644 --- a/poincare/test/approximation.cpp +++ b/poincare/test/approximation.cpp @@ -128,20 +128,20 @@ QUIZ_CASE(poincare_approximation_power) { assert_expression_approximates_to("0^2", "0"); assert_expression_approximates_to("0^(-2)", Undefined::Name()); - assert_expression_approximates_to("(-2)^4.2", "14.8690638497+10.8030072384×𝐒", Radian, Cartesian, 12); - assert_expression_approximates_to("(-0.1)^4", "0.0001", Radian, Cartesian, 12); + assert_expression_approximates_to("(-2)^4.2", "14.8690638497+10.8030072384×𝐒", Radian, Metric, Cartesian, 12); + assert_expression_approximates_to("(-0.1)^4", "0.0001", Radian, Metric, Cartesian, 12); assert_expression_approximates_to("0^2", "0"); assert_expression_approximates_to("𝐒^𝐒", "2.0787957635076ᴇ-1"); - assert_expression_approximates_to("1.0066666666667^60", "1.48985", Radian, Cartesian, 6); - assert_expression_approximates_to("1.0066666666667^60", "1.489845708305", Radian, Cartesian, 13); + assert_expression_approximates_to("1.0066666666667^60", "1.48985", Radian, Metric, Cartesian, 6); + assert_expression_approximates_to("1.0066666666667^60", "1.489845708305", Radian, Metric, Cartesian, 13); assert_expression_approximates_to("β„―^(𝐒×π)", "-1"); assert_expression_approximates_to("β„―^(𝐒×π)", "-1"); - assert_expression_approximates_to("β„―^(𝐒×π+2)", "-7.38906", Radian, Cartesian, 6); + assert_expression_approximates_to("β„―^(𝐒×π+2)", "-7.38906", Radian, Metric, Cartesian, 6); assert_expression_approximates_to("β„―^(𝐒×π+2)", "-7.3890560989307"); assert_expression_approximates_to("(-1)^(1/3)", "0.5+0.8660254×𝐒"); assert_expression_approximates_to("(-1)^(1/3)", "0.5+8.6602540378444ᴇ-1×𝐒"); - assert_expression_approximates_to("β„―^(𝐒×π/3)", "0.5+0.866025×𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("β„―^(𝐒×π/3)", "0.5+0.866025×𝐒", Radian, Metric, Cartesian, 6); assert_expression_approximates_to("β„―^(𝐒×π/3)", "0.5+8.6602540378444ᴇ-1×𝐒"); assert_expression_approximates_to("𝐒^(2/3)", "0.5+0.8660254×𝐒"); assert_expression_approximates_to("𝐒^(2/3)", "0.5+8.6602540378444ᴇ-1×𝐒"); @@ -151,8 +151,8 @@ QUIZ_CASE(poincare_approximation_power) { assert_expression_approximates_to_scalar("[[1,2][3,4]]^2", NAN); - assert_expression_approximates_to("(-10)^0.00000001", "unreal", Radian, Real); - assert_expression_approximates_to("(-10)^0.00000001", "1+3.141593ᴇ-8×𝐒", Radian, Cartesian); + assert_expression_approximates_to("(-10)^0.00000001", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("(-10)^0.00000001", "1+3.141593ᴇ-8×𝐒", Radian, Metric, Cartesian); assert_expression_simplifies_approximates_to("3.5^2.0000001", "12.25"); assert_expression_simplifies_approximates_to("3.7^2.0000001", "13.69"); } @@ -232,7 +232,7 @@ QUIZ_CASE(poincare_approximation_function) { assert_expression_approximates_to("abs(-1)", "1"); assert_expression_approximates_to("abs(-1)", "1"); - assert_expression_approximates_to("abs(-2.3ᴇ-39)", "2.3ᴇ-39", Degree, Cartesian, 5); + assert_expression_approximates_to("abs(-2.3ᴇ-39)", "2.3ᴇ-39", Degree, Metric, Cartesian, 5); assert_expression_approximates_to("abs(-2.3ᴇ-39)", "2.3ᴇ-39"); assert_expression_approximates_to("abs(3+2𝐒)", "3.605551"); @@ -244,22 +244,22 @@ QUIZ_CASE(poincare_approximation_function) { assert_expression_approximates_to("abs([[3+2𝐒,3+4𝐒][5+2𝐒,3+2𝐒]])", "[[3.605551,5][5.385165,3.605551]]"); assert_expression_approximates_to("abs([[3+2𝐒,3+4𝐒][5+2𝐒,3+2𝐒]])", "[[3.605551275464,5][5.3851648071345,3.605551275464]]"); - assert_expression_approximates_to("binomcdf(5.3, 9, 0.7)", "0.270341", Degree, Cartesian, 6); // FIXME: precision problem - assert_expression_approximates_to("binomcdf(5.3, 9, 0.7)", "0.270340902", Degree, Cartesian, 10); //FIXME precision problem + assert_expression_approximates_to("binomcdf(5.3, 9, 0.7)", "0.270341", Degree, Metric, Cartesian, 6); // FIXME: precision problem + assert_expression_approximates_to("binomcdf(5.3, 9, 0.7)", "0.270340902", Degree, Metric, Cartesian, 10); //FIXME precision problem assert_expression_approximates_to("binomial(10, 4)", "210"); assert_expression_approximates_to("binomial(10, 4)", "210"); - assert_expression_approximates_to("binompdf(4.4, 9, 0.7)", "0.0735138", Degree, Cartesian, 6); // FIXME: precision problem + assert_expression_approximates_to("binompdf(4.4, 9, 0.7)", "0.0735138", Degree, Metric, Cartesian, 6); // FIXME: precision problem assert_expression_approximates_to("binompdf(4.4, 9, 0.7)", "0.073513818"); assert_expression_approximates_to("ceil(0.2)", "1"); assert_expression_approximates_to("ceil(0.2)", "1"); - assert_expression_approximates_to("det([[1,23,3][4,5,6][7,8,9]])", "126", Degree, Cartesian, 6); // FIXME: the determinant computation is not precised enough to be displayed with 7 significant digits + assert_expression_approximates_to("det([[1,23,3][4,5,6][7,8,9]])", "126", Degree, Metric, Cartesian, 6); // FIXME: the determinant computation is not precised enough to be displayed with 7 significant digits assert_expression_approximates_to("det([[1,23,3][4,5,6][7,8,9]])", "126"); - assert_expression_approximates_to("det([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "126-231×𝐒", Degree, Cartesian, 6); // FIXME: the determinant computation is not precised enough to be displayed with 7 significant digits + assert_expression_approximates_to("det([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "126-231×𝐒", Degree, Metric, Cartesian, 6); // FIXME: the determinant computation is not precised enough to be displayed with 7 significant digits assert_expression_approximates_to("det([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "126-231×𝐒"); assert_expression_approximates_to("diff(2Γ—x, x, 2)", "2"); @@ -319,7 +319,7 @@ QUIZ_CASE(poincare_approximation_function) { assert_expression_approximates_to("log(2)", "0.30103"); assert_expression_approximates_to("log(2)", "3.0102999566398ᴇ-1"); - assert_expression_approximates_to("normcdf(5, 7, 0.3162)", "1.265256ᴇ-10", Radian, Cartesian, 7); + assert_expression_approximates_to("normcdf(5, 7, 0.3162)", "1.265256ᴇ-10", Radian, Metric, Cartesian, 7); assert_expression_approximates_to("normcdf(1.2, 3.4, 5.6)", "0.3472125"); assert_expression_approximates_to("normcdf(1.2, 3.4, 5.6)", "3.4721249841587ᴇ-1"); @@ -375,10 +375,10 @@ QUIZ_CASE(poincare_approximation_function) { assert_expression_approximates_to("factor(-123/24)", "-5.125"); assert_expression_approximates_to("factor(𝐒)", "undef"); - assert_expression_approximates_to("inverse([[1,2,3][4,5,-6][7,8,9]])", "[[-1.2917,-0.083333,0.375][1.0833,0.16667,-0.25][0.041667,-0.083333,0.041667]]", Degree, Cartesian, 5); // inverse is not precise enough to display 7 significative digits + assert_expression_approximates_to("inverse([[1,2,3][4,5,-6][7,8,9]])", "[[-1.2917,-0.083333,0.375][1.0833,0.16667,-0.25][0.041667,-0.083333,0.041667]]", Degree, Metric, Cartesian, 5); // inverse is not precise enough to display 7 significative digits assert_expression_approximates_to("inverse([[1,2,3][4,5,-6][7,8,9]])", "[[-1.2916666666667,-8.3333333333333ᴇ-2,0.375][1.0833333333333,1.6666666666667ᴇ-1,-0.25][4.1666666666667ᴇ-2,-8.3333333333333ᴇ-2,4.1666666666667ᴇ-2]]"); - assert_expression_approximates_to("inverse([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "[[-0.0118-0.0455×𝐒,-0.5-0.727×𝐒,0.318+0.489×𝐒][0.0409+0.00364×𝐒,0.04-0.0218×𝐒,-0.0255+0.00091×𝐒][0.00334-0.00182×𝐒,0.361+0.535×𝐒,-0.13-0.358×𝐒]]", Degree, Cartesian, 3); // inverse is not precise enough to display 7 significative digits - assert_expression_approximates_to("inverse([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "[[-0.0118289353958-0.0454959053685×𝐒,-0.500454959054-0.727024567789×𝐒,0.31847133758+0.488626023658×𝐒][0.0409463148317+3.63967242948ᴇ-3×𝐒,0.0400363967243-0.0218380345769×𝐒,-0.0254777070064+9.0991810737ᴇ-4×𝐒][3.33636639369ᴇ-3-1.81983621474ᴇ-3×𝐒,0.36093418259+0.534728541098×𝐒,-0.130118289354-0.357597816197×𝐒]]", Degree, Cartesian, 12); // FIXME: inverse is not precise enough to display 14 significative digits + assert_expression_approximates_to("inverse([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "[[-0.0118-0.0455×𝐒,-0.5-0.727×𝐒,0.318+0.489×𝐒][0.0409+0.00364×𝐒,0.04-0.0218×𝐒,-0.0255+0.00091×𝐒][0.00334-0.00182×𝐒,0.361+0.535×𝐒,-0.13-0.358×𝐒]]", Degree, Metric, Cartesian, 3); // inverse is not precise enough to display 7 significative digits + assert_expression_approximates_to("inverse([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "[[-0.0118289353958-0.0454959053685×𝐒,-0.500454959054-0.727024567789×𝐒,0.31847133758+0.488626023658×𝐒][0.0409463148317+3.63967242948ᴇ-3×𝐒,0.0400363967243-0.0218380345769×𝐒,-0.0254777070064+9.0991810737ᴇ-4×𝐒][3.33636639369ᴇ-3-1.81983621474ᴇ-3×𝐒,0.36093418259+0.534728541098×𝐒,-0.130118289354-0.357597816197×𝐒]]", Degree, Metric, Cartesian, 12); // FIXME: inverse is not precise enough to display 14 significative digits assert_expression_approximates_to("prediction(0.1, 100)", "[[0,0.2]]"); assert_expression_approximates_to("prediction(0.1, 100)", "[[0,0.2]]"); @@ -395,8 +395,8 @@ QUIZ_CASE(poincare_approximation_function) { assert_expression_approximates_to("root(3, 3+𝐒)", "1.382007-0.1524428×𝐒"); assert_expression_approximates_to("root(3, 3+𝐒)", "1.3820069623326-0.1524427794159×𝐒"); - assert_expression_approximates_to("root(5^((-𝐒)3^9),𝐒)", "3.504", Degree, Cartesian, 4); - assert_expression_approximates_to("root(5^((-𝐒)3^9),𝐒)", "3.5039410843", Degree, Cartesian, 11); + assert_expression_approximates_to("root(5^((-𝐒)3^9),𝐒)", "3.504", Degree, Metric, Cartesian, 4); + assert_expression_approximates_to("root(5^((-𝐒)3^9),𝐒)", "3.5039410843", Degree, Metric, Cartesian, 11); assert_expression_approximates_to("√(3+𝐒)", "1.755317+0.2848488×𝐒"); assert_expression_approximates_to("√(3+𝐒)", "1.7553173018244+2.8484878459314ᴇ-1×𝐒"); @@ -498,8 +498,8 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("cos(2×𝐒)", "1.0004935208085", Gradian); // On C assert_expression_approximates_to("cos(𝐒-4)", "-1.008625-0.8893952×𝐒", Radian); - assert_expression_approximates_to("cos(𝐒-4)", "0.997716+0.00121754×𝐒", Degree, Cartesian, 6); - assert_expression_approximates_to("cos(𝐒-4)", "0.99815+0.000986352×𝐒", Gradian, Cartesian, 6); + assert_expression_approximates_to("cos(𝐒-4)", "0.997716+0.00121754×𝐒", Degree, Metric, Cartesian, 6); + assert_expression_approximates_to("cos(𝐒-4)", "0.99815+0.000986352×𝐒", Gradian, Metric, Cartesian, 6); /* sin: R -> R (oscillator) * Ri -> Ri (odd) @@ -525,10 +525,10 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("sin(-3×𝐒)", "-0.05238381×𝐒", Degree); assert_expression_approximates_to("sin(-3×𝐒)", "-4.7141332771113ᴇ-2×𝐒", Gradian); // On: C - assert_expression_approximates_to("sin(𝐒-4)", "1.16781-0.768163×𝐒", Radian, Cartesian, 6); - assert_expression_approximates_to("sin(𝐒-4)", "-0.0697671+0.0174117×𝐒", Degree, Cartesian, 6); - assert_expression_approximates_to("sin(𝐒-4)", "-0.0627983+0.0156776×𝐒", Gradian, Cartesian, 6); - assert_expression_approximates_to("sin(1.234567890123456ᴇ-15)", "1.23457ᴇ-15", Radian, Cartesian, 6); + assert_expression_approximates_to("sin(𝐒-4)", "1.16781-0.768163×𝐒", Radian, Metric, Cartesian, 6); + assert_expression_approximates_to("sin(𝐒-4)", "-0.0697671+0.0174117×𝐒", Degree, Metric, Cartesian, 6); + assert_expression_approximates_to("sin(𝐒-4)", "-0.0627983+0.0156776×𝐒", Gradian, Metric, Cartesian, 6); + assert_expression_approximates_to("sin(1.234567890123456ᴇ-15)", "1.23457ᴇ-15", Radian, Metric, Cartesian, 6); /* tan: R -> R (tangent-style) * Ri -> Ri (odd) @@ -550,9 +550,9 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("tan(2×𝐒)", "0.03489241×𝐒", Degree); assert_expression_approximates_to("tan(2×𝐒)", "0.0314056×𝐒", Gradian); // On C - assert_expression_approximates_to("tan(𝐒-4)", "-0.273553+1.00281×𝐒", Radian, Cartesian, 6); - assert_expression_approximates_to("tan(𝐒-4)", "-0.0699054+0.0175368×𝐒", Degree, Cartesian, 6); - assert_expression_approximates_to("tan(𝐒-4)", "-0.0628991+0.0157688×𝐒", Gradian, Cartesian, 6); + assert_expression_approximates_to("tan(𝐒-4)", "-0.273553+1.00281×𝐒", Radian, Metric, Cartesian, 6); + assert_expression_approximates_to("tan(𝐒-4)", "-0.0699054+0.0175368×𝐒", Degree, Metric, Cartesian, 6); + assert_expression_approximates_to("tan(𝐒-4)", "-0.0628991+0.0157688×𝐒", Gradian, Metric, Cartesian, 6); /* acos: [-1,1] -> R * ]-inf,-1[ -> Ο€+RΓ—i (odd imaginary) @@ -567,27 +567,27 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { // On [1, inf[ assert_expression_approximates_to("acos(2)", "1.3169578969248×𝐒", Radian); assert_expression_approximates_to("acos(2)", "75.456129290217×𝐒", Degree); - assert_expression_approximates_to("acos(2)", "83.84×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("acos(2)", "83.84×𝐒", Gradian, Metric, Cartesian, 4); // Symmetry: odd on imaginary assert_expression_approximates_to("acos(-2)", "3.1415926535898-1.3169578969248×𝐒", Radian); assert_expression_approximates_to("acos(-2)", "180-75.456129290217×𝐒", Degree); - assert_expression_approximates_to("acos(-2)", "200-83.84×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("acos(-2)", "200-83.84×𝐒", Gradian, Metric, Cartesian, 4); // On ]-inf, -1[ - assert_expression_approximates_to("acos(-32)", "3.14159265359-4.158638853279×𝐒", Radian, Cartesian, 13); - assert_expression_approximates_to("acos(-32)", "180-238.3×𝐒", Degree, Cartesian, 4); - assert_expression_approximates_to("acos(-32)", "200-264.7×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("acos(-32)", "3.14159265359-4.158638853279×𝐒", Radian, Metric, Cartesian, 13); + assert_expression_approximates_to("acos(-32)", "180-238.3×𝐒", Degree, Metric, Cartesian, 4); + assert_expression_approximates_to("acos(-32)", "200-264.7×𝐒", Gradian, Metric, Cartesian, 4); // On RΓ—i - assert_expression_approximates_to("acos(3×𝐒)", "1.5708-1.8184×𝐒", Radian, Cartesian, 5); - assert_expression_approximates_to("acos(3×𝐒)", "90-104.19×𝐒", Degree, Cartesian, 5); - assert_expression_approximates_to("acos(3×𝐒)", "100-115.8×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("acos(3×𝐒)", "1.5708-1.8184×𝐒", Radian, Metric, Cartesian, 5); + assert_expression_approximates_to("acos(3×𝐒)", "90-104.19×𝐒", Degree, Metric, Cartesian, 5); + assert_expression_approximates_to("acos(3×𝐒)", "100-115.8×𝐒", Gradian, Metric, Cartesian, 4); // Symmetry: odd on imaginary - assert_expression_approximates_to("acos(-3×𝐒)", "1.5708+1.8184×𝐒", Radian, Cartesian, 5); - assert_expression_approximates_to("acos(-3×𝐒)", "90+104.19×𝐒", Degree, Cartesian, 5); - assert_expression_approximates_to("acos(-3×𝐒)", "100+115.8×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("acos(-3×𝐒)", "1.5708+1.8184×𝐒", Radian, Metric, Cartesian, 5); + assert_expression_approximates_to("acos(-3×𝐒)", "90+104.19×𝐒", Degree, Metric, Cartesian, 5); + assert_expression_approximates_to("acos(-3×𝐒)", "100+115.8×𝐒", Gradian, Metric, Cartesian, 4); // On C - assert_expression_approximates_to("acos(𝐒-4)", "2.8894-2.0966×𝐒", Radian, Cartesian, 5); - assert_expression_approximates_to("acos(𝐒-4)", "165.551-120.126×𝐒", Degree, Cartesian, 6); - assert_expression_approximates_to("acos(𝐒-4)", "183.9-133.5×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("acos(𝐒-4)", "2.8894-2.0966×𝐒", Radian, Metric, Cartesian, 5); + assert_expression_approximates_to("acos(𝐒-4)", "165.551-120.126×𝐒", Degree, Metric, Cartesian, 6); + assert_expression_approximates_to("acos(𝐒-4)", "183.9-133.5×𝐒", Gradian, Metric, Cartesian, 4); // Key values assert_expression_approximates_to("acos(0)", "90", Degree); assert_expression_approximates_to("acos(-1)", "180", Degree); @@ -605,36 +605,36 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("asin(0.5)", "0.5235987755983", Radian); assert_expression_approximates_to("asin(0.03)", "3.0004501823477ᴇ-2", Radian); assert_expression_approximates_to("asin(0.5)", "30", Degree); - assert_expression_approximates_to("asin(0.5)", "33.3333", Gradian, Cartesian, 6); + assert_expression_approximates_to("asin(0.5)", "33.3333", Gradian, Metric, Cartesian, 6); // On [1, inf[ assert_expression_approximates_to("asin(2)", "1.5707963267949-1.3169578969248×𝐒", Radian); assert_expression_approximates_to("asin(2)", "90-75.456129290217×𝐒", Degree); - assert_expression_approximates_to("asin(2)", "100-83.84×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("asin(2)", "100-83.84×𝐒", Gradian, Metric, Cartesian, 4); // Symmetry: odd assert_expression_approximates_to("asin(-2)", "-1.5707963267949+1.3169578969248×𝐒", Radian); assert_expression_approximates_to("asin(-2)", "-90+75.456129290217×𝐒", Degree); - assert_expression_approximates_to("asin(-2)", "-100+83.84×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("asin(-2)", "-100+83.84×𝐒", Gradian, Metric, Cartesian, 4); // On ]-inf, -1[ - assert_expression_approximates_to("asin(-32)", "-1.571+4.159×𝐒", Radian, Cartesian, 4); - assert_expression_approximates_to("asin(-32)", "-90+238×𝐒", Degree, Cartesian, 3); - assert_expression_approximates_to("asin(-32)", "-100+265×𝐒", Gradian, Cartesian, 3); + assert_expression_approximates_to("asin(-32)", "-1.571+4.159×𝐒", Radian, Metric, Cartesian, 4); + assert_expression_approximates_to("asin(-32)", "-90+238×𝐒", Degree, Metric, Cartesian, 3); + assert_expression_approximates_to("asin(-32)", "-100+265×𝐒", Gradian, Metric, Cartesian, 3); // On RΓ—i assert_expression_approximates_to("asin(3×𝐒)", "1.8184464592321×𝐒", Radian); - assert_expression_approximates_to("asin(3×𝐒)", "115.8×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("asin(3×𝐒)", "115.8×𝐒", Gradian, Metric, Cartesian, 4); // Symmetry: odd assert_expression_approximates_to("asin(-3×𝐒)", "-1.8184464592321×𝐒", Radian); - assert_expression_approximates_to("asin(-3×𝐒)", "-115.8×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("asin(-3×𝐒)", "-115.8×𝐒", Gradian, Metric, Cartesian, 4); // On C - assert_expression_approximates_to("asin(𝐒-4)", "-1.3186+2.0966×𝐒", Radian, Cartesian, 5); - assert_expression_approximates_to("asin(𝐒-4)", "-75.551+120.13×𝐒", Degree, Cartesian, 5); - assert_expression_approximates_to("asin(𝐒-4)", "-83.95+133.5×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("asin(𝐒-4)", "-1.3186+2.0966×𝐒", Radian, Metric, Cartesian, 5); + assert_expression_approximates_to("asin(𝐒-4)", "-75.551+120.13×𝐒", Degree, Metric, Cartesian, 5); + assert_expression_approximates_to("asin(𝐒-4)", "-83.95+133.5×𝐒", Gradian, Metric, Cartesian, 4); // Key values assert_expression_approximates_to("asin(0)", "0", Degree); assert_expression_approximates_to("asin(0)", "0", Gradian); - assert_expression_approximates_to("asin(-1)", "-90", Degree, Cartesian, 6); - assert_expression_approximates_to("asin(-1)", "-100", Gradian, Cartesian, 6); + assert_expression_approximates_to("asin(-1)", "-90", Degree, Metric, Cartesian, 6); + assert_expression_approximates_to("asin(-1)", "-100", Gradian, Metric, Cartesian, 6); assert_expression_approximates_to("asin(1)", "90", Degree); - assert_expression_approximates_to("asin(1)", "100", Gradian, Cartesian); + assert_expression_approximates_to("asin(1)", "100", Gradian, Metric, Cartesian); /* atan: R -> R (odd) * [-𝐒,𝐒] -> R×𝐒 (odd) @@ -645,31 +645,31 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("atan(2)", "1.1071487177941", Radian); assert_expression_approximates_to("atan(0.01)", "9.9996666866652ᴇ-3", Radian); assert_expression_approximates_to("atan(2)", "63.434948822922", Degree); - assert_expression_approximates_to("atan(2)", "70.48", Gradian, Cartesian, 4); + assert_expression_approximates_to("atan(2)", "70.48", Gradian, Metric, Cartesian, 4); assert_expression_approximates_to("atan(0.5)", "0.4636476", Radian); // Symmetry: odd assert_expression_approximates_to("atan(-2)", "-1.1071487177941", Radian); assert_expression_approximates_to("atan(-2)", "-63.434948822922", Degree); // On [-𝐒, 𝐒] - assert_expression_approximates_to("atan(0.2×𝐒)", "0.202733×𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("atan(0.2×𝐒)", "0.202733×𝐒", Radian, Metric, Cartesian, 6); // Symmetry: odd - assert_expression_approximates_to("atan(-0.2×𝐒)", "-0.202733×𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("atan(-0.2×𝐒)", "-0.202733×𝐒", Radian, Metric, Cartesian, 6); // On [𝐒, inf×𝐒[ assert_expression_approximates_to("atan(26×𝐒)", "1.5707963267949+3.8480520568064ᴇ-2×𝐒", Radian); assert_expression_approximates_to("atan(26×𝐒)", "90+2.2047714220164×𝐒", Degree); - assert_expression_approximates_to("atan(26×𝐒)", "100+2.45×𝐒", Gradian, Cartesian, 3); + assert_expression_approximates_to("atan(26×𝐒)", "100+2.45×𝐒", Gradian, Metric, Cartesian, 3); // Symmetry: odd assert_expression_approximates_to("atan(-26×𝐒)", "-1.5707963267949-3.8480520568064ᴇ-2×𝐒", Radian); assert_expression_approximates_to("atan(-26×𝐒)", "-90-2.2047714220164×𝐒", Degree); - assert_expression_approximates_to("atan(-26×𝐒)", "-100-2.45×𝐒", Gradian, Cartesian, 3); + assert_expression_approximates_to("atan(-26×𝐒)", "-100-2.45×𝐒", Gradian, Metric, Cartesian, 3); // On ]-inf×𝐒, -𝐒[ assert_expression_approximates_to("atan(-3.4×𝐒)", "-1.570796-0.3030679×𝐒", Radian); - assert_expression_approximates_to("atan(-3.4×𝐒)", "-90-17.3645×𝐒", Degree, Cartesian, 6); - assert_expression_approximates_to("atan(-3.4×𝐒)", "-100-19.29×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("atan(-3.4×𝐒)", "-90-17.3645×𝐒", Degree, Metric, Cartesian, 6); + assert_expression_approximates_to("atan(-3.4×𝐒)", "-100-19.29×𝐒", Gradian, Metric, Cartesian, 4); // On C assert_expression_approximates_to("atan(𝐒-4)", "-1.338973+0.05578589×𝐒", Radian); - assert_expression_approximates_to("atan(𝐒-4)", "-76.7175+3.1963×𝐒", Degree, Cartesian, 6); - assert_expression_approximates_to("atan(𝐒-4)", "-85.24+3.551×𝐒", Gradian, Cartesian, 4); + assert_expression_approximates_to("atan(𝐒-4)", "-76.7175+3.1963×𝐒", Degree, Metric, Cartesian, 6); + assert_expression_approximates_to("atan(𝐒-4)", "-85.24+3.551×𝐒", Gradian, Metric, Cartesian, 4); // Key values assert_expression_approximates_to("atan(0)", "0", Degree); assert_expression_approximates_to("atan(0)", "0", Gradian); @@ -695,9 +695,9 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("cosh(8×π×𝐒/2)", "1", Radian); assert_expression_approximates_to("cosh(9×π×𝐒/2)", "0", Radian); // On C - assert_expression_approximates_to("cosh(𝐒-4)", "14.7547-22.9637×𝐒", Radian, Cartesian, 6); - assert_expression_approximates_to("cosh(𝐒-4)", "14.7547-22.9637×𝐒", Degree, Cartesian, 6); - assert_expression_approximates_to("cosh(𝐒-4)", "14.7547-22.9637×𝐒", Gradian, Cartesian, 6); + assert_expression_approximates_to("cosh(𝐒-4)", "14.7547-22.9637×𝐒", Radian, Metric, Cartesian, 6); + assert_expression_approximates_to("cosh(𝐒-4)", "14.7547-22.9637×𝐒", Degree, Metric, Cartesian, 6); + assert_expression_approximates_to("cosh(𝐒-4)", "14.7547-22.9637×𝐒", Gradian, Metric, Cartesian, 6); /* sinh: R -> R (odd) * R×𝐒 -> R×𝐒 (oscillator) @@ -717,8 +717,8 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("sinh(8×π×𝐒/2)", "0", Radian); assert_expression_approximates_to("sinh(9×π×𝐒/2)", "𝐒", Radian); // On C - assert_expression_approximates_to("sinh(𝐒-4)", "-14.7448+22.9791×𝐒", Radian, Cartesian, 6); - assert_expression_approximates_to("sinh(𝐒-4)", "-14.7448+22.9791×𝐒", Degree, Cartesian, 6); + assert_expression_approximates_to("sinh(𝐒-4)", "-14.7448+22.9791×𝐒", Radian, Metric, Cartesian, 6); + assert_expression_approximates_to("sinh(𝐒-4)", "-14.7448+22.9791×𝐒", Degree, Metric, Cartesian, 6); /* tanh: R -> R (odd) * R×𝐒 -> R×𝐒 (tangent-style) @@ -738,8 +738,8 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("tanh(8×π×𝐒/2)", "0", Radian); assert_expression_approximates_to("tanh(9×π×𝐒/2)", Undefined::Name(), Radian);*/ // On C - assert_expression_approximates_to("tanh(𝐒-4)", "-1.00028+0.000610241×𝐒", Radian, Cartesian, 6); - assert_expression_approximates_to("tanh(𝐒-4)", "-1.00028+0.000610241×𝐒", Degree, Cartesian, 6); + assert_expression_approximates_to("tanh(𝐒-4)", "-1.00028+0.000610241×𝐒", Radian, Metric, Cartesian, 6); + assert_expression_approximates_to("tanh(𝐒-4)", "-1.00028+0.000610241×𝐒", Degree, Metric, Cartesian, 6); /* acosh: [-1,1] -> R×𝐒 * ]-inf,-1[ -> π×𝐒+R (even on real) @@ -753,19 +753,19 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("acosh(2)", "1.3169578969248", Gradian); // On ]-inf, -1[ assert_expression_approximates_to("acosh(-4)", "2.0634370688956+3.1415926535898×𝐒", Radian); - assert_expression_approximates_to("acosh(-4)", "2.06344+3.14159×𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("acosh(-4)", "2.06344+3.14159×𝐒", Radian, Metric, Cartesian, 6); // On ]1,inf[: Symmetry: even on real assert_expression_approximates_to("acosh(4)", "2.0634370688956", Radian); assert_expression_approximates_to("acosh(4)", "2.063437", Radian); // On ]-inf×𝐒, 0[ assert_expression_approximates_to("acosh(-42×𝐒)", "4.4309584920805-1.5707963267949×𝐒", Radian); - assert_expression_approximates_to("acosh(-42×𝐒)", "4.431-1.571×𝐒", Radian, Cartesian, 4); + assert_expression_approximates_to("acosh(-42×𝐒)", "4.431-1.571×𝐒", Radian, Metric, Cartesian, 4); // On ]0, 𝐒×inf[: Symmetry: even on real assert_expression_approximates_to("acosh(42×𝐒)", "4.4309584920805+1.5707963267949×𝐒", Radian); - assert_expression_approximates_to("acosh(42×𝐒)", "4.431+1.571×𝐒", Radian, Cartesian, 4); + assert_expression_approximates_to("acosh(42×𝐒)", "4.431+1.571×𝐒", Radian, Metric, Cartesian, 4); // On C - assert_expression_approximates_to("acosh(𝐒-4)", "2.0966+2.8894×𝐒", Radian, Cartesian, 5); - assert_expression_approximates_to("acosh(𝐒-4)", "2.0966+2.8894×𝐒", Degree, Cartesian, 5); + assert_expression_approximates_to("acosh(𝐒-4)", "2.0966+2.8894×𝐒", Radian, Metric, Cartesian, 5); + assert_expression_approximates_to("acosh(𝐒-4)", "2.0966+2.8894×𝐒", Degree, Metric, Cartesian, 5); // Key values //assert_expression_approximates_to("acosh(-1)", "3.1415926535898×𝐒", Radian); assert_expression_approximates_to("acosh(1)", "0", Radian); @@ -793,13 +793,13 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("asinh(-0.3×𝐒)", "-0.3046927×𝐒", Degree); // On ]-inf×𝐒, -𝐒[ assert_expression_approximates_to("asinh(-22×𝐒)", "-3.7836727043295-1.5707963267949×𝐒", Radian); - assert_expression_approximates_to("asinh(-22×𝐒)", "-3.784-1.571×𝐒", Degree, Cartesian, 4); + assert_expression_approximates_to("asinh(-22×𝐒)", "-3.784-1.571×𝐒", Degree, Metric, Cartesian, 4); // On ]𝐒, inf×𝐒[, Symmetry: odd assert_expression_approximates_to("asinh(22×𝐒)", "3.7836727043295+1.5707963267949×𝐒", Radian); - assert_expression_approximates_to("asinh(22×𝐒)", "3.784+1.571×𝐒", Degree, Cartesian, 4); + assert_expression_approximates_to("asinh(22×𝐒)", "3.784+1.571×𝐒", Degree, Metric, Cartesian, 4); // On C - assert_expression_approximates_to("asinh(𝐒-4)", "-2.123+0.2383×𝐒", Radian, Cartesian, 4); - assert_expression_approximates_to("asinh(𝐒-4)", "-2.123+0.2383×𝐒", Degree, Cartesian, 4); + assert_expression_approximates_to("asinh(𝐒-4)", "-2.123+0.2383×𝐒", Radian, Metric, Cartesian, 4); + assert_expression_approximates_to("asinh(𝐒-4)", "-2.123+0.2383×𝐒", Degree, Metric, Cartesian, 4); /* atanh: [-1,1] -> R (odd) * ]-inf,-1[ -> Ο€/2*𝐒+R (odd) @@ -826,15 +826,15 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("atanh(-4×𝐒)", "-1.325817663668×𝐒", Radian); assert_expression_approximates_to("atanh(-4×𝐒)", "-1.325818×𝐒", Radian); // On C - assert_expression_approximates_to("atanh(𝐒-4)", "-0.238878+1.50862×𝐒", Radian, Cartesian, 6); - assert_expression_approximates_to("atanh(𝐒-4)", "-0.238878+1.50862×𝐒", Degree, Cartesian, 6); + assert_expression_approximates_to("atanh(𝐒-4)", "-0.238878+1.50862×𝐒", Radian, Metric, Cartesian, 6); + assert_expression_approximates_to("atanh(𝐒-4)", "-0.238878+1.50862×𝐒", Degree, Metric, Cartesian, 6); // Check that the complex part is not neglected - assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-26×𝐒)", "13+5ᴇ-16×𝐒", Radian, Cartesian, 3); - assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-60×𝐒)", "13+5ᴇ-50×𝐒", Radian, Cartesian, 3); - assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-150×𝐒)", "13+5ᴇ-140×𝐒", Radian, Cartesian, 3); - assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-250×𝐒)", "13+5ᴇ-240×𝐒", Radian, Cartesian, 3); - assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-300×𝐒)", "13+5ᴇ-290×𝐒", Radian, Cartesian, 3); + assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-26×𝐒)", "13+5ᴇ-16×𝐒", Radian, Metric, Cartesian, 3); + assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-60×𝐒)", "13+5ᴇ-50×𝐒", Radian, Metric, Cartesian, 3); + assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-150×𝐒)", "13+5ᴇ-140×𝐒", Radian, Metric, Cartesian, 3); + assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-250×𝐒)", "13+5ᴇ-240×𝐒", Radian, Metric, Cartesian, 3); + assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-300×𝐒)", "13+5ᴇ-290×𝐒", Radian, Metric, Cartesian, 3); // WARNING: evaluate on branch cut can be multivalued assert_expression_approximates_to("acos(2)", "1.3169578969248×𝐒", Radian); @@ -876,100 +876,100 @@ QUIZ_CASE(poincare_approximation_store_matrix) { QUIZ_CASE(poincare_approximation_complex_format) { // Real - assert_expression_approximates_to("0", "0", Radian, Real); - assert_expression_approximates_to("0", "0", Radian, Real); - assert_expression_approximates_to("10", "10", Radian, Real); - assert_expression_approximates_to("-10", "-10", Radian, Real); - assert_expression_approximates_to("100", "100", Radian, Real); - assert_expression_approximates_to("0.1", "0.1", Radian, Real); - assert_expression_approximates_to("0.1234567", "0.1234567", Radian, Real); - assert_expression_approximates_to("0.123456789012345", "1.2345678901235ᴇ-1", Radian, Real); - assert_expression_approximates_to("1+2×𝐒", "unreal", Radian, Real); - assert_expression_approximates_to("1+𝐒-𝐒", "unreal", Radian, Real); - assert_expression_approximates_to("1+𝐒-1", "unreal", Radian, Real); - assert_expression_approximates_to("1+𝐒", "unreal", Radian, Real); - assert_expression_approximates_to("3+𝐒", "unreal", Radian, Real); - assert_expression_approximates_to("3-𝐒", "unreal", Radian, Real); - assert_expression_approximates_to("3-𝐒-3", "unreal", Radian, Real); - assert_expression_approximates_to("𝐒", "unreal", Radian, Real); - assert_expression_approximates_to("√(-1)", "unreal", Radian, Real); - assert_expression_approximates_to("√(-1)Γ—βˆš(-1)", "unreal", Radian, Real); - assert_expression_approximates_to("ln(-2)", "unreal", Radian, Real); + assert_expression_approximates_to("0", "0", Radian, Metric, Real); + assert_expression_approximates_to("0", "0", Radian, Metric, Real); + assert_expression_approximates_to("10", "10", Radian, Metric, Real); + assert_expression_approximates_to("-10", "-10", Radian, Metric, Real); + assert_expression_approximates_to("100", "100", Radian, Metric, Real); + assert_expression_approximates_to("0.1", "0.1", Radian, Metric, Real); + assert_expression_approximates_to("0.1234567", "0.1234567", Radian, Metric, Real); + assert_expression_approximates_to("0.123456789012345", "1.2345678901235ᴇ-1", Radian, Metric, Real); + assert_expression_approximates_to("1+2×𝐒", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("1+𝐒-𝐒", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("1+𝐒-1", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("1+𝐒", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("3+𝐒", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("3-𝐒", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("3-𝐒-3", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("𝐒", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("√(-1)", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("√(-1)Γ—βˆš(-1)", "unreal", Radian, Metric, Real); + assert_expression_approximates_to("ln(-2)", "unreal", Radian, Metric, Real); // Power/Root approximates to the first REAL root in Real mode - assert_expression_simplifies_approximates_to("(-8)^(1/3)", "-2", Radian, Real); // Power have to be simplified first in order to spot the right form c^(p/q) with p, q integers - assert_expression_approximates_to("root(-8,3)", "-2", Radian, Real); // Root approximates to the first REAL root in Real mode - assert_expression_approximates_to("8^(1/3)", "2", Radian, Real); - assert_expression_simplifies_approximates_to("(-8)^(2/3)", "4", Radian, Real); // Power have to be simplified first (cf previous comment) - assert_expression_approximates_to("root(-8, 3)^2", "4", Radian, Real); - assert_expression_approximates_to("root(-8,3)", "-2", Radian, Real); + assert_expression_simplifies_approximates_to("(-8)^(1/3)", "-2", Radian, Metric, Real); // Power have to be simplified first in order to spot the right form c^(p/q) with p, q integers + assert_expression_approximates_to("root(-8,3)", "-2", Radian, Metric, Real); // Root approximates to the first REAL root in Real mode + assert_expression_approximates_to("8^(1/3)", "2", Radian, Metric, Real); + assert_expression_simplifies_approximates_to("(-8)^(2/3)", "4", Radian, Metric, Real); // Power have to be simplified first (cf previous comment) + assert_expression_approximates_to("root(-8, 3)^2", "4", Radian, Metric, Real); + assert_expression_approximates_to("root(-8,3)", "-2", Radian, Metric, Real); // Cartesian - assert_expression_approximates_to("0", "0", Radian, Cartesian); - assert_expression_approximates_to("0", "0", Radian, Cartesian); - assert_expression_approximates_to("10", "10", Radian, Cartesian); - assert_expression_approximates_to("-10", "-10", Radian, Cartesian); - assert_expression_approximates_to("100", "100", Radian, Cartesian); - assert_expression_approximates_to("0.1", "0.1", Radian, Cartesian); - assert_expression_approximates_to("0.1234567", "0.1234567", Radian, Cartesian); - assert_expression_approximates_to("0.123456789012345", "1.2345678901235ᴇ-1", Radian, Cartesian); - assert_expression_approximates_to("1+2×𝐒", "1+2×𝐒", Radian, Cartesian); - assert_expression_approximates_to("1+𝐒-𝐒", "1", Radian, Cartesian); - assert_expression_approximates_to("1+𝐒-1", "𝐒", Radian, Cartesian); - assert_expression_approximates_to("1+𝐒", "1+𝐒", Radian, Cartesian); - assert_expression_approximates_to("3+𝐒", "3+𝐒", Radian, Cartesian); - assert_expression_approximates_to("3-𝐒", "3-𝐒", Radian, Cartesian); - assert_expression_approximates_to("3-𝐒-3", "-𝐒", Radian, Cartesian); - assert_expression_approximates_to("𝐒", "𝐒", Radian, Cartesian); - assert_expression_approximates_to("√(-1)", "𝐒", Radian, Cartesian); - assert_expression_approximates_to("√(-1)Γ—βˆš(-1)", "-1", Radian, Cartesian); - assert_expression_approximates_to("ln(-2)", "6.9314718055995ᴇ-1+3.1415926535898×𝐒", Radian, Cartesian); - assert_expression_approximates_to("(-8)^(1/3)", "1+1.7320508075689×𝐒", Radian, Cartesian); - assert_expression_approximates_to("(-8)^(2/3)", "-2+3.4641×𝐒", Radian, Cartesian, 6); - assert_expression_approximates_to("root(-8,3)", "1+1.7320508075689×𝐒", Radian, Cartesian); + assert_expression_approximates_to("0", "0", Radian, Metric, Cartesian); + assert_expression_approximates_to("0", "0", Radian, Metric, Cartesian); + assert_expression_approximates_to("10", "10", Radian, Metric, Cartesian); + assert_expression_approximates_to("-10", "-10", Radian, Metric, Cartesian); + assert_expression_approximates_to("100", "100", Radian, Metric, Cartesian); + assert_expression_approximates_to("0.1", "0.1", Radian, Metric, Cartesian); + assert_expression_approximates_to("0.1234567", "0.1234567", Radian, Metric, Cartesian); + assert_expression_approximates_to("0.123456789012345", "1.2345678901235ᴇ-1", Radian, Metric, Cartesian); + assert_expression_approximates_to("1+2×𝐒", "1+2×𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("1+𝐒-𝐒", "1", Radian, Metric, Cartesian); + assert_expression_approximates_to("1+𝐒-1", "𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("1+𝐒", "1+𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("3+𝐒", "3+𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("3-𝐒", "3-𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("3-𝐒-3", "-𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("𝐒", "𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("√(-1)", "𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("√(-1)Γ—βˆš(-1)", "-1", Radian, Metric, Cartesian); + assert_expression_approximates_to("ln(-2)", "6.9314718055995ᴇ-1+3.1415926535898×𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("(-8)^(1/3)", "1+1.7320508075689×𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("(-8)^(2/3)", "-2+3.4641×𝐒", Radian, Metric, Cartesian, 6); + assert_expression_approximates_to("root(-8,3)", "1+1.7320508075689×𝐒", Radian, Metric, Cartesian); // Polar - assert_expression_approximates_to("0", "0", Radian, Polar); - assert_expression_approximates_to("0", "0", Radian, Polar); - assert_expression_approximates_to("10", "10", Radian, Polar); - assert_expression_approximates_to("-10", "10Γ—β„―^\u00123.1415926535898×𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("0", "0", Radian, Metric, Polar); + assert_expression_approximates_to("0", "0", Radian, Metric, Polar); + assert_expression_approximates_to("10", "10", Radian, Metric, Polar); + assert_expression_approximates_to("-10", "10Γ—β„―^\u00123.1415926535898×𝐒\u0013", Radian, Metric, Polar); - assert_expression_approximates_to("100", "100", Radian, Polar); - assert_expression_approximates_to("0.1", "0.1", Radian, Polar); - assert_expression_approximates_to("0.1234567", "0.1234567", Radian, Polar); - assert_expression_approximates_to("0.12345678", "0.12345678", Radian, Polar); + assert_expression_approximates_to("100", "100", Radian, Metric, Polar); + assert_expression_approximates_to("0.1", "0.1", Radian, Metric, Polar); + assert_expression_approximates_to("0.1234567", "0.1234567", Radian, Metric, Polar); + assert_expression_approximates_to("0.12345678", "0.12345678", Radian, Metric, Polar); - assert_expression_approximates_to("1+2×𝐒", "2.236068Γ—β„―^\u00121.107149×𝐒\u0013", Radian, Polar); - assert_expression_approximates_to("1+𝐒-𝐒", "1", Radian, Polar); - assert_expression_approximates_to("1+𝐒-1", "β„―^\u00121.57079632679×𝐒\u0013", Radian, Polar, 12); - assert_expression_approximates_to("1+𝐒", "1.414214Γ—β„―^\u00120.7853982×𝐒\u0013", Radian, Polar); - assert_expression_approximates_to("3+𝐒", "3.16227766017Γ—β„―^\u00120.321750554397×𝐒\u0013", Radian, Polar,12); - assert_expression_approximates_to("3-𝐒", "3.162278Γ—β„―^\u0012-0.3217506×𝐒\u0013", Radian, Polar); - assert_expression_approximates_to("3-𝐒-3", "β„―^\u0012-1.57079632679×𝐒\u0013", Radian, Polar,12); + assert_expression_approximates_to("1+2×𝐒", "2.236068Γ—β„―^\u00121.107149×𝐒\u0013", Radian, Metric, Polar); + assert_expression_approximates_to("1+𝐒-𝐒", "1", Radian, Metric, Polar); + assert_expression_approximates_to("1+𝐒-1", "β„―^\u00121.57079632679×𝐒\u0013", Radian, Metric, Polar, 12); + assert_expression_approximates_to("1+𝐒", "1.414214Γ—β„―^\u00120.7853982×𝐒\u0013", Radian, Metric, Polar); + assert_expression_approximates_to("3+𝐒", "3.16227766017Γ—β„―^\u00120.321750554397×𝐒\u0013", Radian, Metric, Polar,12); + assert_expression_approximates_to("3-𝐒", "3.162278Γ—β„―^\u0012-0.3217506×𝐒\u0013", Radian, Metric, Polar); + assert_expression_approximates_to("3-𝐒-3", "β„―^\u0012-1.57079632679×𝐒\u0013", Radian, Metric, Polar,12); // 2β„―^(𝐒) has a too low precision in float on the web platform - assert_expression_approximates_to("3β„―^(2*𝐒)", "3Γ—β„―^\u00122×𝐒\u0013", Radian, Polar, 4); - assert_expression_approximates_to("2β„―^(-𝐒)", "2Γ—β„―^\u0012-𝐒\u0013", Radian, Polar, 9); + assert_expression_approximates_to("3β„―^(2*𝐒)", "3Γ—β„―^\u00122×𝐒\u0013", Radian, Metric, Polar, 4); + assert_expression_approximates_to("2β„―^(-𝐒)", "2Γ—β„―^\u0012-𝐒\u0013", Radian, Metric, Polar, 9); - assert_expression_approximates_to("𝐒", "β„―^\u00121.570796×𝐒\u0013", Radian, Polar); - assert_expression_approximates_to("√(-1)", "β„―^\u00121.5707963267949×𝐒\u0013", Radian, Polar); - assert_expression_approximates_to("√(-1)Γ—βˆš(-1)", "β„―^\u00123.1415926535898×𝐒\u0013", Radian, Polar); - assert_expression_approximates_to("(-8)^(1/3)", "2Γ—β„―^\u00121.0471975511966×𝐒\u0013", Radian, Polar); - assert_expression_approximates_to("(-8)^(2/3)", "4Γ—β„―^\u00122.094395×𝐒\u0013", Radian, Polar); - assert_expression_approximates_to("root(-8,3)", "2Γ—β„―^\u00121.0471975511966×𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("𝐒", "β„―^\u00121.570796×𝐒\u0013", Radian, Metric, Polar); + assert_expression_approximates_to("√(-1)", "β„―^\u00121.5707963267949×𝐒\u0013", Radian, Metric, Polar); + assert_expression_approximates_to("√(-1)Γ—βˆš(-1)", "β„―^\u00123.1415926535898×𝐒\u0013", Radian, Metric, Polar); + assert_expression_approximates_to("(-8)^(1/3)", "2Γ—β„―^\u00121.0471975511966×𝐒\u0013", Radian, Metric, Polar); + assert_expression_approximates_to("(-8)^(2/3)", "4Γ—β„―^\u00122.094395×𝐒\u0013", Radian, Metric, Polar); + assert_expression_approximates_to("root(-8,3)", "2Γ—β„―^\u00121.0471975511966×𝐒\u0013", Radian, Metric, Polar); // Cartesian to Polar and vice versa - assert_expression_approximates_to("2+3×𝐒", "3.60555127546Γ—β„―^\u00120.982793723247×𝐒\u0013", Radian, Polar, 12); - assert_expression_approximates_to("3.60555127546Γ—β„―^(0.982793723247×𝐒)", "2+3×𝐒", Radian, Cartesian, 12); - assert_expression_approximates_to("12.04159457879229548012824103Γ—β„―^(1.4876550949×𝐒)", "1+12×𝐒", Radian, Cartesian, 5); + assert_expression_approximates_to("2+3×𝐒", "3.60555127546Γ—β„―^\u00120.982793723247×𝐒\u0013", Radian, Metric, Polar, 12); + assert_expression_approximates_to("3.60555127546Γ—β„―^(0.982793723247×𝐒)", "2+3×𝐒", Radian, Metric, Cartesian, 12); + assert_expression_approximates_to("12.04159457879229548012824103Γ—β„―^(1.4876550949×𝐒)", "1+12×𝐒", Radian, Metric, Cartesian, 5); // Overflow - assert_expression_approximates_to("-2ᴇ20+2ᴇ20×𝐒", "-2ᴇ20+2ᴇ20×𝐒", Radian, Cartesian); + assert_expression_approximates_to("-2ᴇ20+2ᴇ20×𝐒", "-2ᴇ20+2ᴇ20×𝐒", Radian, Metric, Cartesian); /* TODO: this test fails on the device because libm hypotf (which is called * eventually by std::abs) is not accurate enough. We might change the * embedded libm? */ - //assert_expression_approximates_to("-2ᴇ20+2ᴇ20×𝐒", "2.828427ᴇ20Γ—β„―^\u00122.356194×𝐒\u0013", Radian, Polar); - assert_expression_approximates_to("-2ᴇ10+2ᴇ10×𝐒", "2.828427ᴇ10Γ—β„―^\u00122.356194×𝐒\u0013", Radian, Polar); - assert_expression_approximates_to("1ᴇ155-1ᴇ155×𝐒", "1ᴇ155-1ᴇ155×𝐒", Radian, Cartesian); - assert_expression_approximates_to("1ᴇ155-1ᴇ155×𝐒", "1.41421356237ᴇ155Γ—β„―^\u0012-0.785398163397×𝐒\u0013", Radian, Polar,12); + //assert_expression_approximates_to("-2ᴇ20+2ᴇ20×𝐒", "2.828427ᴇ20Γ—β„―^\u00122.356194×𝐒\u0013", Radian, Metric, Polar); + assert_expression_approximates_to("-2ᴇ10+2ᴇ10×𝐒", "2.828427ᴇ10Γ—β„―^\u00122.356194×𝐒\u0013", Radian, Metric, Polar); + assert_expression_approximates_to("1ᴇ155-1ᴇ155×𝐒", "1ᴇ155-1ᴇ155×𝐒", Radian, Metric, Cartesian); + assert_expression_approximates_to("1ᴇ155-1ᴇ155×𝐒", "1.41421356237ᴇ155Γ—β„―^\u0012-0.785398163397×𝐒\u0013", Radian, Metric, Polar,12); assert_expression_approximates_to("-2ᴇ100+2ᴇ100×𝐒", Undefined::Name()); assert_expression_approximates_to("-2ᴇ360+2ᴇ360×𝐒", Undefined::Name()); assert_expression_approximates_to("-2ᴇ100+2ᴇ10×𝐒", "-inf+2ᴇ10×𝐒"); @@ -981,8 +981,8 @@ QUIZ_CASE(poincare_approximation_complex_format) { QUIZ_CASE(poincare_approximation_mix) { assert_expression_approximates_to("-2-3", "-5"); assert_expression_approximates_to("1.2Γ—β„―^(1)", "3.261938"); - assert_expression_approximates_to("2β„―^(3)", "40.1711", Radian, Cartesian, 6); // WARNING: the 7th significant digit is wrong on blackbos simulator - assert_expression_approximates_to("β„―^2Γ—β„―^(1)", "20.0855", Radian, Cartesian, 6); // WARNING: the 7th significant digit is wrong on simulator + assert_expression_approximates_to("2β„―^(3)", "40.1711", Radian, Metric, Cartesian, 6); // WARNING: the 7th significant digit is wrong on blackbos simulator + assert_expression_approximates_to("β„―^2Γ—β„―^(1)", "20.0855", Radian, Metric, Cartesian, 6); // WARNING: the 7th significant digit is wrong on simulator assert_expression_approximates_to("β„―^2Γ—β„―^(1)", "20.085536923188"); assert_expression_approximates_to("2Γ—3^4+2", "164"); assert_expression_approximates_to("-2Γ—3^4+2", "-160"); @@ -995,13 +995,13 @@ QUIZ_CASE(poincare_approximation_mix) { assert_expression_approximates_to("4/2Γ—(2+3)", "10"); assert_expression_simplifies_and_approximates_to("1.0092^(20)", "1.2010050593402"); - assert_expression_simplifies_and_approximates_to("1.0092^(50)Γ—ln(3/2)", "0.6409373488899", Degree, Cartesian, 13); - assert_expression_simplifies_and_approximates_to("1.0092^(50)Γ—ln(1.0092)", "1.447637354655ᴇ-2", Degree, Cartesian, 13); + assert_expression_simplifies_and_approximates_to("1.0092^(50)Γ—ln(3/2)", "0.6409373488899", Degree, Metric, Cartesian, 13); + assert_expression_simplifies_and_approximates_to("1.0092^(50)Γ—ln(1.0092)", "1.447637354655ᴇ-2", Degree, Metric, Cartesian, 13); assert_expression_approximates_to("1.0092^(20)", "1.2010050593402"); - assert_expression_approximates_to("1.0092^(50)Γ—ln(3/2)", "0.6409373488899", Degree, Cartesian, 13); - assert_expression_approximates_to("1.0092^(50)Γ—ln(1.0092)", "1.447637354655ᴇ-2", Degree, Cartesian, 13); + assert_expression_approximates_to("1.0092^(50)Γ—ln(3/2)", "0.6409373488899", Degree, Metric, Cartesian, 13); + assert_expression_approximates_to("1.0092^(50)Γ—ln(1.0092)", "1.447637354655ᴇ-2", Degree, Metric, Cartesian, 13); assert_expression_simplifies_approximates_to("1.0092^(20)", "1.2010050593402"); - assert_expression_simplifies_approximates_to("1.0092^(50)Γ—ln(3/2)", "0.6409373488899", Degree, Cartesian, 13); + assert_expression_simplifies_approximates_to("1.0092^(50)Γ—ln(3/2)", "0.6409373488899", Degree, Metric, Cartesian, 13); //assert_expression_approximates_to("1.0092^(20)", "1.201005"); TODO does not work assert_expression_approximates_to("1.0092^(50)Γ—ln(3/2)", "0.6409366"); //assert_expression_simplifies_approximates_to("1.0092^(20)", "1.2010050593402"); TODO does not work diff --git a/poincare/test/derivative.cpp b/poincare/test/derivative.cpp index 05d2a0a1a..b9a910014 100644 --- a/poincare/test/derivative.cpp +++ b/poincare/test/derivative.cpp @@ -34,7 +34,7 @@ void assert_parses_and_reduces_as(const char * expression, const char * simplifi ExpressionNode::SymbolicComputation symbolicComputation = ReplaceAllSymbolsWithDefinitionsOrUndefined; #endif - assert_parsed_expression_simplify_to(expression, simplifiedDerivative, User, Radian, Cartesian, symbolicComputation); + assert_parsed_expression_simplify_to(expression, simplifiedDerivative, User, Radian, Metric, Cartesian, symbolicComputation); } QUIZ_CASE(poincare_derivative_literals) { @@ -166,4 +166,4 @@ QUIZ_CASE(poincare_derivative_functions) { #endif emptyGlobalContext(); -} \ No newline at end of file +} diff --git a/poincare/test/expression_properties.cpp b/poincare/test/expression_properties.cpp index cc3d11c4d..97af3fde3 100644 --- a/poincare/test/expression_properties.cpp +++ b/poincare/test/expression_properties.cpp @@ -105,10 +105,10 @@ constexpr Poincare::ExpressionNode::Sign Positive = Poincare::ExpressionNode::Si constexpr Poincare::ExpressionNode::Sign Negative = Poincare::ExpressionNode::Sign::Negative; constexpr Poincare::ExpressionNode::Sign Unknown = Poincare::ExpressionNode::Sign::Unknown; -void assert_reduced_expression_sign(const char * expression, Poincare::ExpressionNode::Sign sign, Preferences::ComplexFormat complexFormat = Cartesian, Preferences::AngleUnit angleUnit = Radian) { +void assert_reduced_expression_sign(const char * expression, Poincare::ExpressionNode::Sign sign, Preferences::ComplexFormat complexFormat = Cartesian, Preferences::AngleUnit angleUnit = Radian, Preferences::UnitFormat unitFormat = Metric) { Shared::GlobalContext globalContext; Expression e = parse_expression(expression, &globalContext, false); - e = e.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForApproximation)); + e = e.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, unitFormat, ExpressionNode::ReductionTarget::SystemForApproximation)); quiz_assert_print_if_failure(e.sign(&globalContext) == sign, expression); } @@ -166,14 +166,14 @@ QUIZ_CASE(poincare_properties_sign) { void assert_expression_is_real(const char * expression) { Shared::GlobalContext context; // isReal can be call only on reduced expressions - Expression e = parse_expression(expression, &context, false).reduce(ExpressionNode::ReductionContext(&context, Cartesian, Radian, ExpressionNode::ReductionTarget::SystemForApproximation)); + Expression e = parse_expression(expression, &context, false).reduce(ExpressionNode::ReductionContext(&context, Cartesian, Radian, Metric, ExpressionNode::ReductionTarget::SystemForApproximation)); quiz_assert_print_if_failure(e.isReal(&context), expression); } void assert_expression_is_not_real(const char * expression) { Shared::GlobalContext context; // isReal can be call only on reduced expressions - Expression e = parse_expression(expression, &context, false).reduce(ExpressionNode::ReductionContext(&context, Cartesian, Radian, ExpressionNode::ReductionTarget::SystemForApproximation)); + Expression e = parse_expression(expression, &context, false).reduce(ExpressionNode::ReductionContext(&context, Cartesian, Radian, Metric, ExpressionNode::ReductionTarget::SystemForApproximation)); quiz_assert_print_if_failure(!e.isReal(&context), expression); } @@ -207,10 +207,10 @@ QUIZ_CASE(poincare_properties_is_real) { assert_expression_is_not_real("(-2)^0.4"); } -void assert_reduced_expression_polynomial_degree(const char * expression, int degree, const char * symbolName = "x", Preferences::ComplexFormat complexFormat = Cartesian, Preferences::AngleUnit angleUnit = Radian) { +void assert_reduced_expression_polynomial_degree(const char * expression, int degree, const char * symbolName = "x", Preferences::ComplexFormat complexFormat = Cartesian, Preferences::AngleUnit angleUnit = Radian, Preferences::UnitFormat unitFormat = Metric) { Shared::GlobalContext globalContext; Expression e = parse_expression(expression, &globalContext, false); - Expression result = e.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, SystemForApproximation)); + Expression result = e.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, unitFormat, SystemForApproximation)); quiz_assert_print_if_failure(result.polynomialDegree(&globalContext, symbolName) == degree, expression); } @@ -240,9 +240,9 @@ QUIZ_CASE(poincare_properties_polynomial_degree) { Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); } -void assert_reduced_expression_has_characteristic_range(Expression e, float range, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) { +void assert_reduced_expression_has_characteristic_range(Expression e, float range, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree, Preferences::UnitFormat unitFormat = Metric) { Shared::GlobalContext globalContext; - e = e.reduce(ExpressionNode::ReductionContext(&globalContext, Preferences::ComplexFormat::Cartesian, angleUnit, ExpressionNode::ReductionTarget::SystemForApproximation)); + e = e.reduce(ExpressionNode::ReductionContext(&globalContext, Preferences::ComplexFormat::Cartesian, angleUnit, unitFormat, ExpressionNode::ReductionTarget::SystemForApproximation)); if (std::isnan(range)) { quiz_assert(std::isnan(e.characteristicXRange(&globalContext, angleUnit))); } else { @@ -323,16 +323,16 @@ QUIZ_CASE(poincare_properties_get_variables) { assert_expression_has_variables("a+b+c+d+e+f", variableBuffer9, 6); } -void assert_reduced_expression_has_polynomial_coefficient(const char * expression, const char * symbolName, const char ** coefficients, Preferences::ComplexFormat complexFormat = Cartesian, Preferences::AngleUnit angleUnit = Radian, ExpressionNode::SymbolicComputation symbolicComputation = ReplaceAllDefinedSymbolsWithDefinition) { +void assert_reduced_expression_has_polynomial_coefficient(const char * expression, const char * symbolName, const char ** coefficients, Preferences::ComplexFormat complexFormat = Cartesian, Preferences::AngleUnit angleUnit = Radian, Preferences::UnitFormat unitFormat = Metric, ExpressionNode::SymbolicComputation symbolicComputation = ReplaceAllDefinedSymbolsWithDefinition) { Shared::GlobalContext globalContext; Expression e = parse_expression(expression, &globalContext, false); - e = e.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, SystemForAnalysis, symbolicComputation)); + e = e.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, unitFormat, SystemForAnalysis, symbolicComputation)); Expression coefficientBuffer[Poincare::Expression::k_maxNumberOfPolynomialCoefficients]; - int d = e.getPolynomialReducedCoefficients(symbolName, coefficientBuffer, &globalContext, complexFormat, Radian, symbolicComputation); + int d = e.getPolynomialReducedCoefficients(symbolName, coefficientBuffer, &globalContext, complexFormat, Radian, unitFormat, symbolicComputation); for (int i = 0; i <= d; i++) { Expression f = parse_expression(coefficients[i], &globalContext, false); - coefficientBuffer[i] = coefficientBuffer[i].reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, SystemForAnalysis, symbolicComputation)); - f = f.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, SystemForAnalysis, symbolicComputation)); + coefficientBuffer[i] = coefficientBuffer[i].reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, unitFormat, SystemForAnalysis, symbolicComputation)); + f = f.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, unitFormat, SystemForAnalysis, symbolicComputation)); quiz_assert_print_if_failure(coefficientBuffer[i].isIdenticalTo(f), expression); } quiz_assert_print_if_failure(coefficients[d+1] == 0, expression); @@ -363,9 +363,9 @@ QUIZ_CASE(poincare_properties_get_polynomial_coefficients) { const char * coefficient7[] = {"4", 0}; assert_reduced_expression_has_polynomial_coefficient("x+1", "x", coefficient7 ); const char * coefficient8[] = {"2", "1", 0}; - assert_reduced_expression_has_polynomial_coefficient("x+2", "x", coefficient8, Real, Radian, DoNotReplaceAnySymbol); - assert_reduced_expression_has_polynomial_coefficient("x+2", "x", coefficient8, Real, Radian, ReplaceDefinedFunctionsWithDefinitions); - assert_reduced_expression_has_polynomial_coefficient("f(x)", "x", coefficient4, Cartesian, Radian, ReplaceDefinedFunctionsWithDefinitions); + assert_reduced_expression_has_polynomial_coefficient("x+2", "x", coefficient8, Real, Radian, Metric, DoNotReplaceAnySymbol); + assert_reduced_expression_has_polynomial_coefficient("x+2", "x", coefficient8, Real, Radian, Metric, ReplaceDefinedFunctionsWithDefinitions); + assert_reduced_expression_has_polynomial_coefficient("f(x)", "x", coefficient4, Cartesian, Radian, Metric, ReplaceDefinedFunctionsWithDefinitions); // Clear the storage Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -374,7 +374,7 @@ QUIZ_CASE(poincare_properties_get_polynomial_coefficients) { void assert_reduced_expression_unit_is(const char * expression, const char * unit) { Shared::GlobalContext globalContext; - ExpressionNode::ReductionContext redContext(&globalContext, Real, Degree, SystemForApproximation); + ExpressionNode::ReductionContext redContext(&globalContext, Real, Degree, Metric, SystemForApproximation); Expression e = parse_expression(expression, &globalContext, false); e = e.reduce(redContext); Expression u1; @@ -395,7 +395,7 @@ QUIZ_CASE(poincare_properties_remove_unit) { } void assert_seconds_split_to(double totalSeconds, const char * splittedTime, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { - Expression time = Unit::BuildTimeSplit(totalSeconds, context, complexFormat, angleUnit); + Expression time = Unit::BuildTimeSplit(totalSeconds, context); constexpr static int bufferSize = 100; char buffer[bufferSize]; time.serialize(buffer, bufferSize, DecimalMode); @@ -404,7 +404,7 @@ void assert_seconds_split_to(double totalSeconds, const char * splittedTime, Con Expression extract_unit(const char * expression) { Shared::GlobalContext globalContext; - ExpressionNode::ReductionContext reductionContext = ExpressionNode::ReductionContext(&globalContext, Cartesian, Degree, User, ReplaceAllSymbolsWithUndefined, NoUnitConversion); + ExpressionNode::ReductionContext reductionContext = ExpressionNode::ReductionContext(&globalContext, Cartesian, Degree, Metric, User, ReplaceAllSymbolsWithUndefined, NoUnitConversion); Expression e = parse_expression(expression, &globalContext, false).reduce(reductionContext); Expression unit; e.removeUnit(&unit); diff --git a/poincare/test/helper.cpp b/poincare/test/helper.cpp index d940dd108..ba8298bc8 100644 --- a/poincare/test/helper.cpp +++ b/poincare/test/helper.cpp @@ -37,10 +37,10 @@ void quiz_assert_log_if_failure(bool test, TreeHandle tree) { quiz_assert(test); } -void assert_parsed_expression_process_to(const char * expression, const char * result, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation, ExpressionNode::UnitConversion unitConversion, ProcessExpression process, int numberOfSignifiantDigits) { +void assert_parsed_expression_process_to(const char * expression, const char * result, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation, ExpressionNode::UnitConversion unitConversion, ProcessExpression process, int numberOfSignifiantDigits) { Shared::GlobalContext globalContext; Expression e = parse_expression(expression, &globalContext, false); - Expression m = process(e, ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, target, symbolicComputation, unitConversion)); + Expression m = process(e, ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, unitFormat, target, symbolicComputation, unitConversion)); constexpr int bufferSize = 500; char buffer[bufferSize]; m.serialize(buffer, bufferSize, DecimalMode, numberOfSignifiantDigits); @@ -76,23 +76,23 @@ Poincare::Expression parse_expression(const char * expression, Context * context return result; } -void assert_reduce(const char * expression, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target) { +void assert_reduce(const char * expression, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target) { Shared::GlobalContext globalContext; Expression e = parse_expression(expression, &globalContext, false); - assert_expression_reduce(e, angleUnit, complexFormat, target, expression); + assert_expression_reduce(e, angleUnit, unitFormat, complexFormat, target, expression); } -void assert_expression_reduce(Expression e, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target, const char * printIfFailure) { +void assert_expression_reduce(Expression e, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target, const char * printIfFailure) { Shared::GlobalContext globalContext; - e = e.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, target)); + e = e.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, unitFormat, target)); quiz_assert_print_if_failure(!(e.isUninitialized()), printIfFailure); } -void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, ExpressionNode::ReductionTarget target, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::SymbolicComputation symbolicComputation, ExpressionNode::UnitConversion unitConversion) { - assert_parsed_expression_process_to(expression, simplifiedExpression, target, complexFormat, angleUnit, symbolicComputation, unitConversion, [](Expression e, ExpressionNode::ReductionContext reductionContext) { +void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, ExpressionNode::ReductionTarget target, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, Preferences::ComplexFormat complexFormat, ExpressionNode::SymbolicComputation symbolicComputation, ExpressionNode::UnitConversion unitConversion) { + assert_parsed_expression_process_to(expression, simplifiedExpression, target, complexFormat, angleUnit, unitFormat, symbolicComputation, unitConversion, [](Expression e, ExpressionNode::ReductionContext reductionContext) { Expression copy = e.clone(); if (reductionContext.target() == ExpressionNode::ReductionTarget::User) { - copy.simplifyAndApproximate(©, nullptr, reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit(), reductionContext.symbolicComputation(), reductionContext.unitConversion()); + copy.simplifyAndApproximate(©, nullptr, reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit(), reductionContext.unitFormat(), reductionContext.symbolicComputation(), reductionContext.unitConversion()); } else { copy = copy.simplify(reductionContext); } @@ -119,29 +119,29 @@ bool IsApproximatelyEqual(double observedValue, double expectedValue, double pre } template -void assert_expression_approximates_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) { +void assert_expression_approximates_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) { int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits; numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : numberOfDigits; - assert_parsed_expression_process_to(expression, approximation, SystemForApproximation, complexFormat, angleUnit, ReplaceAllSymbolsWithDefinitionsOrUndefined, DefaultUnitConversion, [](Expression e, ExpressionNode::ReductionContext reductionContext) { + assert_parsed_expression_process_to(expression, approximation, SystemForApproximation, complexFormat, angleUnit, unitFormat, ReplaceAllSymbolsWithDefinitionsOrUndefined, DefaultUnitConversion, [](Expression e, ExpressionNode::ReductionContext reductionContext) { return e.approximate(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); }, numberOfDigits); } -void assert_expression_simplifies_and_approximates_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) { +void assert_expression_simplifies_and_approximates_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) { int numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : PrintFloat::k_numberOfStoredSignificantDigits; - assert_parsed_expression_process_to(expression, approximation, SystemForApproximation, complexFormat, angleUnit, ReplaceAllSymbolsWithDefinitionsOrUndefined, DefaultUnitConversion, [](Expression e, ExpressionNode::ReductionContext reductionContext) { + assert_parsed_expression_process_to(expression, approximation, SystemForApproximation, complexFormat, angleUnit, unitFormat, ReplaceAllSymbolsWithDefinitionsOrUndefined, DefaultUnitConversion, [](Expression e, ExpressionNode::ReductionContext reductionContext) { Expression reduced; Expression approximated; - e.simplifyAndApproximate(&reduced, &approximated, reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit(), reductionContext.symbolicComputation()); + e.simplifyAndApproximate(&reduced, &approximated, reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit(), reductionContext.unitFormat(), reductionContext.symbolicComputation()); return approximated; }, numberOfDigits); } template -void assert_expression_simplifies_approximates_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) { +void assert_expression_simplifies_approximates_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) { int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits; numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : numberOfDigits; - assert_parsed_expression_process_to(expression, approximation, SystemForApproximation, complexFormat, angleUnit, ReplaceAllSymbolsWithDefinitionsOrUndefined, DefaultUnitConversion, [](Expression e, ExpressionNode::ReductionContext reductionContext) { + assert_parsed_expression_process_to(expression, approximation, SystemForApproximation, complexFormat, angleUnit, unitFormat, ReplaceAllSymbolsWithDefinitionsOrUndefined, DefaultUnitConversion, [](Expression e, ExpressionNode::ReductionContext reductionContext) { e = e.simplify(reductionContext); return e.approximate(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); }, numberOfDigits); @@ -166,7 +166,7 @@ void assert_expression_layouts_as(Poincare::Expression expression, Poincare::Lay quiz_assert(l.isIdenticalTo(layout)); } -template void assert_expression_approximates_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); -template void assert_expression_approximates_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); -template void assert_expression_simplifies_approximates_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); -template void assert_expression_simplifies_approximates_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); +template void assert_expression_approximates_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::UnitFormat, Poincare::Preferences::ComplexFormat, int); +template void assert_expression_approximates_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::UnitFormat, Poincare::Preferences::ComplexFormat, int); +template void assert_expression_simplifies_approximates_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::UnitFormat, Poincare::Preferences::ComplexFormat, int); +template void assert_expression_simplifies_approximates_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::UnitFormat, Poincare::Preferences::ComplexFormat, int); diff --git a/poincare/test/helper.h b/poincare/test/helper.h index 841a5bc11..13ba89acc 100644 --- a/poincare/test/helper.h +++ b/poincare/test/helper.h @@ -19,6 +19,8 @@ constexpr Poincare::ExpressionNode::UnitConversion InternationalSystemUnitConver constexpr Poincare::Preferences::AngleUnit Degree = Poincare::Preferences::AngleUnit::Degree; constexpr Poincare::Preferences::AngleUnit Radian = Poincare::Preferences::AngleUnit::Radian; constexpr Poincare::Preferences::AngleUnit Gradian = Poincare::Preferences::AngleUnit::Gradian; +constexpr Poincare::Preferences::UnitFormat Metric = Poincare::Preferences::UnitFormat::Metric; +constexpr Poincare::Preferences::UnitFormat Imperial = Poincare::Preferences::UnitFormat::Imperial; constexpr Poincare::Preferences::ComplexFormat Cartesian = Poincare::Preferences::ComplexFormat::Cartesian; constexpr Poincare::Preferences::ComplexFormat Polar = Poincare::Preferences::ComplexFormat::Polar; constexpr Poincare::Preferences::ComplexFormat Real = Poincare::Preferences::ComplexFormat::Real; @@ -31,7 +33,7 @@ void quiz_assert_log_if_failure(bool test, Poincare::TreeHandle tree); typedef Poincare::Expression (*ProcessExpression)(Poincare::Expression, Poincare::ExpressionNode::ReductionContext reductionContext); -void assert_parsed_expression_process_to(const char * expression, const char * result, Poincare::ExpressionNode::ReductionTarget target, Poincare::Preferences::ComplexFormat complexFormat, Poincare::Preferences::AngleUnit angleUnit, Poincare::ExpressionNode::SymbolicComputation symbolicComputation, Poincare::ExpressionNode::UnitConversion unitConversion, ProcessExpression process, int numberOfSignifiantDigits = Poincare::PrintFloat::k_numberOfStoredSignificantDigits); +void assert_parsed_expression_process_to(const char * expression, const char * result, Poincare::ExpressionNode::ReductionTarget target, Poincare::Preferences::ComplexFormat complexFormat, Poincare::Preferences::AngleUnit angleUnit, Poincare::Preferences::UnitFormat unitFormat, Poincare::ExpressionNode::SymbolicComputation symbolicComputation, Poincare::ExpressionNode::UnitConversion unitConversion, ProcessExpression process, int numberOfSignifiantDigits = Poincare::PrintFloat::k_numberOfStoredSignificantDigits); // Parsing @@ -39,11 +41,12 @@ Poincare::Expression parse_expression(const char * expression, Poincare::Context // Simplification -void assert_reduce(const char * expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User); +void assert_reduce(const char * expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::UnitFormat unitFormat = Metric, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User); -void assert_expression_reduce(Poincare::Expression expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User, const char * printIfFailure = "Error"); +void assert_expression_reduce(Poincare::Expression expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::UnitFormat unitFormat = Metric, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User, const char * printIfFailure = "Error"); -void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, Poincare::ExpressionNode::ReductionTarget target = User, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion unitConversion = DefaultUnitConversion); + +void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, Poincare::ExpressionNode::ReductionTarget target = User, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::UnitFormat unitFormat = Metric, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion unitConversion = DefaultUnitConversion); // Approximation @@ -51,10 +54,10 @@ void assert_parsed_expression_simplify_to(const char * expression, const char * * according to precision and reference parameters */ bool IsApproximatelyEqual(double observedValue, double expectedValue, double precision, double reference); template -void assert_expression_approximates_to(const char * expression, const char * approximation, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1); -void assert_expression_simplifies_and_approximates_to(const char * expression, const char * approximation, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1); +void assert_expression_approximates_to(const char * expression, const char * approximation, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::UnitFormat unitFormat = Metric, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1); +void assert_expression_simplifies_and_approximates_to(const char * expression, const char * approximation, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::UnitFormat unitFormat = Metric, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1); template -void assert_expression_simplifies_approximates_to(const char * expression, const char * approximation, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1); +void assert_expression_simplifies_approximates_to(const char * expression, const char * approximation, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::UnitFormat unitFormat = Metric, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1); // Expression serializing diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index 301f6b8f9..5a7bfd3d5 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -106,7 +106,7 @@ QUIZ_CASE(poincare_simplification_infinity) { } QUIZ_CASE(poincare_simplification_addition) { - assert_parsed_expression_simplify_to("1/x^2+3", "\u00123Γ—x^2+1\u0013/x^2", User, Radian, Real); + assert_parsed_expression_simplify_to("1/x^2+3", "\u00123Γ—x^2+1\u0013/x^2", User, Radian, Metric, Real); assert_parsed_expression_simplify_to("1+x", "x+1"); assert_parsed_expression_simplify_to("1/2+1/3+1/4+1/5+1/6+1/7", "223/140"); assert_parsed_expression_simplify_to("1+x+4-i-2x", "-i-x+5"); @@ -528,11 +528,11 @@ QUIZ_CASE(poincare_simplification_power) { assert_parsed_expression_simplify_to("β„―^(𝐒×π/3)", "1/2+√(3)/2×𝐒"); assert_parsed_expression_simplify_to("(-1)^(1/3)", "1/2+√(3)/2×𝐒"); assert_parsed_expression_simplify_to("√(-x)", "√(-x)"); - assert_parsed_expression_simplify_to("√(x)^2", "x", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("√(-3)^2", "unreal", User, Radian, Real); + assert_parsed_expression_simplify_to("√(x)^2", "x", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("√(-3)^2", "unreal", User, Radian, Metric, Real); // Principal angle of root of unity - assert_parsed_expression_simplify_to("(-5)^(-1/3)", "1/\u00122Γ—root(5,3)\u0013-√(3)/\u00122Γ—root(5,3)\u0013×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("1+((8+√(6))^(1/2))^-1+(8+√(6))^(1/2)", "\u0012√(√(6)+8)+√(6)+9\u0013/√(√(6)+8)", User, Radian, Real); + assert_parsed_expression_simplify_to("(-5)^(-1/3)", "1/\u00122Γ—root(5,3)\u0013-√(3)/\u00122Γ—root(5,3)\u0013×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("1+((8+√(6))^(1/2))^-1+(8+√(6))^(1/2)", "\u0012√(√(6)+8)+√(6)+9\u0013/√(√(6)+8)", User, Radian, Metric, Real); assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)", "[[-59/4,27/4][81/8,-37/8]]"); assert_parsed_expression_simplify_to("[[1,2][3,4]]^3", "[[37,54][81,118]]"); assert_parsed_expression_simplify_to("(3_m^2)^3", "27Γ—_m^6"); @@ -672,8 +672,8 @@ QUIZ_CASE(poincare_simplification_function) { assert_parsed_expression_simplify_to("sign(2+𝐒)", "sign(2+𝐒)"); /* Test with no symbolic computation to check that n inside a sum expression * is not replaced by Undefined */ - assert_parsed_expression_simplify_to("sum(n,n,1,5)", "sum(n,n,1,5)", User, Radian, Cartesian, ReplaceAllSymbolsWithDefinitionsOrUndefined); - assert_parsed_expression_simplify_to("sum(1/n,n,1,2)", "sum(1/n,n,1,2)", User, Radian, Cartesian, ReplaceAllSymbolsWithDefinitionsOrUndefined); + assert_parsed_expression_simplify_to("sum(n,n,1,5)", "sum(n,n,1,5)", User, Radian, Metric, Cartesian, ReplaceAllSymbolsWithDefinitionsOrUndefined); + assert_parsed_expression_simplify_to("sum(1/n,n,1,2)", "sum(1/n,n,1,2)", User, Radian, Metric, Cartesian, ReplaceAllSymbolsWithDefinitionsOrUndefined); assert_parsed_expression_simplify_to("permute(99,4)", "90345024"); assert_parsed_expression_simplify_to("permute(20,-10)", Undefined::Name()); assert_parsed_expression_simplify_to("re(1/2)", "1/2"); @@ -1154,8 +1154,8 @@ QUIZ_CASE(poincare_simplification_unit_convert) { assert_parsed_expression_simplify_to("4β†’_km/_m", Undefined::Name()); assert_parsed_expression_simplify_to("3Γ—_minβ†’_s+1-1", Undefined::Name()); - assert_reduce("_mβ†’a", Radian, Real); - assert_reduce("_mβ†’b", Radian, Real); + assert_reduce("_mβ†’a", Radian, Metric, Real); + assert_reduce("_mβ†’b", Radian, Metric, Real); assert_parsed_expression_simplify_to("1_kmβ†’aΓ—b", Undefined::Name()); assert_reduce("2β†’a"); @@ -1171,170 +1171,171 @@ QUIZ_CASE(poincare_simplification_unit_convert) { QUIZ_CASE(poincare_simplification_complex_format) { // Real - assert_parsed_expression_simplify_to("𝐒", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("√(-1)", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("√(-1)Γ—βˆš(-1)", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("ln(-2)", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("(-8)^(2/3)", "4", User, Radian, Real); - assert_parsed_expression_simplify_to("(-8)^(2/5)", "2Γ—root(2,5)", User, Radian, Real); - assert_parsed_expression_simplify_to("(-8)^(1/5)", "-root(8,5)", User, Radian, Real); - assert_parsed_expression_simplify_to("(-8)^(1/4)", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("(-8)^(1/3)", "-2", User, Radian, Real); - assert_parsed_expression_simplify_to("[[1,2+√(-1)]]", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("atan(2)", "atan(2)", User, Radian, Real); - assert_parsed_expression_simplify_to("atan(-2)", "-atan(2)", User, Radian, Real); + assert_parsed_expression_simplify_to("𝐒", "unreal", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("√(-1)", "unreal", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("√(-1)Γ—βˆš(-1)", "unreal", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("ln(-2)", "unreal", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("(-8)^(2/3)", "4", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("(-8)^(2/5)", "2Γ—root(2,5)", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("(-8)^(1/5)", "-root(8,5)", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("(-8)^(1/4)", "unreal", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("(-8)^(1/3)", "-2", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("[[1,2+√(-1)]]", "unreal", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("atan(2)", "atan(2)", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("atan(-2)", "-atan(2)", User, Radian, Metric, Real); // User defined variable - assert_parsed_expression_simplify_to("a", "a", User, Radian, Real); + assert_parsed_expression_simplify_to("a", "a", User, Radian, Metric, Real); // a = 2+i - assert_reduce("2+𝐒→a", Radian, Real); - assert_parsed_expression_simplify_to("a", "unreal", User, Radian, Real); + assert_reduce("2+𝐒→a", Radian, Metric, Real); + assert_parsed_expression_simplify_to("a", "unreal", User, Radian, Metric, Real); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); // User defined function // f : x β†’ x+1 - assert_reduce("x+1+𝐒→f(x)", Radian, Real); - assert_parsed_expression_simplify_to("f(3)", "unreal", User, Radian, Real); + assert_reduce("x+1+𝐒→f(x)", Radian, Metric, Real); + assert_parsed_expression_simplify_to("f(3)", "unreal", User, Radian, Metric, Real); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); // Cartesian - assert_parsed_expression_simplify_to("-2.3ᴇ3", "-2300", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("3", "3", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("inf", "inf", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("1+2+𝐒", "3+𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("-(5+2×𝐒)", "-5-2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(5+2×𝐒)", "5+2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("𝐒+𝐒", "2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("-2+2×𝐒", "-2+2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(3+𝐒)-(2+4×𝐒)", "1-3×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(2+3×𝐒)Γ—(4-2×𝐒)", "14+8×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(3+𝐒)/2", "3/2+1/2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(3+𝐒)/(2+𝐒)", "7/5-1/5×𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("-2.3ᴇ3", "-2300", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("3", "3", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("inf", "inf", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("1+2+𝐒", "3+𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("-(5+2×𝐒)", "-5-2×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("(5+2×𝐒)", "5+2×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("𝐒+𝐒", "2×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("-2+2×𝐒", "-2+2×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("(3+𝐒)-(2+4×𝐒)", "1-3×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("(2+3×𝐒)Γ—(4-2×𝐒)", "14+8×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("(3+𝐒)/2", "3/2+1/2×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("(3+𝐒)/(2+𝐒)", "7/5-1/5×𝐒", User, Radian, Metric, Cartesian); // The simplification of (3+𝐒)^(2+𝐒) in a Cartesian complex form generates to many nodes - //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10Γ—cos((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2)Γ—β„―^((2Γ—atan(3)-Ο€)/2)+10Γ—sin((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2)Γ—β„―^((2Γ—atan(3)-Ο€)/2)𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "(𝐒+3)^\u0012𝐒+2\u0013", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("√(1+6𝐒)", "√(2Γ—βˆš(37)+2)/2+√(2Γ—βˆš(37)-2)/2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(1+𝐒)^2", "2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("2×𝐒", "2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("𝐒!", "𝐒!", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("3!", "6", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("x!", "x!", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("β„―", "β„―", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("Ο€", "Ο€", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("𝐒", "𝐒", User, Radian, Cartesian); + //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10Γ—cos((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2)Γ—β„―^((2Γ—atan(3)-Ο€)/2)+10Γ—sin((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2)Γ—β„―^((2Γ—atan(3)-Ο€)/2)𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "(𝐒+3)^\u0012𝐒+2\u0013", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("√(1+6𝐒)", "√(2Γ—βˆš(37)+2)/2+√(2Γ—βˆš(37)-2)/2×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("(1+𝐒)^2", "2×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("2×𝐒", "2×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("𝐒!", "𝐒!", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("3!", "6", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("x!", "x!", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("β„―", "β„―", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("Ο€", "Ο€", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("𝐒", "𝐒", User, Radian, Metric, Cartesian); - assert_parsed_expression_simplify_to("atan(2)", "atan(2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("atan(-2)", "-atan(2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("abs(-3)", "3", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("abs(-3+𝐒)", "√(10)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("atan(2)", "atan(2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("atan(2+𝐒)", "atan(2+𝐒)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("binomial(10, 4)", "210", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("ceil(-1.3)", "-1", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("arg(-2)", "Ο€", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("atan(2)", "atan(2)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("atan(-2)", "-atan(2)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("abs(-3)", "3", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("abs(-3+𝐒)", "√(10)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("atan(2)", "atan(2)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("atan(2+𝐒)", "atan(2+𝐒)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("binomial(10, 4)", "210", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("ceil(-1.3)", "-1", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("arg(-2)", "Ο€", User, Radian, Metric, Cartesian); // TODO: confidence is not simplified yet //assert_parsed_expression_simplify_to("confidence(-2,-3)", "confidence(-2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("conj(-2)", "-2", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("conj(-2+2×𝐒+𝐒)", "-2-3×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("cos(12)", "cos(12)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("cos(12+𝐒)", "cos(12+𝐒)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("diff(3Γ—x, x, 3)", "3", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("quo(34,x)", "quo(34,x)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("rem(5,3)", "2", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("floor(x)", "floor(x)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("frac(x)", "frac(x)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("gcd(x,y)", "gcd(x,y)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("gcd(x,gcd(y,z))", "gcd(x,y,z)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("gcd(3, 1, 2, x, x^2)", "gcd(x^2,x,3,2,1)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("im(1+𝐒)", "1", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("int(x^2, x, 1, 2)", "int(x^2,x,1,2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("lcm(x,y)", "lcm(x,y)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("lcm(x,lcm(y,z))", "lcm(x,y,z)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("lcm(3, 1, 2, x, x^2)", "lcm(x^2,x,3,2,1)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("conj(-2)", "-2", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("conj(-2+2×𝐒+𝐒)", "-2-3×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("cos(12)", "cos(12)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("cos(12+𝐒)", "cos(12+𝐒)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("diff(3Γ—x, x, 3)", "3", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("quo(34,x)", "quo(34,x)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("rem(5,3)", "2", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("floor(x)", "floor(x)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("frac(x)", "frac(x)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("gcd(x,y)", "gcd(x,y)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("gcd(x,gcd(y,z))", "gcd(x,y,z)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("gcd(3, 1, 2, x, x^2)", "gcd(x^2,x,3,2,1)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("im(1+𝐒)", "1", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("int(x^2, x, 1, 2)", "int(x^2,x,1,2)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("lcm(x,y)", "lcm(x,y)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("lcm(x,lcm(y,z))", "lcm(x,y,z)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("lcm(3, 1, 2, x, x^2)", "lcm(x^2,x,3,2,1)", User, Radian, Metric, Cartesian); // TODO: dim is not simplified yet - //assert_parsed_expression_simplify_to("dim(x)", "dim(x)", User, Radian, Cartesian); + //assert_parsed_expression_simplify_to("dim(x)", "dim(x)", User, Radian, Metric, Cartesian); - assert_parsed_expression_simplify_to("root(2,𝐒)", "cos(ln(2))-sin(ln(2))×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("root(2,𝐒+1)", "√(2)Γ—cos(\u001290Γ—ln(2)\u0013/Ο€)-√(2)Γ—sin(\u001290Γ—ln(2)\u0013/Ο€)×𝐒", User, Degree, Cartesian); - assert_parsed_expression_simplify_to("root(2,𝐒+1)", "√(2)Γ—cos(ln(2)/2)-√(2)Γ—sin(ln(2)/2)×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("permute(10, 4)", "5040", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("root(2,𝐒)", "cos(ln(2))-sin(ln(2))×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("root(2,𝐒+1)", "√(2)Γ—cos(\u001290Γ—ln(2)\u0013/Ο€)-√(2)Γ—sin(\u001290Γ—ln(2)\u0013/Ο€)×𝐒", User, Degree, Metric, Cartesian); + assert_parsed_expression_simplify_to("root(2,𝐒+1)", "√(2)Γ—cos(ln(2)/2)-√(2)Γ—sin(ln(2)/2)×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("permute(10, 4)", "5040", User, Radian, Metric, Cartesian); // TODO: prediction is not simplified yet - //assert_parsed_expression_simplify_to("prediction(-2,-3)", "prediction(-2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("randint(2,2)", "2", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("random()", "random()", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("re(x)", "re(x)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("round(x,y)", "round(x,y)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("sign(x)", "sign(x)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("sin(23)", "sin(23)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("sin(23+𝐒)", "sin(23+𝐒)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("√(1-𝐒)", "√(2Γ—βˆš(2)+2)/2-√(2Γ—βˆš(2)-2)/2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("tan(23)", "tan(23)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("tan(23+𝐒)", "tan(23+𝐒)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("[[1,√(-1)]]", "[[1,𝐒]]", User, Radian, Cartesian); + //assert_parsed_expression_simplify_to("prediction(-2,-3)", "prediction(-2)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("randint(2,2)", "2", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("random()", "random()", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("re(x)", "re(x)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("round(x,y)", "round(x,y)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("sign(x)", "sign(x)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("sin(23)", "sin(23)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("sin(23+𝐒)", "sin(23+𝐒)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("√(1-𝐒)", "√(2Γ—βˆš(2)+2)/2-√(2Γ—βˆš(2)-2)/2×𝐒", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("tan(23)", "tan(23)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("tan(23+𝐒)", "tan(23+𝐒)", User, Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("[[1,√(-1)]]", "[[1,𝐒]]", User, Radian, Metric, Cartesian); // User defined variable - assert_parsed_expression_simplify_to("a", "a", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("a", "a", User, Radian, Metric, Cartesian); // a = 2+i - assert_reduce("2+𝐒→a", Radian, Cartesian); - assert_parsed_expression_simplify_to("a", "2+𝐒", User, Radian, Cartesian); + assert_reduce("2+𝐒→a", Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("a", "2+𝐒", User, Radian, Metric, Cartesian); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); // User defined function // f : x β†’ x+1 - assert_reduce("x+1+𝐒→f(x)", Radian, Cartesian); - assert_parsed_expression_simplify_to("f(3)", "4+𝐒", User, Radian, Cartesian); + assert_reduce("x+1+𝐒→f(x)", Radian, Metric, Cartesian); + assert_parsed_expression_simplify_to("f(3)", "4+𝐒", User, Radian, Metric, Cartesian); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); // Polar - assert_parsed_expression_simplify_to("-2.3ᴇ3", "2300Γ—β„―^\u0012π×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("3", "3", User, Radian, Polar); - assert_parsed_expression_simplify_to("inf", "inf", User, Radian, Polar); - assert_parsed_expression_simplify_to("1+2+𝐒", "√(10)Γ—β„―^\u0012\u0012-2Γ—atan(3)+Ο€\u0013/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("1+2+𝐒", "√(10)Γ—β„―^\u0012\u0012-π×atan(3)+90Γ—Ο€\u0013/180×𝐒\u0013", User, Degree, Polar); - assert_parsed_expression_simplify_to("-(5+2×𝐒)", "√(29)Γ—β„―^\u0012\u0012-2Γ—atan(5/2)-Ο€\u0013/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("(5+2×𝐒)", "√(29)Γ—β„―^\u0012\u0012-2Γ—atan(5/2)+Ο€\u0013/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("𝐒+𝐒", "2Γ—β„―^\u0012Ο€/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("𝐒+𝐒", "2Γ—β„―^\u0012Ο€/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("-2+2×𝐒", "2Γ—βˆš(2)Γ—β„―^\u0012\u00123Γ—Ο€\u0013/4×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("(3+𝐒)-(2+4×𝐒)", "√(10)Γ—β„―^\u0012\u00122Γ—atan(1/3)-Ο€\u0013/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("(2+3×𝐒)Γ—(4-2×𝐒)", "2Γ—βˆš(65)Γ—β„―^\u0012\u0012-2Γ—atan(7/4)+Ο€\u0013/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("(3+𝐒)/2", "√(10)/2Γ—β„―^\u0012\u0012-2Γ—atan(3)+Ο€\u0013/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("(3+𝐒)/(2+𝐒)", "√(2)Γ—β„―^\u0012\u00122Γ—atan(7)-Ο€\u0013/2×𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("-2.3ᴇ3", "2300Γ—β„―^\u0012π×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("3", "3", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("inf", "inf", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("1+2+𝐒", "√(10)Γ—β„―^\u0012\u0012-2Γ—atan(3)+Ο€\u0013/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("1+2+𝐒", "√(10)Γ—β„―^\u0012\u0012-π×atan(3)+90Γ—Ο€\u0013/180×𝐒\u0013", User, Degree, Metric, Polar); + assert_parsed_expression_simplify_to("-(5+2×𝐒)", "√(29)Γ—β„―^\u0012\u0012-2Γ—atan(5/2)-Ο€\u0013/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("(5+2×𝐒)", "√(29)Γ—β„―^\u0012\u0012-2Γ—atan(5/2)+Ο€\u0013/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("𝐒+𝐒", "2Γ—β„―^\u0012Ο€/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("𝐒+𝐒", "2Γ—β„―^\u0012Ο€/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("-2+2×𝐒", "2Γ—βˆš(2)Γ—β„―^\u0012\u00123Γ—Ο€\u0013/4×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("(3+𝐒)-(2+4×𝐒)", "√(10)Γ—β„―^\u0012\u00122Γ—atan(1/3)-Ο€\u0013/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("(2+3×𝐒)Γ—(4-2×𝐒)", "2Γ—βˆš(65)Γ—β„―^\u0012\u0012-2Γ—atan(7/4)+Ο€\u0013/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("(3+𝐒)/2", "√(10)/2Γ—β„―^\u0012\u0012-2Γ—atan(3)+Ο€\u0013/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("(3+𝐒)/(2+𝐒)", "√(2)Γ—β„―^\u0012\u00122Γ—atan(7)-Ο€\u0013/2×𝐒\u0013", User, Radian, Metric, Polar); // TODO: simplify atan(tan(x)) = xΒ±kΓ—pi? - //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10β„―^\u0012\u00122Γ—atan(3)-Ο€\u0013/2\u0013Γ—β„―^\u0012\u0012\u0012-4Γ—atan(3)+ln(2)+ln(5)+2Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10β„―^\u0012\u00122Γ—atan(3)-Ο€\u0013/2\u0013Γ—β„―^\u0012\u0012\u0012-4Γ—atan(3)+ln(2)+ln(5)+2Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Metric, Polar); // The simplification of (3+𝐒)^(2+𝐒) in a Polar complex form generates to many nodes - //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10β„―^\u0012\u00122Γ—atan(3)-Ο€\u0013/2\u0013Γ—β„―^\u0012\u0012atan(tan((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2))+Ο€\u0013𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "(𝐒+3)^\u0012𝐒+2\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("(1+𝐒)^2", "2Γ—β„―^\u0012Ο€/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("2×𝐒", "2Γ—β„―^\u0012Ο€/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("3!", "6", User, Radian, Polar); - assert_parsed_expression_simplify_to("x!", "x!", User, Radian, Polar); - assert_parsed_expression_simplify_to("β„―", "β„―", User, Radian, Polar); - assert_parsed_expression_simplify_to("Ο€", "Ο€", User, Radian, Polar); - assert_parsed_expression_simplify_to("𝐒", "β„―^\u0012Ο€/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("abs(-3)", "3", User, Radian, Polar); - assert_parsed_expression_simplify_to("abs(-3+𝐒)", "√(10)", User, Radian, Polar); - assert_parsed_expression_simplify_to("conj(2Γ—β„―^(𝐒×π/2))", "2Γ—β„―^\u0012-Ο€/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("-2Γ—β„―^(𝐒×π/2)", "2Γ—β„―^\u0012-Ο€/2×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("[[1,√(-1)]]", "[[1,β„―^\u0012Ο€/2×𝐒\u0013]]", User, Radian, Polar); - assert_parsed_expression_simplify_to("atan(2)", "atan(2)", User, Radian, Polar); - assert_parsed_expression_simplify_to("atan(-2)", "atan(2)Γ—β„―^\u0012π×𝐒\u0013", User, Radian, Polar); - assert_parsed_expression_simplify_to("cos(42Ο€)", "-cos(42Γ—Ο€)Γ—β„―^\x12π×𝐒\x13", User, Degree, Polar); + //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10β„―^\u0012\u00122Γ—atan(3)-Ο€\u0013/2\u0013Γ—β„―^\u0012\u0012atan(tan((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2))+Ο€\u0013𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "(𝐒+3)^\u0012𝐒+2\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("(1+𝐒)^2", "2Γ—β„―^\u0012Ο€/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("2×𝐒", "2Γ—β„―^\u0012Ο€/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("3!", "6", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("x!", "x!", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("β„―", "β„―", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("Ο€", "Ο€", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("𝐒", "β„―^\u0012Ο€/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("abs(-3)", "3", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("abs(-3+𝐒)", "√(10)", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("conj(2Γ—β„―^(𝐒×π/2))", "2Γ—β„―^\u0012-Ο€/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("-2Γ—β„―^(𝐒×π/2)", "2Γ—β„―^\u0012-Ο€/2×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("[[1,√(-1)]]", "[[1,β„―^\u0012Ο€/2×𝐒\u0013]]", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("atan(2)", "atan(2)", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("atan(-2)", "atan(2)Γ—β„―^\u0012π×𝐒\u0013", User, Radian, Metric, Polar); + assert_parsed_expression_simplify_to("cos(42Ο€)", "-cos(42Γ—Ο€)Γ—β„―^\x12π×𝐒\x13", User, Degree, Metric, Polar); // User defined variable - assert_parsed_expression_simplify_to("a", "a", User, Radian, Polar); + assert_parsed_expression_simplify_to("a", "a", User, Radian, Metric, Polar); // a = 2 + 𝐒 - assert_reduce("2+𝐒→a", Radian, Polar); - assert_parsed_expression_simplify_to("a", "√(5)Γ—β„―^\u0012\u0012-2Γ—atan(2)+Ο€\u0013/2×𝐒\u0013", User, Radian, Polar); + assert_reduce("2+𝐒→a", Radian, Metric, Polar); + assert_parsed_expression_simplify_to("a", "√(5)Γ—β„―^\u0012\u0012-2Γ—atan(2)+Ο€\u0013/2×𝐒\u0013", User, Radian, Metric, Polar); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); // User defined function // f: x β†’ x+1 - assert_reduce("x+1+𝐒→f(x)", Radian, Polar); - assert_parsed_expression_simplify_to("f(3)", "√(17)Γ—β„―^\u0012\u0012-2Γ—atan(4)+Ο€\u0013/2×𝐒\u0013", User, Radian, Polar); + + assert_reduce("x+1+𝐒→f(x)", Radian, Metric, Polar); + assert_parsed_expression_simplify_to("f(3)", "√(17)Γ—β„―^\u0012\u0012-2Γ—atan(4)+Ο€\u0013/2×𝐒\u0013", User, Radian, Metric, Polar); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); } @@ -1391,19 +1392,19 @@ QUIZ_CASE(poincare_simplification_reduction_target) { } QUIZ_CASE(poincare_simplification_unit_conversion) { - assert_parsed_expression_simplify_to("1000000_cm", "10Γ—_km", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, DefaultUnitConversion); - assert_parsed_expression_simplify_to("1000000_cm", "1000000Γ—_cm", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, NoUnitConversion); - assert_parsed_expression_simplify_to("1000000_cm", "10000Γ—_m", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, InternationalSystemUnitConversion); + assert_parsed_expression_simplify_to("1000000_cm", "10Γ—_km", User, Degree, Metric, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, DefaultUnitConversion); + assert_parsed_expression_simplify_to("1000000_cm", "1000000Γ—_cm", User, Degree, Metric, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, NoUnitConversion); + assert_parsed_expression_simplify_to("1000000_cm", "10000Γ—_m", User, Degree, Metric, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, InternationalSystemUnitConversion); } QUIZ_CASE(poincare_simplification_user_function) { // User defined function // f: x β†’ x*1 - assert_reduce("x*3β†’f(x)", Radian, Polar); - assert_parsed_expression_simplify_to("f(1+1)", "6", User, Radian, Polar); + assert_reduce("x*3β†’f(x)", Radian, Metric, Polar); + assert_parsed_expression_simplify_to("f(1+1)", "6", User, Radian, Metric, Polar); // f: x β†’ 3 - assert_reduce("3β†’f(x)", Radian, Polar); - assert_parsed_expression_simplify_to("f(1/0)", Undefined::Name(), User, Radian, Polar); + assert_reduce("3β†’f(x)", Radian, Metric, Polar); + assert_parsed_expression_simplify_to("f(1/0)", Undefined::Name(), User, Radian, Metric, Polar); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); } @@ -1483,7 +1484,7 @@ QUIZ_CASE(poincare_simplification_mix) { assert_parsed_expression_simplify_to("(((√(6)-√(2))/4)/((√(6)+√(2))/4))+1", "-√(3)+3"); assert_parsed_expression_simplify_to("1/√(𝐒) Γ— (√(2)-π’Γ—βˆš(2))", "-2×𝐒"); // TODO: get rid of complex at denominator? - assert_expression_simplifies_approximates_to("abs(√(300000.0003^23))", "9.702740901018ᴇ62", Degree, Cartesian, 13); + assert_expression_simplifies_approximates_to("abs(√(300000.0003^23))", "9.702740901018ᴇ62", Degree, Metric, Cartesian, 13); } QUIZ_CASE(poincare_hyperbolic_trigonometry) { @@ -1499,49 +1500,49 @@ QUIZ_CASE(poincare_hyperbolic_trigonometry) { assert_parsed_expression_simplify_to("acosh(cosh(3))", "3"); assert_parsed_expression_simplify_to("acosh(cosh(0.5))", "1/2"); assert_parsed_expression_simplify_to("acosh(cosh(-3))", "3"); - assert_parsed_expression_simplify_to("acosh(cosh(3))", "3", User, Radian, Real); - assert_parsed_expression_simplify_to("acosh(cosh(0.5))", "1/2", User, Radian, Real); - assert_parsed_expression_simplify_to("acosh(cosh(-3))", "3", User, Radian, Real); + assert_parsed_expression_simplify_to("acosh(cosh(3))", "3", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("acosh(cosh(0.5))", "1/2", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("acosh(cosh(-3))", "3", User, Radian, Metric, Real); // cosh(acosh) assert_parsed_expression_simplify_to("cosh(acosh(3))", "3"); assert_parsed_expression_simplify_to("cosh(acosh(0.5))", "1/2"); assert_parsed_expression_simplify_to("cosh(acosh(-3))", "-3"); - assert_parsed_expression_simplify_to("cosh(acosh(3))", "3", User, Radian, Real); - assert_parsed_expression_simplify_to("cosh(acosh(0.5))", "cosh(acosh(1/2))", User, Radian, Real); - assert_parsed_expression_simplify_to("cosh(acosh(-3))", "cosh(acosh(-3))", User, Radian, Real); + assert_parsed_expression_simplify_to("cosh(acosh(3))", "3", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("cosh(acosh(0.5))", "cosh(acosh(1/2))", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("cosh(acosh(-3))", "cosh(acosh(-3))", User, Radian, Metric, Real); // sinh(asinh) assert_parsed_expression_simplify_to("sinh(asinh(3))", "3"); assert_parsed_expression_simplify_to("sinh(asinh(0.5))", "1/2"); assert_parsed_expression_simplify_to("sinh(asinh(-3))", "-3"); - assert_parsed_expression_simplify_to("sinh(asinh(3))", "3", User, Radian, Real); - assert_parsed_expression_simplify_to("sinh(asinh(0.5))", "1/2", User, Radian, Real); - assert_parsed_expression_simplify_to("sinh(asinh(-3))", "-3", User, Radian, Real); + assert_parsed_expression_simplify_to("sinh(asinh(3))", "3", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("sinh(asinh(0.5))", "1/2", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("sinh(asinh(-3))", "-3", User, Radian, Metric, Real); // asinh(sinh) assert_parsed_expression_simplify_to("asinh(sinh(3))", "3"); assert_parsed_expression_simplify_to("asinh(sinh(0.5))", "1/2"); assert_parsed_expression_simplify_to("asinh(sinh(-3))", "-3"); - assert_parsed_expression_simplify_to("asinh(sinh(3))", "3", User, Radian, Real); - assert_parsed_expression_simplify_to("asinh(sinh(0.5))", "1/2", User, Radian, Real); - assert_parsed_expression_simplify_to("asinh(sinh(-3))", "-3", User, Radian, Real); + assert_parsed_expression_simplify_to("asinh(sinh(3))", "3", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("asinh(sinh(0.5))", "1/2", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("asinh(sinh(-3))", "-3", User, Radian, Metric, Real); // tanh(atanh) assert_parsed_expression_simplify_to("tanh(atanh(3))", "3"); assert_parsed_expression_simplify_to("tanh(atanh(0.5))", "1/2"); assert_parsed_expression_simplify_to("tanh(atanh(-3))", "-3"); - assert_parsed_expression_simplify_to("tanh(atanh(3))", "tanh(atanh(3))", User, Radian, Real); - assert_parsed_expression_simplify_to("tanh(atanh(0.5))", "1/2", User, Radian, Real); - assert_parsed_expression_simplify_to("tanh(atanh(-3))", "-tanh(atanh(3))", User, Radian, Real); + assert_parsed_expression_simplify_to("tanh(atanh(3))", "tanh(atanh(3))", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("tanh(atanh(0.5))", "1/2", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("tanh(atanh(-3))", "-tanh(atanh(3))", User, Radian, Metric, Real); // atanh(tanh) assert_parsed_expression_simplify_to("atanh(tanh(3))", "3"); assert_parsed_expression_simplify_to("atanh(tanh(0.5))", "1/2"); assert_parsed_expression_simplify_to("atanh(tanh(-3))", "-3"); - assert_parsed_expression_simplify_to("atanh(tanh(3))", "3", User, Radian, Real); - assert_parsed_expression_simplify_to("atanh(tanh(0.5))", "1/2", User, Radian, Real); - assert_parsed_expression_simplify_to("atanh(tanh(-3))", "-3", User, Radian, Real); + assert_parsed_expression_simplify_to("atanh(tanh(3))", "3", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("atanh(tanh(0.5))", "1/2", User, Radian, Metric, Real); + assert_parsed_expression_simplify_to("atanh(tanh(-3))", "-3", User, Radian, Metric, Real); } QUIZ_CASE(poincare_probability) {