From fe8825df355c528a7957b945553ae6ca81c9ea88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 27 Dec 2018 15:08:12 +0100 Subject: [PATCH] [shared] PoincareHelpers: update the complexFormat (force it to Cartesian with complex input). --- apps/calculation/calculation.cpp | 3 +- apps/regression/model/model.cpp | 2 +- apps/shared/poincare_helpers.h | 51 +++++++++++++++------- apps/shared/storage_cartesian_function.cpp | 12 ++--- apps/solver/equation_store.cpp | 12 +++-- poincare/src/expression.cpp | 11 ++--- 6 files changed, 50 insertions(+), 41 deletions(-) diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index 36365d3d5..c98c20c34 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -181,7 +181,8 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual( if (exactOutputExpression.isUninitialized()) { exactOutputExpression = Undefined(); } - m_equalSign = exactOutputExpression.isEqualToItsApproximationLayout(approximateOutput(context), buffer, bufferSize, preferences->complexFormat(), preferences->angleUnit(), preferences->displayMode(), preferences->numberOfSignificantDigits(), *context) ? EqualSign::Equal : EqualSign::Approximation; + Preferences::ComplexFormat complexFormat = Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), m_inputText); + m_equalSign = exactOutputExpression.isEqualToItsApproximationLayout(approximateOutput(context), buffer, bufferSize, complexFormat, preferences->angleUnit(), preferences->displayMode(), preferences->numberOfSignificantDigits(), *context) ? EqualSign::Equal : EqualSign::Approximation; return m_equalSign; } diff --git a/apps/regression/model/model.cpp b/apps/regression/model/model.cpp index fb62cd1b0..867a88266 100644 --- a/apps/regression/model/model.cpp +++ b/apps/regression/model/model.cpp @@ -20,7 +20,7 @@ double Model::levelSet(double * modelCoefficients, double xMin, double step, dou PoincareHelpers::Simplify(&yExpression, *context); Expression modelExpression = simplifiedExpression(modelCoefficients, context); Preferences * preferences = Preferences::sharedPreferences(); - double result = modelExpression.nextIntersection("x", xMin, step, xMax, *context, preferences->complexFormat(), preferences->angleUnit(), yExpression).abscissa; + double result = PoincareHelpers::NextIntersection(modelExpression, "x", xMin, step, xMax, *context, yExpression).abscissa; return result; } diff --git a/apps/shared/poincare_helpers.h b/apps/shared/poincare_helpers.h index da42565a3..af2d43fa8 100644 --- a/apps/shared/poincare_helpers.h +++ b/apps/shared/poincare_helpers.h @@ -26,52 +26,72 @@ inline int Serialize(const Poincare::Expression e, char * buffer, int bufferSize template inline Poincare::Expression Approximate(const Poincare::Expression e, Poincare::Context & context) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); - Poincare::Preferences::ComplexFormat complexFormat = preferences->complexFormat(); - complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(complexFormat, e, context); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), e, context); return e.approximate(context, complexFormat, preferences->angleUnit()); } template inline T ApproximateToScalar(const Poincare::Expression e, Poincare::Context & context) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); - Poincare::Preferences::ComplexFormat complexFormat = preferences->complexFormat(); - complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(complexFormat, e, context); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), e, context); return e.approximateToScalar(context, complexFormat, preferences->angleUnit()); } template inline T ApproximateWithValueForSymbol(const Poincare::Expression e, const char * symbol, T x, Poincare::Context & context) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); - Poincare::Preferences::ComplexFormat complexFormat = preferences->complexFormat(); - complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(complexFormat, e, context); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), e, context); return e.approximateWithValueForSymbol(symbol, x, context, complexFormat, preferences->angleUnit()); } template inline T ApproximateToScalar(const char * text, Poincare::Context & context) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); - Poincare::Preferences::ComplexFormat complexFormat = preferences->complexFormat(); - complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(complexFormat, text); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text); return Poincare::Expression::approximateToScalar(text, context, complexFormat, preferences->angleUnit()); } inline Poincare::Expression ParseAndSimplify(const char * text, Poincare::Context & context) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); - return Poincare::Expression::ParseAndSimplify(text, context, preferences->complexFormat(), preferences->angleUnit()); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text); + return Poincare::Expression::ParseAndSimplify(text, context, complexFormat, preferences->angleUnit()); } -inline void Simplify(Poincare::Expression * e, Poincare::Context & context, Poincare::Preferences::ComplexFormat complexFormat = Poincare::Preferences::sharedPreferences()->complexFormat()) { - complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(complexFormat, *e, context); - *e = e->simplify(context, complexFormat, Poincare::Preferences::sharedPreferences()->angleUnit()); +inline void Simplify(Poincare::Expression * e, Poincare::Context & context) { + Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), *e, context); + *e = e->simplify(context, complexFormat, preferences->angleUnit()); } inline void ParseAndSimplifyAndApproximate(const char * text, Poincare::Expression * simplifiedExpression, Poincare::Expression * approximateExpression, Poincare::Context & context) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); - Poincare::Expression::ParseAndSimplifyAndApproximate(text, simplifiedExpression, approximateExpression, context, preferences->complexFormat(), preferences->angleUnit()); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text); + Poincare::Expression::ParseAndSimplifyAndApproximate(text, simplifiedExpression, approximateExpression, context, complexFormat, preferences->angleUnit()); } -inline void SimplifyAndApproximate(Poincare::Expression * e, Poincare::Expression * approximate, Poincare::Context & context, Poincare::Preferences::ComplexFormat complexFormat = Poincare::Preferences::sharedPreferences()->complexFormat()) { - e->simplifyAndApproximate(e, approximate, context, complexFormat, Poincare::Preferences::sharedPreferences()->angleUnit()); +inline typename Poincare::Expression::Coordinate2D NextMinimum(const Poincare::Expression e, const char * symbol, double start, double step, double max, Poincare::Context & context) { + Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), e, context); + return e.nextMinimum(symbol, start, step, max, context, complexFormat, preferences->angleUnit()); +} + +inline typename Poincare::Expression::Coordinate2D NextMaximum(const Poincare::Expression e, const char * symbol, double start, double step, double max, Poincare::Context & context) { + Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), e, context); + return e.nextMaximum(symbol, start, step, max, context, complexFormat, preferences->angleUnit()); +} + +inline double NextRoot(const Poincare::Expression e, const char * symbol, double start, double step, double max, Poincare::Context & context) { + Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), e, context); + return e.nextRoot(symbol, start, step, max, context, complexFormat, preferences->angleUnit()); +} + +inline typename Poincare::Expression::Coordinate2D NextIntersection(const Poincare::Expression e, const char * symbol, double start, double step, double max, Poincare::Context & context, const Poincare::Expression expression) { + Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); + Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), e, context); + complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(complexFormat, expression, context); + return e.nextIntersection(symbol, start, step, max, context, complexFormat, preferences->angleUnit(), expression); } } @@ -79,4 +99,3 @@ inline void SimplifyAndApproximate(Poincare::Expression * e, Poincare::Expressio } #endif - diff --git a/apps/shared/storage_cartesian_function.cpp b/apps/shared/storage_cartesian_function.cpp index 1dc520041..ff46ec7cb 100644 --- a/apps/shared/storage_cartesian_function.cpp +++ b/apps/shared/storage_cartesian_function.cpp @@ -103,26 +103,22 @@ double StorageCartesianFunction::sumBetweenBounds(double start, double end, Poin Expression::Coordinate2D StorageCartesianFunction::nextMinimumFrom(double start, double step, double max, Context * context) const { const char unknownX[2] = {Poincare::Symbol::UnknownX, 0}; - Preferences * preferences = Preferences::sharedPreferences(); - return expressionReduced(context).nextMinimum(unknownX, start, step, max, *context, preferences->complexFormat(), preferences->angleUnit()); + return PoincareHelpers::NextMinimum(expressionReduced(context), unknownX, start, step, max, *context); } Expression::Coordinate2D StorageCartesianFunction::nextMaximumFrom(double start, double step, double max, Context * context) const { const char unknownX[2] = {Poincare::Symbol::UnknownX, 0}; - Preferences * preferences = Preferences::sharedPreferences(); - return expressionReduced(context).nextMaximum(unknownX, start, step, max, *context, preferences->complexFormat(), preferences->angleUnit()); + return PoincareHelpers::NextMaximum(expressionReduced(context), unknownX, start, step, max, *context); } double StorageCartesianFunction::nextRootFrom(double start, double step, double max, Context * context) const { const char unknownX[2] = {Poincare::Symbol::UnknownX, 0}; - Preferences * preferences = Preferences::sharedPreferences(); - return expressionReduced(context).nextRoot(unknownX, start, step, max, *context, preferences->complexFormat(), preferences->angleUnit()); + return PoincareHelpers::NextRoot(expressionReduced(context), unknownX, start, step, max, *context); } Expression::Coordinate2D StorageCartesianFunction::nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, Expression e) const { const char unknownX[2] = {Poincare::Symbol::UnknownX, 0}; - Preferences * preferences = Preferences::sharedPreferences(); - return expressionReduced(context).nextIntersection(unknownX, start, step, max, *context, preferences->complexFormat(), preferences->angleUnit(), e); + return PoincareHelpers::NextIntersection(expressionReduced(context), unknownX, start, step, max, *context, e); } StorageCartesianFunction::CartesianFunctionRecordData * StorageCartesianFunction::recordData() const { diff --git a/apps/solver/equation_store.cpp b/apps/solver/equation_store.cpp index 97b66eaf1..1becac586 100644 --- a/apps/solver/equation_store.cpp +++ b/apps/solver/equation_store.cpp @@ -78,8 +78,7 @@ bool EquationStore::haveMoreApproximationSolutions(Context * context) { return false; } double step = (m_intervalApproximateSolutions[1]-m_intervalApproximateSolutions[0])*k_precision; - Preferences * preferences = Preferences::sharedPreferences(); - return !std::isnan(definedModelAtIndex(0)->standardForm(context).nextRoot(m_variables[0], m_approximateSolutions[m_numberOfSolutions-1], step, m_intervalApproximateSolutions[1], *context, preferences->complexFormat(), preferences->angleUnit())); + return !std::isnan(PoincareHelpers::NextRoot(definedModelAtIndex(0)->standardForm(context), m_variables[0], m_approximateSolutions[m_numberOfSolutions-1], step, m_intervalApproximateSolutions[1], *context)); } void EquationStore::approximateSolve(Poincare::Context * context) { @@ -88,9 +87,8 @@ void EquationStore::approximateSolve(Poincare::Context * context) { m_numberOfSolutions = 0; double start = m_intervalApproximateSolutions[0]; double step = (m_intervalApproximateSolutions[1]-m_intervalApproximateSolutions[0])*k_precision; - Preferences * preferences = Preferences::sharedPreferences(); 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, preferences->complexFormat(), preferences->angleUnit()); + m_approximateSolutions[i] = PoincareHelpers::NextRoot(definedModelAtIndex(0)->standardForm(context), m_variables[0], start, step, m_intervalApproximateSolutions[1], *context); if (std::isnan(m_approximateSolutions[i])) { break; } else { @@ -252,7 +250,7 @@ EquationStore::Error EquationStore::resolveLinearSystem(Expression exactSolution m_numberOfSolutions = n; for (int i = 0; i < m_numberOfSolutions; i++) { exactSolutions[i] = Ab.matrixChild(i,n); - PoincareHelpers::SimplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], *context, updatedComplexFormat()); + exactSolutions[i].simplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], *context, updatedComplexFormat(), Poincare::Preferences::sharedPreferences()->angleUnit()); } } } @@ -264,7 +262,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact assert(degree == 2); // Compute delta = b*b-4ac Expression delta = Subtraction(Power(coefficients[1].clone(), Rational(2)), Multiplication(Rational(4), coefficients[0].clone(), coefficients[2].clone())); - PoincareHelpers::Simplify(&delta, *context, updatedComplexFormat()); + delta = delta.simplify(*context, updatedComplexFormat(), Poincare::Preferences::sharedPreferences()->angleUnit()); if (delta.isUninitialized()) { delta = Poincare::Undefined(); } @@ -281,7 +279,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact } exactSolutions[m_numberOfSolutions] = delta; for (int i = 0; i <= m_numberOfSolutions; i++) { - PoincareHelpers::SimplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], *context, updatedComplexFormat()); + exactSolutions[i].simplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], *context, updatedComplexFormat(), Poincare::Preferences::sharedPreferences()->angleUnit()); } return Error::NoError; #if 0 diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index a2e0d9c80..96dd82867 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -383,7 +383,7 @@ Expression Expression::ParseAndSimplify(const char * text, Context & context, Pr if (exp.isUninitialized()) { return Undefined(); } - exp = exp.simplify(context, UpdatedComplexFormatWithTextInput(complexFormat, text), angleUnit); + exp = exp.simplify(context, complexFormat, angleUnit); /* simplify might have been interrupted, in which case the resulting * expression is uninitialized, so we need to check that. */ if (exp.isUninitialized()) { @@ -400,7 +400,7 @@ void Expression::ParseAndSimplifyAndApproximate(const char * text, Expression * *approximateExpression = Undefined(); return; } - exp.simplifyAndApproximate(simplifiedExpression, approximateExpression, context, UpdatedComplexFormatWithTextInput(complexFormat, text), angleUnit); + exp.simplifyAndApproximate(simplifiedExpression, approximateExpression, context, complexFormat, angleUnit); /* simplify might have been interrupted, in which case the resulting * expression is uninitialized, so we need to check that. */ if (simplifiedExpression->isUninitialized()) { @@ -568,7 +568,7 @@ U Expression::approximateToScalar(Context& context, Preferences::ComplexFormat c template U Expression::approximateToScalar(const char * text, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { - Expression exp = ParseAndSimplify(text, context, UpdatedComplexFormatWithTextInput(complexFormat, text), angleUnit); + Expression exp = ParseAndSimplify(text, context, complexFormat, angleUnit); assert(!exp.isUninitialized()); return exp.approximateToScalar(context, complexFormat, angleUnit); } @@ -673,14 +673,12 @@ Expression Expression::CreateComplexExpression(Expression ra, Expression tb, Pre /* Expression roots/extrema solver*/ typename Expression::Coordinate2D Expression::nextMinimum(const char * symbol, double start, double step, double max, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { - complexFormat = UpdatedComplexFormatWithExpressionInput(complexFormat, *this, context); return nextMinimumOfExpression(symbol, start, step, max, [](const char * symbol, double x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1 = Expression()) { return expression0.approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit); }, context, complexFormat, angleUnit); } typename Expression::Coordinate2D Expression::nextMaximum(const char * symbol, double start, double step, double max, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { - complexFormat = UpdatedComplexFormatWithExpressionInput(complexFormat, *this, context); Coordinate2D minimumOfOpposite = nextMinimumOfExpression(symbol, start, step, max, [](const char * symbol, double x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1 = Expression()) { return -expression0.approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit); }, context, complexFormat, angleUnit); @@ -688,15 +686,12 @@ typename Expression::Coordinate2D Expression::nextMaximum(const char * symbol, d } double Expression::nextRoot(const char * symbol, double start, double step, double max, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { - complexFormat = UpdatedComplexFormatWithExpressionInput(complexFormat, *this, context); return nextIntersectionWithExpression(symbol, start, step, max, [](const char * symbol, double x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1 = Expression()) { return expression0.approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit); }, context, complexFormat, angleUnit, nullptr); } typename Expression::Coordinate2D Expression::nextIntersection(const char * symbol, double start, double step, double max, Poincare::Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { - complexFormat = UpdatedComplexFormatWithExpressionInput(complexFormat, *this, context); - complexFormat = UpdatedComplexFormatWithExpressionInput(complexFormat, expression, context); double resultAbscissa = nextIntersectionWithExpression(symbol, start, step, max, [](const char * symbol, double x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { return expression0.approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit)-expression1.approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit); }, context, complexFormat, angleUnit, expression);