diff --git a/apps/graph/cartesian_function.cpp b/apps/graph/cartesian_function.cpp index 1a5fb6c87..73cfc7327 100644 --- a/apps/graph/cartesian_function.cpp +++ b/apps/graph/cartesian_function.cpp @@ -57,8 +57,4 @@ Expression::Coordinate2D CartesianFunction::nextIntersectionFrom(double start, d return expression(context).nextIntersection(symbol(), start, step, max, *context, Preferences::sharedPreferences()->angleUnit(), function->expression(context)); } -char CartesianFunction::symbol() const { - return 'x'; -} - } diff --git a/apps/graph/cartesian_function.h b/apps/graph/cartesian_function.h index 9015ad7dd..b9339d68e 100644 --- a/apps/graph/cartesian_function.h +++ b/apps/graph/cartesian_function.h @@ -17,7 +17,7 @@ public: Poincare::Expression::Coordinate2D nextMaximumFrom(double start, double step, double max, Poincare::Context * context) const; double nextRootFrom(double start, double step, double max, Poincare::Context * context) const; Poincare::Expression::Coordinate2D nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, const Shared::Function * function) const; - char symbol() const override; + const char * symbol() const override { return "x"; } private: bool m_displayDerivative; }; diff --git a/apps/sequence/sequence.cpp b/apps/sequence/sequence.cpp index cae5ba05a..38d743563 100644 --- a/apps/sequence/sequence.cpp +++ b/apps/sequence/sequence.cpp @@ -140,10 +140,6 @@ void Sequence::setSecondInitialConditionContent(const char * c) { m_secondInitialConditionLayout = Layout(); } -char Sequence::symbol() const { - return 'n'; -} - int Sequence::numberOfElements() { return (int)m_type + 1; } diff --git a/apps/sequence/sequence.h b/apps/sequence/sequence.h index 1f6416e85..54209258b 100644 --- a/apps/sequence/sequence.h +++ b/apps/sequence/sequence.h @@ -54,7 +54,7 @@ private: constexpr static double k_maxNumberOfTermsInSum = 100000.0; constexpr static size_t k_dataLengthInBytes = (3*TextField::maxBufferSize()+3)*sizeof(char)+sizeof(int)+1; static_assert((k_dataLengthInBytes & 0x3) == 0, "The sequence data size is not a multiple of 4 bytes (cannot compute crc)"); // Assert that dataLengthInBytes is a multiple of 4 - char symbol() const override; + const char * symbol() const override { return "n"; } template T templatedApproximateAtAbscissa(T x, SequenceContext * sqctx) const; Type m_type; char m_firstInitialConditionText[TextField::maxBufferSize()]; diff --git a/apps/shared/function.h b/apps/shared/function.h index 74e83e418..41a503ff3 100644 --- a/apps/shared/function.h +++ b/apps/shared/function.h @@ -25,7 +25,7 @@ private: constexpr static size_t k_dataLengthInBytes = (TextField::maxBufferSize()+2)*sizeof(char)+2; static_assert((k_dataLengthInBytes & 0x3) == 0, "The function data size is not a multiple of 4 bytes (cannot compute crc)"); // Assert that dataLengthInBytes is a multiple of 4 template T templatedApproximateAtAbscissa(T x, Poincare::Context * context) const; - virtual char symbol() const = 0; + virtual const char * symbol() const = 0; const char * m_name; KDColor m_color; bool m_active; diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index a22b91802..2ebc40a5a 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -169,16 +169,16 @@ public: template Expression approximate(Context& context, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat) const; template U approximateToScalar(Context& context, Preferences::AngleUnit angleUnit) const; template static U approximateToScalar(const char * text, Context& context, Preferences::AngleUnit angleUnit); - template U approximateWithValueForSymbol(char symbol, U x, Context & context, Preferences::AngleUnit angleUnit) const; + template U approximateWithValueForSymbol(const char * symbol, U x, Context & context, Preferences::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, Preferences::AngleUnit angleUnit) const; - Coordinate2D nextMaximum(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const; - double nextRoot(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const; - Coordinate2D nextIntersection(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const; + Coordinate2D nextMinimum(const char * symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const; + Coordinate2D nextMaximum(const char * symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const; + double nextRoot(const char * symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const; + Coordinate2D nextIntersection(const char * symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const; protected: Expression(const ExpressionNode * n) : TreeHandle(n) {} @@ -241,13 +241,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, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1); - Coordinate2D nextMinimumOfExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression = Expression(), bool lookForRootMinimum = false) const; - void bracketMinimum(char symbol, double start, double step, double max, double result[3], EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression = Expression()) const; - Coordinate2D brentMinimum(char symbol, double ax, double bx, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression = Expression()) const; - double nextIntersectionWithExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const; - void bracketRoot(char symbol, double start, double step, double max, double result[2], EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const; - double brentRoot(char symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const; + typedef double (*EvaluationAtAbscissa)(const char * symbol, double abscissa, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1); + Coordinate2D nextMinimumOfExpression(const char * symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, 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], EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression = Expression()) const; + Coordinate2D brentMinimum(const char * symbol, double ax, double bx, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression = Expression()) const; + double nextIntersectionWithExpression(const char * symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const; + void bracketRoot(const char * symbol, double start, double step, double max, double result[2], EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const; + double brentRoot(const char * symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const; }; } diff --git a/poincare/src/derivative.cpp b/poincare/src/derivative.cpp index c37b93f01..fdf8d59b4 100644 --- a/poincare/src/derivative.cpp +++ b/poincare/src/derivative.cpp @@ -29,7 +29,7 @@ Evaluation DerivativeNode::templatedApproximate(Context& context, Preferences static T epsilon = sizeof(T) == sizeof(double) ? DBL_EPSILON : FLT_EPSILON; Evaluation xInput = childAtIndex(1)->approximate(T(), context, angleUnit); T x = xInput.toScalar(); - T functionValue = Expression(childAtIndex(0)).approximateWithValueForSymbol('x', x, context, angleUnit); + T functionValue = Expression(childAtIndex(0)).approximateWithValueForSymbol("x", x, context, angleUnit); // No complex/matrix version of Derivative if (std::isnan(x) || std::isnan(functionValue)) { return Complex::Undefined(); @@ -55,8 +55,8 @@ Evaluation DerivativeNode::templatedApproximate(Context& context, Preferences template T DerivativeNode::growthRateAroundAbscissa(T x, T h, Context & context, Preferences::AngleUnit angleUnit) const { - T expressionPlus = Expression(childAtIndex(0)).approximateWithValueForSymbol('x', x+h, context, angleUnit); - T expressionMinus = Expression(childAtIndex(0)).approximateWithValueForSymbol('x', x-h, context, angleUnit); + T expressionPlus = Expression(childAtIndex(0)).approximateWithValueForSymbol("x", x+h, context, angleUnit); + T expressionMinus = Expression(childAtIndex(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 ebb6afac0..d77e9239f 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -310,7 +310,7 @@ U Expression::approximateToScalar(const char * text, Context& context, Preferenc } template -U Expression::approximateWithValueForSymbol(char symbol, U x, Context & context, Preferences::AngleUnit angleUnit) const { +U Expression::approximateWithValueForSymbol(const char * symbol, U x, Context & context, Preferences::AngleUnit angleUnit) const { VariableContext variableContext = VariableContext(symbol, &context); variableContext.setApproximationForVariable(x); return approximateToScalar(variableContext, angleUnit); @@ -324,27 +324,27 @@ U Expression::epsilon() { /* Expression roots/extrema solver*/ -typename Expression::Coordinate2D Expression::nextMinimum(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const { - return nextMinimumOfExpression(symbol, start, step, max, [](char symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1 = Expression()) { +typename Expression::Coordinate2D Expression::nextMinimum(const char * symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const { + return nextMinimumOfExpression(symbol, start, step, max, [](const char * symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1 = Expression()) { return expression0.approximateWithValueForSymbol(symbol, x, context, angleUnit); }, context, angleUnit); } -typename Expression::Coordinate2D Expression::nextMaximum(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const { - Coordinate2D minimumOfOpposite = nextMinimumOfExpression(symbol, start, step, max, [](char symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1 = Expression()) { +typename Expression::Coordinate2D Expression::nextMaximum(const char * symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const { + Coordinate2D minimumOfOpposite = nextMinimumOfExpression(symbol, start, step, max, [](const char * symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1 = Expression()) { 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, Preferences::AngleUnit angleUnit) const { - return nextIntersectionWithExpression(symbol, start, step, max, [](char symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1 = Expression()) { +double Expression::nextRoot(const char * symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const { + return nextIntersectionWithExpression(symbol, start, step, max, [](const char * symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1 = Expression()) { return expression0.approximateWithValueForSymbol(symbol, x, context, angleUnit); }, context, angleUnit, nullptr); } -typename Expression::Coordinate2D Expression::nextIntersection(char symbol, double start, double step, double max, Poincare::Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { - double resultAbscissa = nextIntersectionWithExpression(symbol, start, step, max, [](char symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { +typename Expression::Coordinate2D Expression::nextIntersection(const char * symbol, double start, double step, double max, Poincare::Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { + double resultAbscissa = nextIntersectionWithExpression(symbol, start, step, max, [](const char * symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { return expression0.approximateWithValueForSymbol(symbol, x, context, angleUnit)-expression1.approximateWithValueForSymbol(symbol, x, context, angleUnit); }, context, angleUnit, expression); typename Expression::Coordinate2D result = {.abscissa = resultAbscissa, .value = approximateWithValueForSymbol(symbol, resultAbscissa, context, angleUnit)}; @@ -354,7 +354,7 @@ typename Expression::Coordinate2D Expression::nextIntersection(char symbol, doub return result; } -typename Expression::Coordinate2D Expression::nextMinimumOfExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluate, Context & context, Preferences::AngleUnit angleUnit, const Expression expression, bool lookForRootMinimum) const { +typename Expression::Coordinate2D Expression::nextMinimumOfExpression(const char * symbol, double start, double step, double max, EvaluationAtAbscissa evaluate, Context & context, Preferences::AngleUnit angleUnit, const Expression expression, bool lookForRootMinimum) const { Coordinate2D result = {.abscissa = NAN, .value = NAN}; if (start == max || step == 0.0) { return result; @@ -391,7 +391,7 @@ typename Expression::Coordinate2D Expression::nextMinimumOfExpression(char symbo return result; } -void Expression::bracketMinimum(char symbol, double start, double step, double max, double result[3], EvaluationAtAbscissa evaluate, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { +void Expression::bracketMinimum(const char * symbol, double start, double step, double max, double result[3], EvaluationAtAbscissa evaluate, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { Coordinate2D p[3]; 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)}; @@ -416,7 +416,7 @@ void Expression::bracketMinimum(char symbol, double start, double step, double m result[2] = NAN; } -typename Expression::Coordinate2D Expression::brentMinimum(char symbol, double ax, double bx, EvaluationAtAbscissa evaluate, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { +typename Expression::Coordinate2D Expression::brentMinimum(const char * symbol, double ax, double bx, EvaluationAtAbscissa evaluate, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { /* Bibliography: R. P. Brent, Algorithms for finding zeros and extrema of * functions without calculating derivatives */ if (ax > bx) { @@ -510,7 +510,7 @@ typename Expression::Coordinate2D Expression::brentMinimum(char symbol, double a return result; } -double Expression::nextIntersectionWithExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { +double Expression::nextIntersectionWithExpression(const char * symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { if (start == max || step == 0.0) { return NAN; } @@ -526,14 +526,14 @@ double Expression::nextIntersectionWithExpression(char symbol, double start, dou double extremumMax = std::isnan(result) ? max : result; Coordinate2D resultExtremum[2] = { - nextMinimumOfExpression(symbol, start, step, extremumMax, [](char symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { + nextMinimumOfExpression(symbol, start, step, extremumMax, [](const char * symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { if (expression1.isUninitialized()) { return expression0.approximateWithValueForSymbol(symbol, x, context, angleUnit); } else { return expression0.approximateWithValueForSymbol(symbol, x, context, angleUnit)-expression1.approximateWithValueForSymbol(symbol, x, context, angleUnit); } }, context, angleUnit, expression, true), - nextMinimumOfExpression(symbol, start, step, extremumMax, [](char symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { + nextMinimumOfExpression(symbol, start, step, extremumMax, [](const char * symbol, double x, Context & context, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { if (expression1.isUninitialized()) { return -expression0.approximateWithValueForSymbol(symbol, x, context, angleUnit); } else { @@ -551,7 +551,7 @@ 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, Preferences::AngleUnit angleUnit, const Expression expression) const { +void Expression::bracketRoot(const char * symbol, double start, double step, double max, double result[2], EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { double a = start; double b = start+step; while (step > 0.0 ? b <= max : b >= max) { @@ -569,7 +569,7 @@ void Expression::bracketRoot(char symbol, double start, double step, double max, result[1] = NAN; } -double Expression::brentRoot(char symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { +double Expression::brentRoot(const char * symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const { if (ax > bx) { return brentRoot(symbol, bx, ax, precision, evaluation, context, angleUnit, expression); } @@ -657,7 +657,7 @@ template double Expression::approximateToScalar(const char * text, Conte template Evaluation Expression::approximateToEvaluation(Context& context, Preferences::AngleUnit angleUnit) const; template Evaluation Expression::approximateToEvaluation(Context& context, Preferences::AngleUnit angleUnit) const; -template float Expression::approximateWithValueForSymbol(char symbol, float x, Context & context, Preferences::AngleUnit angleUnit) const; -template double Expression::approximateWithValueForSymbol(char symbol, double x, Context & context, Preferences::AngleUnit angleUnit) const; +template float Expression::approximateWithValueForSymbol(const char * symbol, float x, Context & context, Preferences::AngleUnit angleUnit) const; +template double Expression::approximateWithValueForSymbol(const char * symbol, double x, Context & context, Preferences::AngleUnit angleUnit) const; }