diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index 2fa5afee9..e6eab7058 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -61,9 +61,9 @@ void Calculation::setContent(const char * c, Context * context, Expression * ans /* We do not store directly the text enter by the user because we do not want * to keep Ans symbol in the calculation store. */ PoincareHelpers::WriteTextInBuffer(m_input, m_inputText, sizeof(m_inputText)); - m_exactOutput = Expression::ParseAndSimplify(m_inputText, *context); + m_exactOutput = PoincareHelpers::ParseAndSimplify(m_inputText, *context); PoincareHelpers::WriteTextInBuffer(m_exactOutput, m_exactOutputText, sizeof(m_exactOutputText)); - m_approximateOutput = m_exactOutput->approximate(*context); + m_approximateOutput = PoincareHelpers::Approximate(m_exactOutput, *context); PoincareHelpers::WriteTextInBuffer(m_approximateOutput, m_approximateOutputText, sizeof(m_approximateOutputText)); } @@ -172,7 +172,7 @@ Expression * Calculation::approximateOutput(Context * context) { * call 'evaluate'. */ Expression * exp = Expression::parse(m_approximateOutputText); if (exp != nullptr) { - m_approximateOutput = exp->approximate(*context); + m_approximateOutput = PoincareHelpers::Approximate(exp, *context); delete exp; } else { m_approximateOutput = new Undefined(); @@ -202,7 +202,7 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual( if (m_equalSign != EqualSign::Unknown) { return m_equalSign; } - m_equalSign = exactOutput(context)->isEqualToItsApproximationLayout(approximateOutput(context), k_printedExpressionSize, Preferences::sharedPreferences()->displayMode(), Preferences::sharedPreferences()->numberOfSignificantDigits(), *context) ? EqualSign::Equal : EqualSign::Approximation; + m_equalSign = exactOutput(context)->isEqualToItsApproximationLayout(approximateOutput(context), k_printedExpressionSize, Preferences::sharedPreferences()->angleUnit(), Preferences::sharedPreferences()->displayMode(), Preferences::sharedPreferences()->numberOfSignificantDigits(), *context) ? EqualSign::Equal : EqualSign::Approximation; return m_equalSign; } diff --git a/apps/graph/cartesian_function.cpp b/apps/graph/cartesian_function.cpp index 10cdb0a24..cccc14b30 100644 --- a/apps/graph/cartesian_function.cpp +++ b/apps/graph/cartesian_function.cpp @@ -1,8 +1,10 @@ #include "cartesian_function.h" +#include "../shared/poincare_helpers.h" #include #include using namespace Poincare; +using namespace Shared; namespace Graph { @@ -27,7 +29,7 @@ double CartesianFunction::approximateDerivative(double x, Poincare::Context * co /* TODO: when we will simplify derivative, we might want to simplify the * derivative here. However, we might want to do it once for all x (to avoid * lagging in the derivative table. */ - return derivative.approximateToScalar(*context); + return PoincareHelpers::ApproximateToScalar(&derivative, *context); } double CartesianFunction::sumBetweenBounds(double start, double end, Poincare::Context * context) const { @@ -38,23 +40,23 @@ double CartesianFunction::sumBetweenBounds(double start, double end, Poincare::C /* TODO: when we will simplify integral, we might want to simplify the * integral here. However, we might want to do it once for all x (to avoid * lagging in the derivative table. */ - return integral.approximateToScalar(*context); + return PoincareHelpers::ApproximateToScalar(&integral, *context); } Expression::Coordinate2D CartesianFunction::nextMinimumFrom(double start, double step, double max, Context * context) const { - return expression(context)->nextMinimum(symbol(), start, step, max, *context); + return expression(context)->nextMinimum(symbol(), start, step, max, *context, Preferences::sharedPreferences()->angleUnit()); } Expression::Coordinate2D CartesianFunction::nextMaximumFrom(double start, double step, double max, Context * context) const { - return expression(context)->nextMaximum(symbol(), start, step, max, *context); + return expression(context)->nextMaximum(symbol(), start, step, max, *context, Preferences::sharedPreferences()->angleUnit()); } double CartesianFunction::nextRootFrom(double start, double step, double max, Context * context) const { - return expression(context)->nextRoot(symbol(), start, step, max, *context); + return expression(context)->nextRoot(symbol(), start, step, max, *context, Preferences::sharedPreferences()->angleUnit()); } Expression::Coordinate2D CartesianFunction::nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, const Shared::Function * function) const { - return expression(context)->nextIntersection(symbol(), start, step, max, *context, function->expression(context)); + return expression(context)->nextIntersection(symbol(), start, step, max, *context, Preferences::sharedPreferences()->angleUnit(), function->expression(context)); } char CartesianFunction::symbol() const { diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index 086a7ad6f..38ca4baad 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -44,7 +44,7 @@ float GraphController::interestingXRange() { TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); for (int i = 0; i < functionStore()->numberOfActiveFunctions(); i++) { Function * f = functionStore()->activeFunctionAtIndex(i); - float fRange = f->expression(myApp->localContext())->characteristicXRange(*(myApp->localContext())); + float fRange = f->expression(myApp->localContext())->characteristicXRange(*(myApp->localContext()), Preferences::sharedPreferences()->angleUnit()); if (!std::isnan(fRange)) { characteristicRange = fRange > characteristicRange ? fRange : characteristicRange; } diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index e889ea174..51dbac287 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -1,6 +1,7 @@ #include "calculation_controller.h" #include "../constant.h" #include "../apps_container.h" +#include "../shared/poincare_helpers.h" #include "app.h" #include "calculation/discrete_calculation.h" #include "calculation/left_integral_calculation.h" @@ -208,7 +209,7 @@ bool CalculationController::textFieldShouldFinishEditing(TextField * textField, bool CalculationController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { App * probaApp = (App *)app(); Context * globalContext = probaApp->container()->globalContext(); - double floatBody = Expression::approximateToScalar(text, *globalContext); + double floatBody = PoincareHelpers::ApproximateToScalar(text, *globalContext); if (std::isnan(floatBody) || std::isinf(floatBody)) { app()->displayWarning(I18n::Message::UndefinedValue); return false; diff --git a/apps/regression/model/cubic_model.cpp b/apps/regression/model/cubic_model.cpp index c39a3b170..c0a32306c 100644 --- a/apps/regression/model/cubic_model.cpp +++ b/apps/regression/model/cubic_model.cpp @@ -1,9 +1,11 @@ #include "cubic_model.h" +#include "../../shared/poincare_helpers.h" #include #include #include "../../poincare/include/poincare_layouts.h" using namespace Poincare; +using namespace Shared; namespace Regression { @@ -64,7 +66,7 @@ Expression * CubicModel::simplifiedExpression(double * modelCoefficients, Poinca Expression * dExpression = new Decimal(d); Expression * const operands[] = {ax3Expression, bx2Expression, cxExpression, dExpression}; Expression * result = new Addition(operands, 4, false); - Expression::Simplify(&result, *context); + PoincareHelpers::Simplify(&result, *context); return result; } diff --git a/apps/regression/model/model.cpp b/apps/regression/model/model.cpp index 8b9f55e17..750b1b7f3 100644 --- a/apps/regression/model/model.cpp +++ b/apps/regression/model/model.cpp @@ -1,5 +1,6 @@ #include "model.h" #include "../store.h" +#include "../../shared/poincare_helpers.h" #include #include #include @@ -12,9 +13,9 @@ namespace Regression { double Model::levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) { Expression * yExpression = static_cast(new Decimal(y)); - Expression::Simplify(&yExpression, *context); + PoincareHelpers::Simplify(&yExpression, *context); Expression * modelExpression = simplifiedExpression(modelCoefficients, context); - double result = modelExpression->nextIntersection('x', xMin, step, xMax, *context, yExpression).abscissa; + double result = modelExpression->nextIntersection('x', xMin, step, xMax, *context, Preferences::sharedPreferences()->angleUnit(), yExpression).abscissa; delete modelExpression; delete yExpression; return result; diff --git a/apps/regression/model/quadratic_model.cpp b/apps/regression/model/quadratic_model.cpp index a3b2f9b77..17c558dd1 100644 --- a/apps/regression/model/quadratic_model.cpp +++ b/apps/regression/model/quadratic_model.cpp @@ -1,9 +1,11 @@ #include "quadratic_model.h" +#include "../../shared/poincare_helpers.h" #include #include #include "../../poincare/include/poincare_layouts.h" using namespace Poincare; +using namespace Shared; namespace Regression { @@ -48,7 +50,7 @@ Expression * QuadraticModel::simplifiedExpression(double * modelCoefficients, Po Expression * cExpression = new Decimal(c); Expression * const operands[] = {ax2Expression, bxExpression, cExpression}; Expression * result = new Addition(operands, 3, false); - Expression::Simplify(&result, *context); + PoincareHelpers::Simplify(&result, *context); return result; } diff --git a/apps/regression/model/quartic_model.cpp b/apps/regression/model/quartic_model.cpp index 0ab65ca78..34741c9a2 100644 --- a/apps/regression/model/quartic_model.cpp +++ b/apps/regression/model/quartic_model.cpp @@ -1,9 +1,11 @@ #include "quartic_model.h" +#include "../../shared/poincare_helpers.h" #include #include #include "../../poincare/include/poincare_layouts.h" using namespace Poincare; +using namespace Shared; namespace Regression { @@ -80,7 +82,7 @@ Expression * QuarticModel::simplifiedExpression(double * modelCoefficients, Poin Expression * eExpression = new Decimal(e); Expression * const operands[] = {ax4Expression, bx3Expression, cx2Expression, dxExpression, eExpression}; Expression * result = new Addition(operands, 5, false); - Expression::Simplify(&result, *context); + PoincareHelpers::Simplify(&result, *context); return result; } diff --git a/apps/regression/model/trigonometric_model.cpp b/apps/regression/model/trigonometric_model.cpp index 8bcaf543e..e0c726c86 100644 --- a/apps/regression/model/trigonometric_model.cpp +++ b/apps/regression/model/trigonometric_model.cpp @@ -1,10 +1,12 @@ #include "trigonometric_model.h" +#include "../../shared/poincare_helpers.h" #include "../../poincare/include/poincare_layouts.h" #include #include #include using namespace Poincare; +using namespace Shared; namespace Regression { @@ -50,7 +52,7 @@ Expression * TrigonometricModel::simplifiedExpression(double * modelCoefficients Expression * asinExpression = new Multiplication(aExpression, sinExpression, false); Expression * dExpression = new Decimal(d); Expression * result = new Addition(asinExpression, dExpression, false); - Expression::Simplify(&result, *context); + PoincareHelpers::Simplify(&result, *context); return result; } diff --git a/apps/regression/store.cpp b/apps/regression/store.cpp index 6565e8bd9..1751ead7a 100644 --- a/apps/regression/store.cpp +++ b/apps/regression/store.cpp @@ -29,7 +29,7 @@ Store::Store() : InteractiveCurveViewRange(nullptr), DoublePairStore(), m_seriesChecksum{0, 0, 0}, - m_angleUnit(Poincare::Expression::AngleUnit::Default) + m_angleUnit(Poincare::Expression::AngleUnit::Degree) { for (int i = 0; i < k_numberOfSeries; i++) { m_regressionTypes[i] = Model::Type::Linear; diff --git a/apps/sequence/list/list_parameter_controller.cpp b/apps/sequence/list/list_parameter_controller.cpp index d119bcaad..6beed66cf 100644 --- a/apps/sequence/list/list_parameter_controller.cpp +++ b/apps/sequence/list/list_parameter_controller.cpp @@ -2,6 +2,7 @@ #include "list_controller.h" #include "../app.h" #include "../../apps_container.h" +#include "../../shared/poincare_helpers.h" using namespace Poincare; using namespace Shared; @@ -126,7 +127,7 @@ bool ListParameterController::textFieldDidFinishEditing(TextField * textField, c * SecondIndex = FirstIndex + 1 */ AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container(); Context * globalContext = appsContainer->globalContext(); - float floatBody = Expression::approximateToScalar(text, *globalContext); + float floatBody = PoincareHelpers::ApproximateToScalar(text, *globalContext); int index = std::round(floatBody); if (std::isnan(floatBody) || std::isinf(floatBody)) { app()->displayWarning(I18n::Message::UndefinedValue); diff --git a/apps/sequence/sequence.cpp b/apps/sequence/sequence.cpp index 8f5b68410..06870034a 100644 --- a/apps/sequence/sequence.cpp +++ b/apps/sequence/sequence.cpp @@ -152,14 +152,14 @@ void Sequence::setInitialRank(int rank) { Poincare::Expression * Sequence::firstInitialConditionExpression(Context * context) const { if (m_firstInitialConditionExpression == nullptr) { - m_firstInitialConditionExpression = Poincare::Expression::ParseAndSimplify(m_firstInitialConditionText, *context); + m_firstInitialConditionExpression = PoincareHelpers::ParseAndSimplify(m_firstInitialConditionText, *context); } return m_firstInitialConditionExpression; } Poincare::Expression * Sequence::secondInitialConditionExpression(Context * context) const { if (m_secondInitialConditionExpression == nullptr) { - m_secondInitialConditionExpression = Poincare::Expression::ParseAndSimplify(m_secondInitialConditionText, *context); + m_secondInitialConditionExpression = PoincareHelpers::ParseAndSimplify(m_secondInitialConditionText, *context); } return m_secondInitialConditionExpression; } @@ -336,32 +336,32 @@ T Sequence::approximateToNextRank(int n, SequenceContext * sqctx) const { { ctx.setValueForSymbol(un, &unSymbol); ctx.setValueForSymbol(vn, &vnSymbol); - return expression(sqctx)->approximateWithValueForSymbol(symbol(), (T)n, ctx); + return expression(sqctx)->approximateWithValueForSymbol(symbol(), (T)n, ctx, Poincare::Preferences::sharedPreferences()->angleUnit()); } case Type::SingleRecurrence: { if (n == m_initialRank) { - return firstInitialConditionExpression(sqctx)->template approximateToScalar(*sqctx); + return PoincareHelpers::ApproximateToScalar(firstInitialConditionExpression(sqctx), *sqctx); } ctx.setValueForSymbol(un, &un1Symbol); ctx.setValueForSymbol(unm1, &unSymbol); ctx.setValueForSymbol(vn, &vn1Symbol); ctx.setValueForSymbol(vnm1, &vnSymbol); - return expression(sqctx)->approximateWithValueForSymbol(symbol(), (T)(n-1), ctx); + return expression(sqctx)->approximateWithValueForSymbol(symbol(), (T)(n-1), ctx, Poincare::Preferences::sharedPreferences()->angleUnit()); } default: { if (n == m_initialRank) { - return firstInitialConditionExpression(sqctx)->template approximateToScalar(*sqctx); + return PoincareHelpers::ApproximateToScalar(firstInitialConditionExpression(sqctx), *sqctx); } if (n == m_initialRank+1) { - return secondInitialConditionExpression(sqctx)->template approximateToScalar(*sqctx); + return PoincareHelpers::ApproximateToScalar(secondInitialConditionExpression(sqctx), *sqctx); } ctx.setValueForSymbol(unm1, &un1Symbol); ctx.setValueForSymbol(unm2, &unSymbol); ctx.setValueForSymbol(vnm1, &vn1Symbol); ctx.setValueForSymbol(vnm2, &vnSymbol); - return expression(sqctx)->approximateWithValueForSymbol(symbol(), (T)(n-2), ctx); + return expression(sqctx)->approximateWithValueForSymbol(symbol(), (T)(n-2), ctx, Poincare::Preferences::sharedPreferences()->angleUnit()); } } } diff --git a/apps/settings/sub_controller.cpp b/apps/settings/sub_controller.cpp index fad10800c..30f7aa1de 100644 --- a/apps/settings/sub_controller.cpp +++ b/apps/settings/sub_controller.cpp @@ -2,10 +2,12 @@ #include "helpers.h" #include "../global_preferences.h" #include "../apps_container.h" +#include "../shared/poincare_helpers.h" #include #include using namespace Poincare; +using namespace Shared; namespace Settings { @@ -217,7 +219,7 @@ bool SubController::textFieldShouldFinishEditing(TextField * textField, Ion::Eve bool SubController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { Context * globalContext = textFieldDelegateApp()->localContext(); - float floatBody = Expression::approximateToScalar(text, *globalContext); + float floatBody = PoincareHelpers::ApproximateToScalar(text, *globalContext); if (std::isnan(floatBody) || std::isinf(floatBody)) { floatBody = PrintFloat::k_numberOfPrintedSignificantDigits; } diff --git a/apps/shared/editable_cell_table_view_controller.cpp b/apps/shared/editable_cell_table_view_controller.cpp index d845a6f58..bd9323d19 100644 --- a/apps/shared/editable_cell_table_view_controller.cpp +++ b/apps/shared/editable_cell_table_view_controller.cpp @@ -1,5 +1,6 @@ #include "editable_cell_table_view_controller.h" #include "../apps_container.h" +#include "../shared/poincare_helpers.h" #include "../constant.h" #include "text_field_delegate_app.h" #include @@ -25,7 +26,7 @@ bool EditableCellTableViewController::textFieldShouldFinishEditing(TextField * t bool EditableCellTableViewController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container(); Context * globalContext = appsContainer->globalContext(); - double floatBody = Expression::approximateToScalar(text, *globalContext); + double floatBody = PoincareHelpers::ApproximateToScalar(text, *globalContext); if (std::isnan(floatBody) || std::isinf(floatBody)) { app()->displayWarning(I18n::Message::UndefinedValue); return false; diff --git a/apps/shared/expression_model.cpp b/apps/shared/expression_model.cpp index e5d8f3aef..9120ef50c 100644 --- a/apps/shared/expression_model.cpp +++ b/apps/shared/expression_model.cpp @@ -40,7 +40,7 @@ const char * ExpressionModel::text() const { Poincare::Expression * ExpressionModel::expression(Poincare::Context * context) const { if (m_expression == nullptr) { - m_expression = Expression::ParseAndSimplify(m_text, *context); + m_expression = PoincareHelpers::ParseAndSimplify(m_text, *context); } return m_expression; } diff --git a/apps/shared/float_parameter_controller.cpp b/apps/shared/float_parameter_controller.cpp index 3df9969ad..04e26a0f5 100644 --- a/apps/shared/float_parameter_controller.cpp +++ b/apps/shared/float_parameter_controller.cpp @@ -1,6 +1,7 @@ #include "float_parameter_controller.h" #include "../constant.h" #include "../apps_container.h" +#include "../shared/poincare_helpers.h" #include "text_field_delegate_app.h" #include #include @@ -119,7 +120,7 @@ bool FloatParameterController::textFieldShouldFinishEditing(TextField * textFiel bool FloatParameterController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container(); Context * globalContext = appsContainer->globalContext(); - double floatBody = Expression::approximateToScalar(text, *globalContext); + double floatBody = PoincareHelpers::ApproximateToScalar(text, *globalContext); if (std::isnan(floatBody) || std::isinf(floatBody)) { app()->displayWarning(I18n::Message::UndefinedValue); return false; diff --git a/apps/shared/function.cpp b/apps/shared/function.cpp index 584f83e03..aaf14c388 100644 --- a/apps/shared/function.cpp +++ b/apps/shared/function.cpp @@ -41,7 +41,7 @@ void Function::setActive(bool active) { template T Function::templatedApproximateAtAbscissa(T x, Poincare::Context * context) const { - return expression(context)->approximateWithValueForSymbol(symbol(), x, *context); + return expression(context)->approximateWithValueForSymbol(symbol(), x, *context, Preferences::sharedPreferences()->angleUnit()); } } diff --git a/apps/shared/poincare_helpers.h b/apps/shared/poincare_helpers.h index 45b8c67bf..655f30853 100644 --- a/apps/shared/poincare_helpers.h +++ b/apps/shared/poincare_helpers.h @@ -20,6 +20,29 @@ inline int WriteTextInBuffer(const Poincare::Expression * e, char * buffer, int return e->writeTextInBuffer(buffer, bufferSize, Poincare::Preferences::sharedPreferences()->displayMode(), numberOfSignificantDigits); } +template +inline Poincare::Expression * Approximate(const Poincare::Expression * e, Poincare::Context & context) { + return e->approximate(context, Poincare::Preferences::sharedPreferences()->angleUnit(), Poincare::Preferences::sharedPreferences()->complexFormat()); +} + +template +inline T ApproximateToScalar(const Poincare::Expression * e, Poincare::Context & context) { + return e->approximateToScalar(context, Poincare::Preferences::sharedPreferences()->angleUnit()); +} + +template +inline T ApproximateToScalar(const char * text, Poincare::Context & context) { + return Poincare::Expression::approximateToScalar(text, context, Poincare::Preferences::sharedPreferences()->angleUnit()); +} + +inline Poincare::Expression * ParseAndSimplify(const char * text, Poincare::Context & context) { + return Poincare::Expression::ParseAndSimplify(text, context, Poincare::Preferences::sharedPreferences()->angleUnit()); +} + +inline void Simplify(Poincare::Expression ** expressionAddress, Poincare::Context & context) { + return Poincare::Expression::Simplify(expressionAddress, context, Poincare::Preferences::sharedPreferences()->angleUnit()); +} + } } diff --git a/apps/shared/store_controller.cpp b/apps/shared/store_controller.cpp index 5c7093117..0480d6c44 100644 --- a/apps/shared/store_controller.cpp +++ b/apps/shared/store_controller.cpp @@ -1,5 +1,6 @@ #include "store_controller.h" #include "../apps_container.h" +#include "../shared/poincare_helpers.h" #include "../constant.h" #include #include @@ -85,7 +86,7 @@ bool StoreController::textFieldDidFinishEditing(TextField * textField, const cha } AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container(); Context * globalContext = appsContainer->globalContext(); - double floatBody = Expression::approximateToScalar(text, *globalContext); + double floatBody = PoincareHelpers::ApproximateToScalar(text, *globalContext); if (std::isnan(floatBody) || std::isinf(floatBody)) { app()->displayWarning(I18n::Message::UndefinedValue); return false; @@ -299,7 +300,7 @@ bool StoreController::privateFillColumnWithFormula(Expression * formula, Express // Set the context store->setSeriesPairIndex(j); // Compute the new value using the formula - double evaluation = formula->approximateToScalar(*store); + double evaluation = PoincareHelpers::ApproximateToScalar(formula, *store); if (std::isnan(evaluation) || std::isinf(evaluation)) { app()->displayWarning(I18n::Message::DataNotSuitable); return false; @@ -309,7 +310,7 @@ bool StoreController::privateFillColumnWithFormula(Expression * formula, Express // Fill in the table with the formula values for (int j = 0; j < numberOfValuesToCompute; j++) { store->setSeriesPairIndex(j); - double evaluation = formula->approximateToScalar(*store); + double evaluation = PoincareHelpers::ApproximateToScalar(formula, *store); setDataAtLocation(evaluation, currentColumn, j + 1); } selectableTableView()->reloadData(); diff --git a/apps/shared/sum_graph_controller.cpp b/apps/shared/sum_graph_controller.cpp index 6bdcccacf..bfaef786e 100644 --- a/apps/shared/sum_graph_controller.cpp +++ b/apps/shared/sum_graph_controller.cpp @@ -127,7 +127,7 @@ void SumGraphController::setFunction(Function * function) { bool SumGraphController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container(); Context * globalContext = appsContainer->globalContext(); - double floatBody = Expression::approximateToScalar(text, *globalContext); + double floatBody = PoincareHelpers::ApproximateToScalar(text, *globalContext); if (std::isnan(floatBody) || std::isinf(floatBody)) { app()->displayWarning(I18n::Message::UndefinedValue); return false; diff --git a/apps/solver/equation.cpp b/apps/solver/equation.cpp index 9c9b964cc..602d0522b 100644 --- a/apps/solver/equation.cpp +++ b/apps/solver/equation.cpp @@ -37,7 +37,7 @@ Expression * Equation::standardForm(Context * context) const { if (m_standardForm == nullptr) { Expression * e = expression(context); if (e->type() == Expression::Type::Equal) { - m_standardForm = static_cast(e)->standardEquation(*context); + m_standardForm = static_cast(e)->standardEquation(*context, Preferences::sharedPreferences()->angleUnit()); } else if (e->type() == Expression::Type::Rational && static_cast(e)->isOne()) { // The equality was reduced which means the equality was always true. m_standardForm = new Rational(0); diff --git a/apps/solver/equation_store.cpp b/apps/solver/equation_store.cpp index f03dd3ff0..bf6646cfa 100644 --- a/apps/solver/equation_store.cpp +++ b/apps/solver/equation_store.cpp @@ -69,7 +69,7 @@ bool EquationStore::haveMoreApproximationSolutions(Context * context) { return false; } double step = (m_intervalApproximateSolutions[1]-m_intervalApproximateSolutions[0])*k_precision; - return !std::isnan(definedModelAtIndex(0)->standardForm(context)->nextRoot(m_variables[0], m_approximateSolutions[m_numberOfSolutions-1], step, m_intervalApproximateSolutions[1], *context)); + return !std::isnan(definedModelAtIndex(0)->standardForm(context)->nextRoot(m_variables[0], m_approximateSolutions[m_numberOfSolutions-1], step, m_intervalApproximateSolutions[1], *context, Preferences::sharedPreferences()->angleUnit())); } void EquationStore::approximateSolve(Poincare::Context * context) { @@ -79,7 +79,7 @@ void EquationStore::approximateSolve(Poincare::Context * context) { double start = m_intervalApproximateSolutions[0]; double step = (m_intervalApproximateSolutions[1]-m_intervalApproximateSolutions[0])*k_precision; for (int i = 0; i < k_maxNumberOfApproximateSolutions; i++) { - m_approximateSolutions[i] = definedModelAtIndex(0)->standardForm(context)->nextRoot(m_variables[0], start, step, m_intervalApproximateSolutions[1], *context); + m_approximateSolutions[i] = definedModelAtIndex(0)->standardForm(context)->nextRoot(m_variables[0], start, step, m_intervalApproximateSolutions[1], *context, Preferences::sharedPreferences()->angleUnit()); if (std::isnan(m_approximateSolutions[i])) { break; } else { @@ -112,7 +112,7 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) { Expression * constants[k_maxNumberOfEquations]; bool isLinear = true; // Invalid the linear system if one equation is non-linear for (int i = 0; i < numberOfDefinedModels(); i++) { - isLinear = isLinear && definedModelAtIndex(i)->standardForm(context)->getLinearCoefficients(m_variables, coefficients[i], &constants[i], *context); + isLinear = isLinear && definedModelAtIndex(i)->standardForm(context)->getLinearCoefficients(m_variables, coefficients[i], &constants[i], *context, Preferences::sharedPreferences()->angleUnit()); // Clean allocated memory if the system is not linear if (!isLinear) { for (int j = 0; j < i; j++) { @@ -144,7 +144,7 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) { assert(numberOfVariables == 1 && numberOfDefinedModels() == 1); char x = m_variables[0]; Expression * polynomialCoefficients[Expression::k_maxNumberOfPolynomialCoefficients]; - int degree = definedModelAtIndex(0)->standardForm(context)->getPolynomialCoefficients(x, polynomialCoefficients, *context); + int degree = definedModelAtIndex(0)->standardForm(context)->getPolynomialCoefficients(x, polynomialCoefficients, *context, Preferences::sharedPreferences()->angleUnit()); if (degree == 2) { /* Polynomial degree <= 2*/ m_type = Type::PolynomialMonovariable; @@ -161,7 +161,7 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) { for (int i = 0; i < k_maxNumberOfExactSolutions; i++) { if (exactSolutions[i]) { m_exactSolutionExactLayouts[i] = PoincareHelpers::CreateLayout(exactSolutions[i]); - Expression * approximate = exactSolutions[i]->approximate(*context); + Expression * approximate = PoincareHelpers::Approximate(exactSolutions[i], *context); m_exactSolutionApproximateLayouts[i] = PoincareHelpers::CreateLayout(approximate); /* Check for identity between exact and approximate layouts */ char exactBuffer[Shared::ExpressionModel::k_expressionBufferSize]; @@ -171,7 +171,7 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) { m_exactSolutionIdentity[i] = strcmp(exactBuffer, approximateBuffer) == 0; /* Check for equality between exact and approximate layouts */ if (!m_exactSolutionIdentity[i]) { - m_exactSolutionEquality[i] = exactSolutions[i]->isEqualToItsApproximationLayout(approximate, Shared::ExpressionModel::k_expressionBufferSize, Preferences::sharedPreferences()->displayMode(), Preferences::sharedPreferences()->numberOfSignificantDigits(), *context); + m_exactSolutionEquality[i] = exactSolutions[i]->isEqualToItsApproximationLayout(approximate, Shared::ExpressionModel::k_expressionBufferSize, Preferences::sharedPreferences()->angleUnit(), Preferences::sharedPreferences()->displayMode(), Preferences::sharedPreferences()->numberOfSignificantDigits(), *context); } delete approximate; delete exactSolutions[i]; @@ -222,7 +222,7 @@ EquationStore::Error EquationStore::resolveLinearSystem(Expression * exactSoluti Expression * sol = Ab->matrixOperand(i,n); exactSolutions[i] = sol; Ab->detachOperand(sol); - Expression::Simplify(&exactSolutions[i], *context); + PoincareHelpers::Simplify(&exactSolutions[i], *context); } } } @@ -237,7 +237,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression * exa Expression * deltaSubOperand[3] = {new Rational(4), coefficients[0]->clone(), coefficients[2]->clone()}; // Compute delta = b*b-4ac Expression * delta = new Subtraction(new Power(coefficients[1]->clone(), new Rational(2), false), new Multiplication(deltaSubOperand, 3, false), false); - Expression::Simplify(&delta, *context); + PoincareHelpers::Simplify(&delta, *context); if (delta->isRationalZero()) { // if delta = 0, x0=x1= -b/(2a) exactSolutions[0] = new Division(new Opposite(coefficients[1], false), new Multiplication(new Rational(2), coefficients[2], false), false); @@ -252,7 +252,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression * exa exactSolutions[m_numberOfSolutions] = delta; delete coefficients[0]; for (int i = 0; i < m_numberOfSolutions; i++) { - Expression::Simplify(&exactSolutions[i], *context); + PoincareHelpers::Simplify(&exactSolutions[i], *context); } return Error::NoError; #if 0 @@ -269,7 +269,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression * exa Expression * mult4Operands[3] = {new Rational(-4), d->clone(), new Power(b->clone(), new Rational(3), false)}; Expression * add0Operands[5] = {new Multiplication(mult0Operands, 2, false), new Multiplication(mult1Operands, 5, false), new Multiplication(mult2Operands, 3, false), new Multiplication(mult3Operands, 3, false), new Multiplication(mult4Operands, 3, false)}; Expression * delta = new Addition(add0Operands, 5, false); - Simplify(&delta, *context); + PoincareHelpers::Simplify(&delta, *context); // Delta0 = b^2-3ac Expression * mult5Operands[3] = {new Rational(3), a->clone(), c->clone()}; Expression * delta0 = new Subtraction(new Power(b->clone(), new Rational(2), false), new Multiplication(mult5Operands, 3, false), false); diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h index 8868c311c..98a7a55e4 100644 --- a/poincare/include/poincare/cosine.h +++ b/poincare/include/poincare/cosine.h @@ -15,7 +15,7 @@ class Cosine : public StaticHierarchy<1>::StaticHierarchy { public: Type type() const override; Expression * clone() const override; - float characteristicXRange(Context & context, AngleUnit angleUnit = AngleUnit::Default) const override; + float characteristicXRange(Context & context, AngleUnit angleUnit) const override; template static std::complex computeOnComplex(const std::complex c, AngleUnit angleUnit = AngleUnit::Radian) { return Trigonometry::computeOnComplex(c, angleUnit, std::cos); } diff --git a/poincare/include/poincare/equal.h b/poincare/include/poincare/equal.h index 122de19b8..dde26bf2b 100644 --- a/poincare/include/poincare/equal.h +++ b/poincare/include/poincare/equal.h @@ -14,7 +14,7 @@ public: Expression * clone() const override; int polynomialDegree(char symbolName) const override; // For the equation A = B, create the reduced expression A-B - Expression * standardEquation(Context & context, AngleUnit angleUnit = AngleUnit::Default) const; + Expression * standardEquation(Context & context, AngleUnit angleUnit) const; private: /* Simplification */ Expression * shallowReduce(Context& context, AngleUnit angleUnit) override; diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 5fcb71267..faa715232 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -151,12 +151,10 @@ public: enum class ComplexFormat { Cartesian = 0, Polar = 1, - Default = 2 }; enum class AngleUnit { Degree = 0, Radian = 1, - Default = 2 }; /* Constructor & Destructor */ @@ -208,7 +206,7 @@ public: * the return value is NAN. * NB: so far, we consider that the only way of building a periodic function * is to use sin/tan/cos(f(x)) with f a linear function. */ - virtual float characteristicXRange(Context & context, AngleUnit angleUnit = AngleUnit::Default) const; + virtual float characteristicXRange(Context & context, AngleUnit angleUnit) const; static bool IsMatrix(const Expression * e, Context & context); /* polynomialDegree returns: @@ -227,14 +225,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, Expression * coefficients[], Expression * constant[], Context & context) const; + bool getLinearCoefficients(char * variables, Expression * coefficients[], Expression * constant[], Context & context, AngleUnit angleUnit) const; /* getPolynomialCoefficients fills the table coefficients with the expressions * of the first 3 polynomial coefficients and return polynomialDegree. * coefficients has up to 3 entries. It supposed to be called on Reduced * expression. */ static constexpr int k_maxPolynomialDegree = 2; static constexpr int k_maxNumberOfPolynomialCoefficients = k_maxPolynomialDegree+1; - int getPolynomialCoefficients(char symbolName, Expression * coefficients[], Context & context) const; + int getPolynomialCoefficients(char symbolName, Expression * coefficients[], Context & context, AngleUnit angleUnit) const; /* Comparison */ /* isIdenticalTo is the "easy" equality, it returns true if both trees have @@ -245,34 +243,34 @@ public: * order on expresssions. */ return SimplificationOrder(this, e, true) == 0; } - bool isEqualToItsApproximationLayout(Expression * approximation, int bufferSize, PrintFloat::Mode floatDisplayMode, int numberOfSignificantDigits, Context & context); + bool isEqualToItsApproximationLayout(Expression * approximation, int bufferSize, AngleUnit angleUnit, PrintFloat::Mode floatDisplayMode, int numberOfSignificantDigits, Context & context); /* Layout Engine */ virtual ExpressionLayout * createLayout(PrintFloat::Mode floatDisplayMode, int numberOfSignificantDigits) const = 0; // Returned object must be deleted virtual int writeTextInBuffer(char * buffer, int bufferSize, PrintFloat::Mode floatDisplayMode, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const = 0; /* Simplification */ - static Expression * ParseAndSimplify(const char * text, Context & context, AngleUnit angleUnit = AngleUnit::Default); - static void Simplify(Expression ** expressionAddress, Context & context, AngleUnit angleUnit = AngleUnit::Default); - static void Reduce(Expression ** expressionAddress, Context & context, AngleUnit angleUnit = AngleUnit::Default, bool recursively = true); + static Expression * ParseAndSimplify(const char * text, Context & context, AngleUnit angleUnit); + static void Simplify(Expression ** expressionAddress, Context & context, AngleUnit angleUnit); + static void Reduce(Expression ** expressionAddress, Context & context, AngleUnit angleUnit, bool recursively = true); /* Evaluation Engine */ /* The function approximate creates a new expression and thus mallocs memory. * Do not forget to delete the new expression to avoid leaking. */ - template Expression * approximate(Context& context, AngleUnit angleUnit = AngleUnit::Default, ComplexFormat complexFormat = ComplexFormat::Default) const; - template T approximateToScalar(Context& context, AngleUnit angleUnit = AngleUnit::Default, ComplexFormat complexFormat = ComplexFormat::Default) const; - template static T approximateToScalar(const char * text, Context& context, AngleUnit angleUnit = AngleUnit::Default, ComplexFormat complexFormat = ComplexFormat::Default); - template T approximateWithValueForSymbol(char symbol, T x, Context & context) const; + template Expression * approximate(Context& context, AngleUnit angleUnit, ComplexFormat complexFormat) const; + template T approximateToScalar(Context& context, AngleUnit angleUnit) const; + template static T approximateToScalar(const char * text, Context& context, AngleUnit angleUnit); + template T approximateWithValueForSymbol(char symbol, T x, Context & context, AngleUnit angleUnit) const; /* Expression roots/extrema solver*/ struct Coordinate2D { double abscissa; double value; }; - Coordinate2D nextMinimum(char symbol, double start, double step, double max, Context & context) const; - Coordinate2D nextMaximum(char symbol, double start, double step, double max, Context & context) const; - double nextRoot(char symbol, double start, double step, double max, Context & context) const; - Coordinate2D nextIntersection(char symbol, double start, double step, double max, Context & context, const Expression * expression) const; + Coordinate2D nextMinimum(char symbol, double start, double step, double max, Context & context, AngleUnit angleUnit) const; + Coordinate2D nextMaximum(char symbol, double start, double step, double max, Context & context, AngleUnit angleUnit) const; + double nextRoot(char symbol, double start, double step, double max, Context & context, AngleUnit angleUnit) const; + Coordinate2D nextIntersection(char symbol, double start, double step, double max, Context & context, AngleUnit angleUnit, const Expression * expression) const; /* Evaluation engine */ template static T epsilon(); @@ -337,13 +335,13 @@ private: constexpr static double k_sqrtEps = 1.4901161193847656E-8; // sqrt(DBL_EPSILON) constexpr static double k_goldenRatio = 0.381966011250105151795413165634361882279690820194237137864; // (3-sqrt(5))/2 constexpr static double k_maxFloat = 1e100; - typedef double (*EvaluationAtAbscissa)(char symbol, double abscissa, Context & context, const Expression * expression0, const Expression * expression1); - Coordinate2D nextMinimumOfExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, const Expression * expression = nullptr, bool lookForRootMinimum = false) const; - void bracketMinimum(char symbol, double start, double step, double max, double result[3], EvaluationAtAbscissa evaluation, Context & context, const Expression * expression = nullptr) const; - Coordinate2D brentMinimum(char symbol, double ax, double bx, EvaluationAtAbscissa evaluation, Context & context, const Expression * expression = nullptr) const; - double nextIntersectionWithExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, const Expression * expression) const; - void bracketRoot(char symbol, double start, double step, double max, double result[2], EvaluationAtAbscissa evaluation, Context & context, const Expression * expression) const; - double brentRoot(char symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, const Expression * expression) const; + typedef double (*EvaluationAtAbscissa)(char symbol, double abscissa, Context & context, AngleUnit angleUnit, const Expression * expression0, const Expression * expression1); + Coordinate2D nextMinimumOfExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, AngleUnit angleUnit, const Expression * expression = nullptr, bool lookForRootMinimum = false) const; + void bracketMinimum(char symbol, double start, double step, double max, double result[3], EvaluationAtAbscissa evaluation, Context & context, AngleUnit angleUnit, const Expression * expression = nullptr) const; + Coordinate2D brentMinimum(char symbol, double ax, double bx, EvaluationAtAbscissa evaluation, Context & context, AngleUnit angleUnit, const Expression * expression = nullptr) const; + double nextIntersectionWithExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, AngleUnit angleUnit, const Expression * expression) const; + void bracketRoot(char symbol, double start, double step, double max, double result[2], EvaluationAtAbscissa evaluation, Context & context, AngleUnit angleUnit, const Expression * expression) const; + double brentRoot(char symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, AngleUnit angleUnit, const Expression * expression) const; Expression * m_parent; }; diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h index f19f68c5c..6d5feb1d4 100644 --- a/poincare/include/poincare/sine.h +++ b/poincare/include/poincare/sine.h @@ -11,7 +11,7 @@ namespace Poincare { class Sine : public StaticHierarchy<1> { using StaticHierarchy<1>::StaticHierarchy; friend class Tangent; - float characteristicXRange(Context & context, AngleUnit angleUnit = AngleUnit::Default) const override; + float characteristicXRange(Context & context, AngleUnit angleUnit) const override; public: Type type() const override; Expression * clone() const override; diff --git a/poincare/include/poincare/symbol.h b/poincare/include/poincare/symbol.h index 3ede81851..aae9f58f8 100644 --- a/poincare/include/poincare/symbol.h +++ b/poincare/include/poincare/symbol.h @@ -57,7 +57,7 @@ public: static bool isSeriesSymbol(char c); static bool isRegressionSymbol(char c); bool isApproximate(Context & context) const; - float characteristicXRange(Context & context, AngleUnit angleUnit = AngleUnit::Default) const override; + float characteristicXRange(Context & context, AngleUnit angleUnit) const override; bool hasAnExactRepresentation(Context & context) const; static const char * textForSpecialSymbols(char name); int getVariables(isVariableTest isVariable, char * variables) const override; diff --git a/poincare/include/poincare/tangent.h b/poincare/include/poincare/tangent.h index 8c86306e1..d957b55e1 100644 --- a/poincare/include/poincare/tangent.h +++ b/poincare/include/poincare/tangent.h @@ -13,7 +13,7 @@ class Tangent : public StaticHierarchy<1> { public: Type type() const override; Expression * clone() const override; - float characteristicXRange(Context & context, AngleUnit angleUnit = AngleUnit::Default) const override; + float characteristicXRange(Context & context, AngleUnit angleUnit) const override; private: /* Layout */ ExpressionLayout * createLayout(PrintFloat::Mode floatDisplayMode, int numberOfSignificantDigits) const override { diff --git a/poincare/src/arc_cosine.cpp b/poincare/src/arc_cosine.cpp index 32536a951..d3a5cb893 100644 --- a/poincare/src/arc_cosine.cpp +++ b/poincare/src/arc_cosine.cpp @@ -32,7 +32,6 @@ Expression * ArcCosine::shallowReduce(Context& context, AngleUnit angleUnit) { template std::complex ArcCosine::computeOnComplex(const std::complex c, AngleUnit angleUnit) { - assert(angleUnit != AngleUnit::Default); std::complex result = std::acos(c); if (angleUnit == AngleUnit::Degree && result.imag() == 0.0) { result *= 180/M_PI; diff --git a/poincare/src/arc_sine.cpp b/poincare/src/arc_sine.cpp index f66d53629..f24fb158d 100644 --- a/poincare/src/arc_sine.cpp +++ b/poincare/src/arc_sine.cpp @@ -32,7 +32,6 @@ Expression * ArcSine::shallowReduce(Context& context, AngleUnit angleUnit) { template std::complex ArcSine::computeOnComplex(const std::complex c, AngleUnit angleUnit) { - assert(angleUnit != AngleUnit::Default); std::complex result = std::asin(c); if (angleUnit == AngleUnit::Degree && result.imag() == 0.0) { result *= 180/M_PI; diff --git a/poincare/src/arc_tangent.cpp b/poincare/src/arc_tangent.cpp index 8def53bf1..7a619aaf2 100644 --- a/poincare/src/arc_tangent.cpp +++ b/poincare/src/arc_tangent.cpp @@ -32,7 +32,6 @@ Expression * ArcTangent::shallowReduce(Context& context, AngleUnit angleUnit) { template std::complex ArcTangent::computeOnComplex(const std::complex c, AngleUnit angleUnit) { - assert(angleUnit != AngleUnit::Default); std::complex result = std::atan(c); if (angleUnit == AngleUnit::Degree && result.imag() == 0.0) { result *= 180/M_PI; diff --git a/poincare/src/derivative.cpp b/poincare/src/derivative.cpp index 390db4f64..a22217360 100644 --- a/poincare/src/derivative.cpp +++ b/poincare/src/derivative.cpp @@ -50,7 +50,7 @@ Complex * Derivative::templatedApproximate(Context& context, AngleUnit angleU Evaluation * xInput = operand(1)->privateApproximate(T(), context, angleUnit); T x = xInput->toScalar(); delete xInput; - T functionValue = operand(0)->approximateWithValueForSymbol('x', x, context); + T functionValue = operand(0)->approximateWithValueForSymbol('x', x, context, angleUnit); // No complex/matrix version of Derivative if (std::isnan(x) || std::isnan(functionValue)) { return new Complex(Complex::Undefined()); @@ -76,8 +76,8 @@ Complex * Derivative::templatedApproximate(Context& context, AngleUnit angleU template T Derivative::growthRateAroundAbscissa(T x, T h, Context & context, AngleUnit angleUnit) const { - T expressionPlus = operand(0)->approximateWithValueForSymbol('x', x+h, context); - T expressionMinus = operand(0)->approximateWithValueForSymbol('x', x-h, context); + T expressionPlus = operand(0)->approximateWithValueForSymbol('x', x+h, context, angleUnit); + T expressionMinus = operand(0)->approximateWithValueForSymbol('x', x-h, context, angleUnit); return (expressionPlus - expressionMinus)/(2*h); } diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index a379e4721..27c027734 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -190,9 +190,6 @@ bool Expression::isApproximate(Context & context) const { } float Expression::characteristicXRange(Context & context, AngleUnit angleUnit) const { - if (angleUnit == AngleUnit::Default) { - angleUnit = Preferences::sharedPreferences()->angleUnit(); - } /* A expression has a characteristic range if at least one of its operand has * one and the other are x-independant. We keep the biggest interesting range * among the operand interesting ranges. */ @@ -237,7 +234,7 @@ bool dependsOnVariables(const Expression * e, Context & context) { return e->type() == Expression::Type::Symbol && Symbol::isVariableSymbol(static_cast(e)->name()); } -bool Expression::getLinearCoefficients(char * variables, Expression * coefficients[], Expression ** constant, Context & context) const { +bool Expression::getLinearCoefficients(char * variables, Expression * coefficients[], Expression ** constant, Context & context, AngleUnit angleUnit) const { char * x = variables; while (*x != 0) { int degree = polynomialDegree(*x); @@ -251,7 +248,7 @@ bool Expression::getLinearCoefficients(char * variables, Expression * coefficien int index = 0; Expression * polynomialCoefficients[k_maxNumberOfPolynomialCoefficients]; while (*x != 0) { - int degree = equation->getPolynomialCoefficients(*x, polynomialCoefficients, context); + int degree = equation->getPolynomialCoefficients(*x, polynomialCoefficients, context, angleUnit); if (degree == 1) { coefficients[index] = polynomialCoefficients[1]; } else { @@ -264,7 +261,7 @@ bool Expression::getLinearCoefficients(char * variables, Expression * coefficien index++; } *constant = new Opposite(equation, false); - Reduce(constant, context); + Reduce(constant, context, angleUnit); /* 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. */ @@ -287,10 +284,10 @@ bool Expression::getLinearCoefficients(char * variables, Expression * coefficien return true; } -int Expression::getPolynomialCoefficients(char symbolName, Expression * coefficients[], Context & context) const { +int Expression::getPolynomialCoefficients(char symbolName, Expression * coefficients[], Context & context, AngleUnit angleUnit) const { int degree = privateGetPolynomialCoefficients(symbolName, coefficients); for (int i = 0; i <= degree; i++) { - Reduce(&coefficients[i], context); + Reduce(&coefficients[i], context, angleUnit); } return degree; } @@ -335,7 +332,7 @@ int Expression::SimplificationOrder(const Expression * e1, const Expression * e2 } } -bool Expression::isEqualToItsApproximationLayout(Expression * approximation, int bufferSize, PrintFloat::Mode floatDisplayMode, int numberOfSignificantDigits, Context & context) { +bool Expression::isEqualToItsApproximationLayout(Expression * approximation, int bufferSize, AngleUnit angleUnit, PrintFloat::Mode floatDisplayMode, int numberOfSignificantDigits, Context & context) { char buffer[bufferSize]; approximation->writeTextInBuffer(buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits); /* Warning: we cannot use directly the the approximate expression but we have @@ -344,7 +341,7 @@ bool Expression::isEqualToItsApproximationLayout(Expression * approximation, int * identical. (For example, 0.000025 might be displayed "0.00003" and stored * as Decimal(0.000025) and isEqualToItsApproximationLayout should return * false) */ - Expression * approximateOutput = Expression::ParseAndSimplify(buffer, context); + Expression * approximateOutput = Expression::ParseAndSimplify(buffer, context, angleUnit); bool equal = isIdenticalTo(approximateOutput); delete approximateOutput; return equal; @@ -366,9 +363,6 @@ Expression * Expression::ParseAndSimplify(const char * text, Context & context, void Expression::Simplify(Expression ** expressionAddress, Context & context, AngleUnit angleUnit) { sSimplificationHasBeenInterrupted = false; - if (angleUnit == AngleUnit::Default) { - angleUnit = Preferences::sharedPreferences()->angleUnit(); - } #if MATRIX_EXACT_REDUCING #else if ((*expressionAddress)->recursivelyMatches(IsMatrix, context)) { @@ -426,12 +420,6 @@ Expression * Expression::deepBeautify(Context & context, AngleUnit angleUnit) { /* Evaluation */ template Expression * Expression::approximate(Context& context, AngleUnit angleUnit, ComplexFormat complexFormat) const { - if (angleUnit == AngleUnit::Default) { - angleUnit = Preferences::sharedPreferences()->angleUnit(); - } - if (complexFormat == ComplexFormat::Default) { - complexFormat = Preferences::sharedPreferences()->complexFormat(); - } Expression * result = nullptr; Evaluation * e = privateApproximate(T(), context, angleUnit); if (e->type() == Evaluation::Type::Complex) { @@ -449,13 +437,7 @@ template Expression * Expression::approximate(Context& context, Angl return result; } -template T Expression::approximateToScalar(Context& context, AngleUnit angleUnit, ComplexFormat complexFormat) const { - if (angleUnit == AngleUnit::Default) { - angleUnit = Preferences::sharedPreferences()->angleUnit(); - } - if (complexFormat == ComplexFormat::Default) { - complexFormat = Preferences::sharedPreferences()->complexFormat(); - } +template T Expression::approximateToScalar(Context& context, AngleUnit angleUnit) const { Evaluation * evaluation = privateApproximate(T(), context, angleUnit); T result = evaluation->toScalar(); /*if (evaluation->type() == Type::Matrix) { @@ -467,9 +449,9 @@ template T Expression::approximateToScalar(Context& context, AngleUn return result; } -template T Expression::approximateToScalar(const char * text, Context& context, AngleUnit angleUnit, ComplexFormat complexFormat) { +template T Expression::approximateToScalar(const char * text, Context& context, AngleUnit angleUnit) { Expression * exp = ParseAndSimplify(text, context, angleUnit); - T result = exp->approximateToScalar(context, angleUnit, complexFormat); + T result = exp->approximateToScalar(context, angleUnit); delete exp; return result; } @@ -481,37 +463,37 @@ template T Expression::epsilon() { /* Expression roots/extrema solver*/ -Expression::Coordinate2D Expression::nextMinimum(char symbol, double start, double step, double max, Context & context) const { - return nextMinimumOfExpression(symbol, start, step, max, [](char symbol, double x, Context & context, const Expression * expression0, const Expression * expression1 = nullptr) { - return expression0->approximateWithValueForSymbol(symbol, x, context); - }, context); +Expression::Coordinate2D Expression::nextMinimum(char symbol, double start, double step, double max, Context & context, AngleUnit angleUnit) const { + return nextMinimumOfExpression(symbol, start, step, max, [](char symbol, double x, Context & context, AngleUnit angleUnit, const Expression * expression0, const Expression * expression1 = nullptr) { + return expression0->approximateWithValueForSymbol(symbol, x, context, angleUnit); + }, context, angleUnit); } -Expression::Coordinate2D Expression::nextMaximum(char symbol, double start, double step, double max, Context & context) const { - Coordinate2D minimumOfOpposite = nextMinimumOfExpression(symbol, start, step, max, [](char symbol, double x, Context & context, const Expression * expression0, const Expression * expression1 = nullptr) { - return -expression0->approximateWithValueForSymbol(symbol, x, context); - }, context); +Expression::Coordinate2D Expression::nextMaximum(char symbol, double start, double step, double max, Context & context, AngleUnit angleUnit) const { + Coordinate2D minimumOfOpposite = nextMinimumOfExpression(symbol, start, step, max, [](char symbol, double x, Context & context, AngleUnit angleUnit, const Expression * expression0, const Expression * expression1 = nullptr) { + return -expression0->approximateWithValueForSymbol(symbol, x, context, angleUnit); + }, context, angleUnit); return {.abscissa = minimumOfOpposite.abscissa, .value = -minimumOfOpposite.value}; } -double Expression::nextRoot(char symbol, double start, double step, double max, Context & context) const { - return nextIntersectionWithExpression(symbol, start, step, max, [](char symbol, double x, Context & context, const Expression * expression0, const Expression * expression1 = nullptr) { - return expression0->approximateWithValueForSymbol(symbol, x, context); - }, context, nullptr); +double Expression::nextRoot(char symbol, double start, double step, double max, Context & context, AngleUnit angleUnit) const { + return nextIntersectionWithExpression(symbol, start, step, max, [](char symbol, double x, Context & context, AngleUnit angleUnit, const Expression * expression0, const Expression * expression1 = nullptr) { + return expression0->approximateWithValueForSymbol(symbol, x, context, angleUnit); + }, context, angleUnit, nullptr); } -Expression::Coordinate2D Expression::nextIntersection(char symbol, double start, double step, double max, Poincare::Context & context, const Expression * expression) const { - double resultAbscissa = nextIntersectionWithExpression(symbol, start, step, max, [](char symbol, double x, Context & context, const Expression * expression0, const Expression * expression1) { - return expression0->approximateWithValueForSymbol(symbol, x, context)-expression1->approximateWithValueForSymbol(symbol, x, context); - }, context, expression); - Expression::Coordinate2D result = {.abscissa = resultAbscissa, .value = approximateWithValueForSymbol(symbol, resultAbscissa, context)}; +Expression::Coordinate2D Expression::nextIntersection(char symbol, double start, double step, double max, Poincare::Context & context, AngleUnit angleUnit, const Expression * expression) const { + double resultAbscissa = nextIntersectionWithExpression(symbol, start, step, max, [](char symbol, double x, Context & context, AngleUnit angleUnit, const Expression * expression0, const Expression * expression1) { + return expression0->approximateWithValueForSymbol(symbol, x, context, angleUnit)-expression1->approximateWithValueForSymbol(symbol, x, context, angleUnit); + }, context, angleUnit, expression); + Expression::Coordinate2D result = {.abscissa = resultAbscissa, .value = approximateWithValueForSymbol(symbol, resultAbscissa, context, angleUnit)}; if (std::fabs(result.value) < step*k_solverPrecision) { result.value = 0.0; } return result; } -Expression::Coordinate2D Expression::nextMinimumOfExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluate, Context & context, const Expression * expression, bool lookForRootMinimum) const { +Expression::Coordinate2D Expression::nextMinimumOfExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluate, Context & context, AngleUnit angleUnit, const Expression * expression, bool lookForRootMinimum) const { Coordinate2D result = {.abscissa = NAN, .value = NAN}; if (start == max || step == 0.0) { return result; @@ -520,13 +502,13 @@ Expression::Coordinate2D Expression::nextMinimumOfExpression(char symbol, double double x = start; bool endCondition = false; do { - bracketMinimum(symbol, x, step, max, bracket, evaluate, context, expression); - result = brentMinimum(symbol, bracket[0], bracket[2], evaluate, context, expression); + bracketMinimum(symbol, x, step, max, bracket, evaluate, context, angleUnit, expression); + result = brentMinimum(symbol, bracket[0], bracket[2], evaluate, context, angleUnit, expression); x = bracket[1]; // Because of float approximation, exact zero is never reached if (std::fabs(result.abscissa) < std::fabs(step)*k_solverPrecision) { result.abscissa = 0; - result.value = evaluate(symbol, 0, context, this, expression); + result.value = evaluate(symbol, 0, context, angleUnit, this, expression); } /* Ignore extremum whose value is undefined or too big because they are * really unlikely to be local extremum. */ @@ -548,13 +530,13 @@ Expression::Coordinate2D Expression::nextMinimumOfExpression(char symbol, double return result; } -void Expression::bracketMinimum(char symbol, double start, double step, double max, double result[3], EvaluationAtAbscissa evaluate, Context & context, const Expression * expression) const { +void Expression::bracketMinimum(char symbol, double start, double step, double max, double result[3], EvaluationAtAbscissa evaluate, Context & context, AngleUnit angleUnit, const Expression * expression) const { Coordinate2D p[3]; - p[0] = {.abscissa = start, .value = evaluate(symbol, start, context, this, expression)}; - p[1] = {.abscissa = start+step, .value = evaluate(symbol, start+step, context, this, expression)}; + p[0] = {.abscissa = start, .value = evaluate(symbol, start, context, angleUnit, this, expression)}; + p[1] = {.abscissa = start+step, .value = evaluate(symbol, start+step, context, angleUnit, this, expression)}; double x = start+2.0*step; while (step > 0.0 ? x <= max : x >= max) { - p[2] = {.abscissa = x, .value = evaluate(symbol, x, context, this, expression)}; + p[2] = {.abscissa = x, .value = evaluate(symbol, x, context, angleUnit, this, expression)}; if ((p[0].value > p[1].value || std::isnan(p[0].value)) && (p[2].value > p[1].value || std::isnan(p[2].value)) && (!std::isnan(p[0].value) || !std::isnan(p[2].value))) { result[0] = p[0].abscissa; result[1] = p[1].abscissa; @@ -573,11 +555,11 @@ void Expression::bracketMinimum(char symbol, double start, double step, double m result[2] = NAN; } -Expression::Coordinate2D Expression::brentMinimum(char symbol, double ax, double bx, EvaluationAtAbscissa evaluate, Context & context, const Expression * expression) const { +Expression::Coordinate2D Expression::brentMinimum(char symbol, double ax, double bx, EvaluationAtAbscissa evaluate, Context & context, AngleUnit angleUnit, const Expression * expression) const { /* Bibliography: R. P. Brent, Algorithms for finding zeros and extrema of * functions without calculating derivatives */ if (ax > bx) { - return brentMinimum(symbol, bx, ax, evaluate, context, expression); + return brentMinimum(symbol, bx, ax, evaluate, context, angleUnit, expression); } double e = 0.0; double a = ax; @@ -585,7 +567,7 @@ Expression::Coordinate2D Expression::brentMinimum(char symbol, double ax, double double x = a+k_goldenRatio*(b-a); double v = x; double w = x; - double fx = evaluate(symbol, x, context, this, expression); + double fx = evaluate(symbol, x, context, angleUnit, this, expression); double fw = fx; double fv = fw; @@ -597,10 +579,10 @@ Expression::Coordinate2D Expression::brentMinimum(char symbol, double ax, double double tol1 = k_sqrtEps*std::fabs(x)+1E-10; double tol2 = 2.0*tol1; if (std::fabs(x-m) <= tol2-0.5*(b-a)) { - double middleFax = evaluate(symbol, (x+a)/2.0, context, this, expression); - double middleFbx = evaluate(symbol, (x+b)/2.0, context, this, expression); - double fa = evaluate(symbol, a, context, this, expression); - double fb = evaluate(symbol, b, context, this, expression); + double middleFax = evaluate(symbol, (x+a)/2.0, context, angleUnit, this, expression); + double middleFbx = evaluate(symbol, (x+b)/2.0, context, angleUnit, this, expression); + double fa = evaluate(symbol, a, context, angleUnit, this, expression); + double fb = evaluate(symbol, b, context, angleUnit, this, expression); if (middleFax-fa <= k_sqrtEps && fx-middleFax <= k_sqrtEps && fx-middleFbx <= k_sqrtEps && middleFbx-fb <= k_sqrtEps) { Coordinate2D result = {.abscissa = x, .value = fx}; return result; @@ -633,7 +615,7 @@ Expression::Coordinate2D Expression::brentMinimum(char symbol, double ax, double d = k_goldenRatio*e; } u = x + (std::fabs(d) >= tol1 ? d : (d>0 ? tol1 : -tol1)); - fu = evaluate(symbol, u, context, this, expression); + fu = evaluate(symbol, u, context, angleUnit, this, expression); if (fu <= fx) { if (u 0.0 ? x <= max : x >= max)); double extremumMax = std::isnan(result) ? max : result; Coordinate2D resultExtremum[2] = { - nextMinimumOfExpression(symbol, start, step, extremumMax, [](char symbol, double x, Context & context, const Expression * expression0, const Expression * expression1) { + nextMinimumOfExpression(symbol, start, step, extremumMax, [](char symbol, double x, Context & context, AngleUnit angleUnit, const Expression * expression0, const Expression * expression1) { if (expression1) { - return expression0->approximateWithValueForSymbol(symbol, x, context)-expression1->approximateWithValueForSymbol(symbol, x, context); + return expression0->approximateWithValueForSymbol(symbol, x, context, angleUnit)-expression1->approximateWithValueForSymbol(symbol, x, context, angleUnit); } else { - return expression0->approximateWithValueForSymbol(symbol, x, context); + return expression0->approximateWithValueForSymbol(symbol, x, context, angleUnit); } - }, context, expression, true), - nextMinimumOfExpression(symbol, start, step, extremumMax, [](char symbol, double x, Context & context, const Expression * expression0, const Expression * expression1) { + }, context, angleUnit, expression, true), + nextMinimumOfExpression(symbol, start, step, extremumMax, [](char symbol, double x, Context & context, AngleUnit angleUnit, const Expression * expression0, const Expression * expression1) { if (expression1) { - return expression1->approximateWithValueForSymbol(symbol, x, context)-expression0->approximateWithValueForSymbol(symbol, x, context); + return expression1->approximateWithValueForSymbol(symbol, x, context, angleUnit)-expression0->approximateWithValueForSymbol(symbol, x, context, angleUnit); } else { - return -expression0->approximateWithValueForSymbol(symbol, x, context); + return -expression0->approximateWithValueForSymbol(symbol, x, context, angleUnit); } - }, context, expression, true)}; + }, context, angleUnit, expression, true)}; for (int i = 0; i < 2; i++) { if (!std::isnan(resultExtremum[i].abscissa) && (std::isnan(result) || std::fabs(result - start) > std::fabs(resultExtremum[i].abscissa - start))) { result = resultExtremum[i].abscissa; @@ -708,12 +690,12 @@ double Expression::nextIntersectionWithExpression(char symbol, double start, dou return result; } -void Expression::bracketRoot(char symbol, double start, double step, double max, double result[2], EvaluationAtAbscissa evaluation, Context & context, const Expression * expression) const { +void Expression::bracketRoot(char symbol, double start, double step, double max, double result[2], EvaluationAtAbscissa evaluation, Context & context, AngleUnit angleUnit, const Expression * expression) const { double a = start; double b = start+step; while (step > 0.0 ? b <= max : b >= max) { - double fa = evaluation(symbol, a, context, this, expression); - double fb = evaluation(symbol, b, context, this, expression); + double fa = evaluation(symbol, a, context, angleUnit, this, expression); + double fb = evaluation(symbol, b, context, angleUnit, this, expression); if (fa*fb <= 0) { result[0] = a; result[1] = b; @@ -727,17 +709,17 @@ void Expression::bracketRoot(char symbol, double start, double step, double max, } -double Expression::brentRoot(char symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, const Expression * expression) const { +double Expression::brentRoot(char symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, AngleUnit angleUnit, const Expression * expression) const { if (ax > bx) { - return brentRoot(symbol, bx, ax, precision, evaluation, context, expression); + return brentRoot(symbol, bx, ax, precision, evaluation, context, angleUnit, expression); } double a = ax; double b = bx; double c = bx; double d = b-a; double e = b-a; - double fa = evaluation(symbol, a, context, this, expression); - double fb = evaluation(symbol, b, context, this, expression); + double fa = evaluation(symbol, a, context, angleUnit, this, expression); + double fb = evaluation(symbol, b, context, angleUnit, this, expression); double fc = fb; for (int i = 0; i < 100; i++) { if ((fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0)) { @@ -757,7 +739,7 @@ double Expression::brentRoot(char symbol, double ax, double bx, double precision double tol1 = 2.0*DBL_EPSILON*std::fabs(b)+0.5*precision; double xm = 0.5*(c-b); if (std::fabs(xm) <= tol1 || fb == 0.0) { - double fbcMiddle = evaluation(symbol, 0.5*(b+c), context, this, expression); + double fbcMiddle = evaluation(symbol, 0.5*(b+c), context, angleUnit, this, expression); double isContinuous = (fb <= fbcMiddle && fbcMiddle <= fc) || (fc <= fbcMiddle && fbcMiddle <= fb); if (isContinuous) { return b; @@ -795,16 +777,16 @@ double Expression::brentRoot(char symbol, double ax, double bx, double precision } else { b += xm > 0.0 ? tol1 : tol1; } - fb = evaluation(symbol, b, context, this, expression); + fb = evaluation(symbol, b, context, angleUnit, this, expression); } return NAN; } template -T Expression::approximateWithValueForSymbol(char symbol, T x, Context & context) const { +T Expression::approximateWithValueForSymbol(char symbol, T x, Context & context, AngleUnit angleUnit) const { VariableContext variableContext = VariableContext(symbol, &context); variableContext.setApproximationForVariable(x); - T value = approximateToScalar(variableContext); + T value = approximateToScalar(variableContext, angleUnit); return value; } @@ -817,9 +799,6 @@ Expression * Expression::CreateDecimal(T f) { } template Expression * Expression::complexToExpression(std::complex c, ComplexFormat complexFormat) { - if (complexFormat == ComplexFormat::Default) { - complexFormat = Preferences::sharedPreferences()->complexFormat(); - } if (std::isnan(c.real()) || std::isnan(c.imag()) || std::isinf(c.real()) || std::isinf(c.imag())) { return new Undefined(); } @@ -890,11 +869,11 @@ template Expression * Expression::complexToExpression(std::complex(Context& context, AngleUnit angleUnit, ComplexFormat complexFormat) const; template Poincare::Expression * Poincare::Expression::approximate(Context& context, AngleUnit angleUnit, ComplexFormat complexFormat) const; -template double Poincare::Expression::approximateToScalar(char const*, Poincare::Context&, Poincare::Expression::AngleUnit, ComplexFormat complexFormat); -template float Poincare::Expression::approximateToScalar(char const*, Poincare::Context&, Poincare::Expression::AngleUnit, ComplexFormat complexFormat); -template double Poincare::Expression::approximateToScalar(Poincare::Context&, Poincare::Expression::AngleUnit, ComplexFormat complexFormat) const; -template float Poincare::Expression::approximateToScalar(Poincare::Context&, Poincare::Expression::AngleUnit, ComplexFormat complexFormat) const; +template double Poincare::Expression::approximateToScalar(char const*, Poincare::Context&, Poincare::Expression::AngleUnit); +template float Poincare::Expression::approximateToScalar(char const*, Poincare::Context&, Poincare::Expression::AngleUnit); +template double Poincare::Expression::approximateToScalar(Poincare::Context&, Poincare::Expression::AngleUnit) const; +template float Poincare::Expression::approximateToScalar(Poincare::Context&, Poincare::Expression::AngleUnit) const; template double Poincare::Expression::epsilon(); template float Poincare::Expression::epsilon(); -template double Poincare::Expression::approximateWithValueForSymbol(char, double, Poincare::Context&) const; -template float Poincare::Expression::approximateWithValueForSymbol(char, float, Poincare::Context&) const; +template double Poincare::Expression::approximateWithValueForSymbol(char, double, Poincare::Context&, AngleUnit) const; +template float Poincare::Expression::approximateWithValueForSymbol(char, float, Poincare::Context&, AngleUnit) const; diff --git a/poincare/src/global_context.cpp b/poincare/src/global_context.cpp index 38b289e4d..de0597da0 100644 --- a/poincare/src/global_context.cpp +++ b/poincare/src/global_context.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -94,7 +95,7 @@ void GlobalContext::setExpressionForSymbolName(const Expression * expression, co if (symbol->isMatrixSymbol()) { int indexMatrix = symbol->name() - (char)Symbol::SpecialSymbols::M0; assert(indexMatrix >= 0 && indexMatrix < k_maxNumberOfMatrixExpressions); - Expression * evaluation = expression ? expression->approximate(context) : nullptr; // evaluate before deleting anything (to be able to evaluate M1+2->M1) + Expression * evaluation = expression ? expression->approximate(context, Preferences::sharedPreferences()->angleUnit(), Preferences::sharedPreferences()->complexFormat()) : nullptr; // evaluate before deleting anything (to be able to evaluate M1+2->M1) if (m_matrixExpressions[indexMatrix] != nullptr) { delete m_matrixExpressions[indexMatrix]; m_matrixExpressions[indexMatrix] = nullptr; @@ -115,7 +116,7 @@ void GlobalContext::setExpressionForSymbolName(const Expression * expression, co if (index < 0 || index >= k_maxNumberOfScalarExpressions) { return; } - Expression * evaluation = expression ? expression->approximate(context) : nullptr; // evaluate before deleting anything (to be able to evaluate A+2->A) + Expression * evaluation = expression ? expression->approximate(context, Preferences::sharedPreferences()->angleUnit(), Preferences::sharedPreferences()->complexFormat()) : nullptr; // evaluate before deleting anything (to be able to evaluate A+2->A) if (m_expressions[index] != nullptr) { delete m_expressions[index]; m_expressions[index] = nullptr; diff --git a/poincare/src/integral.cpp b/poincare/src/integral.cpp index 4a5b1d134..80bb539f2 100644 --- a/poincare/src/integral.cpp +++ b/poincare/src/integral.cpp @@ -76,7 +76,7 @@ ExpressionLayout * Integral::createLayout(PrintFloat::Mode floatDisplayMode, int template T Integral::functionValueAtAbscissa(T x, Context & context, AngleUnit angleUnit) const { - return operand(0)->approximateWithValueForSymbol('x', x, context); + return operand(0)->approximateWithValueForSymbol('x', x, context, angleUnit); } #ifdef LAGRANGE_METHOD diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index b4e1454ae..dfacb4278 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -139,7 +139,7 @@ template MatrixComplex Power::computeOnMatrixAndComplex(const Mat if (inverse == nullptr) { return MatrixComplex::Undefined(); } - Complex minusC = Complex(Opposite::compute(d, AngleUnit::Default)); + Complex minusC = Complex(-d); MatrixComplex result = Power::computeOnMatrixAndComplex(*inverse, minusC); delete inverse; return result; diff --git a/poincare/src/trigonometry.cpp b/poincare/src/trigonometry.cpp index 62e8d7bca..45ed90edc 100644 --- a/poincare/src/trigonometry.cpp +++ b/poincare/src/trigonometry.cpp @@ -19,9 +19,6 @@ namespace Poincare { float Trigonometry::characteristicXRange(const Expression * e, Context & context, Expression::AngleUnit angleUnit) { assert(e->numberOfOperands() == 1); - if (angleUnit == Expression::AngleUnit::Default) { - angleUnit = Preferences::sharedPreferences()->angleUnit(); - } const Expression * op = e->operand(0); int d = op->polynomialDegree('x'); // op is not linear so we cannot not easily find an interesting range @@ -39,7 +36,7 @@ float Trigonometry::characteristicXRange(const Expression * e, Context & context Poincare::Approximation x(1.0f); const Poincare::Expression * args[2] = {op, &x}; Poincare::Derivative derivative(args, true); - float a = derivative.approximateToScalar(context); + float a = derivative.approximateToScalar(context, angleUnit); float pi = angleUnit == Expression::AngleUnit::Radian ? M_PI : 180.0f; return 2.0f*pi/std::fabs(a); } @@ -243,7 +240,6 @@ Expression * Trigonometry::table(const Expression * e, Expression::Type type, Co template std::complex Trigonometry::computeOnComplex(const std::complex c, Expression::AngleUnit angleUnit, Approximation approximate) { - assert(angleUnit != Expression::AngleUnit::Default); std::complex input(c); if (angleUnit == Expression::AngleUnit::Degree && input.imag() == 0.0) { input = input*std::complex(M_PI/180.0); diff --git a/poincare/src/variable_context.cpp b/poincare/src/variable_context.cpp index c4559b553..dd92476bf 100644 --- a/poincare/src/variable_context.cpp +++ b/poincare/src/variable_context.cpp @@ -21,11 +21,10 @@ void VariableContext::setApproximationForVariable(T value) { template void VariableContext::setExpressionForSymbolName(const Expression * expression, const Symbol * symbol, Context & context) { if (symbol->name() == m_name) { - assert(false); if (expression == nullptr) { return; } - m_value = Approximation(expression->approximateToScalar(context)); + m_value = Approximation(expression->approximateToScalar(context, Preferences::sharedPreferences()->angleUnit())); } else { m_parentContext->setExpressionForSymbolName(expression, symbol, context); } diff --git a/poincare/test/properties.cpp b/poincare/test/properties.cpp index 123d85510..ec365d916 100644 --- a/poincare/test/properties.cpp +++ b/poincare/test/properties.cpp @@ -108,7 +108,7 @@ void assert_parsed_expression_has_polynomial_coefficient(const char * expression Expression * e = parse_expression(expression); Expression::Reduce(&e, globalContext, angleUnit); Expression * coefficientBuffer[Poincare::Expression::k_maxNumberOfPolynomialCoefficients]; - int d = e->getPolynomialCoefficients(symbolName, coefficientBuffer, globalContext); + int d = e->getPolynomialCoefficients(symbolName, coefficientBuffer, globalContext, Radian); for (int i = 0; i <= d; i++) { Expression * f = parse_expression(coefficients[i]); Expression::Reduce(&coefficientBuffer[i], globalContext, angleUnit);