diff --git a/apps/graph/graph/calculation_graph_controller.cpp b/apps/graph/graph/calculation_graph_controller.cpp index 2e168bbb5..dcec7a32b 100644 --- a/apps/graph/graph/calculation_graph_controller.cpp +++ b/apps/graph/graph/calculation_graph_controller.cpp @@ -19,7 +19,7 @@ CalculationGraphController::CalculationGraphController(Responder * parentRespond void CalculationGraphController::viewWillAppear() { assert(!m_record.isNull()); - Coordinate2D pointOfInterest = computeNewPointOfInteresetFromAbscissa(m_graphRange->xMin(), 1); + Coordinate2D pointOfInterest = computeNewPointOfInteresetFromAbscissa(m_graphRange->xMin(), 1); if (std::isnan(pointOfInterest.abscissa())) { m_isActive = false; m_graphView->setCursorView(nullptr); @@ -44,7 +44,7 @@ void CalculationGraphController::reloadBannerView() { reloadBannerViewForCursorOnFunction(m_cursor, m_record, functionStore()); } -Coordinate2D CalculationGraphController::computeNewPointOfInteresetFromAbscissa(double start, int direction) { +Coordinate2D CalculationGraphController::computeNewPointOfInteresetFromAbscissa(double start, int direction) { double step = m_graphRange->xGridUnit()/10.0; step = direction < 0 ? -step : step; double max = direction > 0 ? m_graphRange->xMax() : m_graphRange->xMin(); @@ -69,7 +69,7 @@ bool CalculationGraphController::handleEnter() { } bool CalculationGraphController::moveCursorHorizontally(int direction) { - Coordinate2D newPointOfInterest = computeNewPointOfInteresetFromAbscissa(m_cursor->x(), direction); + Coordinate2D newPointOfInterest = computeNewPointOfInteresetFromAbscissa(m_cursor->x(), direction); if (std::isnan(newPointOfInterest.abscissa())) { return false; } diff --git a/apps/graph/graph/calculation_graph_controller.h b/apps/graph/graph/calculation_graph_controller.h index 8b7afdcff..9ba3b8a2c 100644 --- a/apps/graph/graph/calculation_graph_controller.h +++ b/apps/graph/graph/calculation_graph_controller.h @@ -20,9 +20,9 @@ protected: float cursorBottomMarginRatio() override { return 0.15f; } BannerView * bannerView() override { return m_bannerView; } void reloadBannerView() override; - Poincare::Coordinate2D computeNewPointOfInteresetFromAbscissa(double start, int direction); + Poincare::Coordinate2D computeNewPointOfInteresetFromAbscissa(double start, int direction); CartesianFunctionStore * functionStore() const; - virtual Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) = 0; + virtual Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) = 0; GraphView * m_graphView; BannerView * m_bannerView; Shared::InteractiveCurveViewRange * m_graphRange; diff --git a/apps/graph/graph/extremum_graph_controller.cpp b/apps/graph/graph/extremum_graph_controller.cpp index aa84d7e1f..999b211d9 100644 --- a/apps/graph/graph/extremum_graph_controller.cpp +++ b/apps/graph/graph/extremum_graph_controller.cpp @@ -15,7 +15,7 @@ const char * MinimumGraphController::title() { return I18n::translate(I18n::Message::Minimum); } -Coordinate2D MinimumGraphController::computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) { +Coordinate2D MinimumGraphController::computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) { // TODO The following three lines should be factored. constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; @@ -32,7 +32,7 @@ const char * MaximumGraphController::title() { return I18n::translate(I18n::Message::Maximum); } -Coordinate2D MaximumGraphController::computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) { +Coordinate2D MaximumGraphController::computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) { // TODO The following three lines should be factored. constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; diff --git a/apps/graph/graph/extremum_graph_controller.h b/apps/graph/graph/extremum_graph_controller.h index 983336b90..1966faf46 100644 --- a/apps/graph/graph/extremum_graph_controller.h +++ b/apps/graph/graph/extremum_graph_controller.h @@ -10,7 +10,7 @@ public: MinimumGraphController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor); const char * title() override; private: - Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; + Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; }; class MaximumGraphController : public CalculationGraphController { @@ -18,7 +18,7 @@ public: MaximumGraphController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor); const char * title() override; private: - Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; + Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; }; } diff --git a/apps/graph/graph/intersection_graph_controller.cpp b/apps/graph/graph/intersection_graph_controller.cpp index 8ef991990..cb74e6d4a 100644 --- a/apps/graph/graph/intersection_graph_controller.cpp +++ b/apps/graph/graph/intersection_graph_controller.cpp @@ -40,17 +40,17 @@ void IntersectionGraphController::reloadBannerView() { bannerView()->reload(); } -Poincare::Coordinate2D IntersectionGraphController::computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) { +Poincare::Coordinate2D IntersectionGraphController::computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) { // TODO The following three lines should be factored. constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; Poincare::SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknownX); - Poincare::Coordinate2D result = Poincare::Coordinate2D(NAN, NAN); + Poincare::Coordinate2D result = Poincare::Coordinate2D(NAN, NAN); for (int i = 0; i < functionStore()->numberOfActiveFunctions(); i++) { Ion::Storage::Record record = functionStore()->activeRecordAtIndex(i); if (record != m_record) { Poincare::Expression e = functionStore()->modelForRecord(record)->expressionReduced(context); - Poincare::Coordinate2D intersection = Shared::PoincareHelpers::NextIntersection(functionStore()->modelForRecord(m_record)->expressionReduced(context), unknownX, start, step, max, context, e); + Poincare::Coordinate2D intersection = Shared::PoincareHelpers::NextIntersection(functionStore()->modelForRecord(m_record)->expressionReduced(context), unknownX, start, step, max, context, e); if ((std::isnan(result.abscissa()) || std::fabs(intersection.abscissa()-start) < std::fabs(result.abscissa()-start)) && !std::isnan(intersection.abscissa())) { m_intersectedRecord = record; result = (std::isnan(result.abscissa()) || std::fabs(intersection.abscissa()-start) < std::fabs(result.abscissa()-start)) ? intersection : result; diff --git a/apps/graph/graph/intersection_graph_controller.h b/apps/graph/graph/intersection_graph_controller.h index 30c30386a..b4c454145 100644 --- a/apps/graph/graph/intersection_graph_controller.h +++ b/apps/graph/graph/intersection_graph_controller.h @@ -12,7 +12,7 @@ public: const char * title() override; private: void reloadBannerView() override; - Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; + Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; Ion::Storage::Record m_intersectedRecord; }; diff --git a/apps/graph/graph/preimage_graph_controller.cpp b/apps/graph/graph/preimage_graph_controller.cpp index bf0785328..4c705da6c 100644 --- a/apps/graph/graph/preimage_graph_controller.cpp +++ b/apps/graph/graph/preimage_graph_controller.cpp @@ -23,7 +23,7 @@ PreimageGraphController::PreimageGraphController( { } -Poincare::Coordinate2D PreimageGraphController::computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) { +Poincare::Coordinate2D PreimageGraphController::computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) { // TODO The following three lines should be factored. constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; diff --git a/apps/graph/graph/preimage_graph_controller.h b/apps/graph/graph/preimage_graph_controller.h index 67ebdd43c..3de1246f0 100644 --- a/apps/graph/graph/preimage_graph_controller.h +++ b/apps/graph/graph/preimage_graph_controller.h @@ -16,7 +16,7 @@ public: double image() { return m_image; } void setImage(double value) { m_image = value; } private: - Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; + Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; double m_image; }; diff --git a/apps/graph/graph/root_graph_controller.cpp b/apps/graph/graph/root_graph_controller.cpp index e4062447a..dd41713d4 100644 --- a/apps/graph/graph/root_graph_controller.cpp +++ b/apps/graph/graph/root_graph_controller.cpp @@ -16,12 +16,12 @@ const char * RootGraphController::title() { return I18n::translate(I18n::Message::Zeros); } -Coordinate2D RootGraphController::computeNewPointOfInterest(double start, double step, double max, Context * context) { +Coordinate2D RootGraphController::computeNewPointOfInterest(double start, double step, double max, Context * context) { // TODO The following three lines should be factored. constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; Poincare::SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknownX); - return Coordinate2D(Shared::PoincareHelpers::NextRoot(functionStore()->modelForRecord(m_record)->expressionReduced(context), unknownX, start, step, max, context), 0.0); + return Coordinate2D(Shared::PoincareHelpers::NextRoot(functionStore()->modelForRecord(m_record)->expressionReduced(context), unknownX, start, step, max, context), 0.0); } } diff --git a/apps/graph/graph/root_graph_controller.h b/apps/graph/graph/root_graph_controller.h index e76130e76..9a952bc2b 100644 --- a/apps/graph/graph/root_graph_controller.h +++ b/apps/graph/graph/root_graph_controller.h @@ -10,7 +10,7 @@ public: RootGraphController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor); const char * title() override; private: - Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; + Poincare::Coordinate2D computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; }; } diff --git a/apps/probability/distribution/distribution.cpp b/apps/probability/distribution/distribution.cpp index 08c99e410..0ad2091e2 100644 --- a/apps/probability/distribution/distribution.cpp +++ b/apps/probability/distribution/distribution.cpp @@ -111,7 +111,7 @@ double Distribution::cumulativeDistributiveInverseForProbabilityUsingIncreasingF if (*probability <= 0.0) { return -INFINITY; } - Poincare::Coordinate2D result = Poincare::Solver::IncreasingFunctionRoot( + Poincare::Coordinate2D result = Poincare::Solver::IncreasingFunctionRoot( ax, bx, FLT_EPSILON, diff --git a/apps/shared/poincare_helpers.h b/apps/shared/poincare_helpers.h index bc124f49d..6d6407436 100644 --- a/apps/shared/poincare_helpers.h +++ b/apps/shared/poincare_helpers.h @@ -69,13 +69,13 @@ inline void ParseAndSimplifyAndApproximate(const char * text, Poincare::Expressi Poincare::Expression::ParseAndSimplifyAndApproximate(text, simplifiedExpression, approximateExpression, context, complexFormat, preferences->angleUnit(), symbolicComputation); } -inline typename Poincare::Coordinate2D NextMinimum(const Poincare::Expression e, const char * symbol, double start, double step, double max, Poincare::Context * context) { +inline typename Poincare::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::Coordinate2D NextMaximum(const Poincare::Expression e, const char * symbol, double start, double step, double max, Poincare::Context * context) { +inline typename Poincare::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()); @@ -87,7 +87,7 @@ inline double NextRoot(const Poincare::Expression e, const char * symbol, double return e.nextRoot(symbol, start, step, max, context, complexFormat, preferences->angleUnit()); } -inline typename Poincare::Coordinate2D NextIntersection(const Poincare::Expression e, const char * symbol, double start, double step, double max, Poincare::Context * context, const Poincare::Expression expression) { +inline typename Poincare::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); diff --git a/poincare/include/poincare/coordinate_2D.h b/poincare/include/poincare/coordinate_2D.h index 52480fd44..c625f16cb 100644 --- a/poincare/include/poincare/coordinate_2D.h +++ b/poincare/include/poincare/coordinate_2D.h @@ -5,16 +5,17 @@ namespace Poincare { +template class Coordinate2D final { public: - Coordinate2D (double abscissa = NAN, double value = NAN) : m_abscissa(abscissa), m_value(value) {} - double abscissa() const { return m_abscissa; } - double value() const { return m_value; } - void setAbscissa(double a) { m_abscissa = a; } - void setValue(double v) { m_value = v; } + Coordinate2D(T abscissa = NAN, T value = NAN) : m_abscissa(abscissa), m_value(value) {} + T abscissa() const { return m_abscissa; } + T value() const { return m_value; } + void setAbscissa(T a) { m_abscissa = a; } + void setValue(T v) { m_value = v; } private: - double m_abscissa; - double m_value; + T m_abscissa; + T m_value; }; } diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 604fc5c98..155931203 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -241,10 +241,10 @@ public: template static U ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); template U approximateWithValueForSymbol(const char * symbol, U x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; /* Expression roots/extrema solver */ - Coordinate2D nextMinimum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; - Coordinate2D nextMaximum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Coordinate2D nextMinimum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Coordinate2D nextMaximum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; double nextRoot(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; - Coordinate2D nextIntersection(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const; + Coordinate2D nextIntersection(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const; /* This class is meant to contain data about named functions (e.g. sin, tan...) * in one place: their name, their number of children and a pointer to a builder. @@ -391,9 +391,9 @@ private: /* Expression roots/extrema solver*/ constexpr static double k_solverPrecision = 1.0E-5; constexpr static double k_maxFloat = 1e100; - Coordinate2D nextMinimumOfExpression(const char * symbol, double start, double step, double max, Solver::ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression = Expression(), bool lookForRootMinimum = false) const; + Coordinate2D nextMinimumOfExpression(const char * symbol, double start, double step, double max, Solver::ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression = Expression(), bool lookForRootMinimum = false) const; void bracketMinimum(const char * symbol, double start, double step, double max, double result[3], Solver::ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression = Expression()) const; - Coordinate2D brentMinimum(const char * symbol, double ax, double bx, Solver::ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression = Expression()) const; + Coordinate2D brentMinimum(const char * symbol, double ax, double bx, Solver::ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression = Expression()) const; double nextIntersectionWithExpression(const char * symbol, double start, double step, double max, Solver::ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const; void bracketRoot(const char * symbol, double start, double step, double max, double result[2], Solver::ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const; double brentRoot(const char * symbol, double ax, double bx, double precision, Solver::ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const; diff --git a/poincare/include/poincare/solver.h b/poincare/include/poincare/solver.h index 639ef3a0d..fa6a7feeb 100644 --- a/poincare/include/poincare/solver.h +++ b/poincare/include/poincare/solver.h @@ -11,11 +11,11 @@ class Solver { public: // Minimum typedef double (*ValueAtAbscissa)(double abscissa, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1, const void * context2, const void * context3); - static Coordinate2D BrentMinimum(double ax, double bx, ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1 = nullptr, const void * context2 = nullptr, const void * context3 = nullptr); + static Coordinate2D BrentMinimum(double ax, double bx, ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1 = nullptr, const void * context2 = nullptr, const void * context3 = nullptr); // Root static double BrentRoot(double ax, double bx, double precision, ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1 = nullptr, const void * context2 = nullptr, const void * context3 = nullptr); - static Coordinate2D IncreasingFunctionRoot(double ax, double bx, double precision, ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1 = nullptr, const void * context2 = nullptr, const void * context3 = nullptr); + static Coordinate2D IncreasingFunctionRoot(double ax, double bx, double precision, ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1 = nullptr, const void * context2 = nullptr, const void * context3 = nullptr); // Proba diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index dbdd4cc6c..77f019a38 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -873,7 +873,7 @@ Expression Expression::CreateComplexExpression(Expression ra, Expression tb, Pre /* Expression roots/extrema solver*/ -Coordinate2D Expression::nextMinimum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Coordinate2D Expression::nextMinimum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return nextMinimumOfExpression(symbol, start, step, max, [](double x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1, const void * context2, const void * context3) { const Expression * expression0 = reinterpret_cast(context1); @@ -882,14 +882,14 @@ Coordinate2D Expression::nextMinimum(const char * symbol, double start, double s }, context, complexFormat, angleUnit); } -Coordinate2D Expression::nextMaximum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { - Coordinate2D minimumOfOpposite = nextMinimumOfExpression(symbol, start, step, max, +Coordinate2D Expression::nextMaximum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { + Coordinate2D minimumOfOpposite = nextMinimumOfExpression(symbol, start, step, max, [](double x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1, const void * context2, const void * context3) { const Expression * expression0 = reinterpret_cast(context1); const char * symbol = reinterpret_cast(context2); return -expression0->approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit); }, context, complexFormat, angleUnit); - return Coordinate2D(minimumOfOpposite.abscissa(), -minimumOfOpposite.value()); + return Coordinate2D(minimumOfOpposite.abscissa(), -minimumOfOpposite.value()); } double Expression::nextRoot(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { @@ -901,7 +901,7 @@ double Expression::nextRoot(const char * symbol, double start, double step, doub }, context, complexFormat, angleUnit, nullptr); } -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 { +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 { double resultAbscissa = nextIntersectionWithExpression(symbol, start, step, max, [](double x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1, const void * context2, const void * context3) { const Expression * expression0 = reinterpret_cast(context1); @@ -909,15 +909,15 @@ Coordinate2D Expression::nextIntersection(const char * symbol, double start, dou const Expression * expression1 = reinterpret_cast(context3); return expression0->approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit)-expression1->approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit); }, context, complexFormat, angleUnit, expression); - Coordinate2D result(resultAbscissa, approximateWithValueForSymbol(symbol, resultAbscissa, context, complexFormat, angleUnit)); + Coordinate2D result(resultAbscissa, approximateWithValueForSymbol(symbol, resultAbscissa, context, complexFormat, angleUnit)); if (std::fabs(result.value()) < step*k_solverPrecision) { result.setValue(0.0); } return result; } -Coordinate2D Expression::nextMinimumOfExpression(const char * symbol, double start, double step, double max, Solver::ValueAtAbscissa evaluate, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression, bool lookForRootMinimum) const { - Coordinate2D result; +Coordinate2D Expression::nextMinimumOfExpression(const char * symbol, double start, double step, double max, Solver::ValueAtAbscissa evaluate, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression, bool lookForRootMinimum) const { + Coordinate2D result; if (start == max || step == 0.0) { return result; } @@ -954,10 +954,10 @@ Coordinate2D Expression::nextMinimumOfExpression(const char * symbol, double sta } void Expression::bracketMinimum(const char * symbol, double start, double step, double max, double result[3], Solver::ValueAtAbscissa evaluate, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { - Coordinate2D p[3] = { - Coordinate2D(start, evaluate(start, context, complexFormat, angleUnit, this, symbol, &expression)), - Coordinate2D(start+step, evaluate(start+step, context, complexFormat, angleUnit, this, symbol, &expression)), - Coordinate2D() + Coordinate2D p[3] = { + Coordinate2D(start, evaluate(start, context, complexFormat, angleUnit, this, symbol, &expression)), + Coordinate2D(start+step, evaluate(start+step, context, complexFormat, angleUnit, this, symbol, &expression)), + Coordinate2D() }; double x = start+2.0*step; while (step > 0.0 ? x <= max : x >= max) { @@ -984,7 +984,7 @@ void Expression::bracketMinimum(const char * symbol, double start, double step, result[2] = NAN; } -Coordinate2D Expression::brentMinimum(const char * symbol, double ax, double bx, Solver::ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { +Coordinate2D Expression::brentMinimum(const char * symbol, double ax, double bx, Solver::ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { return Solver::BrentMinimum( ax, bx, @@ -1012,7 +1012,7 @@ double Expression::nextIntersectionWithExpression(const char * symbol, double st } while (std::isnan(result) && (step > 0.0 ? x <= max : x >= max)); double extremumMax = std::isnan(result) ? max : result; - Coordinate2D resultExtremum[2] = { + Coordinate2D resultExtremum[2] = { nextMinimumOfExpression(symbol, start, step, extremumMax, [](double x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1, const void * context2, const void * context3) { const Expression * expression0 = reinterpret_cast(context1); diff --git a/poincare/src/solver.cpp b/poincare/src/solver.cpp index fdffd3376..08580bab1 100644 --- a/poincare/src/solver.cpp +++ b/poincare/src/solver.cpp @@ -5,7 +5,7 @@ namespace Poincare { -Coordinate2D Solver::BrentMinimum(double ax, double bx, ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1, const void * context2, const void * context3) { +Coordinate2D Solver::BrentMinimum(double ax, double bx, ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1, const void * context2, const void * context3) { /* Bibliography: R. P. Brent, Algorithms for finding zeros and extrema of * functions without calculating derivatives */ if (ax > bx) { @@ -34,7 +34,7 @@ Coordinate2D Solver::BrentMinimum(double ax, double bx, ValueAtAbscissa evaluati double fa = evaluation(a, context, complexFormat, angleUnit, context1, context2, context3); double fb = evaluation(b, context, complexFormat, angleUnit, context1, context2, context3); if (middleFax-fa <= k_sqrtEps && fx-middleFax <= k_sqrtEps && fx-middleFbx <= k_sqrtEps && middleFbx-fb <= k_sqrtEps) { - return Coordinate2D(x, fx); + return Coordinate2D(x, fx); } } double p = 0; @@ -94,7 +94,7 @@ Coordinate2D Solver::BrentMinimum(double ax, double bx, ValueAtAbscissa evaluati } } } - return Coordinate2D(x, fx); + return Coordinate2D(x, fx); } double Solver::BrentRoot(double ax, double bx, double precision, ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1, const void * context2, const void * context3) { @@ -174,7 +174,7 @@ double Solver::BrentRoot(double ax, double bx, double precision, ValueAtAbscissa return NAN; } -Coordinate2D Solver::IncreasingFunctionRoot(double ax, double bx, double precision, ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1, const void * context2, const void * context3) { +Coordinate2D Solver::IncreasingFunctionRoot(double ax, double bx, double precision, ValueAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const void * context1, const void * context2, const void * context3) { assert(ax < bx); double min = ax; double max = bx; @@ -183,10 +183,10 @@ Coordinate2D Solver::IncreasingFunctionRoot(double ax, double bx, double precisi if (eval >= 0) { if (eval <= DBL_EPSILON) { // The value on the left bracket is 0, return it. - return Coordinate2D(currentAbscissa, eval); + return Coordinate2D(currentAbscissa, eval); } // The minimal value is already bigger than 0, return NAN. - return Coordinate2D(NAN, NAN); + return Coordinate2D(NAN, NAN); } while (max - min > precision) { currentAbscissa = (min + max) / 2.0; @@ -200,9 +200,9 @@ Coordinate2D Solver::IncreasingFunctionRoot(double ax, double bx, double precisi } } if (std::fabs(eval) < precision) { - return Coordinate2D(currentAbscissa, eval); + return Coordinate2D(currentAbscissa, eval); } - return Coordinate2D(NAN, NAN); + return Coordinate2D(NAN, NAN); } template diff --git a/poincare/test/function_solver.cpp b/poincare/test/function_solver.cpp index 0523a6afd..7ede9e044 100644 --- a/poincare/test/function_solver.cpp +++ b/poincare/test/function_solver.cpp @@ -24,7 +24,7 @@ bool doubles_are_approximately_equal(double d1, double d2) { void assert_next_extrema_are( ExtremumType extremumType, int numberOfExtrema, - Coordinate2D * extrema, + Coordinate2D * extrema, Expression e, const char * symbol, Context * context, @@ -37,13 +37,13 @@ void assert_next_extrema_are( double currentStart = start; for (int i = 0; i < numberOfExtrema; i++) { quiz_assert_log_if_failure(!std::isnan(currentStart), e); - Coordinate2D nextExtrema; + Coordinate2D nextExtrema; if (extremumType == ExtremumType::Maximum) { nextExtrema = e.nextMaximum(symbol, currentStart, step, max, context, complexFormat, angleUnit); } else if (extremumType == ExtremumType::Minimum) { nextExtrema = e.nextMinimum(symbol, currentStart, step, max, context, complexFormat, angleUnit); } else if (extremumType == ExtremumType::Root) { - nextExtrema = Coordinate2D(e.nextRoot(symbol, currentStart, step, max, context, complexFormat, angleUnit), 0.0 ); + nextExtrema = Coordinate2D(e.nextRoot(symbol, currentStart, step, max, context, complexFormat, angleUnit), 0.0 ); } currentStart = nextExtrema.abscissa() + step; quiz_assert_log_if_failure( @@ -62,16 +62,16 @@ QUIZ_CASE(poincare_function_extremum) { Expression e = Cosine::Builder(Symbol::Builder(symbol, symbolLength)); { constexpr int numberOfMaxima = 3; - Coordinate2D maxima[numberOfMaxima] = { - Coordinate2D(0.0, 1.0), - Coordinate2D(360.0, 1.0), - Coordinate2D(NAN, NAN)}; + Coordinate2D maxima[numberOfMaxima] = { + Coordinate2D(0.0, 1.0), + Coordinate2D(360.0, 1.0), + Coordinate2D(NAN, NAN)}; assert_next_extrema_are(ExtremumType::Maximum, numberOfMaxima, maxima, e, symbol, &globalContext, -1.0, 0.1, 500.0); } { constexpr int numberOfMinima = 1; - Coordinate2D minima[numberOfMinima] = { - Coordinate2D(180.0, -1.0)}; + Coordinate2D minima[numberOfMinima] = { + Coordinate2D(180.0, -1.0)}; assert_next_extrema_are(ExtremumType::Minimum, numberOfMinima, minima, e, symbol, &globalContext, 0.0, 0.1, 300.0); } } @@ -80,14 +80,14 @@ QUIZ_CASE(poincare_function_extremum) { Expression e = Power::Builder(Symbol::Builder(symbol, symbolLength), Rational::Builder(2)); { constexpr int numberOfMaxima = 1; - Coordinate2D maxima[numberOfMaxima] = { - Coordinate2D(NAN, NAN)}; + Coordinate2D maxima[numberOfMaxima] = { + Coordinate2D(NAN, NAN)}; assert_next_extrema_are(ExtremumType::Maximum, numberOfMaxima, maxima, e, symbol, &globalContext); } { constexpr int numberOfMinima = 1; - Coordinate2D minima[numberOfMinima] = { - Coordinate2D(0.0, 0.0)}; + Coordinate2D minima[numberOfMinima] = { + Coordinate2D(0.0, 0.0)}; assert_next_extrema_are(ExtremumType::Minimum, numberOfMinima, minima, e, symbol, &globalContext); } } @@ -97,14 +97,14 @@ QUIZ_CASE(poincare_function_extremum) { Expression e = Rational::Builder(3); { constexpr int numberOfMaxima = 1; - Coordinate2D maxima[numberOfMaxima] = { - Coordinate2D(NAN, 3.0)}; + Coordinate2D maxima[numberOfMaxima] = { + Coordinate2D(NAN, 3.0)}; assert_next_extrema_are(ExtremumType::Maximum, numberOfMaxima, maxima, e, symbol, &globalContext); } { constexpr int numberOfMinima = 1; - Coordinate2D minima[numberOfMinima] = { - Coordinate2D(NAN, 3.0)}; + Coordinate2D minima[numberOfMinima] = { + Coordinate2D(NAN, 3.0)}; assert_next_extrema_are(ExtremumType::Minimum, numberOfMinima, minima, e, symbol, &globalContext); } } @@ -114,14 +114,14 @@ QUIZ_CASE(poincare_function_extremum) { Expression e = Rational::Builder(0); { constexpr int numberOfMaxima = 1; - Coordinate2D maxima[numberOfMaxima] = { - Coordinate2D(NAN, 0.0)}; + Coordinate2D maxima[numberOfMaxima] = { + Coordinate2D(NAN, 0.0)}; assert_next_extrema_are(ExtremumType::Maximum, numberOfMaxima, maxima, e, symbol, &globalContext); } { constexpr int numberOfMinima = 1; - Coordinate2D minima[numberOfMinima] = { - Coordinate2D(NAN, 0.0)}; + Coordinate2D minima[numberOfMinima] = { + Coordinate2D(NAN, 0.0)}; assert_next_extrema_are(ExtremumType::Minimum, numberOfMinima, minima, e, symbol, &globalContext); } } @@ -135,35 +135,35 @@ QUIZ_CASE(poincare_function_root) { // cos Expression e = Cosine::Builder(Symbol::Builder(symbol, symbolLength)); constexpr int numberOfRoots = 3; - Coordinate2D roots[numberOfRoots] = { - Coordinate2D(90.0, 0.0), - Coordinate2D(270.0, 0.0), - Coordinate2D(450.0, 0.0)}; + Coordinate2D roots[numberOfRoots] = { + Coordinate2D(90.0, 0.0), + Coordinate2D(270.0, 0.0), + Coordinate2D(450.0, 0.0)}; assert_next_extrema_are(ExtremumType::Root, numberOfRoots, roots, e, symbol, &globalContext, 0.0, 0.1, 500.0); } { // x^2 Expression e = Power::Builder(Symbol::Builder(symbol, symbolLength), Rational::Builder(2)); constexpr int numberOfRoots = 1; - Coordinate2D roots[numberOfRoots] = { - Coordinate2D(0.0, 0.0)}; + Coordinate2D roots[numberOfRoots] = { + Coordinate2D(0.0, 0.0)}; assert_next_extrema_are(ExtremumType::Root, numberOfRoots, roots, e, symbol, &globalContext); } { // x^2-4 Expression e = Subtraction::Builder(Power::Builder(Symbol::Builder(symbol, symbolLength), Rational::Builder(2)), Rational::Builder(4)); constexpr int numberOfRoots = 2; - Coordinate2D roots[numberOfRoots] = { - Coordinate2D(-2.0, 0.0), - Coordinate2D(2.0, 0.0)}; + Coordinate2D roots[numberOfRoots] = { + Coordinate2D(-2.0, 0.0), + Coordinate2D(2.0, 0.0)}; assert_next_extrema_are(ExtremumType::Root, numberOfRoots, roots, e, symbol, &globalContext, -5.0); } { // 3 Expression e = Rational::Builder(3); constexpr int numberOfRoots = 1; - Coordinate2D roots[numberOfRoots] = { - Coordinate2D(NAN, 0.0)}; + Coordinate2D roots[numberOfRoots] = { + Coordinate2D(NAN, 0.0)}; assert_next_extrema_are(ExtremumType::Root, numberOfRoots, roots, e, symbol, &globalContext); } @@ -171,8 +171,8 @@ QUIZ_CASE(poincare_function_root) { // 0 Expression e = Rational::Builder(0); constexpr int numberOfRoots = 1; - Coordinate2D roots[numberOfRoots] = { - Coordinate2D(-0.9, 0.0)}; + Coordinate2D roots[numberOfRoots] = { + Coordinate2D(-0.9, 0.0)}; assert_next_extrema_are(ExtremumType::Root, numberOfRoots, roots, e, symbol, &globalContext); } @@ -181,7 +181,7 @@ QUIZ_CASE(poincare_function_root) { void assert_next_intersections_are( Expression otherExpression, int numberOfIntersections, - Coordinate2D * intersections, + Coordinate2D * intersections, Expression e, const char * symbol, Context * context, @@ -194,7 +194,7 @@ void assert_next_intersections_are( double currentStart = start; for (int i = 0; i < numberOfIntersections; i++) { quiz_assert_log_if_failure(!std::isnan(currentStart), e); - Coordinate2D nextIntersection = e.nextIntersection(symbol, currentStart, step, max, context, complexFormat, angleUnit, otherExpression); + Coordinate2D nextIntersection = e.nextIntersection(symbol, currentStart, step, max, context, complexFormat, angleUnit, otherExpression); currentStart = nextIntersection.abscissa() + step; quiz_assert_log_if_failure( (doubles_are_approximately_equal(intersections[i].abscissa(), nextIntersection.abscissa())) @@ -212,8 +212,8 @@ QUIZ_CASE(poincare_function_intersection) { // cos with y=2 Expression otherExpression = Rational::Builder(2); constexpr int numberOfIntersections = 1; - Coordinate2D intersections[numberOfIntersections] = { - Coordinate2D(NAN, NAN)}; + Coordinate2D intersections[numberOfIntersections] = { + Coordinate2D(NAN, NAN)}; assert_next_intersections_are(otherExpression, numberOfIntersections, intersections, e, symbol, &globalContext); } @@ -221,9 +221,9 @@ QUIZ_CASE(poincare_function_intersection) { // cos with y=1 Expression otherExpression = Rational::Builder(1); constexpr int numberOfIntersections = 2; - Coordinate2D intersections[numberOfIntersections] = { - Coordinate2D(0.0, 1.0), - Coordinate2D(360.0, 1.0)}; + Coordinate2D intersections[numberOfIntersections] = { + Coordinate2D(0.0, 1.0), + Coordinate2D(360.0, 1.0)}; assert_next_intersections_are(otherExpression, numberOfIntersections, intersections, e, symbol, &globalContext); } @@ -231,10 +231,10 @@ QUIZ_CASE(poincare_function_intersection) { // cos with y=0 Expression otherExpression = Rational::Builder(0); constexpr int numberOfIntersections = 3; - Coordinate2D intersections[numberOfIntersections] = { - Coordinate2D(90.0, 0.0), - Coordinate2D(270.0, 0.0), - Coordinate2D(450.0, 0.0)}; + Coordinate2D intersections[numberOfIntersections] = { + Coordinate2D(90.0, 0.0), + Coordinate2D(270.0, 0.0), + Coordinate2D(450.0, 0.0)}; assert_next_intersections_are(otherExpression, numberOfIntersections, intersections, e, symbol, &globalContext); } }