diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index b04d232a1..d7045b374 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -55,7 +55,7 @@ void Calculation::setContent(const char * c, Context * context, Expression ansEx } Expression exactOutput; Expression approximateOutput; - PoincareHelpers::ParseAndSimplifyAndApproximate(m_inputText, &exactOutput, &approximateOutput, *context, false); + PoincareHelpers::ParseAndSimplifyAndApproximate(m_inputText, &exactOutput, &approximateOutput, context, false); PoincareHelpers::Serialize(exactOutput, m_exactOutputText, sizeof(m_exactOutputText)); PoincareHelpers::Serialize(approximateOutput, m_approximateOutputText, sizeof(m_approximateOutputText)); } @@ -159,7 +159,7 @@ Expression Calculation::approximateOutput(Context * context) { * the buffer. Put a special error instead of "undef". */ return Undefined::Builder(); } - return PoincareHelpers::Approximate(exp, *context); + return PoincareHelpers::Approximate(exp, context); } Layout Calculation::createApproximateOutputLayout(Context * context) { @@ -173,7 +173,7 @@ Calculation::DisplayOutput Calculation::displayOutput(Context * context) { if (shouldOnlyDisplayExactOutput()) { m_displayOutput = DisplayOutput::ExactOnly; } else if (input().recursivelyMatches( - [](const Expression e, Context & c) { + [](const Expression e, Context * c) { /* If the input contains: * - Random * - Round @@ -181,7 +181,7 @@ Calculation::DisplayOutput Calculation::displayOutput(Context * context) { ExpressionNode::Type t = e.type(); return (t == ExpressionNode::Type::Random) || (t == ExpressionNode::Type::Round) || Expression::IsMatrix(e, c); }, - *context, true)) + context, true)) { m_displayOutput = DisplayOutput::ApproximateOnly; } else if (strcmp(m_exactOutputText, m_approximateOutputText) == 0) { @@ -192,7 +192,7 @@ Calculation::DisplayOutput Calculation::displayOutput(Context * context) { } else if (strcmp(m_exactOutputText, Undefined::Name()) == 0 || strcmp(m_approximateOutputText, Unreal::Name()) == 0) { // If the approximate result is 'unreal' or the exact result is 'undef' m_displayOutput = DisplayOutput::ApproximateOnly; - } else if (input().recursivelyMatches(Expression::IsApproximate, *context) || exactOutput().recursivelyMatches(Expression::IsApproximate, *context)) { + } else if (input().recursivelyMatches(Expression::IsApproximate, context) || exactOutput().recursivelyMatches(Expression::IsApproximate, context)) { m_displayOutput = DisplayOutput::ExactAndApproximateToggle; } else { m_displayOutput = DisplayOutput::ExactAndApproximate; @@ -214,12 +214,12 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual( constexpr int bufferSize = Constant::MaxSerializedExpressionSize; char buffer[bufferSize]; Preferences * preferences = Preferences::sharedPreferences(); - Expression exactOutputExpression = PoincareHelpers::ParseAndSimplify(m_exactOutputText, *context, false); + Expression exactOutputExpression = PoincareHelpers::ParseAndSimplify(m_exactOutputText, context, false); if (exactOutputExpression.isUninitialized()) { exactOutputExpression = Undefined::Builder(); } 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; + 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/calculation/calculation_store.cpp b/apps/calculation/calculation_store.cpp index 618439860..ed7e31600 100644 --- a/apps/calculation/calculation_store.cpp +++ b/apps/calculation/calculation_store.cpp @@ -96,10 +96,10 @@ Expression CalculationStore::ansExpression(Context * context) { * To avoid turning 'ans->A' in '2->A->A' or '2=A->A' (which cannot be * parsed), ans is replaced by the approximation output when any Store or * Equal expression appears. */ - bool exactOuptutInvolvesStoreEqual = lastCalculation->exactOutput().recursivelyMatches([](const Expression e, Context & context) { + bool exactOuptutInvolvesStoreEqual = lastCalculation->exactOutput().recursivelyMatches([](const Expression e, Context * context) { return e.type() == ExpressionNode::Type::Store || e.type() == ExpressionNode::Type::Equal; - }, *context, false); - if (lastCalculation->input().recursivelyMatches(Expression::IsApproximate, *context) || exactOuptutInvolvesStoreEqual) { + }, context, false); + if (lastCalculation->input().recursivelyMatches(Expression::IsApproximate, context) || exactOuptutInvolvesStoreEqual) { return lastCalculation->approximateOutput(context); } return lastCalculation->exactOutput(); diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index 7240e0ba7..1f95d2d9b 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -46,7 +46,7 @@ float GraphController::interestingXHalfRange() const { Poincare::Context * context = textFieldDelegateApp()->localContext(); for (int i = 0; i < functionStore()->numberOfActiveFunctions(); i++) { ExpiringPointer f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i)); - float fRange = f->expressionReduced(context).characteristicXRange(*context, Poincare::Preferences::sharedPreferences()->angleUnit()); + float fRange = f->expressionReduced(context).characteristicXRange(context, Poincare::Preferences::sharedPreferences()->angleUnit()); if (!std::isnan(fRange)) { characteristicRange = maxFloat(fRange, characteristicRange); } diff --git a/apps/regression/model/model.cpp b/apps/regression/model/model.cpp index 78e7891dd..78e93d45a 100644 --- a/apps/regression/model/model.cpp +++ b/apps/regression/model/model.cpp @@ -18,16 +18,16 @@ void Model::tidy() { Poincare::Expression Model::simplifiedExpression(double * modelCoefficients, Poincare::Context * context) { Expression e = expression(modelCoefficients); if (!e.isUninitialized()) { - PoincareHelpers::Simplify(&e, *context); + PoincareHelpers::Simplify(&e, context); } return e; } double Model::levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) { Expression yExpression = Number::DecimalNumber(y); - PoincareHelpers::Simplify(&yExpression, *context); + PoincareHelpers::Simplify(&yExpression, context); Expression modelExpression = simplifiedExpression(modelCoefficients, context); - double result = PoincareHelpers::NextIntersection(modelExpression, "x", xMin, step, xMax, *context, yExpression).abscissa; + double result = PoincareHelpers::NextIntersection(modelExpression, "x", xMin, step, xMax, context, yExpression).abscissa; return result; } diff --git a/apps/sequence/cache_context.cpp b/apps/sequence/cache_context.cpp index 0645e34e5..d932455f4 100644 --- a/apps/sequence/cache_context.cpp +++ b/apps/sequence/cache_context.cpp @@ -28,7 +28,7 @@ const Expression CacheContext::expressionForSymbol(const SymbolAbstract & sym } template -void CacheContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) { +void CacheContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context * context) { m_parentContext->setExpressionForSymbol(expression, symbol, context); } diff --git a/apps/sequence/cache_context.h b/apps/sequence/cache_context.h index 011596ece..90e69c52c 100644 --- a/apps/sequence/cache_context.h +++ b/apps/sequence/cache_context.h @@ -13,7 +13,7 @@ class CacheContext : public Poincare::Context { public: CacheContext(Poincare::Context * parentContext); const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override; - void setExpressionForSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Poincare::Context & context) override; + void setExpressionForSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Poincare::Context * context) override; void setValueForSymbol(T value, const Poincare::Symbol & symbol); private: int nameIndexForSymbol(const Poincare::Symbol & symbol); diff --git a/apps/sequence/sequence.cpp b/apps/sequence/sequence.cpp index cf03d9e9e..ce8a16327 100644 --- a/apps/sequence/sequence.cpp +++ b/apps/sequence/sequence.cpp @@ -144,32 +144,32 @@ T Sequence::approximateToNextRank(int n, SequenceContext * sqctx) const { { ctx.setValueForSymbol(un, unSymbol); ctx.setValueForSymbol(vn, vnSymbol); - return PoincareHelpers::ApproximateWithValueForSymbol(expressionReduced(sqctx), unknownN, (T)n, ctx); + return PoincareHelpers::ApproximateWithValueForSymbol(expressionReduced(sqctx), unknownN, (T)n, &ctx); } case Type::SingleRecurrence: { if (n == initialRank()) { - return PoincareHelpers::ApproximateToScalar(firstInitialConditionExpressionReduced(sqctx), *sqctx); + return PoincareHelpers::ApproximateToScalar(firstInitialConditionExpressionReduced(sqctx), sqctx); } ctx.setValueForSymbol(un, un1Symbol); ctx.setValueForSymbol(unm1, unSymbol); ctx.setValueForSymbol(vn, vn1Symbol); ctx.setValueForSymbol(vnm1, vnSymbol); - return PoincareHelpers::ApproximateWithValueForSymbol(expressionReduced(sqctx), unknownN, (T)(n-1), ctx); + return PoincareHelpers::ApproximateWithValueForSymbol(expressionReduced(sqctx), unknownN, (T)(n-1), &ctx); } default: { if (n == initialRank()) { - return PoincareHelpers::ApproximateToScalar(firstInitialConditionExpressionReduced(sqctx), *sqctx); + return PoincareHelpers::ApproximateToScalar(firstInitialConditionExpressionReduced(sqctx), sqctx); } if (n == initialRank()+1) { - return PoincareHelpers::ApproximateToScalar(secondInitialConditionExpressionReduced(sqctx), *sqctx); + return PoincareHelpers::ApproximateToScalar(secondInitialConditionExpressionReduced(sqctx), sqctx); } ctx.setValueForSymbol(unm1, un1Symbol); ctx.setValueForSymbol(unm2, unSymbol); ctx.setValueForSymbol(vnm1, vn1Symbol); ctx.setValueForSymbol(vnm2, vnSymbol); - return PoincareHelpers::ApproximateWithValueForSymbol(expressionReduced(sqctx), unknownN, (T)(n-2), ctx); + return PoincareHelpers::ApproximateWithValueForSymbol(expressionReduced(sqctx), unknownN, (T)(n-2), &ctx); } } } diff --git a/apps/sequence/sequence_context.h b/apps/sequence/sequence_context.h index 6b3216aa7..5908028db 100644 --- a/apps/sequence/sequence_context.h +++ b/apps/sequence/sequence_context.h @@ -48,7 +48,7 @@ public: const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override { return m_parentContext->expressionForSymbol(symbol, clone); } - void setExpressionForSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Poincare::Context & context) override { + void setExpressionForSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Poincare::Context * context) override { m_parentContext->setExpressionForSymbol(expression, symbol, context); } template T valueOfSequenceAtPreviousRank(int sequenceIndex, int rank) const { diff --git a/apps/shared/cartesian_function.cpp b/apps/shared/cartesian_function.cpp index 6de019f85..5775fdd58 100644 --- a/apps/shared/cartesian_function.cpp +++ b/apps/shared/cartesian_function.cpp @@ -92,7 +92,7 @@ double CartesianFunction::approximateDerivative(double x, Poincare::Context * co /* TODO: when we approximate 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 PoincareHelpers::ApproximateToScalar(derivative, *context); + return PoincareHelpers::ApproximateToScalar(derivative, context); } double CartesianFunction::sumBetweenBounds(double start, double end, Poincare::Context * context) const { @@ -101,35 +101,35 @@ double CartesianFunction::sumBetweenBounds(double start, double end, Poincare::C /* TODO: when we approximate 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 PoincareHelpers::ApproximateToScalar(integral, *context); + return PoincareHelpers::ApproximateToScalar(integral, context); } Expression::Coordinate2D CartesianFunction::nextMinimumFrom(double start, double step, double max, Context * context) const { constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknownX); - return PoincareHelpers::NextMinimum(expressionReduced(context), unknownX, start, step, max, *context); + return PoincareHelpers::NextMinimum(expressionReduced(context), unknownX, start, step, max, context); } Expression::Coordinate2D CartesianFunction::nextMaximumFrom(double start, double step, double max, Context * context) const { constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknownX); - return PoincareHelpers::NextMaximum(expressionReduced(context), unknownX, start, step, max, *context); + return PoincareHelpers::NextMaximum(expressionReduced(context), unknownX, start, step, max, context); } double CartesianFunction::nextRootFrom(double start, double step, double max, Context * context) const { constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknownX); - return PoincareHelpers::NextRoot(expressionReduced(context), unknownX, start, step, max, *context); + return PoincareHelpers::NextRoot(expressionReduced(context), unknownX, start, step, max, context); } Expression::Coordinate2D CartesianFunction::nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, Expression e) const { constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknownX); - return PoincareHelpers::NextIntersection(expressionReduced(context), unknownX, start, step, max, *context, e); + return PoincareHelpers::NextIntersection(expressionReduced(context), unknownX, start, step, max, context, e); } void * CartesianFunction::Model::expressionAddress(const Ion::Storage::Record * record) const { diff --git a/apps/shared/expression_model.cpp b/apps/shared/expression_model.cpp index 142b9b4b7..258887438 100644 --- a/apps/shared/expression_model.cpp +++ b/apps/shared/expression_model.cpp @@ -31,7 +31,7 @@ void ExpressionModel::text(const Storage::Record * record, char * buffer, size_t bool ExpressionModel::isCircularlyDefined(const Storage::Record * record, Poincare::Context * context) const { if (m_circular == -1) { - m_circular = Expression::ExpressionWithoutSymbols(expressionClone(record), *context).isUninitialized(); + m_circular = Expression::ExpressionWithoutSymbols(expressionClone(record), context).isUninitialized(); } return m_circular; } @@ -40,7 +40,7 @@ Expression ExpressionModel::expressionReduced(const Storage::Record * record, Po if (m_expression.isUninitialized()) { assert(record->fullName() != nullptr); m_expression = Expression::ExpressionFromAddress(expressionAddress(record), expressionSize(record)); - PoincareHelpers::Simplify(&m_expression, *context); + PoincareHelpers::Simplify(&m_expression, context); // simplify might return an uninitialized Expression if interrupted if (m_expression.isUninitialized()) { m_expression = Expression::ExpressionFromAddress(expressionAddress(record), expressionSize(record)); diff --git a/apps/shared/function.cpp b/apps/shared/function.cpp index bc454ed42..f76da5fc5 100644 --- a/apps/shared/function.cpp +++ b/apps/shared/function.cpp @@ -84,7 +84,7 @@ T Function::templatedApproximateAtAbscissa(T x, Poincare::Context * context, Cod constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; Poincare::SerializationHelper::CodePoint(unknownX, bufferSize, unknownSymbol); - return PoincareHelpers::ApproximateWithValueForSymbol(expressionReduced(context), unknownX, x, *context); + return PoincareHelpers::ApproximateWithValueForSymbol(expressionReduced(context), unknownX, x, context); } Function::FunctionRecordDataBuffer * Function::recordData() const { @@ -95,5 +95,5 @@ Function::FunctionRecordDataBuffer * Function::recordData() const { } -template float Shared::Function::templatedApproximateAtAbscissa(float, Poincare::Context*, CodePoint) const; -template double Shared::Function::templatedApproximateAtAbscissa(double, Poincare::Context*, CodePoint) const; +template float Shared::Function::templatedApproximateAtAbscissa(float, Poincare::Context *, CodePoint) const; +template double Shared::Function::templatedApproximateAtAbscissa(double, Poincare::Context *, CodePoint) const; diff --git a/apps/shared/global_context.cpp b/apps/shared/global_context.cpp index fc26e28d5..b77075ac0 100644 --- a/apps/shared/global_context.cpp +++ b/apps/shared/global_context.cpp @@ -62,7 +62,7 @@ const Expression GlobalContext::expressionForSymbol(const SymbolAbstract & symbo return ExpressionForSymbolAndRecord(symbol, r); } -void GlobalContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) { +void GlobalContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context * context) { /* If the new expression contains the symbol, replace it because it will be * destroyed afterwards (to be able to do A+2->A) */ Ion::Storage::Record record = SymbolAbstractRecordWithBaseName(symbol.name()); diff --git a/apps/shared/global_context.h b/apps/shared/global_context.h index 617eca3c5..45ad9f49f 100644 --- a/apps/shared/global_context.h +++ b/apps/shared/global_context.h @@ -37,7 +37,7 @@ public: void setExpressionForSymbol( const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, - Poincare::Context & context) override; + Poincare::Context * context) override; private: // Expression getters diff --git a/apps/shared/poincare_helpers.h b/apps/shared/poincare_helpers.h index 24f3c317c..b62a4d2c7 100644 --- a/apps/shared/poincare_helpers.h +++ b/apps/shared/poincare_helpers.h @@ -24,70 +24,70 @@ inline int Serialize(const Poincare::Expression e, char * buffer, int bufferSize } template -inline Poincare::Expression Approximate(const Poincare::Expression e, Poincare::Context & context) { +inline Poincare::Expression Approximate(const Poincare::Expression e, Poincare::Context * context) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); 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) { +inline T ApproximateToScalar(const Poincare::Expression e, Poincare::Context * context) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); 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) { +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 = 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, bool symbolicComputation = true) { +inline T ApproximateToScalar(const char * text, Poincare::Context * context, bool symbolicComputation = true) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text); return Poincare::Expression::ApproximateToScalar(text, context, complexFormat, preferences->angleUnit(), symbolicComputation); } -inline Poincare::Expression ParseAndSimplify(const char * text, Poincare::Context & context, bool symbolicComputation = true) { +inline Poincare::Expression ParseAndSimplify(const char * text, Poincare::Context * context, bool symbolicComputation = true) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text); return Poincare::Expression::ParseAndSimplify(text, context, complexFormat, preferences->angleUnit(), symbolicComputation); } -inline void Simplify(Poincare::Expression * e, Poincare::Context & context, bool symbolicComputation = true) { +inline void Simplify(Poincare::Expression * e, Poincare::Context * context, bool symbolicComputation = true) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), *e, context); *e = e->simplify(context, complexFormat, preferences->angleUnit(), symbolicComputation); } -inline void ParseAndSimplifyAndApproximate(const char * text, Poincare::Expression * simplifiedExpression, Poincare::Expression * approximateExpression, Poincare::Context & context, bool symbolicComputation = true) { +inline void ParseAndSimplifyAndApproximate(const char * text, Poincare::Expression * simplifiedExpression, Poincare::Expression * approximateExpression, Poincare::Context * context, bool symbolicComputation = true) { Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text); Poincare::Expression::ParseAndSimplifyAndApproximate(text, simplifiedExpression, approximateExpression, context, complexFormat, preferences->angleUnit(), symbolicComputation); } -inline typename Poincare::Expression::Coordinate2D NextMinimum(const Poincare::Expression e, const char * symbol, double start, double step, double max, Poincare::Context & context) { +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) { +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) { +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) { +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); diff --git a/apps/shared/store_context.cpp b/apps/shared/store_context.cpp index 804fff700..967d5d132 100644 --- a/apps/shared/store_context.cpp +++ b/apps/shared/store_context.cpp @@ -7,7 +7,7 @@ using namespace Poincare; namespace Shared { -void StoreContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) { +void StoreContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context * context) { m_parentContext->setExpressionForSymbol(expression, symbol, context); } diff --git a/apps/shared/store_context.h b/apps/shared/store_context.h index 79db7930e..f200add13 100644 --- a/apps/shared/store_context.h +++ b/apps/shared/store_context.h @@ -19,7 +19,7 @@ public: {} void setParentContext(Poincare::Context * parentContext) { m_parentContext = parentContext; } void setSeriesPairIndex(int j) { m_seriesPairIndex = j; } - void setExpressionForSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Poincare::Context & context) override; + void setExpressionForSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Poincare::Context * context) override; protected: Shared::DoublePairStore * m_store; int m_seriesPairIndex; diff --git a/apps/shared/store_controller.cpp b/apps/shared/store_controller.cpp index 02d57849e..7afa6d572 100644 --- a/apps/shared/store_controller.cpp +++ b/apps/shared/store_controller.cpp @@ -259,7 +259,7 @@ bool StoreController::privateFillColumnWithFormula(Expression formula, Expressio char variables[Expression::k_maxNumberOfVariables][k_maxSizeOfStoreSymbols]; variables[0][0] = 0; AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); - int nbOfVariables = formula.getVariables(*(appsContainer->globalContext()), isVariable, (char *)variables, k_maxSizeOfStoreSymbols); + int nbOfVariables = formula.getVariables(appsContainer->globalContext(), isVariable, (char *)variables, k_maxSizeOfStoreSymbols); (void) nbOfVariables; // Remove compilation warning of nused variable assert(nbOfVariables >= 0); int numberOfValuesToCompute = -1; @@ -287,7 +287,7 @@ bool StoreController::privateFillColumnWithFormula(Expression formula, Expressio // Set the context store->setSeriesPairIndex(j); // Compute the new value using the formula - double evaluation = PoincareHelpers::ApproximateToScalar(formula, *store); + double evaluation = PoincareHelpers::ApproximateToScalar(formula, store); if (std::isnan(evaluation) || std::isinf(evaluation)) { Container::activeApp()->displayWarning(I18n::Message::DataNotSuitable); return false; @@ -297,7 +297,7 @@ bool StoreController::privateFillColumnWithFormula(Expression formula, Expressio // Fill in the table with the formula values for (int j = 0; j < numberOfValuesToCompute; j++) { store->setSeriesPairIndex(j); - double evaluation = PoincareHelpers::ApproximateToScalar(formula, *store); + double evaluation = PoincareHelpers::ApproximateToScalar(formula, store); setDataAtLocation(evaluation, currentColumn, j + 1); } selectableTableView()->reloadData(); diff --git a/apps/shared/text_field_delegate_app.cpp b/apps/shared/text_field_delegate_app.cpp index 8287cee34..0279167ff 100644 --- a/apps/shared/text_field_delegate_app.cpp +++ b/apps/shared/text_field_delegate_app.cpp @@ -45,7 +45,7 @@ bool TextFieldDelegateApp::isAcceptableText(const char * text) { } bool TextFieldDelegateApp::hasUndefinedValue(const char * text, double & value) { - value = PoincareHelpers::ApproximateToScalar(text, *localContext()); + value = PoincareHelpers::ApproximateToScalar(text, localContext()); bool isUndefined = std::isnan(value) || std::isinf(value); if (isUndefined) { displayWarning(I18n::Message::UndefinedValue); diff --git a/apps/solver/equation.cpp b/apps/solver/equation.cpp index e8586ae01..ca5791384 100644 --- a/apps/solver/equation.cpp +++ b/apps/solver/equation.cpp @@ -18,7 +18,7 @@ Equation::Equation(Ion::Storage::Record record) : } bool Equation::containsIComplex(Context * context) const { - return expressionClone().recursivelyMatches([](const Expression e, Context & context) { return e.type() == ExpressionNode::Type::Constant && static_cast(e).isIComplex(); }, *context, true); + return expressionClone().recursivelyMatches([](const Expression e, Context * context) { return e.type() == ExpressionNode::Type::Constant && static_cast(e).isIComplex(); }, context, true); } Expression Equation::Model::standardForm(const Storage::Record * record, Context * context) const { @@ -28,13 +28,13 @@ Expression Equation::Model::standardForm(const Storage::Record * record, Context m_standardForm = Unreal::Builder(); return m_standardForm; } - if (e.recursivelyMatches([](const Expression e, Context & context) { return e.type() == ExpressionNode::Type::Undefined || e.type() == ExpressionNode::Type::Infinity || Expression::IsMatrix(e, context); }, *context, true)) { + if (e.recursivelyMatches([](const Expression e, Context * context) { return e.type() == ExpressionNode::Type::Undefined || e.type() == ExpressionNode::Type::Infinity || Expression::IsMatrix(e, context); }, context, true)) { m_standardForm = Undefined::Builder(); return m_standardForm; } if (e.type() == ExpressionNode::Type::Equal) { Preferences * preferences = Preferences::sharedPreferences(); - m_standardForm = static_cast(e).standardEquation(*context, Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), expressionClone(record), *context), preferences->angleUnit()); + m_standardForm = static_cast(e).standardEquation(context, Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), expressionClone(record), context), preferences->angleUnit()); } else { assert(e.type() == ExpressionNode::Type::Rational && static_cast(e).isOne()); // The equality was reduced which means the equality was always true. diff --git a/apps/solver/equation_store.cpp b/apps/solver/equation_store.cpp index df78e173a..9f2b75480 100644 --- a/apps/solver/equation_store.cpp +++ b/apps/solver/equation_store.cpp @@ -95,7 +95,7 @@ bool EquationStore::haveMoreApproximationSolutions(Context * context) { return false; } double step = (m_intervalApproximateSolutions[1]-m_intervalApproximateSolutions[0])*k_precision; - return !std::isnan(PoincareHelpers::NextRoot(modelForRecord(definedRecordAtIndex(0))->standardForm(context), m_variables[0], m_approximateSolutions[m_numberOfSolutions-1], step, m_intervalApproximateSolutions[1], *context)); + return !std::isnan(PoincareHelpers::NextRoot(modelForRecord(definedRecordAtIndex(0))->standardForm(context), m_variables[0], m_approximateSolutions[m_numberOfSolutions-1], step, m_intervalApproximateSolutions[1], context)); } void EquationStore::approximateSolve(Poincare::Context * context) { @@ -105,7 +105,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] = PoincareHelpers::NextRoot(modelForRecord(definedRecordAtIndex(0))->standardForm(context), m_variables[0], start, step, m_intervalApproximateSolutions[1], *context); + m_approximateSolutions[i] = PoincareHelpers::NextRoot(modelForRecord(definedRecordAtIndex(0))->standardForm(context), m_variables[0], start, step, m_intervalApproximateSolutions[1], context); if (std::isnan(m_approximateSolutions[i])) { break; } else { @@ -129,7 +129,7 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) { if (e.type() == ExpressionNode::Type::Unreal) { return Error::EquationUnreal; } - numberOfVariables = e.getVariables(*context, [](const char * symbol) { return true; }, (char *)m_variables, Poincare::SymbolAbstract::k_maxNameSize); + numberOfVariables = e.getVariables(context, [](const char * symbol) { return true; }, (char *)m_variables, Poincare::SymbolAbstract::k_maxNameSize); if (numberOfVariables == -1) { return Error::TooManyVariables; } @@ -147,7 +147,7 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) { bool isLinear = true; // Invalid the linear system if one equation is non-linear Preferences * preferences = Preferences::sharedPreferences(); for (int i = 0; i < numberOfDefinedModels(); i++) { - isLinear = isLinear && modelForRecord(definedRecordAtIndex(i))->standardForm(context).getLinearCoefficients((char *)m_variables, Poincare::SymbolAbstract::k_maxNameSize, coefficients[i], &constants[i], *context, updatedComplexFormat(context), preferences->angleUnit()); + isLinear = isLinear && modelForRecord(definedRecordAtIndex(i))->standardForm(context).getLinearCoefficients((char *)m_variables, Poincare::SymbolAbstract::k_maxNameSize, coefficients[i], &constants[i], context, updatedComplexFormat(context), preferences->angleUnit()); if (!isLinear) { // TODO: should we clean pool allocated memory if the system is not linear #if 0 @@ -178,7 +178,7 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) { // Step 2. Polynomial & Monovariable? assert(numberOfVariables == 1 && numberOfDefinedModels() == 1); Expression polynomialCoefficients[Expression::k_maxNumberOfPolynomialCoefficients]; - int degree = modelForRecord(definedRecordAtIndex(0))->standardForm(context).getPolynomialReducedCoefficients(m_variables[0], polynomialCoefficients, *context, updatedComplexFormat(context), preferences->angleUnit()); + int degree = modelForRecord(definedRecordAtIndex(0))->standardForm(context).getPolynomialReducedCoefficients(m_variables[0], polynomialCoefficients, context, updatedComplexFormat(context), preferences->angleUnit()); if (degree == 2) { // Polynomial degree <= 2 m_type = Type::PolynomialMonovariable; @@ -213,7 +213,7 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) { m_exactSolutionIdentity[solutionIndex] = strcmp(exactBuffer, approximateBuffer) == 0; if (!m_exactSolutionIdentity[solutionIndex]) { char buffer[::Constant::MaxSerializedExpressionSize]; - m_exactSolutionEquality[solutionIndex] = exactSolutions[i].isEqualToItsApproximationLayout(exactSolutionsApproximations[i], buffer, ::Constant::MaxSerializedExpressionSize, preferences->complexFormat(), preferences->angleUnit(), preferences->displayMode(), preferences->numberOfSignificantDigits(), *context); + m_exactSolutionEquality[solutionIndex] = exactSolutions[i].isEqualToItsApproximationLayout(exactSolutionsApproximations[i], buffer, ::Constant::MaxSerializedExpressionSize, preferences->complexFormat(), preferences->angleUnit(), preferences->displayMode(), preferences->numberOfSignificantDigits(), context); } solutionIndex++; } @@ -238,7 +238,7 @@ EquationStore::Error EquationStore::resolveLinearSystem(Expression exactSolution Ab.setDimensions(m, n+1); // Compute the rank of (A | b) - int rankAb = Ab.rank(*context, updatedComplexFormat(context), angleUnit, true); + int rankAb = Ab.rank(context, updatedComplexFormat(context), angleUnit, true); // Initialize the number of solutions m_numberOfSolutions = INT_MAX; @@ -263,7 +263,7 @@ EquationStore::Error EquationStore::resolveLinearSystem(Expression exactSolution m_numberOfSolutions = n; for (int i = 0; i < m_numberOfSolutions; i++) { exactSolutions[i] = Ab.matrixChild(i,n); - exactSolutions[i].simplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], *context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit()); + exactSolutions[i].simplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit()); } } } @@ -275,7 +275,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact assert(degree == 2); // Compute delta = b*b-4ac Expression delta = Subtraction::Builder(Power::Builder(coefficients[1].clone(), Rational::Builder(2)), Multiplication::Builder(Rational::Builder(4), coefficients[0].clone(), coefficients[2].clone())); - delta = delta.simplify(*context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit()); + delta = delta.simplify(context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit()); if (delta.isUninitialized()) { delta = Poincare::Undefined::Builder(); } @@ -292,7 +292,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact } exactSolutions[m_numberOfSolutions-1] = delta; for (int i = 0; i < m_numberOfSolutions; i++) { - exactSolutions[i].simplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], *context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit()); + exactSolutions[i].simplifyAndApproximate(&exactSolutions[i], &exactSolutionsApproximations[i], context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit()); } return Error::NoError; #if 0 diff --git a/apps/solver/test/equation_store.cpp b/apps/solver/test/equation_store.cpp index 096529c19..3bb95fb10 100644 --- a/apps/solver/test/equation_store.cpp +++ b/apps/solver/test/equation_store.cpp @@ -255,7 +255,7 @@ QUIZ_CASE(equation_and_symbolic_computation) { // -3->a Shared::GlobalContext globalContext; - Expression::ParseAndSimplify("-3→a", globalContext, Preferences::ComplexFormat::Polar, Preferences::AngleUnit::Degree); + Expression::ParseAndSimplify("-3→a", &globalContext, Preferences::ComplexFormat::Polar, Preferences::AngleUnit::Degree); // x+a = 0 : x = 3 const char * variables[] = {"x", ""}; diff --git a/poincare/include/poincare/absolute_value.h b/poincare/include/poincare/absolute_value.h index 5a85fd21f..b0bc1a963 100644 --- a/poincare/include/poincare/absolute_value.h +++ b/poincare/include/poincare/absolute_value.h @@ -21,19 +21,19 @@ public: // Properties Type type() const override { return Type::AbsoluteValue; } Sign sign(Context * context) const override { return Sign::Positive; } - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression setSign(Sign s, ReductionContext reductionContext) override; // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } // Approximation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { return Complex::Builder(std::abs(c)); } - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } @@ -42,7 +42,7 @@ public: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; }; class AbsoluteValue final : public Expression { @@ -53,9 +53,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("abs", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); -private: - Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 45a5d7d32..754232868 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -24,8 +24,8 @@ public: // Properties Type type() const override { return Type::Addition; } - int polynomialDegree(Context & context, const char * symbolName) const override; - int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; + int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const override; // Evaluation template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { return Complex::Builder(c+d); } @@ -42,17 +42,17 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression shallowReduce(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext reductionContext) override; /* Evaluation */ template static MatrixComplex computeOnMatrixAndComplex(const MatrixComplex m, const std::complex c, Preferences::ComplexFormat complexFormat) { return ApproximationHelper::ElementWiseOnMatrixComplexAndComplex(m, c, complexFormat, compute); } - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce(this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce(this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } }; @@ -65,17 +65,17 @@ public: static Addition Builder(Expression e1, Expression e2) { return Addition::Builder(ArrayBuilder(e1, e2).array(), 2); } static Addition Builder(Expression * children, size_t numberOfChildren) { return TreeHandle::NAryBuilder(children, numberOfChildren); } // Expression - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const; + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); + Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const; private: static const Number NumeralFactor(const Expression & e); static inline int NumberOfNonNumeralFactors(const Expression & e); static inline const Expression FirstNonNumeralFactor(const Expression & e); - static bool TermsHaveIdenticalNonNumeralFactors(const Expression & e1, const Expression & e2, Context & context); - Expression factorizeOnCommonDenominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - void factorizeChildrenAtIndexesInPlace(int index1, int index2, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + static bool TermsHaveIdenticalNonNumeralFactors(const Expression & e1, const Expression & e2, Context * context); + Expression factorizeOnCommonDenominator(ExpressionNode::ReductionContext reductionContext); + void factorizeChildrenAtIndexesInPlace(int index1, int index2, ExpressionNode::ReductionContext reductionContext); AdditionNode * node() const { return static_cast(Expression::node()); } }; diff --git a/poincare/include/poincare/approximation_helper.h b/poincare/include/poincare/approximation_helper.h index 7160bca38..b079d6a62 100644 --- a/poincare/include/poincare/approximation_helper.h +++ b/poincare/include/poincare/approximation_helper.h @@ -12,13 +12,13 @@ namespace ApproximationHelper { template std::complex TruncateRealOrImaginaryPartAccordingToArgument(std::complex c); template using ComplexCompute = Complex(*)(const std::complex, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - template Evaluation Map(const ExpressionNode * expression, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ComplexCompute compute); + template Evaluation Map(const ExpressionNode * expression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ComplexCompute compute); template using ComplexAndComplexReduction = Complex(*)(const std::complex, const std::complex, Preferences::ComplexFormat complexFormat); template using ComplexAndMatrixReduction = MatrixComplex(*)(const std::complex c, const MatrixComplex m, Preferences::ComplexFormat complexFormat); template using MatrixAndComplexReduction = MatrixComplex(*)(const MatrixComplex m, const std::complex c, Preferences::ComplexFormat complexFormat); template using MatrixAndMatrixReduction = MatrixComplex(*)(const MatrixComplex m, const MatrixComplex n, Preferences::ComplexFormat complexFormat); - template Evaluation MapReduce(const ExpressionNode * expression, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ComplexAndComplexReduction computeOnComplexes, ComplexAndMatrixReduction computeOnComplexAndMatrix, MatrixAndComplexReduction computeOnMatrixAndComplex, MatrixAndMatrixReduction computeOnMatrices); + template Evaluation MapReduce(const ExpressionNode * expression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ComplexAndComplexReduction computeOnComplexes, ComplexAndMatrixReduction computeOnComplexAndMatrix, MatrixAndComplexReduction computeOnMatrixAndComplex, MatrixAndMatrixReduction computeOnMatrices); template MatrixComplex ElementWiseOnMatrixComplexAndComplex(const MatrixComplex n, std::complex c, Preferences::ComplexFormat complexFormat, ComplexAndComplexReduction computeOnComplexes); template MatrixComplex ElementWiseOnComplexMatrices(const MatrixComplex m, const MatrixComplex n, Preferences::ComplexFormat complexFormat, ComplexAndComplexReduction computeOnComplexes); diff --git a/poincare/include/poincare/arc_cosine.h b/poincare/include/poincare/arc_cosine.h index e12c8787c..4a50d65d4 100644 --- a/poincare/include/poincare/arc_cosine.h +++ b/poincare/include/poincare/arc_cosine.h @@ -27,13 +27,13 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -45,7 +45,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("acos", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; diff --git a/poincare/include/poincare/arc_sine.h b/poincare/include/poincare/arc_sine.h index e4efaf1b4..201590ae1 100644 --- a/poincare/include/poincare/arc_sine.h +++ b/poincare/include/poincare/arc_sine.h @@ -26,13 +26,13 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -44,7 +44,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("asin", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/arc_tangent.h b/poincare/include/poincare/arc_tangent.h index ca755d1de..b4648ae20 100644 --- a/poincare/include/poincare/arc_tangent.h +++ b/poincare/include/poincare/arc_tangent.h @@ -23,20 +23,20 @@ public: Type type() const override { return Type::ArcTangent; } // Complex - bool isReal(Context & context) const override { return childAtIndex(0)->isReal(context); } + bool isReal(Context * context) const override { return childAtIndex(0)->isReal(context); } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -48,7 +48,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("atan", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/binomial_coefficient.h b/poincare/include/poincare/binomial_coefficient.h index 801bde559..eb691aeb5 100644 --- a/poincare/include/poincare/binomial_coefficient.h +++ b/poincare/include/poincare/binomial_coefficient.h @@ -19,7 +19,7 @@ public: #endif // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } // Properties Type type() const override{ return Type::BinomialCoefficient; } @@ -29,11 +29,11 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Complex templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Complex templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class BinomialCoefficient final : public Expression { @@ -43,7 +43,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("binomial", 2, &UntypedBuilderTwoChildren); // Expression - Expression shallowReduce(Context & context); + Expression shallowReduce(Context * context); private: constexpr static int k_maxNValue = 300; }; diff --git a/poincare/include/poincare/ceiling.h b/poincare/include/poincare/ceiling.h index 60a3501d6..2924ed60b 100644 --- a/poincare/include/poincare/ceiling.h +++ b/poincare/include/poincare/ceiling.h @@ -19,7 +19,7 @@ public: #endif // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } // Properties Type type() const override { return Type::Ceiling; } @@ -28,13 +28,13 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -46,7 +46,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ceil", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/complex_argument.h b/poincare/include/poincare/complex_argument.h index 89ba80dad..c8a39399e 100644 --- a/poincare/include/poincare/complex_argument.h +++ b/poincare/include/poincare/complex_argument.h @@ -18,7 +18,7 @@ public: } #endif // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } // Properties Type type() const override { return Type::ComplexArgument; } @@ -27,13 +27,13 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -45,7 +45,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("arg", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/complex_cartesian.h b/poincare/include/poincare/complex_cartesian.h index 377394e87..6137befdc 100644 --- a/poincare/include/poincare/complex_cartesian.h +++ b/poincare/include/poincare/complex_cartesian.h @@ -24,14 +24,14 @@ private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { assert(false); return Layout(); } // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression shallowReduce(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext reductionContext) override; private: - template Complex templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template Complex templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class ComplexCartesian final : public Expression { @@ -47,26 +47,25 @@ public: // Simplification Expression shallowReduce(); - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); // Common operations (done in-place) - Expression squareNorm(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - Expression norm(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - Expression argument(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); - ComplexCartesian inverse(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - ComplexCartesian squareRoot(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - ComplexCartesian powerInteger(int n, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); - ComplexCartesian multiply(ComplexCartesian & other, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - ComplexCartesian power(ComplexCartesian & other, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression squareNorm(ExpressionNode::ReductionContext reductionContext); + Expression norm(ExpressionNode::ReductionContext reductionContext); + Expression argument(ExpressionNode::ReductionContext reductionContext); + ComplexCartesian inverse(ExpressionNode::ReductionContext reductionContext); + ComplexCartesian squareRoot(ExpressionNode::ReductionContext reductionContext); + ComplexCartesian powerInteger(int n, ExpressionNode::ReductionContext reductionContext); + ComplexCartesian multiply(ComplexCartesian & other,ExpressionNode::ReductionContext reductionContext); + ComplexCartesian power(ComplexCartesian & other, ExpressionNode::ReductionContext reductionContext); private: static constexpr int k_maxNumberOfNodesBeforeInterrupting = 50; - void factorAndArgumentOfFunction(Expression e, ExpressionNode::Type searchedType, Expression * factor, Expression * argument, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + void factorAndArgumentOfFunction(Expression e, ExpressionNode::Type searchedType, Expression * factor, Expression * argument, ExpressionNode::ReductionContext reductionContext); ComplexCartesian interruptComputationIfManyNodes(); - static Multiplication squareRootHelper(Expression e, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - static Expression powerHelper(Expression norm, Expression trigo, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + static Multiplication squareRootHelper(Expression e, ExpressionNode::ReductionContext reductionContext); + static Expression powerHelper(Expression norm, Expression trigo, ExpressionNode::ReductionContext reductionContext); }; - } #endif diff --git a/poincare/include/poincare/confidence_interval.h b/poincare/include/poincare/confidence_interval.h index 6a42f4ea7..7dec9769f 100644 --- a/poincare/include/poincare/confidence_interval.h +++ b/poincare/include/poincare/confidence_interval.h @@ -21,17 +21,17 @@ public: // Properties Type type() const override { return Type::ConfidenceInterval; } - int polynomialDegree(Context & context, const char * symbolName) const override { return -1; } + int polynomialDegree(Context * context, const char * symbolName) const override { return -1; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class SimplePredictionIntervalNode final : public ConfidenceIntervalNode { @@ -49,7 +49,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("confidence", 2, &UntypedBuilderTwoChildren); // Expression - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); private: constexpr static int k_maxNValue = 300; }; diff --git a/poincare/include/poincare/conjugate.h b/poincare/include/poincare/conjugate.h index 9c0a82c52..a1cf92fec 100644 --- a/poincare/include/poincare/conjugate.h +++ b/poincare/include/poincare/conjugate.h @@ -18,7 +18,7 @@ public: } #endif - bool isReal(Context & context) const override { return childAtIndex(0)->isReal(context); } + bool isReal(Context * context) const override { return childAtIndex(0)->isReal(context); } // Properties Type type() const override { return Type::Conjugate; } @@ -27,13 +27,13 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -45,7 +45,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("conj", 1, &UntypedBuilderOneChild);; - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/constant.h b/poincare/include/poincare/constant.h index 7b8277e84..a09f763b9 100644 --- a/poincare/include/poincare/constant.h +++ b/poincare/include/poincare/constant.h @@ -23,7 +23,7 @@ public: #endif // Complex - bool isReal(Context & context) const override; + bool isReal(Context * context) const override; // Expression Properties Type type() const override { return Type::Constant; } @@ -34,8 +34,8 @@ public: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; /* Approximation */ - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } /* Symbol properties */ bool isPi() const { return isConstantCodePoint(UCodePointGreekSmallLetterPi); } @@ -47,12 +47,12 @@ public: int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; private: char m_name[0]; // MUST be the last member variable size_t nodeSize() const override { return sizeof(ConstantNode); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; bool isConstantCodePoint(CodePoint c) const; }; @@ -67,7 +67,7 @@ public: bool isIComplex() const { return node()->isIComplex(); } // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); private: ConstantNode * node() const { return static_cast(Expression::node()); } diff --git a/poincare/include/poincare/context.h b/poincare/include/poincare/context.h index c42b209a4..4d4700908 100644 --- a/poincare/include/poincare/context.h +++ b/poincare/include/poincare/context.h @@ -9,7 +9,7 @@ class SymbolAbstract; class Context { public: virtual const Expression expressionForSymbol(const SymbolAbstract & symbol, bool clone) = 0; - virtual void setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) = 0; + virtual void setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context * context) = 0; }; } diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h index 42f7c35a1..dde0aa524 100644 --- a/poincare/include/poincare/cosine.h +++ b/poincare/include/poincare/cosine.h @@ -20,11 +20,11 @@ public: #endif // Complex - bool isReal(Context & context) const override { return childAtIndex(0)->isReal(context); } + bool isReal(Context * context) const override { return childAtIndex(0)->isReal(context); } // Properties Type type() const override { return Type::Cosine; } - float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override; + float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override; template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian); @@ -33,12 +33,12 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplication - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -50,7 +50,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("cos", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/decimal.h b/poincare/include/poincare/decimal.h index f728bca31..488098993 100644 --- a/poincare/include/poincare/decimal.h +++ b/poincare/include/poincare/decimal.h @@ -42,13 +42,13 @@ public: // Properties Type type() const override { return Type::Decimal; } Sign sign(Context * context) const override { return m_negative ? Sign::Negative : Sign::Positive; } - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression setSign(Sign s, ReductionContext reductionContext) override; // Approximation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex::Builder(templatedApproximate()); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex::Builder(templatedApproximate()); } @@ -56,8 +56,8 @@ public: int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression shallowReduce(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext reductionContext) override; // Serialization int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override; diff --git a/poincare/include/poincare/derivative.h b/poincare/include/poincare/derivative.h index 04f5ab069..9b5f6f3e5 100644 --- a/poincare/include/poincare/derivative.h +++ b/poincare/include/poincare/derivative.h @@ -20,11 +20,11 @@ public: #endif // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } // Properties Type type() const override { return Type::Derivative; } - int polynomialDegree(Context & context, const char * symbolName) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; private: // Layout @@ -32,15 +32,15 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; - template T approximateWithArgument(T x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; - template T growthRateAroundAbscissa(T x, T h, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; - template T riddersApproximation(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, T x, T h, T * error) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template T approximateWithArgument(T x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template T growthRateAroundAbscissa(T x, T h, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template T riddersApproximation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, T x, T h, T * error) const; // TODO: Change coefficients? constexpr static double k_maxErrorRateOnApproximation = 0.001; constexpr static double k_minInitialRate = 0.01; @@ -54,7 +54,7 @@ public: static Expression UntypedBuilder(Expression children); static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("diff", 3, &UntypedBuilder); - Expression shallowReduce(Context & context); + Expression shallowReduce(Context * context); }; } diff --git a/poincare/include/poincare/determinant.h b/poincare/include/poincare/determinant.h index a05d361bd..903760908 100644 --- a/poincare/include/poincare/determinant.h +++ b/poincare/include/poincare/determinant.h @@ -24,11 +24,11 @@ private: /* Serialization */ int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; /* Simplification */ - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; /* Approximation */ - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; @@ -39,7 +39,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("det", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context); + Expression shallowReduce(Context * context); }; } diff --git a/poincare/include/poincare/division.h b/poincare/include/poincare/division.h index 95593c3f0..d9917bdd6 100644 --- a/poincare/include/poincare/division.h +++ b/poincare/include/poincare/division.h @@ -24,16 +24,16 @@ public: // Properties Type type() const override { return Type::Division; } - int polynomialDegree(Context & context, const char * symbolName) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; // Approximation - virtual Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + virtual Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce( this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } - virtual Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + virtual Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce( this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, @@ -46,7 +46,7 @@ public: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; private: // Approximation @@ -64,7 +64,7 @@ public: static Division Builder() { return TreeHandle::FixedArityBuilder(); } static Division Builder(Expression numerator, Expression denominator) { return TreeHandle::FixedArityBuilder(ArrayBuilder(numerator, denominator).array(), 2); } - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/division_quotient.h b/poincare/include/poincare/division_quotient.h index 300854396..1a32d57a2 100644 --- a/poincare/include/poincare/division_quotient.h +++ b/poincare/include/poincare/division_quotient.h @@ -21,18 +21,18 @@ public: Type type() const override { return Type::DivisionQuotient; } // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class DivisionQuotient final : public Expression { diff --git a/poincare/include/poincare/division_remainder.h b/poincare/include/poincare/division_remainder.h index 6069d92d9..a1b0113a7 100644 --- a/poincare/include/poincare/division_remainder.h +++ b/poincare/include/poincare/division_remainder.h @@ -22,18 +22,18 @@ public: Type type() const override { return Type::DivisionRemainder; } // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class DivisionRemainder final : public Expression { diff --git a/poincare/include/poincare/empty_expression.h b/poincare/include/poincare/empty_expression.h index 80b83ead8..a0332b9bf 100644 --- a/poincare/include/poincare/empty_expression.h +++ b/poincare/include/poincare/empty_expression.h @@ -26,9 +26,9 @@ private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class EmptyExpression final : public Expression { diff --git a/poincare/include/poincare/equal.h b/poincare/include/poincare/equal.h index 0df94cf24..b32f84e59 100644 --- a/poincare/include/poincare/equal.h +++ b/poincare/include/poincare/equal.h @@ -19,17 +19,17 @@ public: // ExpressionNode Type type() const override { return Type::Equal; } - int polynomialDegree(Context & context, const char * symbolName) const override { return -1; } + int polynomialDegree(Context * context, const char * symbolName) const override { return -1; } private: // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Evalutation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class Equal final : public Expression { @@ -38,7 +38,7 @@ public: static Equal Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } // For the equation A = B, create the reduced expression A-B - Expression standardEquation(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Expression standardEquation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; // Expression Expression shallowReduce(); }; diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index e5313d4d4..e277d0ab7 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -130,15 +130,15 @@ public: bool isRationalOne() const; bool isRandom() const { return node()->isRandom(); } bool isParameteredExpression() const { return node()->isParameteredExpression(); } - typedef bool (*ExpressionTest)(const Expression e, Context & context); - bool recursivelyMatches(ExpressionTest test, Context & context, bool replaceSymbols = true) const; + typedef bool (*ExpressionTest)(const Expression e, Context * context); + bool recursivelyMatches(ExpressionTest test, Context * context, bool replaceSymbols = true) const; // Set of ExpressionTest that can be used with recursivelyMatches - static bool IsNAry(const Expression e, Context & context); - static bool IsApproximate(const Expression e, Context & context); - static bool IsRandom(const Expression e, Context & context); - static bool IsMatrix(const Expression e, Context & context); - static bool SortedIsMatrix(const Expression e, Context & context); - static bool IsInfinity(const Expression e, Context & context); + static bool IsNAry(const Expression e, Context * context); + static bool IsApproximate(const Expression e, Context * context); + static bool IsRandom(const Expression e, Context * context); + static bool IsMatrix(const Expression e, Context * context); + static bool SortedIsMatrix(const Expression e, Context * context); + static bool IsInfinity(const Expression e, Context * context); /* 'characteristicXRange' tries to assess the range on x where the expression * (considered as a function on x) has an interesting evolution. For example, * the period of the function on 'x' if it is periodic. If @@ -147,11 +147,11 @@ 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. */ - float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { return node()->characteristicXRange(context, angleUnit); } + float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const { return node()->characteristicXRange(context, angleUnit); } /* polynomialDegree returns: * - (-1) if the expression is not a polynome * - the degree of the polynome otherwise */ - int polynomialDegree(Context & context, const char * symbolName) const { return this->node()->polynomialDegree(context, symbolName); } + int polynomialDegree(Context * context, const char * symbolName) const { return this->node()->polynomialDegree(context, symbolName); } /* getVariables fills the matrix variables with the symbols in the expression * that pass the test isVariable. It returns the number of entries filled in * variables. For instance, getVariables of 'x+y+2*w/cos(4)' would result in @@ -160,19 +160,19 @@ public: * If one of the variable lengths overflows maxVariableLength, getVariables * returns -2. */ static constexpr int k_maxNumberOfVariables = 6; - int getVariables(Context & context, ExpressionNode::isVariableTest isVariable, char * variables, int maxVariableLength) const { return node()->getVariables(context, isVariable, variables, maxVariableLength); } + int getVariables(Context * context, ExpressionNode::isVariableTest isVariable, char * variables, int maxVariableLength) const { return node()->getVariables(context, isVariable, variables, maxVariableLength); } /* getLinearCoefficients return false if the expression is not linear with * the variables hold in 'variables'. Otherwise, it fills 'coefficients' with * the coefficients of the variables hold in 'variables' (following the same * order) and 'constant' with the constant of the expression. */ - bool getLinearCoefficients(char * variables, int maxVariableLength, Expression coefficients[], Expression constant[], Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + bool getLinearCoefficients(char * variables, int maxVariableLength, Expression coefficients[], Expression constant[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; /* getPolynomialCoefficients fills the table coefficients with the expressions * of the first 3 polynomial coefficients and returns the polynomial degree. * It is supposed to be called on a reduced expression. * coefficients has up to 3 entries. */ static constexpr int k_maxPolynomialDegree = 2; static constexpr int k_maxNumberOfPolynomialCoefficients = k_maxPolynomialDegree+1; - int getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + int getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { return node()->replaceSymbolWithExpression(symbol, expression); } Expression replaceUnknown(const Symbol & symbol, const Symbol & unknownSymbol); Expression defaultReplaceUnknown(const Symbol & symbol, const Symbol & unknownSymbol); @@ -181,15 +181,15 @@ public: static bool EncounteredComplex(); static void SetEncounteredComplex(bool encounterComplex); static Preferences::ComplexFormat UpdatedComplexFormatWithTextInput(Preferences::ComplexFormat complexFormat, const char * textInput); - static Preferences::ComplexFormat UpdatedComplexFormatWithExpressionInput(Preferences::ComplexFormat complexFormat, const Expression & e, Context & context); - bool isReal(Context & context) const { return node()->isReal(context); } + static Preferences::ComplexFormat UpdatedComplexFormatWithExpressionInput(Preferences::ComplexFormat complexFormat, const Expression & e, Context * context); + bool isReal(Context * context) const { return node()->isReal(context); } /* Comparison */ /* isIdenticalTo is the "easy" equality, it returns true if both trees have * same structures and all their nodes have same types and values (ie, * sqrt(pi^2) is NOT identical to pi). */ bool isIdenticalTo(const Expression e) const; - bool isEqualToItsApproximationLayout(Expression approximation, char * buffer, int bufferSize, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, Context & context); + bool isEqualToItsApproximationLayout(Expression approximation, char * buffer, int bufferSize, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, Context * context); /* Layout Helper */ Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const; @@ -206,34 +206,34 @@ public: * account the complex format required in the expression they return. * (For instance, in Polar mode, they return an expression of the form * r*e^(i*th) reduced and approximated.) */ - static Expression ParseAndSimplify(const char * text, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); - Expression simplify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); + static Expression ParseAndSimplify(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); + Expression simplify(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); - static void ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); - void simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); - Expression reduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); + static void ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); + void simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); + Expression reduce(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Expression mapOnMatrixChild(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); - static Expression ExpressionWithoutSymbols(Expression expressionWithSymbols, Context & context); + Expression mapOnMatrixChild(ExpressionNode::ReductionContext reductionContext); + static Expression ExpressionWithoutSymbols(Expression expressionWithSymbols, Context * context); Expression radianToDegree(); Expression degreeToRadian(); /* Approximation Helper */ // These methods reset the sApproximationEncounteredComplex flag. They should not be use to implement node approximation template static U Epsilon(); - template Expression approximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; - template U approximateToScalar(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; - template static U ApproximateToScalar(const char * text, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); - template U approximateWithValueForSymbol(const char * symbol, U x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template Expression approximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template U approximateToScalar(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template static U ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true); + template U approximateWithValueForSymbol(const char * symbol, U x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; /* Expression roots/extrema solver */ struct Coordinate2D { double abscissa; double value; }; - 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 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; /* 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. @@ -303,10 +303,10 @@ protected: void removeChildrenInPlace(int currentNumberOfChildren) = delete; /* Properties */ - int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { return node()->getPolynomialCoefficients(context, symbolName, coefficients); } - bool hasReplaceableSymbols(Context & context) const; - Expression shallowReplaceReplaceableSymbols(Context & context) { return node()->shallowReplaceReplaceableSymbols(context); } - Expression defaultReplaceReplaceableSymbols(Context & context); + int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { return node()->getPolynomialCoefficients(context, symbolName, coefficients); } + bool hasReplaceableSymbols(Context * context) const; + Expression shallowReplaceReplaceableSymbols(Context * context) { return node()->shallowReplaceReplaceableSymbols(context); } + Expression defaultReplaceReplaceableSymbols(Context * context); /* Simplification */ /* makePositiveAnyNegativeNumeralFactor looks for: @@ -317,31 +317,31 @@ protected: * is reduced (only a numeral factor was potentially made positive, and if it * was -1, it was removed from the multiplication). */ - Expression makePositiveAnyNegativeNumeralFactor(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return node()->denominator(context, complexFormat, angleUnit); } - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation = true) { return node()->shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); } - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { return node()->shallowBeautify(context, complexFormat, angleUnit, target); } - Expression deepBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression makePositiveAnyNegativeNumeralFactor(ExpressionNode::ReductionContext reductionContext); + Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return node()->denominator(context, complexFormat, angleUnit); } + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext) { return node()->shallowReduce(reductionContext); } + Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext) { return node()->shallowBeautify(reductionContext); } + Expression deepBeautify(ExpressionNode::ReductionContext reductionContext); + Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext); private: static constexpr int k_maxSymbolReplacementsCount = 10; static bool sSymbolReplacementsCountLock; /* Simplification */ - Expression deepReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation = true); - void deepReduceChildren(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation = true) { - return node()->deepReduceChildren(context, complexFormat, angleUnit, target, symbolicComputation); + Expression deepReduce(ExpressionNode::ReductionContext reductionContext); + void deepReduceChildren(ExpressionNode::ReductionContext reductionContext) { + return node()->deepReduceChildren(reductionContext); } - void defaultDeepReduceChildren(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation = true); + void defaultDeepReduceChildren(ExpressionNode::ReductionContext reductionContext); Expression defaultShallowReduce(); Expression defaultShallowBeautify() { return *this; } /* Approximation */ - template Evaluation approximateToEvaluation(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template Evaluation approximateToEvaluation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; /* Properties */ Expression defaultReplaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression expression); - int defaultGetPolynomialCoefficients(Context & context, const char * symbol, Expression expression[]) const; + int defaultGetPolynomialCoefficients(Context * context, const char * symbol, Expression expression[]) const; /* Builder */ static bool IsZero(const Expression e); @@ -354,13 +354,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)(const char * symbol, double abscissa, Context & context, Preferences::ComplexFormat complexFormat, 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::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], EvaluationAtAbscissa evaluation, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression = Expression()) const; - Coordinate2D brentMinimum(const char * symbol, double ax, double bx, EvaluationAtAbscissa 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, EvaluationAtAbscissa 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], EvaluationAtAbscissa evaluation, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const; - double brentRoot(const char * symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const; + typedef double (*EvaluationAtAbscissa)(const char * symbol, double abscissa, Context * context, Preferences::ComplexFormat complexFormat, 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::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], EvaluationAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression = Expression()) const; + Coordinate2D brentMinimum(const char * symbol, double ax, double bx, EvaluationAtAbscissa 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, EvaluationAtAbscissa 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], EvaluationAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const; + double brentRoot(const char * symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const; }; } diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index 917af418f..dd5ba066d 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -113,23 +113,46 @@ public: Unknown = 0, Positive = 1 }; + + class ReductionContext { + public: + ReductionContext(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation = true) : + m_context(context), + m_complexFormat(complexFormat), + m_angleUnit(angleUnit), + m_target(target), + m_symbolicComputation(symbolicComputation) + {} + Context * context() { return m_context; } + Preferences::ComplexFormat complexFormat() const { return m_complexFormat; } + Preferences::AngleUnit angleUnit() const { return m_angleUnit; } + ReductionTarget target() const { return m_target; } + bool symbolicComputation() const { return m_symbolicComputation; } + private: + Context * m_context; + Preferences::ComplexFormat m_complexFormat; + Preferences::AngleUnit m_angleUnit; + ReductionTarget m_target; + bool m_symbolicComputation; + }; + virtual Sign sign(Context * context) const { return Sign::Unknown; } virtual bool isNumber() const { return false; } virtual bool isRandom() const { return false; } virtual bool isParameteredExpression() const { return false; } /*!*/ virtual Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression); /*!*/ virtual Expression replaceUnknown(const Symbol & symbol, const Symbol & unknownSymbol); - /*!*/ virtual Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target); - virtual int polynomialDegree(Context & context, const char * symbolName) const; - /*!*/ virtual int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const; - /*!*/ virtual Expression shallowReplaceReplaceableSymbols(Context & context); + /*!*/ virtual Expression setSign(Sign s, ReductionContext reductionContext); + virtual int polynomialDegree(Context * context, const char * symbolName) const; + /*!*/ virtual int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const; + /*!*/ virtual Expression shallowReplaceReplaceableSymbols(Context * context); typedef bool (*isVariableTest)(const char * c); - virtual int getVariables(Context & context, isVariableTest isVariable, char * variables, int maxSizeVariable) const; - virtual float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const; + virtual int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const; + virtual float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const; bool isOfType(Type * types, int length) const; /* Complex */ - virtual bool isReal(Context & context) const { return false; } + virtual bool isReal(Context * context) const { return false; } /* Simplification */ /* SimplificationOrder returns: @@ -159,15 +182,15 @@ public: typedef float SinglePrecision; typedef double DoublePrecision; constexpr static int k_maxNumberOfSteps = 10000; - virtual Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const = 0; - virtual Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const = 0; + virtual Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const = 0; + virtual Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const = 0; /* Simplification */ - /*!*/ virtual void deepReduceChildren(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation); - /*!*/ virtual Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation); - /*!*/ virtual Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target); + /*!*/ virtual void deepReduceChildren(ReductionContext reductionContext); + /*!*/ virtual Expression shallowReduce(ReductionContext reductionContext); + /*!*/ virtual Expression shallowBeautify(ReductionContext reductionContext); /* Return a clone of the denominator part of the expression */ - /*!*/ virtual Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + /*!*/ virtual Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; /* Hierarchy */ ExpressionNode * childAtIndex(int i) const override { return static_cast(TreeNode::childAtIndex(i)); } diff --git a/poincare/include/poincare/factor.h b/poincare/include/poincare/factor.h index 8ca451238..67abb3b7c 100644 --- a/poincare/include/poincare/factor.h +++ b/poincare/include/poincare/factor.h @@ -25,11 +25,11 @@ private: /* Serialization */ int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; /* Simplification */ - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression shallowBeautify(ReductionContext reductionContext) override; /* Evaluation */ - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); } }; @@ -41,8 +41,8 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("factor", 1, &UntypedBuilderOneChild); - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Multiplication createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + Multiplication createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; } diff --git a/poincare/include/poincare/factorial.h b/poincare/include/poincare/factorial.h index 06bfec105..b1f58bab5 100644 --- a/poincare/include/poincare/factorial.h +++ b/poincare/include/poincare/factorial.h @@ -21,10 +21,10 @@ public: // Properties Type type() const override { return Type::Factorial; } Sign sign(Context * context) const override { return Sign::Positive; } - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression setSign(Sign s, ReductionContext reductionContext) override; // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout @@ -32,14 +32,14 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplication - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression shallowReduce(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } @@ -54,7 +54,7 @@ public: Factorial(const FactorialNode * n) : Expression(n) {} static Factorial Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); Expression shallowBeautify(); private: constexpr static int k_maxOperandValue = 100; diff --git a/poincare/include/poincare/float.h b/poincare/include/poincare/float.h index 9ecdaab70..8d308455f 100644 --- a/poincare/include/poincare/float.h +++ b/poincare/include/poincare/float.h @@ -38,7 +38,7 @@ public: // Properties Type type() const override { return Type::Float; } Sign sign(Context * context) const override { return m_value < 0 ? Sign::Negative : Sign::Positive; } - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression setSign(Sign s, ReductionContext reductionContext) override; int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; // Layout @@ -46,10 +46,10 @@ public: /* Layout */ Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; /* Evaluation */ - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } private: - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return Complex::Builder((U)m_value); } T m_value; diff --git a/poincare/include/poincare/floor.h b/poincare/include/poincare/floor.h index 2b56b4a52..ae1fc48af 100644 --- a/poincare/include/poincare/floor.h +++ b/poincare/include/poincare/floor.h @@ -23,20 +23,20 @@ public: // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -48,7 +48,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("floor", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/frac_part.h b/poincare/include/poincare/frac_part.h index 80f7c3008..d532fd5f3 100644 --- a/poincare/include/poincare/frac_part.h +++ b/poincare/include/poincare/frac_part.h @@ -23,20 +23,20 @@ public: // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -48,7 +48,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("frac", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/function.h b/poincare/include/poincare/function.h index 94422cb2a..aad9921ab 100644 --- a/poincare/include/poincare/function.h +++ b/poincare/include/poincare/function.h @@ -24,13 +24,13 @@ public: // Properties Type type() const override { return Type::Function; } Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) override; - int polynomialDegree(Context & context, const char * symbolName) const override; - int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const override; - int getVariables(Context & context, isVariableTest isVariable, char * variables, int maxSizeVariable) const override; - float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; + int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const override; + int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const override; + float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override; // Complex - bool isReal(Context & context) const override; + bool isReal(Context * context) const override; private: char m_name[0]; // MUST be the last member variable @@ -40,12 +40,12 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; - Expression shallowReplaceReplaceableSymbols(Context & context) override; + Expression shallowReduce(ReductionContext reductionContext) override; + Expression shallowReplaceReplaceableSymbols(Context * context) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class Function : public SymbolAbstract { @@ -57,8 +57,8 @@ public: // Simplification Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); - Expression shallowReplaceReplaceableSymbols(Context & context); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); + Expression shallowReplaceReplaceableSymbols(Context * context); private: //VariableContext unknownXContext(Context & parentContext) const; }; diff --git a/poincare/include/poincare/great_common_divisor.h b/poincare/include/poincare/great_common_divisor.h index 07bb195e7..5c9c1fa8d 100644 --- a/poincare/include/poincare/great_common_divisor.h +++ b/poincare/include/poincare/great_common_divisor.h @@ -20,18 +20,18 @@ public: // ExpressionNode Type type() const override { return Type::GreatCommonDivisor; } // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class GreatCommonDivisor final : public Expression { diff --git a/poincare/include/poincare/hyperbolic_arc_cosine.h b/poincare/include/poincare/hyperbolic_arc_cosine.h index 59f6e725f..f4a6ef928 100644 --- a/poincare/include/poincare/hyperbolic_arc_cosine.h +++ b/poincare/include/poincare/hyperbolic_arc_cosine.h @@ -25,10 +25,10 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; diff --git a/poincare/include/poincare/hyperbolic_arc_sine.h b/poincare/include/poincare/hyperbolic_arc_sine.h index 5f8b4d4b7..6e05ccd4e 100644 --- a/poincare/include/poincare/hyperbolic_arc_sine.h +++ b/poincare/include/poincare/hyperbolic_arc_sine.h @@ -25,10 +25,10 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; diff --git a/poincare/include/poincare/hyperbolic_arc_tangent.h b/poincare/include/poincare/hyperbolic_arc_tangent.h index 2244efbf5..0280ab98b 100644 --- a/poincare/include/poincare/hyperbolic_arc_tangent.h +++ b/poincare/include/poincare/hyperbolic_arc_tangent.h @@ -25,10 +25,10 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; diff --git a/poincare/include/poincare/hyperbolic_cosine.h b/poincare/include/poincare/hyperbolic_cosine.h index 67ab4cf80..749540b8e 100644 --- a/poincare/include/poincare/hyperbolic_cosine.h +++ b/poincare/include/poincare/hyperbolic_cosine.h @@ -25,10 +25,10 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; diff --git a/poincare/include/poincare/hyperbolic_sine.h b/poincare/include/poincare/hyperbolic_sine.h index 6686b4647..2f29c8cc9 100644 --- a/poincare/include/poincare/hyperbolic_sine.h +++ b/poincare/include/poincare/hyperbolic_sine.h @@ -25,10 +25,10 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; diff --git a/poincare/include/poincare/hyperbolic_tangent.h b/poincare/include/poincare/hyperbolic_tangent.h index ba6ec8693..4e76beccf 100644 --- a/poincare/include/poincare/hyperbolic_tangent.h +++ b/poincare/include/poincare/hyperbolic_tangent.h @@ -25,10 +25,10 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; //Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; diff --git a/poincare/include/poincare/hyperbolic_trigonometric_function.h b/poincare/include/poincare/hyperbolic_trigonometric_function.h index ae6884dcc..fa504a0d6 100644 --- a/poincare/include/poincare/hyperbolic_trigonometric_function.h +++ b/poincare/include/poincare/hyperbolic_trigonometric_function.h @@ -12,13 +12,13 @@ public: int numberOfChildren() const override { return 1; } private: // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; }; class HyperbolicTrigonometricFunction : public Expression { public: HyperbolicTrigonometricFunction(const HyperbolicTrigonometricFunctionNode * n) : Expression(n) {} - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/imaginary_part.h b/poincare/include/poincare/imaginary_part.h index a9b760aa1..5515f7010 100644 --- a/poincare/include/poincare/imaginary_part.h +++ b/poincare/include/poincare/imaginary_part.h @@ -22,22 +22,22 @@ public: Type type() const override { return Type::ImaginaryPart; } // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { return Complex::Builder(std::imag(c)); } - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -49,7 +49,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("im", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/infinity.h b/poincare/include/poincare/infinity.h index b1b552394..abd565856 100644 --- a/poincare/include/poincare/infinity.h +++ b/poincare/include/poincare/infinity.h @@ -9,8 +9,6 @@ class InfinityNode final : public NumberNode { public: InfinityNode(bool negative) : NumberNode(), m_negative(negative) {} - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; - // TreeNode size_t size() const override { return sizeof(InfinityNode); } #if POINCARE_TREE_LOG @@ -25,12 +23,13 @@ public: // Properties Type type() const override { return Type::Infinity; } Sign sign(Context * context) const override { return m_negative ? Sign::Negative : Sign::Positive; } + Expression setSign(Sign s, ReductionContext reductionContext) override; // Approximation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(); } @@ -46,7 +45,7 @@ class Infinity final : public Number { public: Infinity(InfinityNode * n) : Number(n) {} static Infinity Builder(bool negative); - Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); + Expression setSign(ExpressionNode::Sign s); static const char * Name() { return "inf"; } diff --git a/poincare/include/poincare/integral.h b/poincare/include/poincare/integral.h index 1f8d31dd6..05fc1c72e 100644 --- a/poincare/include/poincare/integral.h +++ b/poincare/include/poincare/integral.h @@ -20,21 +20,21 @@ public: // ExpressionNode Type type() const override { return Type::Integral; } - int polynomialDegree(Context & context, const char * symbolName) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; template struct DetailedResult { @@ -43,12 +43,12 @@ private: }; constexpr static int k_maxNumberOfIterations = 20; #ifdef LAGRANGE_METHOD - template T lagrangeGaussQuadrature(T a, T b, Context Context & context, Preferences::AngleUnit angleUnit context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template T lagrangeGaussQuadrature(T a, T b, Context Context * context, Preferences::AngleUnit angleUnit context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; #else - template DetailedResult kronrodGaussQuadrature(T a, T b, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; - template T adaptiveQuadrature(T a, T b, T eps, int numberOfIterations, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template DetailedResult kronrodGaussQuadrature(T a, T b, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template T adaptiveQuadrature(T a, T b, T eps, int numberOfIterations, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; #endif - template T functionValueAtAbscissa(T x, Context & xcontext, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template T functionValueAtAbscissa(T x, Context * xcontext, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class Integral final : public ParameteredExpression { @@ -60,7 +60,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("int", 4, &UntypedBuilder); // Expression - Expression shallowReduce(Context & context); + Expression shallowReduce(Context * context); }; } diff --git a/poincare/include/poincare/least_common_multiple.h b/poincare/include/poincare/least_common_multiple.h index 07c36a413..b46bd14e4 100644 --- a/poincare/include/poincare/least_common_multiple.h +++ b/poincare/include/poincare/least_common_multiple.h @@ -20,18 +20,18 @@ public: Type type() const override { return Type::LeastCommonMultiple; } // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: /* Layout */ Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; /* Simplification */ - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; /* Evaluation */ - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class LeastCommonMultiple final : public Expression { diff --git a/poincare/include/poincare/logarithm.h b/poincare/include/poincare/logarithm.h index 1e8bf22f6..6bb32e06c 100644 --- a/poincare/include/poincare/logarithm.h +++ b/poincare/include/poincare/logarithm.h @@ -27,8 +27,8 @@ public: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression shallowReduce(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { /* log has a branch cut on ]-inf, 0]: it is then multivalued on this cut. We @@ -36,9 +36,9 @@ public: * (warning: log takes the other side of the cut values on ]-inf-0i, 0-0i]). */ return Complex::Builder(std::log10(c)); } - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class Logarithm final : public Expression { @@ -47,13 +47,13 @@ public: static Logarithm Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder>(ArrayBuilder(child0, child1).array(), 2); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("log", 2, &UntypedBuilderTwoChildren); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); Expression shallowBeautify(); private: - Expression simpleShallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); + Expression simpleShallowReduce(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Integer simplifyLogarithmIntegerBaseInteger(Integer i, Integer & base, Addition & a, bool isDenominator); - Expression splitLogarithmInteger(Integer i, bool isDenominator, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression splitLogarithmInteger(Integer i, bool isDenominator, ExpressionNode::ReductionContext reductionContext); bool parentIsAPowerOfSameBase() const; }; @@ -64,7 +64,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("log", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/matrix.h b/poincare/include/poincare/matrix.h index d042bc939..be28da009 100644 --- a/poincare/include/poincare/matrix.h +++ b/poincare/include/poincare/matrix.h @@ -36,13 +36,13 @@ public: // Properties Type type() const override { return Type::Matrix; } - int polynomialDegree(Context & context, const char * symbolName) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; // Approximation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } @@ -50,7 +50,7 @@ public: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override; private: - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; /* We could store 2 uint8_t but multiplying m_numberOfRows and * m_numberOfColumns could then lead to overflow. As we are unlikely to use * greater matrix than 100*100, uint16_t is fine. */ @@ -73,7 +73,7 @@ public: Expression matrixChild(int i, int j) { return childAtIndex(i*numberOfColumns()+j); } /* Operation on matrix */ - int rank(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool inPlace = false); + int rank(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool inPlace = false); // Inverse the array in-place. Array has to be given in the form array[row_index][column_index] template static int ArrayInverse(T * array, int numberOfRows, int numberOfColumns); #if MATRIX_EXACT_REDUCING @@ -82,7 +82,7 @@ public: Matrix transpose() const; static Matrix CreateIdentity(int dim); /* createInverse can be called on any matrix reduce or not, approximate or not. */ - Expression inverse(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Expression inverse(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; #endif // TODO: find another solution for inverse and determinant (avoid capping the matrix) static constexpr int k_maxNumberOfCoefficients = 100; @@ -91,7 +91,7 @@ private: void setNumberOfRows(int rows) { assert(rows >= 0); node()->setNumberOfRows(rows); } void setNumberOfColumns(int columns) { assert(columns >= 0); node()->setNumberOfColumns(columns); } /* rowCanonize turns a matrix in its reduced row echelon form. */ - Matrix rowCanonize(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Multiplication m = Multiplication::Builder()); + Matrix rowCanonize(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Multiplication m = Multiplication::Builder()); // Row canonize the array in place template static void ArrayRowCanonize(T * array, int numberOfRows, int numberOfColumns, T * c = nullptr); }; diff --git a/poincare/include/poincare/matrix_dimension.h b/poincare/include/poincare/matrix_dimension.h index e72a4c946..c8f24657e 100644 --- a/poincare/include/poincare/matrix_dimension.h +++ b/poincare/include/poincare/matrix_dimension.h @@ -25,11 +25,11 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class MatrixDimension final : public Expression { diff --git a/poincare/include/poincare/matrix_identity.h b/poincare/include/poincare/matrix_identity.h index b12b29631..9dc9f9bd2 100644 --- a/poincare/include/poincare/matrix_identity.h +++ b/poincare/include/poincare/matrix_identity.h @@ -23,11 +23,11 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class MatrixIdentity final : public Expression { @@ -37,7 +37,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("identity", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/matrix_inverse.h b/poincare/include/poincare/matrix_inverse.h index 84c843bf6..b7149dfea 100644 --- a/poincare/include/poincare/matrix_inverse.h +++ b/poincare/include/poincare/matrix_inverse.h @@ -24,11 +24,11 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class MatrixInverse final : public Expression { @@ -38,7 +38,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("inverse", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/matrix_trace.h b/poincare/include/poincare/matrix_trace.h index 3f7ce6de5..cf130c12a 100644 --- a/poincare/include/poincare/matrix_trace.h +++ b/poincare/include/poincare/matrix_trace.h @@ -24,11 +24,11 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class MatrixTrace final : public Expression { diff --git a/poincare/include/poincare/matrix_transpose.h b/poincare/include/poincare/matrix_transpose.h index 25624c6ef..89b0c1257 100644 --- a/poincare/include/poincare/matrix_transpose.h +++ b/poincare/include/poincare/matrix_transpose.h @@ -24,11 +24,11 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class MatrixTranspose final : public Expression { diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index 57bf6ac21..c0a787d07 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -22,8 +22,8 @@ public: // Properties Type type() const override { return Type::Multiplication; } Sign sign(Context * context) const override; - int polynomialDegree(Context & context, const char * symbolName) const override; - int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; + int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const override; // Approximation template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { return Complex::Builder(c*d); } @@ -34,7 +34,7 @@ public: private: // Property - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression setSign(Sign s, ReductionContext reductionContext) override; // Layout bool childNeedsParenthesis(const TreeNode * child) const override; @@ -44,18 +44,18 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; - Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; + Expression shallowReduce(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext reductionContext) override; + Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; /* Approximation */ template static MatrixComplex computeOnMatrixAndComplex(const MatrixComplex m, const std::complex c, Preferences::ComplexFormat complexFormat) { return ApproximationHelper::ElementWiseOnMatrixComplexAndComplex(m, c, complexFormat, compute); } - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce(this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce(this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } }; @@ -73,24 +73,24 @@ public: template static void computeOnArrays(T * m, T * n, T * result, int mNumberOfColumns, int mNumberOfRows, int nNumberOfColumns); // Expression - Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const; - Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); + Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); + int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const; + Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; private: // Constructors static Multiplication Builder(Expression * children, size_t numberOfChildren) { return TreeHandle::NAryBuilder(children, numberOfChildren); } // Simplification - Expression privateShallowReduce(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool expand, bool canBeInterrupted); + Expression privateShallowReduce(ExpressionNode::ReductionContext reductionContext, bool expand, bool canBeInterrupted); void mergeMultiplicationChildrenInPlace(); - void factorizeBase(int i, int j, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - void mergeInChildByFactorizingBase(int i, Expression e, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - void factorizeExponent(int i, int j, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - Expression distributeOnOperandAtIndex(int index, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - void addMissingFactors(Expression factor, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - void factorizeSineAndCosine(int i, int j, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); + void factorizeBase(int i, int j, ExpressionNode::ReductionContext reductionContext); + void mergeInChildByFactorizingBase(int i, Expression e, ExpressionNode::ReductionContext reductionContext); + void factorizeExponent(int i, int j, ExpressionNode::ReductionContext reductionContext); + Expression distributeOnOperandAtIndex(int index, ExpressionNode::ReductionContext reductionContext); + void addMissingFactors(Expression factor, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); + void factorizeSineAndCosine(int i, int j, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); static bool HaveSameNonNumeralFactors(const Expression & e1, const Expression & e2); static bool TermsHaveIdenticalBase(const Expression & e1, const Expression & e2); static bool TermsHaveIdenticalExponent(const Expression & e1, const Expression & e2); @@ -99,7 +99,7 @@ private: static const Expression CreateExponent(Expression e); /* Warning: mergeNegativePower doesnot always return a multiplication: * *(b^-1,c^-1) -> (bc)^-1 */ - Expression mergeNegativePower(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); + Expression mergeNegativePower(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); static inline const Expression Base(const Expression e); }; diff --git a/poincare/include/poincare/n_ary_expression.h b/poincare/include/poincare/n_ary_expression.h index 94008a1c6..deeabdae1 100644 --- a/poincare/include/poincare/n_ary_expression.h +++ b/poincare/include/poincare/n_ary_expression.h @@ -10,7 +10,6 @@ namespace Poincare { class NAryExpressionNode : public ExpressionNode { // TODO: VariableArityExpressionNode? public: void setChildrenInPlace(Expression other) override { assert(false); } - static bool IsMatrix(Expression e, Context & context); //Tree int numberOfChildren() const override { return m_numberOfChildren; } @@ -22,7 +21,7 @@ public: void eraseNumberOfChildren() override { m_numberOfChildren = 0; } // Complex - bool isReal(Context & context) const override; + bool isReal(Context * context) const override; // Comparison typedef int (*ExpressionOrder)(const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted); @@ -58,8 +57,8 @@ public: * - 1 if all children are real * - 0 if all non real children are ComplexCartesian * - -1 if some chidren are non-real and non ComplexCartesian */ - int allChildrenAreReal(Context & context) const; - static bool SortedIsMatrix(Expression e, Context & context); // this is supposed to be a sorted + int allChildrenAreReal(Context * context) const; + static bool SortedIsMatrix(Expression e, Context * context); // this is supposed to be a sorted protected: NAryExpressionNode * node() const { return static_cast(Expression::node()); } }; diff --git a/poincare/include/poincare/naperian_logarithm.h b/poincare/include/poincare/naperian_logarithm.h index f227a81ca..0c82860ff 100644 --- a/poincare/include/poincare/naperian_logarithm.h +++ b/poincare/include/poincare/naperian_logarithm.h @@ -25,7 +25,7 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; /* Evaluation */ template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { /* ln has a branch cut on ]-inf, 0]: it is then multivalued on this cut. We @@ -33,10 +33,10 @@ private: * (warning: ln takes the other side of the cut values on ]-inf-0i, 0-0i]). */ return Complex::Builder(std::log(c)); } - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -48,7 +48,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ln", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/nth_root.h b/poincare/include/poincare/nth_root.h index b0554785d..d6d9728f5 100644 --- a/poincare/include/poincare/nth_root.h +++ b/poincare/include/poincare/nth_root.h @@ -24,11 +24,11 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; @@ -38,7 +38,7 @@ public: static NthRoot Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("root", 2, &UntypedBuilderTwoChildren); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/number.h b/poincare/include/poincare/number.h index aee56a55c..ebc9d2d3b 100644 --- a/poincare/include/poincare/number.h +++ b/poincare/include/poincare/number.h @@ -25,7 +25,7 @@ public: double doubleApproximation() const; // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } }; class Number : public Expression { @@ -51,7 +51,7 @@ public: ExpressionNode::Sign sign() { return Expression::sign(nullptr); } Number setSign(ExpressionNode::Sign s) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); - return Expression::setSign(s, nullptr, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Degree, ExpressionNode::ReductionTarget::User).convert(); + return Expression::setSign(s, ExpressionNode::ReductionContext(nullptr, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Degree, ExpressionNode::ReductionTarget::User)).convert(); } protected: Number() : Expression() {} diff --git a/poincare/include/poincare/opposite.h b/poincare/include/poincare/opposite.h index e3a1211f0..1a74cf57d 100644 --- a/poincare/include/poincare/opposite.h +++ b/poincare/include/poincare/opposite.h @@ -24,14 +24,14 @@ public: // Properties Type type() const override { return Type::Opposite; } - int polynomialDegree(Context & context, const char * symbolName) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; Sign sign(Context * context) const override; // Approximation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, compute); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, compute); } @@ -41,7 +41,7 @@ public: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; }; class Opposite final : public Expression { @@ -50,7 +50,7 @@ public: static Opposite Builder() { return TreeHandle::FixedArityBuilder(); } static Opposite Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/parenthesis.h b/poincare/include/poincare/parenthesis.h index 245e41581..b89db7c18 100644 --- a/poincare/include/poincare/parenthesis.h +++ b/poincare/include/poincare/parenthesis.h @@ -20,19 +20,19 @@ public: // Properties Type type() const override { return Type::Parenthesis; } - int polynomialDegree(Context & context, const char * symbolName) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Approximation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } private: - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class Parenthesis final : public Expression { diff --git a/poincare/include/poincare/permute_coefficient.h b/poincare/include/poincare/permute_coefficient.h index f068a225c..84f66254c 100644 --- a/poincare/include/poincare/permute_coefficient.h +++ b/poincare/include/poincare/permute_coefficient.h @@ -24,18 +24,18 @@ public: Type type() const override{ return Type::PermuteCoefficient; } // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class PermuteCoefficient final : public Expression { diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index eccb7093d..526abad8e 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -22,15 +22,15 @@ public: #endif // Complex - bool isReal(Context & context) const override; + bool isReal(Context * context) const override; // Properties Type type() const override { return Type::Power; } Sign sign(Context * context) const override; - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression setSign(Sign s, ReductionContext reductionContext) override; - int polynomialDegree(Context & context, const char * symbolName) const override; - int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; + int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const override; template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat); @@ -45,19 +45,19 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplify - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression shallowReduce(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext reductionContext) override; int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; - Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; + Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; // Evaluation template static MatrixComplex computeOnComplexAndMatrix(const std::complex c, const MatrixComplex n, Preferences::ComplexFormat complexFormat); template static MatrixComplex computeOnMatrixAndComplex(const MatrixComplex m, const std::complex d, Preferences::ComplexFormat complexFormat); template static MatrixComplex computeOnMatrices(const MatrixComplex m, const MatrixComplex n, Preferences::ComplexFormat complexFormat); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce(this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce(this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } }; @@ -69,28 +69,28 @@ public: Power(const PowerNode * n) : Expression(n) {} static Power Builder(Expression base, Expression exponent) { return TreeHandle::FixedArityBuilder(ArrayBuilder(base, exponent).array(), 2); } - Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const; - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext); + int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const; + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); + Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); private: constexpr static int k_maxExactPowerMatrix = 100; constexpr static int k_maxNumberOfTermsInExpandedMultinome = 25; // Simplification - Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; - Expression simplifyPowerPower(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); - Expression simplifyPowerMultiplication(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); - Expression simplifyRationalRationalPower(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression simplifyPowerPower(ExpressionNode::ReductionContext reductionContext); + Expression simplifyPowerMultiplication(ExpressionNode::ReductionContext reductionContext); + Expression simplifyRationalRationalPower(ExpressionNode::ReductionContext reductionContext); - static Expression CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bool isDenominator, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - Expression removeSquareRootsFromDenominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation); + static Expression CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bool isDenominator, ExpressionNode::ReductionContext reductionContext); + Expression removeSquareRootsFromDenominator(ExpressionNode::ReductionContext reductionContext); bool parentIsALogarithmOfSameBase() const; bool isNthRootOfUnity() const; Expression equivalentExpressionUsingStandardExpression() const; - static Expression CreateComplexExponent(const Expression & r, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); // Returns e^(i*pi*r) + static Expression CreateComplexExponent(const Expression & r, ExpressionNode::ReductionContext reductionContext); // Returns e^(i*pi*r) static bool TermIsARationalSquareRootOrRational(const Expression& e); static const Rational RadicandInExpression(const Expression & e); static const Rational RationalFactorInExpression(const Expression & e); diff --git a/poincare/include/poincare/prediction_interval.h b/poincare/include/poincare/prediction_interval.h index 525383fa7..ff750b610 100644 --- a/poincare/include/poincare/prediction_interval.h +++ b/poincare/include/poincare/prediction_interval.h @@ -21,17 +21,17 @@ public: // Properties Type type() const override { return Type::PredictionInterval; } - int polynomialDegree(Context & context, const char * symbolName) const override { return -1; } + int polynomialDegree(Context * context, const char * symbolName) const override { return -1; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class PredictionInterval final : public Expression { @@ -41,7 +41,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("prediction95", 2, &UntypedBuilderTwoChildren); // Expression - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/randint.h b/poincare/include/poincare/randint.h index ace041666..0eab1e67f 100644 --- a/poincare/include/poincare/randint.h +++ b/poincare/include/poincare/randint.h @@ -21,7 +21,7 @@ public: Type type() const override { return Type::Randint; } // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } bool isRandom() const override { return true; } private: @@ -29,15 +29,15 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templateApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templateApproximate(context, complexFormat, angleUnit); } - template Evaluation templateApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template Evaluation templateApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; }; class Randint final : public Expression { @@ -47,7 +47,7 @@ public: static Randint Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("randint", 2, &UntypedBuilderTwoChildren); private: - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/random.h b/poincare/include/poincare/random.h index 8fdd3f44d..9746f3c78 100644 --- a/poincare/include/poincare/random.h +++ b/poincare/include/poincare/random.h @@ -19,22 +19,22 @@ public: #endif // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } bool isRandom() const override { return true; } // Properties Type type() const override { return Type::Random; } Sign sign(Context * context) const override { return Sign::Positive; } - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression setSign(Sign s, ReductionContext reductionContext) override; private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templateApproximate(); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templateApproximate(); } template Evaluation templateApproximate() const; @@ -49,8 +49,6 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("random", 0, &UntypedBuilder); template static T random(); -private: - Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); }; } diff --git a/poincare/include/poincare/rational.h b/poincare/include/poincare/rational.h index b490663d2..bfb296676 100644 --- a/poincare/include/poincare/rational.h +++ b/poincare/include/poincare/rational.h @@ -37,8 +37,8 @@ public: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Approximation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex::Builder(templatedApproximate()); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex::Builder(templatedApproximate()); } + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex::Builder(templatedApproximate()); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex::Builder(templatedApproximate()); } template T templatedApproximate() const; // Basic test @@ -52,10 +52,10 @@ public: static int NaturalOrder(const RationalNode * i, const RationalNode * j); private: int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; - Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; - Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; + Expression shallowReduce(ReductionContext reductionContext) override; + Expression shallowBeautify(ReductionContext reductionContext) override; + Expression setSign(Sign s, ReductionContext reductionContext) override; + Expression denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override; bool m_negative; uint8_t m_numberOfDigitsNumerator; uint8_t m_numberOfDigitsDenominator; @@ -112,7 +112,7 @@ private: /* Simplification */ Expression shallowBeautify(); - Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Expression denominator() const; Expression setSign(ExpressionNode::Sign s); }; diff --git a/poincare/include/poincare/real_part.h b/poincare/include/poincare/real_part.h index 716fa5196..ec61002d8 100644 --- a/poincare/include/poincare/real_part.h +++ b/poincare/include/poincare/real_part.h @@ -22,22 +22,22 @@ public: Type type() const override { return Type::RealPart; } // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { return Complex::Builder(std::real(c)); } - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -49,7 +49,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("re", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/round.h b/poincare/include/poincare/round.h index 0962c72ef..428f526a6 100644 --- a/poincare/include/poincare/round.h +++ b/poincare/include/poincare/round.h @@ -19,7 +19,7 @@ public: #endif // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } // Properties Type type() const override { return Type::Round; } @@ -28,11 +28,11 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class Round final : public Expression { diff --git a/poincare/include/poincare/sequence.h b/poincare/include/poincare/sequence.h index ef0a45af0..f7380785b 100644 --- a/poincare/include/poincare/sequence.h +++ b/poincare/include/poincare/sequence.h @@ -16,9 +16,9 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; virtual Layout createSequenceLayout(Layout argumentLayout, Layout symbolLayout, Layout subscriptLayout, Layout superscriptLayout) const = 0; /* Approximation */ - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; virtual float emptySequenceValue() const = 0; virtual Evaluation evaluateWithNextTerm(SinglePrecision p, Evaluation a, Evaluation b, Preferences::ComplexFormat complexFormat) const = 0; virtual Evaluation evaluateWithNextTerm(DoublePrecision p, Evaluation a, Evaluation b, Preferences::ComplexFormat complexFormat) const = 0; diff --git a/poincare/include/poincare/sign_function.h b/poincare/include/poincare/sign_function.h index 4ba6c2914..376a36459 100644 --- a/poincare/include/poincare/sign_function.h +++ b/poincare/include/poincare/sign_function.h @@ -21,23 +21,23 @@ public: // Properties Type type() const override { return Type::SignFunction; } Sign sign(Context * context) const override; - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression setSign(Sign s, ReductionContext reductionContext) override; // Complex - bool isReal(Context & context) const override { return true; } + bool isReal(Context * context) const override { return true; } private: // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -49,7 +49,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sign", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h index d78deaf02..6a2517d87 100644 --- a/poincare/include/poincare/sine.h +++ b/poincare/include/poincare/sine.h @@ -20,11 +20,11 @@ public: #endif // Complex - bool isReal(Context & context) const override { return childAtIndex(0)->isReal(context); } + bool isReal(Context * context) const override { return childAtIndex(0)->isReal(context); } // Properties Type type() const override { return Type::Sine; } - float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override; + float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override; template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian); @@ -34,13 +34,13 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplication - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -52,7 +52,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sin", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/square_root.h b/poincare/include/poincare/square_root.h index dcf030882..96b19309e 100644 --- a/poincare/include/poincare/square_root.h +++ b/poincare/include/poincare/square_root.h @@ -26,13 +26,13 @@ private: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplification - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -42,7 +42,7 @@ public: SquareRoot(const SquareRootNode * n) : Expression(n) {} static SquareRoot Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("√", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/store.h b/poincare/include/poincare/store.h index 5b933e901..efa770cd6 100644 --- a/poincare/include/poincare/store.h +++ b/poincare/include/poincare/store.h @@ -21,19 +21,19 @@ public: // ExpressionNode Type type() const override { return Type::Store; } - int polynomialDegree(Context & context, const char * symbolName) const override { return -1; } + int polynomialDegree(Context * context, const char * symbolName) const override { return -1; } private: // Simplification - void deepReduceChildren(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) override; - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + void deepReduceChildren(ExpressionNode::ReductionContext reductionContext) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Layout Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Evalutation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class Store final : public Expression { @@ -53,10 +53,10 @@ public: } // Expression - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); private: - Expression storeValueForSymbol(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + Expression storeValueForSymbol(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; StoreNode * node() const { return static_cast(Expression::node()); } }; diff --git a/poincare/include/poincare/subtraction.h b/poincare/include/poincare/subtraction.h index 5ce51ebeb..165cf9c33 100644 --- a/poincare/include/poincare/subtraction.h +++ b/poincare/include/poincare/subtraction.h @@ -22,14 +22,14 @@ public: // Properties Type type() const override { return Type::Subtraction; } - int polynomialDegree(Context & context, const char * symbolName) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; // Approximation template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { return Complex::Builder(c - d); } - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce(this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce(this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } @@ -39,7 +39,7 @@ public: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; /* Simplification */ - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; private: /* Evaluation */ @@ -59,7 +59,7 @@ public: static Subtraction Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } // Expression - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; diff --git a/poincare/include/poincare/symbol.h b/poincare/include/poincare/symbol.h index 5052bcf30..26b32e3b7 100644 --- a/poincare/include/poincare/symbol.h +++ b/poincare/include/poincare/symbol.h @@ -23,32 +23,32 @@ public: Type type() const override { return Type::Symbol; } Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) override; Expression replaceUnknown(const Symbol & symbol, const Symbol & unknownSymbol) override; - int polynomialDegree(Context & context, const char * symbolName) const override; - int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const override; - int getVariables(Context & context, isVariableTest isVariable, char * variables, int maxSizeVariable) const override; - float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override; + int polynomialDegree(Context * context, const char * symbolName) const override; + int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const override; + int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const override; + float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override; // Complex - bool isReal(Context & context) const override; + bool isReal(Context * context) const override; /* Layout */ Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; /* Simplification */ - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; - Expression shallowReplaceReplaceableSymbols(Context & context) override; + Expression shallowReduce(ReductionContext reductionContext) override; + Expression shallowReplaceReplaceableSymbols(Context * context) override; /* Approximation */ - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } bool isUnknown(CodePoint unknownSymbol) const; private: char m_name[0]; // MUST be the last member variable size_t nodeSize() const override { return sizeof(SymbolNode); } - template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template Evaluation templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; }; class Symbol final : public SymbolAbstract { @@ -71,11 +71,11 @@ public: static bool isRegressionSymbol(const char * c); // Expression - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression); Expression replaceUnknown(const Symbol & symbol, const Symbol & unknownSymbol); - int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const; - Expression shallowReplaceReplaceableSymbols(Context & context); + int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const; + Expression shallowReplaceReplaceableSymbols(Context * context); private: SymbolNode * node() const { return static_cast(Expression::node()); } }; diff --git a/poincare/include/poincare/symbol_abstract.h b/poincare/include/poincare/symbol_abstract.h index 2c2e10a13..7b7226044 100644 --- a/poincare/include/poincare/symbol_abstract.h +++ b/poincare/include/poincare/symbol_abstract.h @@ -34,7 +34,7 @@ public: // Property Sign sign(Context * context) const override; - Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + Expression setSign(ExpressionNode::Sign s, ReductionContext reductionContext) override; // TreeNode #if POINCARE_TREE_LOG @@ -70,7 +70,7 @@ public: Expression f = context ? context->expressionForSymbol(s, false) : Expression(); return f.isUninitialized() || f.type() == s.type(); } - static bool matches(const SymbolAbstract & symbol, ExpressionTest test, Context & context); + static bool matches(const SymbolAbstract & symbol, ExpressionTest test, Context * context); constexpr static size_t k_maxNameSize = 8; protected: @@ -80,8 +80,8 @@ protected: SymbolAbstractNode * node() const { return static_cast(Expression::node()); } private: - static Expression Expand(const SymbolAbstract & symbol, Context & context, bool clone); - static bool isReal(const SymbolAbstract & symbol, Context & context); + static Expression Expand(const SymbolAbstract & symbol, Context * context, bool clone); + static bool isReal(const SymbolAbstract & symbol, Context * context); }; } diff --git a/poincare/include/poincare/tangent.h b/poincare/include/poincare/tangent.h index a82e636ec..2769ce19b 100644 --- a/poincare/include/poincare/tangent.h +++ b/poincare/include/poincare/tangent.h @@ -20,10 +20,10 @@ public: // Properties Type type() const override { return Type::Tangent; } - float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override; + float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override; // Complex - bool isReal(Context & context) const override { return childAtIndex(0)->isReal(context); } + bool isReal(Context * context) const override { return childAtIndex(0)->isReal(context); } private: // Layout @@ -31,14 +31,14 @@ private: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Simplication - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) override; + Expression shallowReduce(ReductionContext reductionContext) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian); - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } }; @@ -50,7 +50,7 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("tan", 1, &UntypedBuilderOneChild); - Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation); + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; } diff --git a/poincare/include/poincare/trigonometry.h b/poincare/include/poincare/trigonometry.h index 794a65b37..7f2f1b5e7 100644 --- a/poincare/include/poincare/trigonometry.h +++ b/poincare/include/poincare/trigonometry.h @@ -12,14 +12,14 @@ public: Cosine = 0, Sine = 1, }; - static float characteristicXRange(const Expression & e, Context & context, Preferences::AngleUnit angleUnit); + static float characteristicXRange(const Expression & e, Context * context, Preferences::AngleUnit angleUnit); static bool isDirectTrigonometryFunction(const Expression & e); static bool isInverseTrigonometryFunction(const Expression & e); static bool AreInverseFunctions(const Expression & directFunction, const Expression & inverseFunction); static bool ExpressionIsEquivalentToTangent(const Expression & e); - static Expression shallowReduceDirectFunction(Expression & e, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - static Expression shallowReduceInverseFunction(Expression & e, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - static Expression table(const Expression e, ExpressionNode::Type type, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); // , Function f, bool inverse + static Expression shallowReduceDirectFunction(Expression & e, ExpressionNode::ReductionContext reductionContext); + static Expression shallowReduceInverseFunction(Expression & e, ExpressionNode::ReductionContext reductionContext); + static Expression table(const Expression e, ExpressionNode::Type type, ExpressionNode::ReductionContext reductionContext); // , Function f, bool inverse template static std::complex ConvertToRadian(const std::complex c, Preferences::AngleUnit angleUnit); template static std::complex ConvertRadianToAngleUnit(const std::complex c, Preferences::AngleUnit angleUnit); template static std::complex RoundToMeaningfulDigits(const std::complex result, const std::complex input); diff --git a/poincare/include/poincare/trigonometry_cheat_table.h b/poincare/include/poincare/trigonometry_cheat_table.h index 0ae4f678a..7996dd8a1 100644 --- a/poincare/include/poincare/trigonometry_cheat_table.h +++ b/poincare/include/poincare/trigonometry_cheat_table.h @@ -29,7 +29,7 @@ public: Tangent = 4 }; static const TrigonometryCheatTable * Table(); - Expression simplify(const Expression e, ExpressionNode::Type type, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) const; + Expression simplify(const Expression e, ExpressionNode::Type type, ExpressionNode::ReductionContext reductionContext) const; private: @@ -42,7 +42,7 @@ private: public: constexpr Pair(const char * expression, float value = NAN) : m_expression(expression), m_value(value) {} - Expression reducedExpression(bool assertNotUninitialized, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) const; + Expression reducedExpression(bool assertNotUninitialized, ExpressionNode::ReductionContext reductionContext) const; float value() const { return m_value; } private: const char * m_expression; @@ -56,9 +56,9 @@ private: assert(((int) t) >= 0 && ((int) t) < k_numberOfPairs); return m_pairs[(int)t].value(); } - Expression expressionForType(Type t, bool assertNotUninitialized, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) const { + Expression expressionForType(Type t, bool assertNotUninitialized, ExpressionNode::ReductionContext reductionContext) const { assert(((int) t) >= 0 && ((int) t) < k_numberOfPairs); - return m_pairs[(int)t].reducedExpression(assertNotUninitialized, context, complexFormat, angleUnit, target); + return m_pairs[(int)t].reducedExpression(assertNotUninitialized, reductionContext); } private: constexpr static int k_numberOfPairs = 5; @@ -71,9 +71,9 @@ private: assert(i >= 0 && i < k_numberOfEntries); return m_rows[i].floatForType(t); } - Expression expressionForTypeAtIndex(Type t, int i, bool assertNotUninitialized, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) const { + Expression expressionForTypeAtIndex(Type t, int i, bool assertNotUninitialized, ExpressionNode::ReductionContext reductionContext) const { assert(i >= 0 && i < k_numberOfEntries); - return m_rows[i].expressionForType(t, assertNotUninitialized, context, complexFormat, angleUnit, target); + return m_rows[i].expressionForType(t, assertNotUninitialized, reductionContext); } const Row * m_rows; }; diff --git a/poincare/include/poincare/undefined.h b/poincare/include/poincare/undefined.h index 3413d8bd9..3ab003952 100644 --- a/poincare/include/poincare/undefined.h +++ b/poincare/include/poincare/undefined.h @@ -17,18 +17,18 @@ public: #endif // Complex - bool isReal(Context & context) const override { return false; } + bool isReal(Context * context) const override { return false; } // Properties Type type() const override { return Type::Undefined; } - int polynomialDegree(Context & context, const char * symbolName) const override; - Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; + int polynomialDegree(Context * context, const char * symbolName) const override; + Expression setSign(Sign s, ReductionContext reductionContext) override; // Approximation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(); } diff --git a/poincare/include/poincare/unreal.h b/poincare/include/poincare/unreal.h index fdc54ac68..283013752 100644 --- a/poincare/include/poincare/unreal.h +++ b/poincare/include/poincare/unreal.h @@ -20,10 +20,10 @@ public: Type type() const override { return Type::Unreal; } // Approximation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(); } diff --git a/poincare/include/poincare/variable_context.h b/poincare/include/poincare/variable_context.h index 27af51ff9..1df5d850c 100644 --- a/poincare/include/poincare/variable_context.h +++ b/poincare/include/poincare/variable_context.h @@ -13,7 +13,7 @@ public: void setApproximationForVariable(T value); // Context - void setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) override; + void setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context * context) override; const Expression expressionForSymbol(const SymbolAbstract & symbol, bool clone) override; private: diff --git a/poincare/src/absolute_value.cpp b/poincare/src/absolute_value.cpp index 2f57e7b72..8c3768ddf 100644 --- a/poincare/src/absolute_value.cpp +++ b/poincare/src/absolute_value.cpp @@ -13,9 +13,9 @@ constexpr Expression::FunctionHelper AbsoluteValue::s_functionHelper; int AbsoluteValueNode::numberOfChildren() const { return AbsoluteValue::s_functionHelper.numberOfChildren(); } -Expression AbsoluteValueNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression AbsoluteValueNode::setSign(Sign s, ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive); - return AbsoluteValue(this).setSign(s, context, complexFormat, angleUnit); + return AbsoluteValue(this); } Layout AbsoluteValueNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { @@ -26,26 +26,21 @@ int AbsoluteValueNode::serialize(char * buffer, int bufferSize, Preferences::Pri return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, AbsoluteValue::s_functionHelper.name()); } -Expression AbsoluteValueNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return AbsoluteValue(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression AbsoluteValueNode::shallowReduce(ReductionContext reductionContext) { + return AbsoluteValue(this).shallowReduce(reductionContext); } -Expression AbsoluteValue::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { - assert(s == ExpressionNode::Sign::Positive); - return *this; -} - -Expression AbsoluteValue::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression AbsoluteValue::shallowReduce(ExpressionNode::ReductionContext reductionContext) { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { return e; } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - if (c.isReal(context)) { - float app = c.node()->approximate(float(), context, complexFormat, angleUnit).toScalar(); + if (c.isReal(reductionContext.context())) { + float app = c.node()->approximate(float(), reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()).toScalar(); if (!std::isnan(app) && ((c.isNumber() && app >= 0) || app >= Expression::Epsilon())) { /* abs(a) = a with a >= 0 @@ -59,17 +54,17 @@ Expression AbsoluteValue::shallowReduce(Context & context, Preferences::ComplexF // abs(a) = -a with a < 0 (same comment as above to check that a < 0) Multiplication m = Multiplication::Builder(Rational::Builder(-1), c); replaceWithInPlace(m); - return m.shallowReduce(context, complexFormat, angleUnit, target); + return m.shallowReduce(reductionContext); } } if (c.type() == ExpressionNode::Type::ComplexCartesian) { ComplexCartesian complexChild = static_cast(c); - Expression childNorm = complexChild.norm(context, complexFormat, angleUnit, target); + Expression childNorm = complexChild.norm(reductionContext); replaceWithInPlace(childNorm); - return childNorm.shallowReduce(context, complexFormat, angleUnit, target); + return childNorm.shallowReduce(reductionContext); } // abs(-x) = abs(x) - c.makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target); + c.makePositiveAnyNegativeNumeralFactor(reductionContext); return *this; } diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 752db2fef..3ec245e38 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -12,7 +12,7 @@ namespace Poincare { -int AdditionNode::polynomialDegree(Context & context, const char * symbolName) const { +int AdditionNode::polynomialDegree(Context * context, const char * symbolName) const { int degree = 0; for (ExpressionNode * e : children()) { int d = e->polynomialDegree(context, symbolName); @@ -24,7 +24,7 @@ int AdditionNode::polynomialDegree(Context & context, const char * symbolName) c return degree; } -int AdditionNode::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { +int AdditionNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { return Addition(this).getPolynomialCoefficients(context, symbolName, coefficients); } @@ -50,12 +50,12 @@ int AdditionNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo // Simplication -Expression AdditionNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Addition(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression AdditionNode::shallowReduce(ReductionContext reductionContext) { + return Addition(this).shallowReduce(reductionContext); } -Expression AdditionNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { - return Addition(this).shallowBeautify(context, complexFormat, angleUnit, target); +Expression AdditionNode::shallowBeautify(ReductionContext reductionContext) { + return Addition(this).shallowBeautify(reductionContext); } // Addition @@ -68,7 +68,7 @@ const Number Addition::NumeralFactor(const Expression & e) { return Rational::Builder(1); } -int Addition::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { +int Addition::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { int deg = polynomialDegree(context, symbolName); if (deg < 0 || deg > Expression::k_maxPolynomialDegree) { return -1; @@ -87,7 +87,7 @@ int Addition::getPolynomialCoefficients(Context & context, const char * symbolNa return deg; } -Expression Addition::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Addition::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { /* Beautifying AdditionNode essentially consists in adding Subtractions if * needed. * In practice, we want to turn "a+(-1)*b" into "a-b". Or, more precisely, any @@ -105,7 +105,7 @@ Expression Addition::shallowBeautify(Context & context, Preferences::ComplexForm for (int i = 0; i < numberOfChildren(); i++) { // Try to make the child i positive if any negative numeral factor is found - Expression subtractant = childAtIndex(i).makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target); + Expression subtractant = childAtIndex(i).makePositiveAnyNegativeNumeralFactor(reductionContext); if (subtractant.isUninitialized()) { // if subtractant is not initialized, it means the child i had no negative numeral factor @@ -135,7 +135,7 @@ Expression Addition::shallowBeautify(Context & context, Preferences::ComplexForm return result; } -Expression Addition::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Addition::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -224,8 +224,8 @@ Expression Addition::shallowReduce(Context & context, Preferences::ComplexFormat removeChildAtIndexInPlace(i+1); continue; } - if (TermsHaveIdenticalNonNumeralFactors(e1, e2, context)) { - factorizeChildrenAtIndexesInPlace(i, i+1, context, complexFormat, angleUnit, target); + if (TermsHaveIdenticalNonNumeralFactors(e1, e2, reductionContext.context())) { + factorizeChildrenAtIndexesInPlace(i, i+1, reductionContext); continue; } i++; @@ -259,7 +259,7 @@ Expression Addition::shallowReduce(Context & context, Preferences::ComplexFormat * do anything about it now (allChildrenAreReal == -1) * - All children are either real or ComplexCartesian (allChildrenAreReal == 0) * We can bubble up ComplexCartesian nodes. */ - if (allChildrenAreReal(context) == 0) { + if (allChildrenAreReal(reductionContext.context()) == 0) { /* We turn (a+ib)+(c+id) into (a+c)+i(c+d)*/ Addition imag = Addition::Builder(); // we store all imaginary parts in 'imag' Addition real = *this; // we store all real parts in 'real' @@ -279,8 +279,8 @@ Expression Addition::shallowReduce(Context & context, Preferences::ComplexFormat replaceWithInPlace(newComplexCartesian); newComplexCartesian.replaceChildAtIndexInPlace(0, real); newComplexCartesian.replaceChildAtIndexInPlace(1, imag); - real.shallowReduce(context, complexFormat, angleUnit, target); - imag.shallowReduce(context, complexFormat, angleUnit, target); + real.shallowReduce(reductionContext); + imag.shallowReduce(reductionContext); return newComplexCartesian.shallowReduce(); } @@ -288,9 +288,9 @@ Expression Addition::shallowReduce(Context & context, Preferences::ComplexFormat * This step is done only for ReductionTarget::User if the parent expression * is not an addition. */ Expression p = result.parent(); - if (target == ExpressionNode::ReductionTarget::User && result == *this && (p.isUninitialized() || p.type() != ExpressionNode::Type::Addition)) { + if (reductionContext.target() == ExpressionNode::ReductionTarget::User && result == *this && (p.isUninitialized() || p.type() != ExpressionNode::Type::Addition)) { // squashUnaryHierarchy didn't do anything: we're not an unary hierarchy - result = factorizeOnCommonDenominator(context, complexFormat, angleUnit); + result = factorizeOnCommonDenominator(reductionContext); } return result; } @@ -316,7 +316,7 @@ const Expression Addition::FirstNonNumeralFactor(const Expression & e) { return e.childAtIndex(0); } -bool Addition::TermsHaveIdenticalNonNumeralFactors(const Expression & e1, const Expression & e2, Context & context) { +bool Addition::TermsHaveIdenticalNonNumeralFactors(const Expression & e1, const Expression & e2, Context * context) { /* Return true if two expressions differ only by a rational factor. For * example, 2*pi and pi do, 2*pi and 2*ln(2) don't. We do not want to * factorize random(). */ @@ -341,7 +341,7 @@ bool Addition::TermsHaveIdenticalNonNumeralFactors(const Expression & e1, const } } -Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { +Expression Addition::factorizeOnCommonDenominator(ExpressionNode::ReductionContext reductionContext) { /* We want to turn (a/b+c/d+e/b) into (a*d+b*c+e*d)/(b*d), except if one of * the denominators contains random, in which case the factors with random * should stay appart. */ @@ -354,9 +354,9 @@ Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences Multiplication commonDenominator = Multiplication::Builder(); for (int i = 0; i < numberOfChildren(); i++) { Expression childI = childAtIndex(i); - Expression currentDenominator = childI.denominator(context, complexFormat, angleUnit); + Expression currentDenominator = childI.denominator(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); if (!currentDenominator.isUninitialized()) { - if (currentDenominator.recursivelyMatches(Expression::IsRandom, context, true)) { + if (currentDenominator.recursivelyMatches(Expression::IsRandom, reductionContext.context(), true)) { // Remove "random" factors removeChildInPlace(childI, childI.numberOfChildren()); a.addChildAtIndexInPlace(childI, a.numberOfChildren(), a.numberOfChildren()); @@ -364,7 +364,7 @@ Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences continue; } // Make commonDenominator = LeastCommonMultiple(commonDenominator, denominator); - commonDenominator.addMissingFactors(currentDenominator, context, complexFormat, angleUnit); + commonDenominator.addMissingFactors(currentDenominator, reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); } } if (commonDenominator.numberOfChildren() == 0) { @@ -378,11 +378,12 @@ Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences /* Step 2: Create the numerator. We start with this being a/b+c/d+e/b and we * want to create numerator = a/b*b*d + c/d*b*d + e/b*b*d = a*d + c*b + e*d */ + assert(reductionContext.target() == ExpressionNode::ReductionTarget::User); // Else, before, the algorithm used User target -> put back ? Addition numerator = Addition::Builder(); for (int i = 0; i < numberOfChildren(); i++) { Multiplication m = Multiplication::Builder(childAtIndex(i), commonDenominator.clone()); numerator.addChildAtIndexInPlace(m, numerator.numberOfChildren(), numerator.numberOfChildren()); - m.privateShallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, true, false); + m.privateShallowReduce(reductionContext, true, false); } // Step 3: Add the denominator @@ -390,10 +391,10 @@ Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences Multiplication result = Multiplication::Builder(numerator, inverseDenominator); // Step 4: Simplify the numerator - numerator.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + numerator.shallowReduce(reductionContext); // Step 5: Simplify the denominator (in case it's a rational number) - inverseDenominator.deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + inverseDenominator.deepReduce(reductionContext); /* Step 6: We simplify the resulting multiplication forbidding any * distribution of multiplication on additions (to avoid an infinite loop). @@ -401,15 +402,15 @@ Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences int aChildrenCount = a.numberOfChildren(); if (aChildrenCount == 0) { replaceWithInPlace(result); - return result.privateShallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, false, true); + return result.privateShallowReduce(reductionContext, false, true); } a.addChildAtIndexInPlace(result, aChildrenCount, aChildrenCount); - result.privateShallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, false, true); + result.privateShallowReduce(reductionContext, false, true); replaceWithInPlace(a); return a; } -void Addition::factorizeChildrenAtIndexesInPlace(int index1, int index2, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +void Addition::factorizeChildrenAtIndexesInPlace(int index1, int index2, ExpressionNode::ReductionContext reductionContext) { /* This function factorizes two children which only differ by a rational * factor. For example, if this is AdditionNode(2*pi, 3*pi), then 2*pi and 3*pi * could be merged, and this turned into AdditionNode(5*pi). */ @@ -445,7 +446,7 @@ void Addition::factorizeChildrenAtIndexesInPlace(int index1, int index2, Context } // Step 5: Reduce the multiplication (in case the new rational factor is zero) - m.shallowReduce(context, complexFormat, angleUnit, target); + m.shallowReduce(reductionContext); } template Complex Poincare::AdditionNode::compute(std::complex, std::complex, Preferences::ComplexFormat); diff --git a/poincare/src/approximation_helper.cpp b/poincare/src/approximation_helper.cpp index bb4935d00..c0571ba9d 100644 --- a/poincare/src/approximation_helper.cpp +++ b/poincare/src/approximation_helper.cpp @@ -26,7 +26,7 @@ template std::complex ApproximationHelper::TruncateRealOrImagina return c; } -template Evaluation ApproximationHelper::Map(const ExpressionNode * expression, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ComplexCompute compute) { +template Evaluation ApproximationHelper::Map(const ExpressionNode * expression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ComplexCompute compute) { assert(expression->numberOfChildren() == 1); Evaluation input = expression->childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); if (input.type() == EvaluationNode::Type::Complex) { @@ -43,7 +43,7 @@ template Evaluation ApproximationHelper::Map(const ExpressionNode } } -template Evaluation ApproximationHelper::MapReduce(const ExpressionNode * expression, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ComplexAndComplexReduction computeOnComplexes, ComplexAndMatrixReduction computeOnComplexAndMatrix, MatrixAndComplexReduction computeOnMatrixAndComplex, MatrixAndMatrixReduction computeOnMatrices) { +template Evaluation ApproximationHelper::MapReduce(const ExpressionNode * expression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ComplexAndComplexReduction computeOnComplexes, ComplexAndMatrixReduction computeOnComplexAndMatrix, MatrixAndComplexReduction computeOnMatrixAndComplex, MatrixAndMatrixReduction computeOnMatrices) { assert(expression->numberOfChildren() > 0); Evaluation result = expression->childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); for (int i = 1; i < expression->numberOfChildren(); i++) { @@ -93,10 +93,10 @@ template MatrixComplex ApproximationHelper::ElementWiseOnComplexM template std::complex Poincare::ApproximationHelper::TruncateRealOrImaginaryPartAccordingToArgument(std::complex); template std::complex Poincare::ApproximationHelper::TruncateRealOrImaginaryPartAccordingToArgument(std::complex); -template Poincare::Evaluation Poincare::ApproximationHelper::Map(const Poincare::ExpressionNode * expression, Poincare::Context& context, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationHelper::ComplexCompute compute); -template Poincare::Evaluation Poincare::ApproximationHelper::Map(const Poincare::ExpressionNode * expression, Poincare::Context& context, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationHelper::ComplexCompute compute); -template Poincare::Evaluation Poincare::ApproximationHelper::MapReduce(const Poincare::ExpressionNode * expression, Poincare::Context& context, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationHelper::ComplexAndComplexReduction computeOnComplexes, Poincare::ApproximationHelper::ComplexAndMatrixReduction computeOnComplexAndMatrix, Poincare::ApproximationHelper::MatrixAndComplexReduction computeOnMatrixAndComplex, Poincare::ApproximationHelper::MatrixAndMatrixReduction computeOnMatrices); -template Poincare::Evaluation Poincare::ApproximationHelper::MapReduce(const Poincare::ExpressionNode * expression, Poincare::Context& context, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationHelper::ComplexAndComplexReduction computeOnComplexes, Poincare::ApproximationHelper::ComplexAndMatrixReduction computeOnComplexAndMatrix, Poincare::ApproximationHelper::MatrixAndComplexReduction computeOnMatrixAndComplex, Poincare::ApproximationHelper::MatrixAndMatrixReduction computeOnMatrices); +template Poincare::Evaluation Poincare::ApproximationHelper::Map(const Poincare::ExpressionNode * expression, Poincare::Context * context, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationHelper::ComplexCompute compute); +template Poincare::Evaluation Poincare::ApproximationHelper::Map(const Poincare::ExpressionNode * expression, Poincare::Context * context, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationHelper::ComplexCompute compute); +template Poincare::Evaluation Poincare::ApproximationHelper::MapReduce(const Poincare::ExpressionNode * expression, Poincare::Context * context, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationHelper::ComplexAndComplexReduction computeOnComplexes, Poincare::ApproximationHelper::ComplexAndMatrixReduction computeOnComplexAndMatrix, Poincare::ApproximationHelper::MatrixAndComplexReduction computeOnMatrixAndComplex, Poincare::ApproximationHelper::MatrixAndMatrixReduction computeOnMatrices); +template Poincare::Evaluation Poincare::ApproximationHelper::MapReduce(const Poincare::ExpressionNode * expression, Poincare::Context * context, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationHelper::ComplexAndComplexReduction computeOnComplexes, Poincare::ApproximationHelper::ComplexAndMatrixReduction computeOnComplexAndMatrix, Poincare::ApproximationHelper::MatrixAndComplexReduction computeOnMatrixAndComplex, Poincare::ApproximationHelper::MatrixAndMatrixReduction computeOnMatrices); template Poincare::MatrixComplex Poincare::ApproximationHelper::ElementWiseOnMatrixComplexAndComplex(const Poincare::MatrixComplex, const std::complex, Poincare::Preferences::ComplexFormat, Poincare::Complex (*)(std::complex, std::complex, Poincare::Preferences::ComplexFormat)); template Poincare::MatrixComplex Poincare::ApproximationHelper::ElementWiseOnMatrixComplexAndComplex(const Poincare::MatrixComplex, std::complex const, Poincare::Preferences::ComplexFormat, Poincare::Complex (*)(std::complex, std::complex, Poincare::Preferences::ComplexFormat)); template Poincare::MatrixComplex Poincare::ApproximationHelper::ElementWiseOnComplexMatrices(const Poincare::MatrixComplex, const Poincare::MatrixComplex, Poincare::Preferences::ComplexFormat, Poincare::Complex (*)(std::complex, std::complex, Poincare::Preferences::ComplexFormat)); diff --git a/poincare/src/arc_cosine.cpp b/poincare/src/arc_cosine.cpp index 8a281fdcb..6b90aaaad 100644 --- a/poincare/src/arc_cosine.cpp +++ b/poincare/src/arc_cosine.cpp @@ -19,8 +19,8 @@ int ArcCosineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFl return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ArcCosine::s_functionHelper.name()); } -Expression ArcCosineNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return ArcCosine(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression ArcCosineNode::shallowReduce(ReductionContext reductionContext) { + return ArcCosine(this).shallowReduce(reductionContext); } template @@ -49,7 +49,7 @@ Complex ArcCosineNode::computeOnComplex(const std::complex c, Preferences: } -Expression ArcCosine::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression ArcCosine::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -57,9 +57,9 @@ Expression ArcCosine::shallowReduce(Context & context, Preferences::ComplexForma } } if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - return Trigonometry::shallowReduceInverseFunction(*this, context, complexFormat, angleUnit, target); + return Trigonometry::shallowReduceInverseFunction(*this, reductionContext); } } diff --git a/poincare/src/arc_sine.cpp b/poincare/src/arc_sine.cpp index 516dde0c4..f6e893a79 100644 --- a/poincare/src/arc_sine.cpp +++ b/poincare/src/arc_sine.cpp @@ -19,8 +19,8 @@ int ArcSineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloa return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ArcSine::s_functionHelper.name()); } -Expression ArcSineNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return ArcSine(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression ArcSineNode::shallowReduce(ReductionContext reductionContext) { + return ArcSine(this).shallowReduce(reductionContext); } template @@ -49,7 +49,7 @@ Complex ArcSineNode::computeOnComplex(const std::complex c, Preferences::C } -Expression ArcSine::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression ArcSine::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -57,9 +57,9 @@ Expression ArcSine::shallowReduce(Context & context, Preferences::ComplexFormat } } if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - return Trigonometry::shallowReduceInverseFunction(*this, context, complexFormat, angleUnit, target); + return Trigonometry::shallowReduceInverseFunction(*this, reductionContext); } } diff --git a/poincare/src/arc_tangent.cpp b/poincare/src/arc_tangent.cpp index df4b031f5..153bf6820 100644 --- a/poincare/src/arc_tangent.cpp +++ b/poincare/src/arc_tangent.cpp @@ -44,11 +44,11 @@ Complex ArcTangentNode::computeOnComplex(const std::complex c, Preferences return Complex::Builder(Trigonometry::ConvertRadianToAngleUnit(result, angleUnit)); } -Expression ArcTangentNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return ArcTangent(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression ArcTangentNode::shallowReduce(ReductionContext reductionContext) { + return ArcTangent(this).shallowReduce(reductionContext); } -Expression ArcTangent::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression ArcTangent::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -56,9 +56,9 @@ Expression ArcTangent::shallowReduce(Context & context, Preferences::ComplexForm } } if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - return Trigonometry::shallowReduceInverseFunction(*this, context, complexFormat, angleUnit, target); + return Trigonometry::shallowReduceInverseFunction(*this, reductionContext); } } diff --git a/poincare/src/binomial_coefficient.cpp b/poincare/src/binomial_coefficient.cpp index 0dc83df11..be7a18477 100644 --- a/poincare/src/binomial_coefficient.cpp +++ b/poincare/src/binomial_coefficient.cpp @@ -14,8 +14,8 @@ constexpr Expression::FunctionHelper BinomialCoefficient::s_functionHelper; int BinomialCoefficientNode::numberOfChildren() const { return BinomialCoefficient::s_functionHelper.numberOfChildren(); } -Expression BinomialCoefficientNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return BinomialCoefficient(this).shallowReduce(context); +Expression BinomialCoefficientNode::shallowReduce(ReductionContext reductionContext) { + return BinomialCoefficient(this).shallowReduce(reductionContext.context()); } Layout BinomialCoefficientNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { @@ -29,7 +29,7 @@ int BinomialCoefficientNode::serialize(char * buffer, int bufferSize, Preference } template -Complex BinomialCoefficientNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Complex BinomialCoefficientNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation nInput = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation kInput = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T n = nInput.toScalar(); @@ -54,7 +54,7 @@ T BinomialCoefficientNode::compute(T k, T n) { } -Expression BinomialCoefficient::shallowReduce(Context & context) { +Expression BinomialCoefficient::shallowReduce(Context * context) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { diff --git a/poincare/src/ceiling.cpp b/poincare/src/ceiling.cpp index 8ee0713a6..fb8758ac5 100644 --- a/poincare/src/ceiling.cpp +++ b/poincare/src/ceiling.cpp @@ -31,12 +31,12 @@ Complex CeilingNode::computeOnComplex(const std::complex c, Preferences::C return Complex::Builder(std::ceil(c.real())); } -Expression CeilingNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Ceiling(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression CeilingNode::shallowReduce(ReductionContext reductionContext) { + return Ceiling(this).shallowReduce(reductionContext); } -Expression Ceiling::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Ceiling::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -45,7 +45,7 @@ Expression Ceiling::shallowReduce(Context & context, Preferences::ComplexFormat } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } if (c.type() == ExpressionNode::Type::Constant) { Constant s = static_cast(c); diff --git a/poincare/src/complex_argument.cpp b/poincare/src/complex_argument.cpp index 651101cbe..059039054 100644 --- a/poincare/src/complex_argument.cpp +++ b/poincare/src/complex_argument.cpp @@ -24,8 +24,8 @@ int ComplexArgumentNode::serialize(char * buffer, int bufferSize, Preferences::P return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ComplexArgument::s_functionHelper.name()); } -Expression ComplexArgumentNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return ComplexArgument(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression ComplexArgumentNode::shallowReduce(ReductionContext reductionContext) { + return ComplexArgument(this).shallowReduce(reductionContext); } template @@ -34,7 +34,7 @@ Complex ComplexArgumentNode::computeOnComplex(const std::complex c, Prefer } -Expression ComplexArgument::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression ComplexArgument::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -43,11 +43,11 @@ Expression ComplexArgument::shallowReduce(Context & context, Preferences::Comple } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - bool real = c.isReal(context); + bool real = c.isReal(reductionContext.context()); if (real) { - float app = c.node()->approximate(float(), context, complexFormat, angleUnit).toScalar(); + float app = c.node()->approximate(float(), reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()).toScalar(); if (!std::isnan(app) && app >= Expression::Epsilon()) { // arg(x) = 0 if x > 0 Expression result = Rational::Builder(0); @@ -62,9 +62,9 @@ Expression ComplexArgument::shallowReduce(Context & context, Preferences::Comple } if (real || c.type() == ExpressionNode::Type::ComplexCartesian) { ComplexCartesian complexChild = real ? ComplexCartesian::Builder(c, Rational::Builder(0)) : static_cast(c); - Expression childArg = complexChild.argument(context, complexFormat, angleUnit, target, symbolicComputation); + Expression childArg = complexChild.argument(reductionContext); replaceWithInPlace(childArg); - return childArg.shallowReduce(context, complexFormat, angleUnit, target); + return childArg.shallowReduce(reductionContext); } return *this; } diff --git a/poincare/src/complex_cartesian.cpp b/poincare/src/complex_cartesian.cpp index 1c5824c05..f36598324 100644 --- a/poincare/src/complex_cartesian.cpp +++ b/poincare/src/complex_cartesian.cpp @@ -19,16 +19,16 @@ namespace Poincare { -Expression ComplexCartesianNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression ComplexCartesianNode::shallowReduce(ReductionContext reductionContext) { return ComplexCartesian(this).shallowReduce(); } -Expression ComplexCartesianNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { - return ComplexCartesian(this).shallowBeautify(context, complexFormat, angleUnit, target); +Expression ComplexCartesianNode::shallowBeautify(ReductionContext reductionContext) { + return ComplexCartesian(this).shallowBeautify(reductionContext); } template -Complex ComplexCartesianNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Complex ComplexCartesianNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation realEvaluation = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation imagEvalution = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); assert(realEvaluation.type() == EvaluationNode::Type::Complex); @@ -61,11 +61,11 @@ Expression ComplexCartesian::shallowReduce() { return *this; } -Expression ComplexCartesian::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression ComplexCartesian::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { Expression a = real(); Expression b = imag(); - Expression oppositeA = a.makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target); - Expression oppositeB = b.makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target); + Expression oppositeA = a.makePositiveAnyNegativeNumeralFactor(reductionContext); + Expression oppositeB = b.makePositiveAnyNegativeNumeralFactor(reductionContext); a = oppositeA.isUninitialized() ? a : oppositeA; b = oppositeB.isUninitialized() ? b : oppositeB; Expression e = Expression::CreateComplexExpression(a, b, Preferences::ComplexFormat::Cartesian, @@ -78,7 +78,7 @@ Expression ComplexCartesian::shallowBeautify(Context & context, Preferences::Com return e; } -void ComplexCartesian::factorAndArgumentOfFunction(Expression e, ExpressionNode::Type searchedType, Expression * factor, Expression * argument, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +void ComplexCartesian::factorAndArgumentOfFunction(Expression e, ExpressionNode::Type searchedType, Expression * factor, Expression * argument, ExpressionNode::ReductionContext reductionContext) { if (e.type() == searchedType) { *factor = Rational::Builder(1); *argument = e.childAtIndex(0); @@ -90,8 +90,8 @@ void ComplexCartesian::factorAndArgumentOfFunction(Expression e, ExpressionNode: *argument = e.childAtIndex(i).childAtIndex(0); *factor = e.clone(); static_cast(factor)->removeChildAtIndexInPlace(i); - *factor = factor->shallowReduce(context, complexFormat, angleUnit, target); - Expression positiveFactor = factor->makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target); + *factor = factor->shallowReduce(reductionContext); + Expression positiveFactor = factor->makePositiveAnyNegativeNumeralFactor(reductionContext); *factor = positiveFactor.isUninitialized() ? *factor : positiveFactor; return; } @@ -99,44 +99,44 @@ void ComplexCartesian::factorAndArgumentOfFunction(Expression e, ExpressionNode: } } -Expression ComplexCartesian::squareNorm(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression ComplexCartesian::squareNorm(ExpressionNode::ReductionContext reductionContext) { Expression a = real(); Expression b = imag(); Expression aFactor, bFactor, aArgument, bArgument; - factorAndArgumentOfFunction(a, ExpressionNode::Type::Cosine, &aFactor, &aArgument, context, complexFormat, angleUnit, target); - factorAndArgumentOfFunction(b, ExpressionNode::Type::Sine, &bFactor, &bArgument, context, complexFormat, angleUnit, target); + factorAndArgumentOfFunction(a, ExpressionNode::Type::Cosine, &aFactor, &aArgument, reductionContext); + factorAndArgumentOfFunction(b, ExpressionNode::Type::Sine, &bFactor, &bArgument, reductionContext); if (!aFactor.isUninitialized() && !aArgument.isUninitialized() && !bFactor.isUninitialized() && !bArgument.isUninitialized() && aFactor.isIdenticalTo(bFactor) && aArgument.isIdenticalTo(bArgument)) { Power result = Power::Builder(aFactor, Rational::Builder(2)); - aFactor.shallowReduce(context, complexFormat, angleUnit, target); + aFactor.shallowReduce(reductionContext); return result; } Expression a2 = Power::Builder(a, Rational::Builder(2)); Expression b2 = Power::Builder(b, Rational::Builder(2)); Addition add = Addition::Builder(a2, b2); - a2.shallowReduce(context, complexFormat, angleUnit, target); - b2.shallowReduce(context, complexFormat, angleUnit, target); + a2.shallowReduce(reductionContext); + b2.shallowReduce(reductionContext); return add; } -Expression ComplexCartesian::norm(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression ComplexCartesian::norm(ExpressionNode::ReductionContext reductionContext) { if (imag().isRationalZero()) { Expression a = real(); - ExpressionNode::Sign s = a.sign(&context); + ExpressionNode::Sign s = a.sign(reductionContext.context()); if (s == ExpressionNode::Sign::Positive) { // Case 1: the expression is positive real return a;; } else if (s == ExpressionNode::Sign::Negative) { // Case 2: the argument is negative real - return a.setSign(ExpressionNode::Sign::Positive, &context, complexFormat, angleUnit, target); + return a.setSign(ExpressionNode::Sign::Positive, reductionContext); } } - Expression n2 = squareNorm(context, complexFormat, angleUnit, target); + Expression n2 = squareNorm(reductionContext); Expression n = SquareRoot::Builder(n2); - n2.shallowReduce(context, complexFormat, angleUnit, target); + n2.shallowReduce(reductionContext); return n; } -Expression ComplexCartesian::argument(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression ComplexCartesian::argument(ExpressionNode::ReductionContext reductionContext) { Expression a = real(); Expression b = imag(); if (!b.isRationalZero()) { @@ -144,91 +144,91 @@ Expression ComplexCartesian::argument(Context & context, Preferences::ComplexFor // First, compute atan(a/b) or (π/180)*atan(a/b) Expression divab = Division::Builder(a, b.clone()); Expression arcTangent = ArcTangent::Builder(divab); - divab.shallowReduce(context, complexFormat, angleUnit, target); - if (angleUnit == Preferences::AngleUnit::Degree) { + divab.shallowReduce(reductionContext); + if (reductionContext.angleUnit() == Preferences::AngleUnit::Degree) { Expression temp = arcTangent.degreeToRadian(); - arcTangent.shallowReduce(context, complexFormat, angleUnit, target); + arcTangent.shallowReduce(reductionContext); arcTangent = temp; } // Then, compute sign(b) * π/2 - atan(a/b) Expression signb = SignFunction::Builder(b); Expression signbPi2 = Multiplication::Builder(Rational::Builder(1,2), signb, Constant::Builder(UCodePointGreekSmallLetterPi)); - signb.shallowReduce(context, complexFormat, angleUnit, target); + signb.shallowReduce(reductionContext); Expression sub = Subtraction::Builder(signbPi2, arcTangent); - signbPi2.shallowReduce(context, complexFormat, angleUnit, target); - arcTangent.shallowReduce(context, complexFormat, angleUnit, target); + signbPi2.shallowReduce(reductionContext); + arcTangent.shallowReduce(reductionContext); return sub; } else { // if b == 0, argument = (1-sign(a))*π/2 - Expression signa = SignFunction::Builder(a).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + Expression signa = SignFunction::Builder(a).shallowReduce(reductionContext); Subtraction sub = Subtraction::Builder(Rational::Builder(1), signa); - signa.shallowReduce(context, complexFormat, angleUnit, target); + signa.shallowReduce(reductionContext); Multiplication mul = Multiplication::Builder(Rational::Builder(1,2), Constant::Builder(UCodePointGreekSmallLetterPi), sub); - sub.shallowReduce(context, complexFormat, angleUnit, target); + sub.shallowReduce(reductionContext); return mul; } } -ComplexCartesian ComplexCartesian::inverse(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +ComplexCartesian ComplexCartesian::inverse(ExpressionNode::ReductionContext reductionContext) { Expression a = real(); Expression b = imag(); // 1/(a+ib) = a/(a^2+b^2)+i*(-b/(a^2+b^2)) - Expression denominatorReal = clone().convert().squareNorm(context, complexFormat, angleUnit, target); + Expression denominatorReal = clone().convert().squareNorm(reductionContext); Expression denominatorImag = denominatorReal.clone(); Expression denominatorRealInv = Power::Builder(denominatorReal, Rational::Builder(-1)); - denominatorReal.shallowReduce(context, complexFormat, angleUnit, target); + denominatorReal.shallowReduce(reductionContext); Expression denominatorImagInv = Power::Builder(denominatorImag, Rational::Builder(-1)); - denominatorImag.shallowReduce(context, complexFormat, angleUnit, target); + denominatorImag.shallowReduce(reductionContext); Multiplication A = Multiplication::Builder(a, denominatorRealInv); - denominatorRealInv.shallowReduce(context, complexFormat, angleUnit, target); + denominatorRealInv.shallowReduce(reductionContext); Expression numeratorImag = Multiplication::Builder(Rational::Builder(-1), b); Multiplication B = Multiplication::Builder(numeratorImag, denominatorImagInv); - numeratorImag.shallowReduce(context, complexFormat, angleUnit, target); - denominatorImagInv.shallowReduce(context, complexFormat, angleUnit, target); + numeratorImag.shallowReduce(reductionContext); + denominatorImagInv.shallowReduce(reductionContext); ComplexCartesian result = ComplexCartesian::Builder(A,B); - A.shallowReduce(context, complexFormat, angleUnit, target); - B.shallowReduce(context, complexFormat, angleUnit, target); + A.shallowReduce(reductionContext); + B.shallowReduce(reductionContext); return result.interruptComputationIfManyNodes(); } -Multiplication ComplexCartesian::squareRootHelper(Expression e, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Multiplication ComplexCartesian::squareRootHelper(Expression e, ExpressionNode::ReductionContext reductionContext) { //(1/2)*sqrt(2*e) Multiplication doubleE = Multiplication::Builder(Rational::Builder(2), e); - e.shallowReduce(context, complexFormat, angleUnit, target); + e.shallowReduce(reductionContext); Expression sqrt = SquareRoot::Builder(doubleE); - doubleE.shallowReduce(context, complexFormat, angleUnit, target); + doubleE.shallowReduce(reductionContext); Multiplication result = Multiplication::Builder(Rational::Builder(1,2), sqrt); - sqrt.shallowReduce(context, complexFormat, angleUnit, target); + sqrt.shallowReduce(reductionContext); return result; } -ComplexCartesian ComplexCartesian::squareRoot(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +ComplexCartesian ComplexCartesian::squareRoot(ExpressionNode::ReductionContext reductionContext) { Expression a = real(); Expression b = imag(); // A: (1/2)*sqrt(2*(sqrt(a^2+b^2)+a)) // B: (1/2)*sqrt(2*(sqrt(a^2+b^2)-a))*sign(b) - Expression normA = clone().convert().norm(context, complexFormat, angleUnit, target); + Expression normA = clone().convert().norm(reductionContext); Expression normB = normA.clone(); // A = (1/2)*sqrt(2*(sqrt(a^2+b^2)+a)) Addition normAdda = Addition::Builder(normA, a.clone()); - normA.shallowReduce(context, complexFormat, angleUnit, target); - Multiplication A = squareRootHelper(normAdda, context, complexFormat, angleUnit, target); + normA.shallowReduce(reductionContext); + Multiplication A = squareRootHelper(normAdda, reductionContext); // B = B: (1/2)*sqrt(2*(sqrt(a^2+b^2)-a)) Subtraction normSuba = Subtraction::Builder(normB, a); - normB.shallowReduce(context, complexFormat, angleUnit, target); - Multiplication B = squareRootHelper(normSuba, context, complexFormat, angleUnit, target); + normB.shallowReduce(reductionContext); + Multiplication B = squareRootHelper(normSuba, reductionContext); // B = B: (1/2)*sqrt(2*(sqrt(a^2+b^2)-a))*sign(b) Expression signb = SignFunction::Builder(b); B.addChildAtIndexInPlace(signb, B.numberOfChildren(), B.numberOfChildren()); - signb.shallowReduce(context, complexFormat, angleUnit, target); + signb.shallowReduce(reductionContext); ComplexCartesian result = ComplexCartesian::Builder(A, B); - A.shallowReduce(context, complexFormat, angleUnit, target); - B.shallowReduce(context, complexFormat, angleUnit, target); + A.shallowReduce(reductionContext); + B.shallowReduce(reductionContext); return result.interruptComputationIfManyNodes(); } -ComplexCartesian ComplexCartesian::powerInteger(int n, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +ComplexCartesian ComplexCartesian::powerInteger(int n, ExpressionNode::ReductionContext reductionContext) { Expression a = real(); Expression b = imag(); assert(n > 0); @@ -241,7 +241,7 @@ ComplexCartesian ComplexCartesian::powerInteger(int n, Context & context, Prefer Expression bpow = Power::Builder(b, Rational::Builder(n)); if (n/2%2 == 1) { Expression temp = Multiplication::Builder(Rational::Builder(-1), bpow); - bpow.shallowReduce(context, complexFormat, angleUnit, target); + bpow.shallowReduce(reductionContext); bpow = temp; } if (n%2 == 0) { @@ -249,7 +249,7 @@ ComplexCartesian ComplexCartesian::powerInteger(int n, Context & context, Prefer } else { result = ComplexCartesian::Builder(Rational::Builder(0), bpow); } - bpow.shallowReduce(context, complexFormat, angleUnit, target); + bpow.shallowReduce(reductionContext); return result; } // (a+ib) = a^n+i*b*a^(n-1)+(-1)*b^2*a^(n-2)+(-i)*b^3*a^(n-3)+b^3*a^(n-4)+... @@ -265,9 +265,9 @@ ComplexCartesian ComplexCartesian::powerInteger(int n, Context & context, Prefer Power apow = Power::Builder(aclone, Rational::Builder(n-i)); Power bpow = Power::Builder(bclone, Rational::Builder(i)); Multiplication m = Multiplication::Builder(binom, apow, bpow); - binom.shallowReduce(context); - apow.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); - bpow.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + binom.shallowReduce(reductionContext.context()); + apow.shallowReduce(reductionContext); + bpow.shallowReduce(reductionContext); if (i/2%2 == 1) { m.addChildAtIndexInPlace(Rational::Builder(-1), 0, m.numberOfChildren()); } @@ -276,18 +276,18 @@ ComplexCartesian ComplexCartesian::powerInteger(int n, Context & context, Prefer } else { B.addChildAtIndexInPlace(m, B.numberOfChildren(), B.numberOfChildren()); } - m.shallowReduce(context, complexFormat, angleUnit, target); + m.shallowReduce(reductionContext); result = result.interruptComputationIfManyNodes(); if (result.real().isUndefined()) { return result; } } - A.shallowReduce(context, complexFormat, angleUnit, target); - B.shallowReduce(context, complexFormat, angleUnit, target); + A.shallowReduce(reductionContext); + B.shallowReduce(reductionContext); return result; } -ComplexCartesian ComplexCartesian::multiply(ComplexCartesian & other, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +ComplexCartesian ComplexCartesian::multiply(ComplexCartesian & other, ExpressionNode::ReductionContext reductionContext) { Expression a = real(); Expression b = imag(); Expression c = other.real(); @@ -297,73 +297,73 @@ ComplexCartesian ComplexCartesian::multiply(ComplexCartesian & other, Context & Expression ac = Multiplication::Builder(a.clone(), c.clone()); Expression bd = Multiplication::Builder(b.clone(), d.clone()); Subtraction A = Subtraction::Builder(ac, bd); - ac.shallowReduce(context, complexFormat, angleUnit, target); - bd.shallowReduce(context, complexFormat, angleUnit, target); + ac.shallowReduce(reductionContext); + bd.shallowReduce(reductionContext); // Compute ad+bc Expression ad = Multiplication::Builder(a, d); Expression bc = Multiplication::Builder(b, c); Addition B = Addition::Builder(ad, bc); - ad.shallowReduce(context, complexFormat, angleUnit, target); - bc.shallowReduce(context, complexFormat, angleUnit, target); + ad.shallowReduce(reductionContext); + bc.shallowReduce(reductionContext); ComplexCartesian result = ComplexCartesian::Builder(A, B); - A.shallowReduce(context, complexFormat, angleUnit, target); - B.shallowReduce(context, complexFormat, angleUnit, target); + A.shallowReduce(reductionContext); + B.shallowReduce(reductionContext); return result.interruptComputationIfManyNodes(); } -Expression ComplexCartesian::powerHelper(Expression norm, Expression trigo, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression ComplexCartesian::powerHelper(Expression norm, Expression trigo, ExpressionNode::ReductionContext reductionContext) { Multiplication m = Multiplication::Builder(norm, trigo); - norm.shallowReduce(context, complexFormat, angleUnit, target); - trigo.shallowReduce(context, complexFormat, angleUnit, target); + norm.shallowReduce(reductionContext); + trigo.shallowReduce(reductionContext); return m; } -ComplexCartesian ComplexCartesian::power(ComplexCartesian & other, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { - Expression r = clone().convert().norm(context, complexFormat, angleUnit, target); +ComplexCartesian ComplexCartesian::power(ComplexCartesian & other, ExpressionNode::ReductionContext reductionContext) { + Expression r = clone().convert().norm(reductionContext); Expression rclone = r.clone(); - Expression th = argument(context, complexFormat, angleUnit, target, symbolicComputation); + Expression th = argument(reductionContext); Expression thclone = th.clone(); Expression c = other.real(); Expression d = other.imag(); // R = r^c*e^(-th*d) Expression rpowc = Power::Builder(rclone, c.clone()); - rclone.shallowReduce(context, complexFormat, angleUnit, target); + rclone.shallowReduce(reductionContext); Expression thmuld = Multiplication::Builder(Rational::Builder(-1), thclone, d.clone()); - thclone.shallowReduce(context, complexFormat, angleUnit, target); + thclone.shallowReduce(reductionContext); Expression exp = Power::Builder(Constant::Builder(UCodePointScriptSmallE), thmuld); - thmuld.shallowReduce(context, complexFormat, angleUnit, target); + thmuld.shallowReduce(reductionContext); Multiplication norm = Multiplication::Builder(rpowc, exp); - rpowc.shallowReduce(context, complexFormat, angleUnit, target); - exp.shallowReduce(context, complexFormat, angleUnit, target); + rpowc.shallowReduce(reductionContext); + exp.shallowReduce(reductionContext); // TH = d*ln(r)+c*th Expression lnr = NaperianLogarithm::Builder(r); - r.shallowReduce(context, complexFormat, angleUnit, target); + r.shallowReduce(reductionContext); Multiplication dlnr = Multiplication::Builder(d, lnr); - lnr.shallowReduce(context, complexFormat, angleUnit, target); + lnr.shallowReduce(reductionContext); Multiplication thc = Multiplication::Builder(th, c); - th.shallowReduce(context, complexFormat, angleUnit, target); + th.shallowReduce(reductionContext); Expression argument = Addition::Builder(thc, dlnr); - thc.shallowReduce(context, complexFormat, angleUnit, target); - dlnr.shallowReduce(context, complexFormat, angleUnit, target); + thc.shallowReduce(reductionContext); + dlnr.shallowReduce(reductionContext); - if (angleUnit == Preferences::AngleUnit::Degree) { + if (reductionContext.angleUnit() == Preferences::AngleUnit::Degree) { Expression temp = argument.radianToDegree(); - argument.shallowReduce(context, complexFormat, angleUnit, target); + argument.shallowReduce(reductionContext); argument = temp; } // Result = (norm*cos(argument), norm*sin(argument)) Expression normClone = norm.clone(); Expression argClone = argument.clone(); Expression cos = Cosine::Builder(argClone); - argClone.shallowReduce(context, complexFormat, angleUnit, target); - Expression normcosarg = powerHelper(normClone, cos, context, complexFormat, angleUnit, target); + argClone.shallowReduce(reductionContext); + Expression normcosarg = powerHelper(normClone, cos, reductionContext); Expression sin = Sine::Builder(argument); - argument.shallowReduce(context, complexFormat, angleUnit, target); - Expression normsinarg = powerHelper(norm, sin, context, complexFormat, angleUnit, target); + argument.shallowReduce(reductionContext); + Expression normsinarg = powerHelper(norm, sin, reductionContext); ComplexCartesian result = ComplexCartesian::Builder(normcosarg, normsinarg); - normcosarg.shallowReduce(context, complexFormat, angleUnit, target); - normsinarg.shallowReduce(context, complexFormat, angleUnit, target); + normcosarg.shallowReduce(reductionContext); + normsinarg.shallowReduce(reductionContext); return result.interruptComputationIfManyNodes(); } diff --git a/poincare/src/confidence_interval.cpp b/poincare/src/confidence_interval.cpp index bb843ae95..b9780e78e 100644 --- a/poincare/src/confidence_interval.cpp +++ b/poincare/src/confidence_interval.cpp @@ -25,12 +25,12 @@ int ConfidenceIntervalNode::serialize(char * buffer, int bufferSize, Preferences return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ConfidenceInterval::s_functionHelper.name()); } -Expression ConfidenceIntervalNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return ConfidenceInterval(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression ConfidenceIntervalNode::shallowReduce(ReductionContext reductionContext) { + return ConfidenceInterval(this).shallowReduce(reductionContext); } template -Evaluation ConfidenceIntervalNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation ConfidenceIntervalNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation fInput = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation nInput = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T f = static_cast &>(fInput).toScalar(); @@ -52,8 +52,7 @@ int SimplePredictionIntervalNode::serialize(char * buffer, int bufferSize, Prefe return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SimplePredictionInterval::s_functionHelper.name()); } - -Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression ConfidenceInterval::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -62,7 +61,7 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Com } Expression c0 = childAtIndex(0); Expression c1 = childAtIndex(1); - if (SortedIsMatrix(c0, context) || SortedIsMatrix(c1, context)) { + if (SortedIsMatrix(c0, reductionContext.context()) || SortedIsMatrix(c1, reductionContext.context())) { return Undefined::Builder(); } if (c0.type() == ExpressionNode::Type::Rational) { @@ -93,7 +92,7 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Com matrix.addChildAtIndexInPlace(Addition::Builder(r0, sqr), 1, 1); matrix.setDimensions(1, 2); replaceWithInPlace(matrix); - matrix.deepReduceChildren(context, complexFormat, angleUnit, target); + matrix.deepReduceChildren(reductionContext); return matrix; } diff --git a/poincare/src/conjugate.cpp b/poincare/src/conjugate.cpp index 140b20dc2..29d07219d 100644 --- a/poincare/src/conjugate.cpp +++ b/poincare/src/conjugate.cpp @@ -23,8 +23,8 @@ int ConjugateNode::serialize(char * buffer, int bufferSize, Preferences::PrintFl return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Conjugate::s_functionHelper.name()); } -Expression ConjugateNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Conjugate(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression ConjugateNode::shallowReduce(ReductionContext reductionContext) { + return Conjugate(this).shallowReduce(reductionContext); } template @@ -32,7 +32,7 @@ Complex ConjugateNode::computeOnComplex(const std::complex c, Preferences: return Complex::Builder(std::conj(c)); } -Expression Conjugate::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Conjugate::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -41,9 +41,9 @@ Expression Conjugate::shallowReduce(Context & context, Preferences::ComplexForma } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - if (c.isReal(context)) { + if (c.isReal(reductionContext.context())) { replaceWithInPlace(c); return c; } @@ -51,7 +51,7 @@ Expression Conjugate::shallowReduce(Context & context, Preferences::ComplexForma ComplexCartesian complexChild = static_cast(c); Multiplication m = Multiplication::Builder(Rational::Builder(-1), complexChild.imag()); complexChild.replaceChildAtIndexInPlace(1, m); - m.shallowReduce(context, complexFormat, angleUnit, target); + m.shallowReduce(reductionContext); replaceWithInPlace(complexChild); return complexChild; } diff --git a/poincare/src/constant.cpp b/poincare/src/constant.cpp index fc133768e..9d13524cd 100644 --- a/poincare/src/constant.cpp +++ b/poincare/src/constant.cpp @@ -25,7 +25,7 @@ ExpressionNode::Sign ConstantNode::sign(Context * context) const { return Sign::Unknown; } -bool ConstantNode::isReal(Context & context) const { +bool ConstantNode::isReal(Context * context) const { return !isIComplex(); } @@ -70,7 +70,7 @@ int ConstantNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo } template -Evaluation ConstantNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation ConstantNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { if (isIComplex()) { return Complex::Builder(0.0, 1.0); } @@ -81,8 +81,8 @@ Evaluation ConstantNode::templatedApproximate(Context& context, Preferences:: return Complex::Builder(M_E); } -Expression ConstantNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Constant(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression ConstantNode::shallowReduce(ReductionContext reductionContext) { + return Constant(this).shallowReduce(reductionContext); } bool ConstantNode::isConstantCodePoint(CodePoint c) const { @@ -99,12 +99,12 @@ Constant Constant::Builder(CodePoint c) { return SymbolAbstract::Builder(buffer, codePointSize); } -Expression Constant::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Constant::shallowReduce(ExpressionNode::ReductionContext reductionContext) { Expression result; bool isI = isIComplex(); - if (complexFormat == Preferences::ComplexFormat::Real && isI) { + if (reductionContext.complexFormat() == Preferences::ComplexFormat::Real && isI) { result = Unreal::Builder(); - } else if (target == ExpressionNode::ReductionTarget::User && isI) { + } else if (reductionContext.target() == ExpressionNode::ReductionTarget::User && isI) { result = ComplexCartesian::Builder(Rational::Builder(0), Rational::Builder(1)); } if (!result.isUninitialized()) { @@ -114,6 +114,6 @@ Expression Constant::shallowReduce(Context & context, Preferences::ComplexFormat return *this; } -template Evaluation ConstantNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; -template Evaluation ConstantNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; +template Evaluation ConstantNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; +template Evaluation ConstantNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; } diff --git a/poincare/src/cosine.cpp b/poincare/src/cosine.cpp index 7c0e411a6..17b08ca1c 100644 --- a/poincare/src/cosine.cpp +++ b/poincare/src/cosine.cpp @@ -11,7 +11,7 @@ constexpr Expression::FunctionHelper Cosine::s_functionHelper; int CosineNode::numberOfChildren() const { return Cosine::s_functionHelper.numberOfChildren(); } -float CosineNode::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { +float CosineNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const { return Trigonometry::characteristicXRange(Cosine(this), context, angleUnit); } @@ -30,11 +30,11 @@ int CosineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Cosine::s_functionHelper.name()); } -Expression CosineNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Cosine(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression CosineNode::shallowReduce(ReductionContext reductionContext) { + return Cosine(this).shallowReduce(reductionContext); } -Expression Cosine::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Cosine::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -43,9 +43,9 @@ Expression Cosine::shallowReduce(Context & context, Preferences::ComplexFormat c } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - return Trigonometry::shallowReduceDirectFunction(*this, context, complexFormat, angleUnit, target); + return Trigonometry::shallowReduceDirectFunction(*this, reductionContext); } diff --git a/poincare/src/decimal.cpp b/poincare/src/decimal.cpp index 6767d577c..bbc38eef8 100644 --- a/poincare/src/decimal.cpp +++ b/poincare/src/decimal.cpp @@ -53,7 +53,7 @@ size_t DecimalNode::size() const { return DecimalSize(m_numberOfDigitsInMantissa); } -Expression DecimalNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression DecimalNode::setSign(Sign s, ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); return Decimal(this).setSign(s); } @@ -86,11 +86,11 @@ int DecimalNode::simplificationOrderSameType(const ExpressionNode * e, bool asce return ((int)Number(this).sign())*unsignedComparison; } -Expression DecimalNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression DecimalNode::shallowReduce(ReductionContext reductionContext) { return Decimal(this).shallowReduce(); } -Expression DecimalNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression DecimalNode::shallowBeautify(ReductionContext reductionContext) { return Decimal(this).shallowBeautify(); } diff --git a/poincare/src/derivative.cpp b/poincare/src/derivative.cpp index 1a36475ce..d37027df3 100644 --- a/poincare/src/derivative.cpp +++ b/poincare/src/derivative.cpp @@ -14,7 +14,7 @@ constexpr Expression::FunctionHelper Derivative::s_functionHelper; int DerivativeNode::numberOfChildren() const { return Derivative::s_functionHelper.numberOfChildren(); } -int DerivativeNode::polynomialDegree(Context & context, const char * symbolName) const { +int DerivativeNode::polynomialDegree(Context * context, const char * symbolName) const { if (childAtIndex(0)->polynomialDegree(context, symbolName) == 0 && childAtIndex(1)->polynomialDegree(context, symbolName) == 0 && childAtIndex(2)->polynomialDegree(context, symbolName) == 0) @@ -34,12 +34,12 @@ int DerivativeNode::serialize(char * buffer, int bufferSize, Preferences::PrintF return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Derivative::s_functionHelper.name()); } -Expression DerivativeNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Derivative(this).shallowReduce(context); +Expression DerivativeNode::shallowReduce(ReductionContext reductionContext) { + return Derivative(this).shallowReduce(reductionContext.context()); } template -Evaluation DerivativeNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation DerivativeNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { static T min = sizeof(T) == sizeof(double) ? DBL_MIN : FLT_MIN; static T epsilon = sizeof(T) == sizeof(double) ? DBL_EPSILON : FLT_EPSILON; Evaluation evaluationArgumentInput = childAtIndex(2)->approximate(T(), context, complexFormat, angleUnit); @@ -69,23 +69,23 @@ Evaluation DerivativeNode::templatedApproximate(Context& context, Preferences } template -T DerivativeNode::approximateWithArgument(T x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +T DerivativeNode::approximateWithArgument(T x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { assert(childAtIndex(1)->type() == Type::Symbol); - VariableContext variableContext = VariableContext(static_cast(childAtIndex(1))->name(), &context); + VariableContext variableContext = VariableContext(static_cast(childAtIndex(1))->name(), context); variableContext.setApproximationForVariable(x); // Here we cannot use Expression::approximateWithValueForSymbol which would reset the sApproximationEncounteredComplex flag - return childAtIndex(0)->approximate(T(), variableContext, complexFormat, angleUnit).toScalar(); + return childAtIndex(0)->approximate(T(), &variableContext, complexFormat, angleUnit).toScalar(); } template -T DerivativeNode::growthRateAroundAbscissa(T x, T h, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +T DerivativeNode::growthRateAroundAbscissa(T x, T h, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { T expressionPlus = approximateWithArgument(x+h, context, complexFormat, angleUnit); T expressionMinus = approximateWithArgument(x-h, context, complexFormat, angleUnit); return (expressionPlus - expressionMinus)/(2*h); } template -T DerivativeNode::riddersApproximation(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, T x, T h, T * error) const { +T DerivativeNode::riddersApproximation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, T x, T h, T * error) const { /* Ridders' Algorithm * Blibliography: * - Ridders, C.J.F. 1982, Advances in Helperering Software, vol. 4, no. 2, @@ -135,7 +135,7 @@ T DerivativeNode::riddersApproximation(Context & context, Preferences::ComplexFo return ans; } -Expression Derivative::shallowReduce(Context & context) { +Expression Derivative::shallowReduce(Context * context) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { diff --git a/poincare/src/determinant.cpp b/poincare/src/determinant.cpp index aac6f4e2d..98f19ffbe 100644 --- a/poincare/src/determinant.cpp +++ b/poincare/src/determinant.cpp @@ -23,17 +23,16 @@ int DeterminantNode::serialize(char * buffer, int bufferSize, Preferences::Print // TODO: handle this exactly in shallowReduce for small dimensions. template -Evaluation DeterminantNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation DeterminantNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); return Complex::Builder(input.determinant()); } -Expression DeterminantNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Determinant(this).shallowReduce(context); +Expression DeterminantNode::shallowReduce(ReductionContext reductionContext) { + return Determinant(this).shallowReduce(reductionContext.context()); } - -Expression Determinant::shallowReduce(Context & context) { +Expression Determinant::shallowReduce(Context * context) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { diff --git a/poincare/src/division.cpp b/poincare/src/division.cpp index cac81e0a2..409a0e754 100644 --- a/poincare/src/division.cpp +++ b/poincare/src/division.cpp @@ -14,7 +14,7 @@ namespace Poincare { -int DivisionNode::polynomialDegree(Context & context, const char * symbolName) const { +int DivisionNode::polynomialDegree(Context * context, const char * symbolName) const { if (childAtIndex(1)->polynomialDegree(context, symbolName) != 0) { return -1; } @@ -42,8 +42,8 @@ int DivisionNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "/"); } -Expression DivisionNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Division(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression DivisionNode::shallowReduce(ReductionContext reductionContext) { + return Division(this).shallowReduce(reductionContext); } template Complex DivisionNode::compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { @@ -70,7 +70,7 @@ template MatrixComplex DivisionNode::computeOnMatrices(const Matr // Division -Expression Division::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Division::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -79,9 +79,9 @@ Expression Division::shallowReduce(Context & context, Preferences::ComplexFormat } Expression p = Power::Builder(childAtIndex(1), Rational::Builder(-1)); Multiplication m = Multiplication::Builder(childAtIndex(0), p); - p.shallowReduce(context, complexFormat, angleUnit, target); // Imagine Division::Builder(2,1). p would be 1^(-1) which can be simplified + p.shallowReduce(reductionContext); // For instance: Division::Builder(2,1). p would be 1^(-1) which can be simplified replaceWithInPlace(m); - return m.shallowReduce(context, complexFormat, angleUnit, target); + return m.shallowReduce(reductionContext); } } diff --git a/poincare/src/division_quotient.cpp b/poincare/src/division_quotient.cpp index b79fc1440..5ed959d20 100644 --- a/poincare/src/division_quotient.cpp +++ b/poincare/src/division_quotient.cpp @@ -12,7 +12,7 @@ constexpr Expression::FunctionHelper DivisionQuotient::s_functionHelper; int DivisionQuotientNode::numberOfChildren() const { return DivisionQuotient::s_functionHelper.numberOfChildren(); } -Expression DivisionQuotientNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression DivisionQuotientNode::shallowReduce(ReductionContext reductionContext) { return DivisionQuotient(this).shallowReduce(); } @@ -24,7 +24,7 @@ int DivisionQuotientNode::serialize(char * buffer, int bufferSize, Preferences:: } template -Evaluation DivisionQuotientNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation DivisionQuotientNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation f1Input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation f2Input = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T f1 = f1Input.toScalar(); diff --git a/poincare/src/division_remainder.cpp b/poincare/src/division_remainder.cpp index 6086163e0..f56fb875a 100644 --- a/poincare/src/division_remainder.cpp +++ b/poincare/src/division_remainder.cpp @@ -20,12 +20,12 @@ int DivisionRemainderNode::serialize(char * buffer, int bufferSize, Preferences: return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, DivisionRemainder::s_functionHelper.name()); } -Expression DivisionRemainderNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression DivisionRemainderNode::shallowReduce(ReductionContext reductionContext) { return DivisionRemainder(this).shallowReduce(); } template -Evaluation DivisionRemainderNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation DivisionRemainderNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation f1Input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation f2Input = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T f1 = f1Input.toScalar(); diff --git a/poincare/src/empty_expression.cpp b/poincare/src/empty_expression.cpp index 196630cc4..a72775bff 100644 --- a/poincare/src/empty_expression.cpp +++ b/poincare/src/empty_expression.cpp @@ -13,7 +13,7 @@ Layout EmptyExpressionNode::createLayout(Preferences::PrintFloatMode floatDispla return EmptyLayout::Builder(); } -template Evaluation EmptyExpressionNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +template Evaluation EmptyExpressionNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return Complex::Undefined(); } diff --git a/poincare/src/equal.cpp b/poincare/src/equal.cpp index 40778dd6e..9a6fb951c 100644 --- a/poincare/src/equal.cpp +++ b/poincare/src/equal.cpp @@ -20,7 +20,7 @@ extern "C" { } namespace Poincare { -Expression EqualNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression EqualNode::shallowReduce(ReductionContext reductionContext) { return Equal(this).shallowReduce(); } @@ -37,12 +37,12 @@ int EqualNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatM } template -Evaluation EqualNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation EqualNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return Complex::Undefined(); } -Expression Equal::standardEquation(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression Equal::standardEquation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Expression sub = Subtraction::Builder(childAtIndex(0).clone(), childAtIndex(1).clone()); return sub.reduce(context, complexFormat, angleUnit); } diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 4ca7d6dfe..80c72e736 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -82,7 +82,7 @@ bool Expression::isRationalOne() const { return type() == ExpressionNode::Type::Rational && convert().isOne(); } -bool Expression::recursivelyMatches(ExpressionTest test, Context & context, bool replaceSymbols) const { +bool Expression::recursivelyMatches(ExpressionTest test, Context * context, bool replaceSymbols) const { if (test(*this, context)) { return true; } @@ -98,19 +98,19 @@ bool Expression::recursivelyMatches(ExpressionTest test, Context & context, bool return false; } -bool Expression::IsApproximate(const Expression e, Context & context) { +bool Expression::IsApproximate(const Expression e, Context * context) { return e.type() == ExpressionNode::Type::Decimal || e.type() == ExpressionNode::Type::Float; } -bool Expression::IsRandom(const Expression e, Context & context) { +bool Expression::IsRandom(const Expression e, Context * context) { return e.isRandom(); } -bool Expression::IsNAry(const Expression e, Context & context) { +bool Expression::IsNAry(const Expression e, Context * context) { return e.type() == ExpressionNode::Type::Addition || e.type() == ExpressionNode::Type::Multiplication; } -bool Expression::IsMatrix(const Expression e, Context & context) { +bool Expression::IsMatrix(const Expression e, Context * context) { return e.type() == ExpressionNode::Type::Matrix || e.type() == ExpressionNode::Type::ConfidenceInterval || e.type() == ExpressionNode::Type::MatrixDimension @@ -120,7 +120,7 @@ bool Expression::IsMatrix(const Expression e, Context & context) { || e.type() == ExpressionNode::Type::MatrixTranspose; } -bool Expression::SortedIsMatrix(const Expression e, Context & context) { +bool Expression::SortedIsMatrix(const Expression e, Context * context) { // TODO should we replace symbols? if (IsMatrix(e, context)) { return true; @@ -131,7 +131,7 @@ bool Expression::SortedIsMatrix(const Expression e, Context & context) { return false; } -bool Expression::IsInfinity(const Expression e, Context & context) { +bool Expression::IsInfinity(const Expression e, Context * context) { return e.type() == ExpressionNode::Type::Infinity; } @@ -153,7 +153,7 @@ bool containsVariables(const Expression e, char * variables, int maxVariableSize return false; } -bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Expression coefficients[], Expression constant[], Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Expression coefficients[], Expression constant[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { assert(!recursivelyMatches(IsMatrix, context, true)); // variables is in fact of type char[k_maxNumberOfVariables][maxVariableSize] int index = 0; @@ -180,7 +180,7 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex /* degree is supposed to be 0 or 1. Otherwise, it means that equation * is 'undefined' due to the reduction of 0*inf for example. * (ie, x*y*inf = 0) */ - assert(!recursivelyMatches([](const Expression e, Context & context) { return e.isUndefined(); }, context, true)); + assert(!recursivelyMatches([](const Expression e, Context * context) { return e.isUndefined(); }, context, true)); return false; } /* The equation is can be written: a_1*x+a_0 with a_1 and a_0 x-independent. @@ -205,9 +205,9 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex // Private -void Expression::defaultDeepReduceChildren(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +void Expression::defaultDeepReduceChildren(ExpressionNode::ReductionContext reductionContext) { for (int i = 0; i < numberOfChildren(); i++) { - childAtIndex(i).deepReduce(context, complexFormat, angleUnit, target, symbolicComputation); + childAtIndex(i).deepReduce(reductionContext); } } @@ -247,17 +247,17 @@ void Expression::defaultSetChildrenInPlace(Expression other) { } } -bool Expression::hasReplaceableSymbols(Context & context) const { - return recursivelyMatches([](const Expression e, Context & context) { +bool Expression::hasReplaceableSymbols(Context * context) const { + return recursivelyMatches([](const Expression e, Context * context) { return (e.type() == ExpressionNode::Type::Symbol && !static_cast(e).isSystemSymbol() - && !context.expressionForSymbol(static_cast(e), false).isUninitialized()) + && !context->expressionForSymbol(static_cast(e), false).isUninitialized()) || (e.type() == ExpressionNode::Type::Function - && !context.expressionForSymbol(static_cast(e), false).isUninitialized()); + && !context->expressionForSymbol(static_cast(e), false).isUninitialized()); }, context, false); } -Expression Expression::defaultReplaceReplaceableSymbols(Context & context) { +Expression Expression::defaultReplaceReplaceableSymbols(Context * context) { int nbChildren = numberOfChildren(); for (int i = 0; i < nbChildren; i++) { childAtIndex(i).shallowReplaceReplaceableSymbols(context); @@ -265,13 +265,13 @@ Expression Expression::defaultReplaceReplaceableSymbols(Context & context) { return *this; } -Expression Expression::makePositiveAnyNegativeNumeralFactor(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Expression::makePositiveAnyNegativeNumeralFactor(ExpressionNode::ReductionContext reductionContext) { // The expression is a negative number - if (isNumber() && sign(&context) == ExpressionNode::Sign::Negative) { - return setSign(ExpressionNode::Sign::Positive, &context, complexFormat, angleUnit, target); + if (isNumber() && sign(reductionContext.context()) == ExpressionNode::Sign::Negative) { + return setSign(ExpressionNode::Sign::Positive, reductionContext); } // The expression is a multiplication whose numeral factor is negative - if (type() == ExpressionNode::Type::Multiplication && numberOfChildren() > 0 && childAtIndex(0).isNumber() && childAtIndex(0).sign(&context) == ExpressionNode::Sign::Negative) { + if (type() == ExpressionNode::Type::Multiplication && numberOfChildren() > 0 && childAtIndex(0).isNumber() && childAtIndex(0).sign(reductionContext.context()) == ExpressionNode::Sign::Negative) { Multiplication m = convert(); if (m.childAtIndex(0).type() == ExpressionNode::Type::Rational && m.childAtIndex(0).convert().isMinusOne()) { // The negative numeral factor is -1, we just remove it @@ -280,7 +280,7 @@ Expression Expression::makePositiveAnyNegativeNumeralFactor(Context & context, P return m.squashUnaryHierarchyInPlace(); } else { // Otherwise, we make it positive - m.childAtIndex(0).setSign(ExpressionNode::Sign::Positive, &context, complexFormat, angleUnit, target); + m.childAtIndex(0).setSign(ExpressionNode::Sign::Positive, reductionContext); } return m; } @@ -288,7 +288,7 @@ Expression Expression::makePositiveAnyNegativeNumeralFactor(Context & context, P } template -Evaluation Expression::approximateToEvaluation(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation Expression::approximateToEvaluation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { sApproximationEncounteredComplex = false; // Reset interrupting flag because some evaluation methods use it sSimplificationHasBeenInterrupted = false; @@ -306,7 +306,7 @@ Expression Expression::defaultReplaceSymbolWithExpression(const SymbolAbstract & return *this; } -int Expression::defaultGetPolynomialCoefficients(Context & context, const char * symbol, Expression coefficients[]) const { +int Expression::defaultGetPolynomialCoefficients(Context * context, const char * symbol, Expression coefficients[]) const { int deg = polynomialDegree(context, symbol); if (deg == 0) { coefficients[0] = clone(); @@ -315,7 +315,7 @@ int Expression::defaultGetPolynomialCoefficients(Context & context, const char * return -1; } -int Expression::getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +int Expression::getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { // Reset interrupting flag because we use deepReduce int degree = getPolynomialCoefficients(context, symbolName, coefficients); for (int i = 0; i <= degree; i++) { @@ -353,8 +353,8 @@ Preferences::ComplexFormat Expression::UpdatedComplexFormatWithTextInput(Prefere return complexFormat; } -Preferences::ComplexFormat Expression::UpdatedComplexFormatWithExpressionInput(Preferences::ComplexFormat complexFormat, const Expression & exp, Context & context) { - if (complexFormat == Preferences::ComplexFormat::Real && exp.recursivelyMatches([](const Expression e, Context & context) { return e.type() == ExpressionNode::Type::Constant && static_cast(e).isIComplex(); }, context, true)) { +Preferences::ComplexFormat Expression::UpdatedComplexFormatWithExpressionInput(Preferences::ComplexFormat complexFormat, const Expression & exp, Context * context) { + if (complexFormat == Preferences::ComplexFormat::Real && exp.recursivelyMatches([](const Expression e, Context * context) { return e.type() == ExpressionNode::Type::Constant && static_cast(e).isIComplex(); }, context, true)) { return Preferences::ComplexFormat::Cartesian; } return complexFormat; @@ -368,7 +368,7 @@ bool Expression::isIdenticalTo(const Expression e) const { return ExpressionNode::SimplificationOrder(node(), e.node(), true, true) == 0; } -bool Expression::isEqualToItsApproximationLayout(Expression approximation, char * buffer, int bufferSize, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, Context & context) { +bool Expression::isEqualToItsApproximationLayout(Expression approximation, char * buffer, int bufferSize, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, Context * context) { approximation.serialize(buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits); /* Warning: we cannot use directly the the approximate expression but we have * to re-serialize it because the number of stored significative @@ -391,7 +391,7 @@ int Expression::serialize(char * buffer, int bufferSize, Preferences::PrintFloat /* Simplification */ -Expression Expression::ParseAndSimplify(const char * text, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicSimplification) { +Expression Expression::ParseAndSimplify(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicSimplification) { Expression exp = Parse(text); if (exp.isUninitialized()) { return Undefined::Builder(); @@ -405,7 +405,7 @@ Expression Expression::ParseAndSimplify(const char * text, Context & context, Pr return exp; } -void Expression::ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation) { +void Expression::ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation) { assert(simplifiedExpression); Expression exp = Parse(text); if (exp.isUninitialized()) { @@ -424,11 +424,12 @@ void Expression::ParseAndSimplifyAndApproximate(const char * text, Expression * } } -Expression Expression::simplify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation) { +Expression Expression::simplify(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation) { sSimplificationHasBeenInterrupted = false; - Expression e = deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System, symbolicComputation); + ExpressionNode::ReductionContext c = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System, symbolicComputation); + Expression e = deepReduce(c); if (!sSimplificationHasBeenInterrupted) { - e = e.deepBeautify(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System); + e = e.deepBeautify(c); } return sSimplificationHasBeenInterrupted ? Expression() : e; } @@ -440,14 +441,16 @@ void makePositive(Expression * e, bool * isNegative) { } } -void Expression::simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation) { +void Expression::simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation) { assert(simplifiedExpression); sSimplificationHasBeenInterrupted = false; // Step 1: we reduce the expression - Expression e = clone().deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicComputation); + ExpressionNode::ReductionContext userReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicComputation); + Expression e = clone().deepReduce(userReductionContext); if (sSimplificationHasBeenInterrupted) { sSimplificationHasBeenInterrupted = false; - e = deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System, symbolicComputation); + ExpressionNode::ReductionContext systemReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System, symbolicComputation); + e = deepReduce(systemReductionContext); } *simplifiedExpression = Expression(); if (sSimplificationHasBeenInterrupted) { @@ -468,19 +471,19 @@ void Expression::simplifyAndApproximate(Expression * simplifiedExpression, Expre // Clone the ComplexCartesian to use it to compute the approximation ComplexCartesian ecomplexClone = ecomplex.clone().convert(); // To minimize the error on the approximation, we reduce the number of nodes in the expression by beautifying - ecomplexClone.real().deepBeautify(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); - ecomplexClone.imag().deepBeautify(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + ecomplexClone.real().deepBeautify(userReductionContext); + ecomplexClone.imag().deepBeautify(userReductionContext); *approximateExpression = ecomplexClone.approximate(context, complexFormat, angleUnit); } // Step 3: create the simplied expression with the required complex format Expression ra = complexFormat == Preferences::ComplexFormat::Polar ? - ecomplex.clone().convert().norm(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicComputation) : + ecomplex.clone().convert().norm(userReductionContext).shallowReduce(userReductionContext) : ecomplex.real(); Expression tb = complexFormat == Preferences::ComplexFormat::Polar ? - ecomplex.argument(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicComputation).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicComputation) : + ecomplex.argument(userReductionContext).shallowReduce(userReductionContext) : ecomplex.imag(); - ra = ra.deepBeautify(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); - tb = tb.deepBeautify(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + ra = ra.deepBeautify(userReductionContext); + tb = tb.deepBeautify(userReductionContext); bool raIsNegative = false; bool tbIsNegative = false; makePositive(&ra, &raIsNegative); @@ -489,14 +492,14 @@ void Expression::simplifyAndApproximate(Expression * simplifiedExpression, Expre } else { /* Case 2: The reduced expression has a complex component that could not * be bubbled up. */ - *simplifiedExpression = e.deepBeautify(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + *simplifiedExpression = e.deepBeautify(userReductionContext); if (approximateExpression) { *approximateExpression = simplifiedExpression->approximate(context, complexFormat, angleUnit); } } } -Expression Expression::ExpressionWithoutSymbols(Expression e, Context & context) { +Expression Expression::ExpressionWithoutSymbols(Expression e, Context * context) { if (e.isUninitialized()) { return e; } @@ -527,7 +530,7 @@ Expression Expression::ExpressionWithoutSymbols(Expression e, Context & context) return e; } -Expression Expression::mapOnMatrixChild(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Expression::mapOnMatrixChild(ExpressionNode::ReductionContext reductionContext) { assert(numberOfChildren() == 1 && childAtIndex(0).type() == ExpressionNode::Type::Matrix); Expression c = childAtIndex(0); Matrix matrix = Matrix::Builder(); @@ -535,11 +538,11 @@ Expression Expression::mapOnMatrixChild(Context & context, Preferences::ComplexF Expression f = clone(); // TODO Avoid cloning because 'this' might be very big TODO LEA: emptyBuilder? f.replaceChildAtIndexInPlace(0, c.childAtIndex(i)); matrix.addChildAtIndexInPlace(f, i, i); - f.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + f.shallowReduce(reductionContext); } matrix.setDimensions(c.convert().numberOfRows(), c.convert().numberOfColumns()); replaceWithInPlace(matrix); - return matrix.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + return matrix.shallowReduce(reductionContext); } Expression Expression::radianToDegree() { @@ -552,66 +555,66 @@ Expression Expression::degreeToRadian() { return Multiplication::Builder(*this, Rational::Builder(1, 180), Constant::Builder(UCodePointGreekSmallLetterPi)); } -Expression Expression::reduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { +Expression Expression::reduce(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { sSimplificationHasBeenInterrupted = false; - return deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System, true); + return deepReduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System, true)); } -Expression Expression::deepReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Expression::deepReduce(ExpressionNode::ReductionContext reductionContext) { #if MATRIX_EXACT_REDUCING #else - if (IsMatrix(*this, context)) { + if (IsMatrix(*this, reductionContext.context())) { sSimplificationHasBeenInterrupted = true; return *this; } #endif - deepReduceChildren(context, complexFormat, angleUnit, target, symbolicComputation); + deepReduceChildren(reductionContext); if (sSimplificationHasBeenInterrupted) { return *this; } - return shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + return shallowReduce(reductionContext); } -Expression Expression::deepBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { - Expression e = shallowBeautify(context, complexFormat, angleUnit, target); +Expression Expression::deepBeautify(ExpressionNode::ReductionContext reductionContext) { + Expression e = shallowBeautify(reductionContext); int nbChildren = e.numberOfChildren(); for (int i = 0; i < nbChildren; i++) { - e.childAtIndex(i).deepBeautify(context, complexFormat, angleUnit, target); + e.childAtIndex(i).deepBeautify(reductionContext); } return e; } -Expression Expression::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Expression::setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); - return node()->setSign(s, context, complexFormat, angleUnit, target); + return node()->setSign(s, reductionContext); } /* Evaluation */ template -Expression Expression::approximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression Expression::approximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return isUninitialized() ? Undefined::Builder() : approximateToEvaluation(context, complexFormat, angleUnit).complexToExpression(complexFormat); } template -U Expression::approximateToScalar(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +U Expression::approximateToScalar(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return approximateToEvaluation(context, complexFormat, angleUnit).toScalar(); } template -U Expression::ApproximateToScalar(const char * text, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicSimplification) { +U Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicSimplification) { Expression exp = ParseAndSimplify(text, context, complexFormat, angleUnit, symbolicSimplification); assert(!exp.isUninitialized()); return exp.approximateToScalar(context, complexFormat, angleUnit); } template -U Expression::approximateWithValueForSymbol(const char * symbol, U x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { - VariableContext variableContext = VariableContext(symbol, &context); +U Expression::approximateWithValueForSymbol(const char * symbol, U x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { + VariableContext variableContext = VariableContext(symbol, context); variableContext.setApproximationForVariable(x); - return approximateToScalar(variableContext, complexFormat, angleUnit); + return approximateToScalar(&variableContext, complexFormat, angleUnit); } template @@ -704,27 +707,27 @@ 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 { - 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()) { +typename Expression::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, [](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 { - 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()) { +typename Expression::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, [](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); return {.abscissa = minimumOfOpposite.abscissa, .value = -minimumOfOpposite.value}; } -double Expression::nextRoot(const char * symbol, double start, double step, double max, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { - 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()) { +double Expression::nextRoot(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { + 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 { - 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) { +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 { + 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); typename Expression::Coordinate2D result = {.abscissa = resultAbscissa, .value = approximateWithValueForSymbol(symbol, resultAbscissa, context, complexFormat, angleUnit)}; @@ -734,7 +737,7 @@ typename Expression::Coordinate2D Expression::nextIntersection(const char * symb return result; } -typename Expression::Coordinate2D Expression::nextMinimumOfExpression(const char * symbol, double start, double step, double max, EvaluationAtAbscissa evaluate, Context & context, Preferences::ComplexFormat complexFormat, 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::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression, bool lookForRootMinimum) const { Coordinate2D result = {.abscissa = NAN, .value = NAN}; if (start == max || step == 0.0) { return result; @@ -771,7 +774,7 @@ typename Expression::Coordinate2D Expression::nextMinimumOfExpression(const char return result; } -void Expression::bracketMinimum(const char * symbol, double start, double step, double max, double result[3], EvaluationAtAbscissa evaluate, Context & context, Preferences::ComplexFormat complexFormat, 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::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { Coordinate2D p[3]; p[0] = {.abscissa = start, .value = evaluate(symbol, start, context, complexFormat, angleUnit, *this, expression)}; p[1] = {.abscissa = start+step, .value = evaluate(symbol, start+step, context, complexFormat, angleUnit, *this, expression)}; @@ -796,7 +799,7 @@ void Expression::bracketMinimum(const char * symbol, double start, double step, result[2] = NAN; } -typename Expression::Coordinate2D Expression::brentMinimum(const char * symbol, double ax, double bx, EvaluationAtAbscissa evaluate, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { +typename Expression::Coordinate2D Expression::brentMinimum(const char * symbol, double ax, double bx, EvaluationAtAbscissa evaluate, Context * context, Preferences::ComplexFormat complexFormat, 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) { @@ -890,7 +893,7 @@ typename Expression::Coordinate2D Expression::brentMinimum(const char * symbol, return result; } -double Expression::nextIntersectionWithExpression(const char * symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { +double Expression::nextIntersectionWithExpression(const char * symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { if (start == max || step == 0.0) { return NAN; } @@ -906,14 +909,14 @@ double Expression::nextIntersectionWithExpression(const char * symbol, double st double extremumMax = std::isnan(result) ? max : result; Coordinate2D resultExtremum[2] = { - nextMinimumOfExpression(symbol, start, step, extremumMax, [](const char * symbol, double x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { + nextMinimumOfExpression(symbol, start, step, extremumMax, [](const char * symbol, double x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { if (expression1.isUninitialized()) { return expression0.approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit); } else { return expression0.approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit)-expression1.approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit); } }, context, complexFormat, angleUnit, expression, true), - nextMinimumOfExpression(symbol, start, step, extremumMax, [](const char * symbol, double x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { + nextMinimumOfExpression(symbol, start, step, extremumMax, [](const char * symbol, double x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression0, const Expression expression1) { if (expression1.isUninitialized()) { return -expression0.approximateWithValueForSymbol(symbol, x, context, complexFormat, angleUnit); } else { @@ -931,7 +934,7 @@ double Expression::nextIntersectionWithExpression(const char * symbol, double st return result; } -void Expression::bracketRoot(const char * symbol, double start, double step, double max, double result[2], EvaluationAtAbscissa evaluation, Context & context, Preferences::ComplexFormat complexFormat, 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::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { double a = start; double b = start+step; while (step > 0.0 ? b <= max : b >= max) { @@ -949,7 +952,7 @@ void Expression::bracketRoot(const char * symbol, double start, double step, dou result[1] = NAN; } -double Expression::brentRoot(const char * symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { +double Expression::brentRoot(const char * symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, const Expression expression) const { if (ax > bx) { return brentRoot(symbol, bx, ax, precision, evaluation, context, complexFormat, angleUnit, expression); } @@ -1025,19 +1028,19 @@ double Expression::brentRoot(const char * symbol, double ax, double bx, double p template float Expression::Epsilon(); template double Expression::Epsilon(); -template Expression Expression::approximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; -template Expression Expression::approximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; +template Expression Expression::approximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; +template Expression Expression::approximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; -template float Expression::approximateToScalar(Context& context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; -template double Expression::approximateToScalar(Context& context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; +template float Expression::approximateToScalar(Context * context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; +template double Expression::approximateToScalar(Context * context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; -template float Expression::ApproximateToScalar(const char * text, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation); -template double Expression::ApproximateToScalar(const char * text, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation); +template float Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation); +template double Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation); -template Evaluation Expression::approximateToEvaluation(Context& context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; -template Evaluation Expression::approximateToEvaluation(Context& context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; +template Evaluation Expression::approximateToEvaluation(Context * context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; +template Evaluation Expression::approximateToEvaluation(Context * context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const; -template float Expression::approximateWithValueForSymbol(const char * symbol, float x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; -template double Expression::approximateWithValueForSymbol(const char * symbol, double x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; +template float Expression::approximateWithValueForSymbol(const char * symbol, float x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; +template double Expression::approximateWithValueForSymbol(const char * symbol, double x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; } diff --git a/poincare/src/expression_node.cpp b/poincare/src/expression_node.cpp index d5e901b1d..ecb0320ea 100644 --- a/poincare/src/expression_node.cpp +++ b/poincare/src/expression_node.cpp @@ -22,12 +22,12 @@ Expression ExpressionNode::replaceUnknown(const Symbol & symbol, const Symbol & return Expression(this).defaultReplaceUnknown(symbol, unknownSymbol); } -Expression ExpressionNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression ExpressionNode::setSign(Sign s, ReductionContext reductionContext) { assert(false); return Expression(); } -int ExpressionNode::polynomialDegree(Context & context, const char * symbolName) const { +int ExpressionNode::polynomialDegree(Context * context, const char * symbolName) const { for (ExpressionNode * c : children()) { if (c->polynomialDegree(context, symbolName) != 0) { return -1; @@ -36,15 +36,15 @@ int ExpressionNode::polynomialDegree(Context & context, const char * symbolName) return 0; } -int ExpressionNode::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { +int ExpressionNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { return Expression(this).defaultGetPolynomialCoefficients(context, symbolName, coefficients); } -Expression ExpressionNode::shallowReplaceReplaceableSymbols(Context & context) { +Expression ExpressionNode::shallowReplaceReplaceableSymbols(Context * context) { return Expression(this).defaultReplaceReplaceableSymbols(context); } -int ExpressionNode::getVariables(Context & context, isVariableTest isVariable, char * variables, int maxSizeVariable) const { +int ExpressionNode::getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const { int numberOfVariables = 0; for (ExpressionNode * c : children()) { int n = c->getVariables(context, isVariable, variables, maxSizeVariable); @@ -56,7 +56,7 @@ int ExpressionNode::getVariables(Context & context, isVariableTest isVariable, c return numberOfVariables; } -float ExpressionNode::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { +float ExpressionNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const { /* A expression has a characteristic range if at least one of its childAtIndex has * one and the other are x-independant. We keep the biggest interesting range * among the childAtIndex interesting ranges. */ @@ -108,15 +108,15 @@ int ExpressionNode::simplificationOrderSameType(const ExpressionNode * e, bool a return 0; } -void ExpressionNode::deepReduceChildren(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { - Expression(this).defaultDeepReduceChildren(context, complexFormat, angleUnit, target, symbolicComputation); +void ExpressionNode::deepReduceChildren(ExpressionNode::ReductionContext reductionContext) { + Expression(this).defaultDeepReduceChildren(reductionContext); } -Expression ExpressionNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression ExpressionNode::shallowReduce(ReductionContext reductionContext) { return Expression(this).defaultShallowReduce(); } -Expression ExpressionNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression ExpressionNode::shallowBeautify(ReductionContext reductionContext) { return Expression(this).defaultShallowBeautify(); } @@ -133,7 +133,7 @@ void ExpressionNode::setChildrenInPlace(Expression other) { Expression(this).defaultSetChildrenInPlace(other); } -Expression ExpressionNode::denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression ExpressionNode::denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return Expression(); } diff --git a/poincare/src/factor.cpp b/poincare/src/factor.cpp index f58d7944b..ddafe206c 100644 --- a/poincare/src/factor.cpp +++ b/poincare/src/factor.cpp @@ -26,12 +26,11 @@ int FactorNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Factor::s_functionHelper.name()); } -Expression FactorNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { - return Factor(this).shallowBeautify(context, complexFormat, angleUnit); +Expression FactorNode::shallowBeautify(ReductionContext reductionContext) { + return Factor(this).shallowBeautify(reductionContext); } - -Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { +Expression Factor::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { Expression c = childAtIndex(0); if (c.type() != ExpressionNode::Type::Rational) { Expression result = Undefined::Builder(); @@ -43,7 +42,7 @@ Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat replaceWithInPlace(r); return r; } - Multiplication numeratorDecomp = createMultiplicationOfIntegerPrimeDecomposition(r.unsignedIntegerNumerator(), context, complexFormat, angleUnit); + Multiplication numeratorDecomp = createMultiplicationOfIntegerPrimeDecomposition(r.unsignedIntegerNumerator(), reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); if (numeratorDecomp.numberOfChildren() == 0) { Expression result = Undefined::Builder(); replaceWithInPlace(result); @@ -51,7 +50,7 @@ Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat } Expression result = numeratorDecomp.squashUnaryHierarchyInPlace(); if (!r.integerDenominator().isOne()) { - Multiplication denominatorDecomp = createMultiplicationOfIntegerPrimeDecomposition(r.integerDenominator(), context, complexFormat, angleUnit); + Multiplication denominatorDecomp = createMultiplicationOfIntegerPrimeDecomposition(r.integerDenominator(), reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); if (denominatorDecomp.numberOfChildren() == 0) { Expression result = Undefined::Builder(); replaceWithInPlace(result); @@ -66,7 +65,7 @@ Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat return result; } -Multiplication Factor::createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Multiplication Factor::createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { //TODO LEA Matrices? assert(!i.isZero()); assert(!i.isNegative()); diff --git a/poincare/src/factorial.cpp b/poincare/src/factorial.cpp index 5fa5a51b1..ab769b20f 100644 --- a/poincare/src/factorial.cpp +++ b/poincare/src/factorial.cpp @@ -14,7 +14,7 @@ namespace Poincare { // Property -Expression FactorialNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression FactorialNode::setSign(Sign s, ReductionContext reductionContext) { assert(s == Sign::Positive); return Factorial(this); } @@ -34,11 +34,11 @@ bool FactorialNode::childNeedsParenthesis(const TreeNode * child) const { // Simplification -Expression FactorialNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Factorial(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression FactorialNode::shallowReduce(ReductionContext reductionContext) { + return Factorial(this).shallowReduce(reductionContext); } -Expression FactorialNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression FactorialNode::shallowBeautify(ReductionContext reductionContext) { return Factorial(this).shallowBeautify(); } @@ -77,7 +77,7 @@ int FactorialNode::serialize(char * buffer, int bufferSize, Preferences::PrintFl } -Expression Factorial::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Factorial::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -86,7 +86,7 @@ Expression Factorial::shallowReduce(Context & context, Preferences::ComplexForma } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } if (c.type() == ExpressionNode::Type::Rational) { Rational r = c.convert(); diff --git a/poincare/src/float.cpp b/poincare/src/float.cpp index 3b5f0c453..ea695bc68 100644 --- a/poincare/src/float.cpp +++ b/poincare/src/float.cpp @@ -4,7 +4,7 @@ namespace Poincare { template -Expression FloatNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression FloatNode::setSign(Sign s, ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); Sign currentSign = m_value < 0 ? Sign::Negative : Sign::Positive; Expression thisExpr = Number(this); diff --git a/poincare/src/floor.cpp b/poincare/src/floor.cpp index 03eaded5a..bc39a305c 100644 --- a/poincare/src/floor.cpp +++ b/poincare/src/floor.cpp @@ -31,11 +31,11 @@ Complex FloorNode::computeOnComplex(const std::complex c, Preferences::Com return Complex::Builder(std::floor(c.real())); } -Expression FloorNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Floor(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression FloorNode::shallowReduce(ReductionContext reductionContext) { + return Floor(this).shallowReduce(reductionContext); } -Expression Floor::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Floor::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -44,7 +44,7 @@ Expression Floor::shallowReduce(Context & context, Preferences::ComplexFormat co } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } if (c.type() == ExpressionNode::Type::Constant) { Constant s = static_cast(c); diff --git a/poincare/src/frac_part.cpp b/poincare/src/frac_part.cpp index 29256d1f4..c49dd0357 100644 --- a/poincare/src/frac_part.cpp +++ b/poincare/src/frac_part.cpp @@ -19,8 +19,8 @@ int FracPartNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, FracPart::s_functionHelper.name()); } -Expression FracPartNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return FracPart(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression FracPartNode::shallowReduce(ReductionContext reductionContext) { + return FracPart(this).shallowReduce(reductionContext); } template @@ -32,7 +32,7 @@ Complex FracPartNode::computeOnComplex(const std::complex c, Preferences:: } -Expression FracPart::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression FracPart::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -41,7 +41,7 @@ Expression FracPart::shallowReduce(Context & context, Preferences::ComplexFormat } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } if (c.type() != ExpressionNode::Type::Rational) { return *this; diff --git a/poincare/src/function.cpp b/poincare/src/function.cpp index cca092f6c..d7e98e09b 100644 --- a/poincare/src/function.cpp +++ b/poincare/src/function.cpp @@ -14,7 +14,7 @@ FunctionNode::FunctionNode(const char * newName, int length) : SymbolAbstractNod strlcpy(const_cast(name()), newName, length+1); } -bool FunctionNode::isReal(Context & context) const { +bool FunctionNode::isReal(Context * context) const { Function f(this); return SymbolAbstract::isReal(f, context); } @@ -23,7 +23,7 @@ Expression FunctionNode::replaceSymbolWithExpression(const SymbolAbstract & symb return Function(this).replaceSymbolWithExpression(symbol, expression); } -int FunctionNode::polynomialDegree(Context & context, const char * symbolName) const { +int FunctionNode::polynomialDegree(Context * context, const char * symbolName) const { Function f(this); Expression e = SymbolAbstract::Expand(f, context, true); if (e.isUninitialized()) { @@ -32,7 +32,7 @@ int FunctionNode::polynomialDegree(Context & context, const char * symbolName) c return e.polynomialDegree(context, symbolName); } -int FunctionNode::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { +int FunctionNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { Function f(this); Expression e = SymbolAbstract::Expand(f, context, true); if (e.isUninitialized()) { @@ -41,7 +41,7 @@ int FunctionNode::getPolynomialCoefficients(Context & context, const char * symb return e.getPolynomialCoefficients(context, symbolName, coefficients); } -int FunctionNode::getVariables(Context & context, isVariableTest isVariable, char * variables, int maxSizeVariable) const { +int FunctionNode::getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const { Function f(this); Expression e = SymbolAbstract::Expand(f, context, true); if (e.isUninitialized()) { @@ -50,7 +50,7 @@ int FunctionNode::getVariables(Context & context, isVariableTest isVariable, cha return e.getVariables(context, isVariable, variables, maxSizeVariable); } -float FunctionNode::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { +float FunctionNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const { Function f(this); Expression e = SymbolAbstract::Expand(f,context, true); if (e.isUninitialized()) { @@ -67,24 +67,24 @@ int FunctionNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name()); } -Expression FunctionNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Function(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); // This uses Symbol::shallowReduce +Expression FunctionNode::shallowReduce(ReductionContext reductionContext) { + return Function(this).shallowReduce(reductionContext); // This uses Symbol::shallowReduce } -Expression FunctionNode::shallowReplaceReplaceableSymbols(Context & context) { +Expression FunctionNode::shallowReplaceReplaceableSymbols(Context * context) { return Function(this).shallowReplaceReplaceableSymbols(context); } -Evaluation FunctionNode::approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation FunctionNode::approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return templatedApproximate(context, complexFormat, angleUnit); } -Evaluation FunctionNode::approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation FunctionNode::approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return templatedApproximate(context, complexFormat, angleUnit); } template -Evaluation FunctionNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation FunctionNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Function f(this); Expression e = SymbolAbstract::Expand(f, context, true); if (e.isUninitialized()) { @@ -130,14 +130,14 @@ Expression Function::replaceSymbolWithExpression(const SymbolAbstract & symbol, return *this; } -Expression Function::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Function::shallowReduce(ExpressionNode::ReductionContext reductionContext) { Function f(*this); - Expression e = SymbolAbstract::Expand(f, context, true); + Expression e = SymbolAbstract::Expand(f, reductionContext.context(), true); if (!e.isUninitialized()) { replaceWithInPlace(e); - return e.deepReduce(context, complexFormat, angleUnit, target, symbolicComputation); + return e.deepReduce(reductionContext); } - if (!symbolicComputation) { + if (!reductionContext.symbolicComputation()) { Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; @@ -145,8 +145,8 @@ Expression Function::shallowReduce(Context & context, Preferences::ComplexFormat return *this; } -Expression Function::shallowReplaceReplaceableSymbols(Context & context) { - Expression e = context.expressionForSymbol(*this, true); +Expression Function::shallowReplaceReplaceableSymbols(Context * context) { + Expression e = context->expressionForSymbol(*this, true); if (e.isUninitialized()) { return *this; } @@ -178,7 +178,7 @@ VariableContext Function::unknownXContext(Context & parentContext) const { } /* We here assert that child contains no occurrence of UnknownX to avoid * creating an infinite loop (for instance: unknownXSymbol = unknownXSymbol+2). */ - assert(!child.recursivelyMatches([](const Expression e, Context & context, bool replaceSymbol) { + assert(!child.recursivelyMatches([](const Expression e, Context * context, bool replaceSymbol) { return e.type() == ExpressionNode::Type::Symbol && static_cast(e).isSystemSymbol(); }, parentContext, false)); xContext.setExpressionForSymbol(child, unknownXSymbol, xContext); diff --git a/poincare/src/great_common_divisor.cpp b/poincare/src/great_common_divisor.cpp index d66ef0045..cc7deb12a 100644 --- a/poincare/src/great_common_divisor.cpp +++ b/poincare/src/great_common_divisor.cpp @@ -21,12 +21,12 @@ int GreatCommonDivisorNode::serialize(char * buffer, int bufferSize, Preferences return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, GreatCommonDivisor::s_functionHelper.name()); } -Expression GreatCommonDivisorNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression GreatCommonDivisorNode::shallowReduce(ReductionContext reductionContext) { return GreatCommonDivisor(this).shallowReduce(); } template -Evaluation GreatCommonDivisorNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation GreatCommonDivisorNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation f1Input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation f2Input = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T f1 = f1Input.toScalar(); diff --git a/poincare/src/hyperbolic_trigonometric_function.cpp b/poincare/src/hyperbolic_trigonometric_function.cpp index 6789fd5e8..efb562c63 100644 --- a/poincare/src/hyperbolic_trigonometric_function.cpp +++ b/poincare/src/hyperbolic_trigonometric_function.cpp @@ -3,11 +3,11 @@ namespace Poincare { -Expression HyperbolicTrigonometricFunctionNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return HyperbolicTrigonometricFunction(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression HyperbolicTrigonometricFunctionNode::shallowReduce(ReductionContext reductionContext) { + return HyperbolicTrigonometricFunction(this).shallowReduce(reductionContext); } -Expression HyperbolicTrigonometricFunction::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression HyperbolicTrigonometricFunction::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -16,7 +16,7 @@ Expression HyperbolicTrigonometricFunction::shallowReduce(Context & context, Pre } Expression c = childAtIndex(0); if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } return *this; } diff --git a/poincare/src/imaginary_part.cpp b/poincare/src/imaginary_part.cpp index d35e0db86..8c2987e4d 100644 --- a/poincare/src/imaginary_part.cpp +++ b/poincare/src/imaginary_part.cpp @@ -20,11 +20,11 @@ int ImaginaryPartNode::serialize(char * buffer, int bufferSize, Preferences::Pri return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ImaginaryPart::s_functionHelper.name()); } -Expression ImaginaryPartNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return ImaginaryPart(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression ImaginaryPartNode::shallowReduce(ReductionContext reductionContext) { + return ImaginaryPart(this).shallowReduce(reductionContext); } -Expression ImaginaryPart::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression ImaginaryPart::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -33,9 +33,9 @@ Expression ImaginaryPart::shallowReduce(Context & context, Preferences::ComplexF } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - if (c.isReal(context)) { + if (c.isReal(reductionContext.context())) { Expression result = Rational::Builder(0); replaceWithInPlace(result); return result; @@ -44,7 +44,7 @@ Expression ImaginaryPart::shallowReduce(Context & context, Preferences::ComplexF ComplexCartesian complexChild = static_cast(c); Expression i = complexChild.imag(); replaceWithInPlace(i); - return i.shallowReduce(context, complexFormat, angleUnit, target); + return i.shallowReduce(reductionContext); } return *this; } diff --git a/poincare/src/infinity.cpp b/poincare/src/infinity.cpp index a8dc2a552..c020f7b83 100644 --- a/poincare/src/infinity.cpp +++ b/poincare/src/infinity.cpp @@ -9,9 +9,9 @@ extern "C" { namespace Poincare { -Expression InfinityNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression InfinityNode::setSign(Sign s, ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); - return Infinity(this).setSign(s, context, complexFormat, angleUnit); + return Infinity(this).setSign(s); } Layout InfinityNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { @@ -38,7 +38,7 @@ Infinity Infinity::Builder(bool negative) { return static_cast(h); } -Expression Infinity::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { +Expression Infinity::setSign(ExpressionNode::Sign s) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); Expression result = Infinity::Builder(s == ExpressionNode::Sign::Negative); replaceWithInPlace(result); diff --git a/poincare/src/integral.cpp b/poincare/src/integral.cpp index 6f5523a61..03efa8741 100644 --- a/poincare/src/integral.cpp +++ b/poincare/src/integral.cpp @@ -15,7 +15,7 @@ constexpr Expression::FunctionHelper Integral::s_functionHelper; int IntegralNode::numberOfChildren() const { return Integral::s_functionHelper.numberOfChildren(); } -int IntegralNode::polynomialDegree(Context & context, const char * symbolName) const { +int IntegralNode::polynomialDegree(Context * context, const char * symbolName) const { if (childAtIndex(0)->polynomialDegree(context, symbolName) == 0 && childAtIndex(1)->polynomialDegree(context, symbolName) == 0 && childAtIndex(2)->polynomialDegree(context, symbolName) == 0 @@ -39,12 +39,12 @@ int IntegralNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Integral::s_functionHelper.name()); } -Expression IntegralNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Integral(this).shallowReduce(context); +Expression IntegralNode::shallowReduce(ReductionContext reductionContext) { + return Integral(this).shallowReduce(reductionContext.context()); } template -Evaluation IntegralNode::templatedApproximate(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation IntegralNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation aInput = childAtIndex(2)->approximate(T(), context, complexFormat, angleUnit); Evaluation bInput = childAtIndex(3)->approximate(T(), context, complexFormat, angleUnit); T a = aInput.toScalar(); @@ -61,18 +61,18 @@ Evaluation IntegralNode::templatedApproximate(Context & context, Preferences: } template -T IntegralNode::functionValueAtAbscissa(T x, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +T IntegralNode::functionValueAtAbscissa(T x, Context * xcontext, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { // Here we cannot use Expression::approximateWithValueForSymbol which would reset the sApproximationEncounteredComplex flag assert(childAtIndex(1)->type() == Type::Symbol); - VariableContext variableContext = VariableContext(static_cast(childAtIndex(1))->name(), &context); + VariableContext variableContext = VariableContext(static_cast(childAtIndex(1))->name(), xcontext); variableContext.setApproximationForVariable(x); - return childAtIndex(0)->approximate(T(), variableContext, complexFormat, angleUnit).toScalar(); + return childAtIndex(0)->approximate(T(), &variableContext, complexFormat, angleUnit).toScalar(); } #ifdef LAGRANGE_METHOD template -T IntegralNode::lagrangeGaussQuadrature(T a, T b, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +T IntegralNode::lagrangeGaussQuadrature(T a, T b, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { /* We here use Gauss-Legendre quadrature with n = 5 * Gauss-Legendre abscissae and weights can be found in * C/C++ library source code. */ @@ -103,7 +103,7 @@ T IntegralNode::lagrangeGaussQuadrature(T a, T b, Context & context, Preferences #else template -IntegralNode::DetailedResult IntegralNode::kronrodGaussQuadrature(T a, T b, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +IntegralNode::DetailedResult IntegralNode::kronrodGaussQuadrature(T a, T b, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { static T epsilon = sizeof(T) == sizeof(double) ? DBL_EPSILON : FLT_EPSILON; static T max = sizeof(T) == sizeof(double) ? DBL_MAX : FLT_MAX; /* We here use Kronrod-Legendre quadrature with n = 21 @@ -187,7 +187,7 @@ IntegralNode::DetailedResult IntegralNode::kronrodGaussQuadrature(T a, T b, C } template -T IntegralNode::adaptiveQuadrature(T a, T b, T eps, int numberOfIterations, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +T IntegralNode::adaptiveQuadrature(T a, T b, T eps, int numberOfIterations, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { if (Expression::ShouldStopProcessing()) { return NAN; } @@ -213,7 +213,7 @@ Expression Integral::UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1).convert(), children.childAtIndex(2), children.childAtIndex(3)); } -Expression Integral::shallowReduce(Context & context) { +Expression Integral::shallowReduce(Context * context) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { diff --git a/poincare/src/least_common_multiple.cpp b/poincare/src/least_common_multiple.cpp index 6afcb5b4f..1148bc63b 100644 --- a/poincare/src/least_common_multiple.cpp +++ b/poincare/src/least_common_multiple.cpp @@ -21,12 +21,12 @@ int LeastCommonMultipleNode::serialize(char * buffer, int bufferSize, Preference return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, LeastCommonMultiple::s_functionHelper.name()); } -Expression LeastCommonMultipleNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression LeastCommonMultipleNode::shallowReduce(ReductionContext reductionContext) { return LeastCommonMultiple(this).shallowReduce(); } template -Evaluation LeastCommonMultipleNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation LeastCommonMultipleNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation f1Input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation f2Input = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T f1 = f1Input.toScalar(); diff --git a/poincare/src/logarithm.cpp b/poincare/src/logarithm.cpp index 42ae7689b..0908ad8e8 100644 --- a/poincare/src/logarithm.cpp +++ b/poincare/src/logarithm.cpp @@ -49,32 +49,32 @@ int LogarithmNode::serialize(char * buffer, int bufferSize, Preferences::Prin } template<> -Expression LogarithmNode<1>::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { - return CommonLogarithm(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression LogarithmNode<1>::shallowReduce(ExpressionNode::ReductionContext reductionContext) { + return CommonLogarithm(this).shallowReduce(reductionContext); } template<> -Expression LogarithmNode<2>::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { - return Logarithm(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression LogarithmNode<2>::shallowReduce(ExpressionNode::ReductionContext reductionContext) { + return Logarithm(this).shallowReduce(reductionContext); } template<> -Expression LogarithmNode<1>::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression LogarithmNode<1>::shallowBeautify(ReductionContext reductionContext) { return CommonLogarithm(this); } template<> -Expression LogarithmNode<2>::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression LogarithmNode<2>::shallowBeautify(ReductionContext reductionContext) { return Logarithm(this).shallowBeautify(); } template<> -template Evaluation LogarithmNode<1>::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +template Evaluation LogarithmNode<1>::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); } template<> -template Evaluation LogarithmNode<2>::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +template Evaluation LogarithmNode<2>::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation x = childAtIndex(0)->approximate(U(), context, complexFormat, angleUnit); Evaluation n = childAtIndex(1)->approximate(U(), context, complexFormat, angleUnit); std::complex result = std::complex(NAN, NAN); @@ -86,7 +86,7 @@ template Evaluation LogarithmNode<2>::templatedApproximate(Contex return Complex::Builder(result); } -Expression CommonLogarithm::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression CommonLogarithm::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -95,14 +95,14 @@ Expression CommonLogarithm::shallowReduce(Context & context, Preferences::Comple } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } Logarithm log = Logarithm::Builder(childAtIndex(0), Rational::Builder(10)); replaceWithInPlace(log); - return log.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + return log.shallowReduce(reductionContext); } -Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Logarithm::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -110,15 +110,17 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma } } - if (SortedIsMatrix(childAtIndex(1), context)) { + if (SortedIsMatrix(childAtIndex(1), reductionContext.context())) { return Undefined::Builder(); } Expression c = childAtIndex(0); - if (c.sign(&context) == ExpressionNode::Sign::Negative || childAtIndex(1).sign(&context) == ExpressionNode::Sign::Negative) { + if (c.sign(reductionContext.context()) == ExpressionNode::Sign::Negative + || childAtIndex(1).sign(reductionContext.context()) == ExpressionNode::Sign::Negative) + { return *this; } - Expression f = simpleShallowReduce(context, complexFormat, angleUnit); + Expression f = simpleShallowReduce(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); if (f.type() != ExpressionNode::Type::Logarithm) { return f; } @@ -135,14 +137,14 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma } // log(+inf, a) ? - if (c.type() == ExpressionNode::Type::Infinity && c.sign(&context) == ExpressionNode::Sign::Positive) { + if (c.type() == ExpressionNode::Type::Infinity && c.sign(reductionContext.context()) == ExpressionNode::Sign::Positive) { Expression base = childAtIndex(1); // log(+inf, a) --> ±inf with a rational and a > 0 if (base.type() == ExpressionNode::Type::Rational && !static_cast(base).isNegative() && !static_cast(base).isZero()) { // log(+inf,a) with a < 1 --> -inf // log(+inf,a) with a > 1 --> inf if (static_cast(base).signedIntegerNumerator().isLowerThan(static_cast(base).integerDenominator())) { - c = c.setSign(ExpressionNode::Sign::Negative, &context, complexFormat, angleUnit, target); + c = c.setSign(ExpressionNode::Sign::Negative, reductionContext); } replaceWithInPlace(c); return c; @@ -153,7 +155,7 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma } // log(x^y, b)->y*log(x, b) if x>0 - if (c.type() == ExpressionNode::Type::Power && c.childAtIndex(0).sign(&context) == ExpressionNode::Sign::Positive) { + if (c.type() == ExpressionNode::Type::Power && c.childAtIndex(0).sign(reductionContext.context()) == ExpressionNode::Sign::Positive) { Power p = static_cast(c); Expression x = p.childAtIndex(0); Expression y = p.childAtIndex(1); @@ -161,28 +163,28 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma Multiplication mult = Multiplication::Builder(y); replaceWithInPlace(mult); mult.addChildAtIndexInPlace(*this, 1, 1); // --> y*log(x,b) - shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); // reduce log (ie log(e, e) = 1) - return mult.shallowReduce(context, complexFormat, angleUnit, target); + shallowReduce(reductionContext); // reduce log (ie log(e, e) = 1) + return mult.shallowReduce(reductionContext); } // log(x*y, b)->log(x,b)+log(y, b) if x,y>0 if (c.type() == ExpressionNode::Type::Multiplication) { Addition a = Addition::Builder(); for (int i = 0; i < c.numberOfChildren()-1; i++) { Expression factor = c.childAtIndex(i); - if (factor.sign(&context) == ExpressionNode::Sign::Positive) { + if (factor.sign(reductionContext.context()) == ExpressionNode::Sign::Positive) { Expression newLog = clone(); static_cast(c).removeChildInPlace(factor, factor.numberOfChildren()); newLog.replaceChildAtIndexInPlace(0, factor); a.addChildAtIndexInPlace(newLog, a.numberOfChildren(), a.numberOfChildren()); - newLog.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + newLog.shallowReduce(reductionContext); } } if (a.numberOfChildren() > 0) { - c.shallowReduce(context, complexFormat, angleUnit, target); - Expression reducedLastLog = shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + c.shallowReduce(reductionContext); + Expression reducedLastLog = shallowReduce(reductionContext); reducedLastLog.replaceWithInPlace(a); a.addChildAtIndexInPlace(reducedLastLog, a.numberOfChildren(), a.numberOfChildren()); - return a.shallowReduce(context, complexFormat, angleUnit, target); + return a.shallowReduce(reductionContext); } } // log(r) with r Rational @@ -197,21 +199,21 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma r = Rational::Builder(newNumerator, newDenomitor); } // log(r) = a0log(p0)+a1log(p1)+... with r = p0^a0*p1^a1*... (Prime decomposition) - a.addChildAtIndexInPlace(splitLogarithmInteger(r.signedIntegerNumerator(), false, context, complexFormat, angleUnit, target), a.numberOfChildren(), a.numberOfChildren()); - a.addChildAtIndexInPlace(splitLogarithmInteger(r.integerDenominator(), true, context, complexFormat, angleUnit, target), a.numberOfChildren(), a.numberOfChildren()); + a.addChildAtIndexInPlace(splitLogarithmInteger(r.signedIntegerNumerator(), false, reductionContext), a.numberOfChildren(), a.numberOfChildren()); + a.addChildAtIndexInPlace(splitLogarithmInteger(r.integerDenominator(), true, reductionContext), a.numberOfChildren(), a.numberOfChildren()); replaceWithInPlace(a); - return a.shallowReduce(context, complexFormat, angleUnit, target); + return a.shallowReduce(reductionContext); } // log(m) with m Matrix if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } return *this; } -Expression Logarithm::simpleShallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { +Expression Logarithm::simpleShallowReduce(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { Expression c = childAtIndex(0); Expression b = childAtIndex(1); // log(0,0)->Undefined @@ -307,7 +309,7 @@ Integer Logarithm::simplifyLogarithmIntegerBaseInteger(Integer i, Integer & base return i; } -Expression Logarithm::splitLogarithmInteger(Integer i, bool isDenominator, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Logarithm::splitLogarithmInteger(Integer i, bool isDenominator, ExpressionNode::ReductionContext reductionContext) { assert(!i.isZero()); assert(!i.isNegative()); Integer factors[Arithmetic::k_maxNumberOfPrimeFactors]; @@ -335,9 +337,9 @@ Expression Logarithm::splitLogarithmInteger(Integer i, bool isDenominator, Conte Logarithm e = clone().convert(); e.replaceChildAtIndexInPlace(0, Rational::Builder(factors[index])); Multiplication m = Multiplication::Builder(Rational::Builder(coefficients[index]), e); - e.simpleShallowReduce(context, complexFormat, angleUnit); + e.simpleShallowReduce(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); a.addChildAtIndexInPlace(m, a.numberOfChildren(), a.numberOfChildren()); - m.shallowReduce(context, complexFormat, angleUnit, target); + m.shallowReduce(reductionContext); } return a; } @@ -359,10 +361,10 @@ Expression Logarithm::shallowBeautify() { return *this; } -template Evaluation LogarithmNode<1>::templatedApproximate(Poincare::Context&, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit) const; -template Evaluation LogarithmNode<1>::templatedApproximate(Poincare::Context&, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit) const; -template Evaluation LogarithmNode<2>::templatedApproximate(Poincare::Context&, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit) const; -template Evaluation LogarithmNode<2>::templatedApproximate(Poincare::Context&, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit) const; +template Evaluation LogarithmNode<1>::templatedApproximate(Poincare::Context *, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit) const; +template Evaluation LogarithmNode<1>::templatedApproximate(Poincare::Context *, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit) const; +template Evaluation LogarithmNode<2>::templatedApproximate(Poincare::Context *, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit) const; +template Evaluation LogarithmNode<2>::templatedApproximate(Poincare::Context *, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit) const; template int LogarithmNode<1>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const; template int LogarithmNode<2>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const; diff --git a/poincare/src/matrix.cpp b/poincare/src/matrix.cpp index b06957e3b..c27dff4e0 100644 --- a/poincare/src/matrix.cpp +++ b/poincare/src/matrix.cpp @@ -18,7 +18,7 @@ void MatrixNode::didAddChildAtIndex(int newNumberOfChildren) { setNumberOfColumns(newNumberOfChildren); } -int MatrixNode::polynomialDegree(Context & context, const char * symbolName) const { +int MatrixNode::polynomialDegree(Context * context, const char * symbolName) const { return -1; } @@ -82,7 +82,7 @@ int MatrixNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat } template -Evaluation MatrixNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation MatrixNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { MatrixComplex matrix = MatrixComplex::Builder(); for (ExpressionNode * c : children()) { matrix.addChildAtIndexInPlace(c->approximate(T(), context, complexFormat, angleUnit), matrix.numberOfChildren(), matrix.numberOfChildren()); @@ -111,7 +111,7 @@ void Matrix::addChildrenAsRowInPlace(TreeHandle t, int i) { setDimensions(previousNumberOfRows + 1, previousNumberOfColumns == 0 ? t.numberOfChildren() : previousNumberOfColumns); } -int Matrix::rank(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool inPlace) { +int Matrix::rank(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool inPlace) { Matrix m = inPlace ? *this : clone().convert(); m = m.rowCanonize(context, complexFormat, angleUnit); int rank = m.numberOfRows(); @@ -165,10 +165,11 @@ int Matrix::ArrayInverse(T * array, int numberOfRows, int numberOfColumns) { return 0; } -Matrix Matrix::rowCanonize(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Multiplication determinant) { +Matrix Matrix::rowCanonize(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Multiplication determinant) { Expression::SetInterruption(false); // The matrix children have to be reduced to be able to spot 0 - deepReduceChildren(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System); + ExpressionNode::ReductionContext systemReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System); + deepReduceChildren(systemReductionContext); int m = numberOfRows(); int n = numberOfColumns(); @@ -194,17 +195,21 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::ComplexFormat complex swapChildrenInPlace(iPivot*n+col, h*n+col); } // Update determinant: det *= -1 - if (!determinant.isUninitialized()) { determinant.addChildAtIndexInPlace(Rational::Builder(-1), 0, determinant.numberOfChildren()); } + if (!determinant.isUninitialized()) { + determinant.addChildAtIndexInPlace(Rational::Builder(-1), 0, determinant.numberOfChildren()); + } } /* Set to 1 M[h][k] by linear combination */ Expression divisor = matrixChild(h, k); // Update determinant: det *= divisor - if (!determinant.isUninitialized()) { determinant.addChildAtIndexInPlace(divisor.clone(), 0, determinant.numberOfChildren()); } + if (!determinant.isUninitialized()) { + determinant.addChildAtIndexInPlace(divisor.clone(), 0, determinant.numberOfChildren()); + } for (int j = k+1; j < n; j++) { Expression opHJ = matrixChild(h, j); Expression newOpHJ = Division::Builder(opHJ, divisor.clone()); replaceChildAtIndexInPlace(h*n+j, newOpHJ); - newOpHJ = newOpHJ.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System); + newOpHJ = newOpHJ.shallowReduce(systemReductionContext); } replaceChildInPlace(divisor, Rational::Builder(1)); @@ -216,8 +221,8 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::ComplexFormat complex Expression opIJ = matrixChild(i, j); Expression newOpIJ = Subtraction::Builder(opIJ, Multiplication::Builder(matrixChild(h, j).clone(), factor.clone())); replaceChildAtIndexInPlace(i*n+j, newOpIJ); - newOpIJ.childAtIndex(1).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System); - newOpIJ = newOpIJ.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System); + newOpIJ.childAtIndex(1).shallowReduce(systemReductionContext); + newOpIJ = newOpIJ.shallowReduce(systemReductionContext); } replaceChildAtIndexInPlace(i*n+k, Rational::Builder(0)); } @@ -305,7 +310,7 @@ Matrix Matrix::CreateIdentity(int dim) { return matrix; } -Expression Matrix::inverse(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression Matrix::inverse(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { if (m_numberOfRows != m_numberOfColumns) { return Undefined::Builder(); } diff --git a/poincare/src/matrix_dimension.cpp b/poincare/src/matrix_dimension.cpp index e0277df49..61cd69ed1 100644 --- a/poincare/src/matrix_dimension.cpp +++ b/poincare/src/matrix_dimension.cpp @@ -11,7 +11,7 @@ constexpr Expression::FunctionHelper MatrixDimension::s_functionHelper; int MatrixDimensionNode::numberOfChildren() const { return MatrixDimension::s_functionHelper.numberOfChildren(); } -Expression MatrixDimensionNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression MatrixDimensionNode::shallowReduce(ReductionContext reductionContext) { return MatrixDimension(this).shallowReduce(); } @@ -24,7 +24,7 @@ int MatrixDimensionNode::serialize(char * buffer, int bufferSize, Preferences::P } template -Evaluation MatrixDimensionNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation MatrixDimensionNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); std::complex operands[2]; if (input.type() == EvaluationNode::Type::MatrixComplex) { diff --git a/poincare/src/matrix_identity.cpp b/poincare/src/matrix_identity.cpp index 03234321d..39f85c467 100644 --- a/poincare/src/matrix_identity.cpp +++ b/poincare/src/matrix_identity.cpp @@ -12,8 +12,8 @@ constexpr Expression::FunctionHelper MatrixIdentity::s_functionHelper; int MatrixIdentityNode::numberOfChildren() const { return MatrixIdentity::s_functionHelper.numberOfChildren(); } -Expression MatrixIdentityNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return MatrixIdentity(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression MatrixIdentityNode::shallowReduce(ReductionContext reductionContext) { + return MatrixIdentity(this).shallowReduce(reductionContext); } Layout MatrixIdentityNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { @@ -25,7 +25,7 @@ int MatrixIdentityNode::serialize(char * buffer, int bufferSize, Preferences::Pr } template -Evaluation MatrixIdentityNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation MatrixIdentityNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); T r = input.toScalar(); // Undefined if the child is not real if (!std::isnan(r) && !std::isinf(r) && r > 0 // The child is defined and positive @@ -38,7 +38,7 @@ Evaluation MatrixIdentityNode::templatedApproximate(Context& context, Prefere } -Expression MatrixIdentity::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression MatrixIdentity::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { diff --git a/poincare/src/matrix_inverse.cpp b/poincare/src/matrix_inverse.cpp index e02f4984d..15f68e062 100644 --- a/poincare/src/matrix_inverse.cpp +++ b/poincare/src/matrix_inverse.cpp @@ -14,8 +14,8 @@ constexpr Expression::FunctionHelper MatrixInverse::s_functionHelper; int MatrixInverseNode::numberOfChildren() const { return MatrixInverse::s_functionHelper.numberOfChildren(); } -Expression MatrixInverseNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return MatrixInverse(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression MatrixInverseNode::shallowReduce(ReductionContext reductionContext) { + return MatrixInverse(this).shallowReduce(reductionContext); } Layout MatrixInverseNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { @@ -28,7 +28,7 @@ int MatrixInverseNode::serialize(char * buffer, int bufferSize, Preferences::Pri // TODO: handle this exactly in shallowReduce for small dimensions. template -Evaluation MatrixInverseNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation MatrixInverseNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation inverse; if (input.type() == EvaluationNode::Type::MatrixComplex) { @@ -43,7 +43,7 @@ Evaluation MatrixInverseNode::templatedApproximate(Context& context, Preferen } -Expression MatrixInverse::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression MatrixInverse::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -54,7 +54,7 @@ Expression MatrixInverse::shallowReduce(Context & context, Preferences::ComplexF #if MATRIX_EXACT_REDUCING #if 0 if (!c.recursivelyMatches(Expression::IsMatrix)) { - return Power::Builder(c, Rational::Builder(-1).shallowReduce(context, complexFormat, angleUnit, target); + return Power::Builder(c, Rational::Builder(-1).shallowReduce(reductionContext); } if (c.type() == ExpressionNode::Type::Matrix) { Matrix mat = static_cast(c); @@ -68,7 +68,7 @@ Expression MatrixInverse::shallowReduce(Context & context, Preferences::ComplexF if (c.type() != ExpressionNode::Type::Matrix) { Expression result = Power::Builder(c, Rational::Builder(-1)); replaceWithInPlace(result); - result = result.shallowReduce(context, complexFormat, angleUnit, target); + result = result.shallowReduce(reductionContext); return result; } return *this; diff --git a/poincare/src/matrix_trace.cpp b/poincare/src/matrix_trace.cpp index 11066de38..f4dcf03a7 100644 --- a/poincare/src/matrix_trace.cpp +++ b/poincare/src/matrix_trace.cpp @@ -13,7 +13,7 @@ constexpr Expression::FunctionHelper MatrixTrace::s_functionHelper; int MatrixTraceNode::numberOfChildren() const { return MatrixTrace::s_functionHelper.numberOfChildren(); } -Expression MatrixTraceNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression MatrixTraceNode::shallowReduce(ReductionContext reductionContext) { return MatrixTrace(this).shallowReduce(); } @@ -26,7 +26,7 @@ int MatrixTraceNode::serialize(char * buffer, int bufferSize, Preferences::Print } template -Evaluation MatrixTraceNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation MatrixTraceNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Complex result = Complex::Builder(input.trace()); return result; diff --git a/poincare/src/matrix_transpose.cpp b/poincare/src/matrix_transpose.cpp index a4d080fce..2f9410b84 100644 --- a/poincare/src/matrix_transpose.cpp +++ b/poincare/src/matrix_transpose.cpp @@ -12,7 +12,7 @@ constexpr Expression::FunctionHelper MatrixTranspose::s_functionHelper; int MatrixTransposeNode::numberOfChildren() const { return MatrixTranspose::s_functionHelper.numberOfChildren(); } -Expression MatrixTransposeNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression MatrixTransposeNode::shallowReduce(ReductionContext reductionContext) { return MatrixTranspose(this).shallowReduce(); } @@ -25,7 +25,7 @@ int MatrixTransposeNode::serialize(char * buffer, int bufferSize, Preferences::P } template -Evaluation MatrixTransposeNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation MatrixTransposeNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation transpose; if (input.type() == EvaluationNode::Type::MatrixComplex) { diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 2728ae2c4..7cd414d4e 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -31,7 +31,7 @@ ExpressionNode::Sign MultiplicationNode::sign(Context * context) const { return (Sign)sign; } -int MultiplicationNode::polynomialDegree(Context & context, const char * symbolName) const { +int MultiplicationNode::polynomialDegree(Context * context, const char * symbolName) const { int degree = 0; for (ExpressionNode * c : children()) { int d = c->polynomialDegree(context, symbolName); @@ -43,7 +43,7 @@ int MultiplicationNode::polynomialDegree(Context & context, const char * symbolN return degree; } -int MultiplicationNode::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { +int MultiplicationNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { return Multiplication(this).getPolynomialCoefficients(context, symbolName, coefficients); } @@ -66,9 +66,9 @@ MatrixComplex MultiplicationNode::computeOnMatrices(const MatrixComplex m, return result; } -Expression MultiplicationNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression MultiplicationNode::setSign(Sign s, ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive); - return Multiplication(this).setSign(s, context, complexFormat, angleUnit, target); + return Multiplication(this).setSign(s, reductionContext); } bool MultiplicationNode::childNeedsParenthesis(const TreeNode * child) const { @@ -98,15 +98,15 @@ int MultiplicationNode::serialize(char * buffer, int bufferSize, Preferences::Pr return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, string); } -Expression MultiplicationNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Multiplication(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression MultiplicationNode::shallowReduce(ReductionContext reductionContext) { + return Multiplication(this).shallowReduce(reductionContext); } -Expression MultiplicationNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { - return Multiplication(this).shallowBeautify(context, complexFormat, angleUnit, target); +Expression MultiplicationNode::shallowBeautify(ReductionContext reductionContext) { + return Multiplication(this).shallowBeautify(reductionContext); } -Expression MultiplicationNode::denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression MultiplicationNode::denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return Multiplication(this).denominator(context, complexFormat, angleUnit); } @@ -125,21 +125,21 @@ void Multiplication::computeOnArrays(T * m, T * n, T * result, int mNumberOfColu } } -Expression Multiplication::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Multiplication::setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive); for (int i = 0; i < numberOfChildren(); i++) { - if (childAtIndex(i).sign(context) == ExpressionNode::Sign::Negative) { - replaceChildAtIndexInPlace(i, childAtIndex(i).setSign(s, context, complexFormat, angleUnit, target)); + if (childAtIndex(i).sign(reductionContext.context()) == ExpressionNode::Sign::Negative) { + replaceChildAtIndexInPlace(i, childAtIndex(i).setSign(s, reductionContext)); } } - return shallowReduce(*context, complexFormat, angleUnit, target); + return shallowReduce(reductionContext); } -Expression Multiplication::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { - return privateShallowReduce(context, complexFormat, angleUnit, target, true, true); +Expression Multiplication::shallowReduce(ExpressionNode::ReductionContext reductionContext) { + return privateShallowReduce(reductionContext, true, true); } -Expression Multiplication::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { /* Beautifying a Multiplication consists in several possible operations: * - Add Opposite ((-3)*x -> -(3*x), useful when printing fractions) * - Adding parenthesis if needed (a*(b+c) is not a*b+c) @@ -147,7 +147,7 @@ Expression Multiplication::shallowBeautify(Context & context, Preferences::Compl * shall become a/b) or a non-integer rational term (3/2*a -> (3*a)/2). */ // Step 1: Turn -n*A into -(n*A) - Expression noNegativeNumeral = makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target); + Expression noNegativeNumeral = makePositiveAnyNegativeNumeralFactor(reductionContext); // If one negative numeral factor was made positive, we turn the expression in an Opposite if (!noNegativeNumeral.isUninitialized()) { Opposite o = Opposite::Builder(); @@ -158,9 +158,9 @@ Expression Multiplication::shallowBeautify(Context & context, Preferences::Compl /* Step 2: Merge negative powers: a*b^(-1)*c^(-pi)*d = a*(b*c^pi)^(-1) * This also turns 2/3*a into 2*a*3^(-1) */ - Expression thisExp = mergeNegativePower(context, complexFormat, angleUnit); + Expression thisExp = mergeNegativePower(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); if (thisExp.type() == ExpressionNode::Type::Power) { - return thisExp.shallowBeautify(context, complexFormat, angleUnit, target); + return thisExp.shallowBeautify(reductionContext); } assert(thisExp.type() == ExpressionNode::Type::Multiplication); @@ -184,7 +184,7 @@ Expression Multiplication::shallowBeautify(Context & context, Preferences::Compl Expression denominatorOperand = childI.childAtIndex(0); removeChildInPlace(childI, childI.numberOfChildren()); - Expression numeratorOperand = shallowReduce(context, complexFormat, angleUnit, target); + Expression numeratorOperand = shallowReduce(reductionContext); // Delete unnecessary parentheses on numerator if (numeratorOperand.type() == ExpressionNode::Type::Parenthesis) { Expression numeratorChild0 = numeratorOperand.childAtIndex(0); @@ -196,12 +196,12 @@ Expression Multiplication::shallowBeautify(Context & context, Preferences::Compl numeratorOperand.replaceWithInPlace(d); d.replaceChildAtIndexInPlace(0, numeratorOperand); d.replaceChildAtIndexInPlace(1, denominatorOperand); - return d.shallowBeautify(context, complexFormat, angleUnit, target); + return d.shallowBeautify(reductionContext); } return thisExp; } -int Multiplication::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { +int Multiplication::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { int deg = polynomialDegree(context, symbolName); if (deg < 0 || deg > Expression::k_maxPolynomialDegree) { return -1; @@ -236,7 +236,7 @@ int Multiplication::getPolynomialCoefficients(Context & context, const char * sy return deg; } -Expression Multiplication::denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression Multiplication::denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { // Merge negative power: a*b^-1*c^(-Pi)*d = a*(b*c^Pi)^-1 // WARNING: we do not want to change the expression but to create a new one. Multiplication thisClone = clone().convert(); @@ -258,7 +258,7 @@ Expression Multiplication::denominator(Context & context, Preferences::ComplexFo return Expression(); } -Expression Multiplication::privateShallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool shouldExpand, bool canBeInterrupted) { +Expression Multiplication::privateShallowReduce(ExpressionNode::ReductionContext reductionContext, bool shouldExpand, bool canBeInterrupted) { { Expression e = Expression::defaultShallowReduce();; if (e.isUndefined()) { @@ -326,7 +326,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: for (int j = 0; j < n; j++) { Expression * mult = new Multiplication::Builder(currentMatrix->childAtIndex(j+om*i1), resultMatrix->childAtIndex(j*m+i2), true); static_cast(newMatrixOperands[e])->addOperand(mult); - mult->shallowReduce(context, complexFormat, angleUnit, target); + mult->shallowReduce(reductionContext); } Reduce(&newMatrixOperands[e], context, complexFormat, angleUnit, false); } @@ -342,9 +342,9 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: Expression * entryI = resultMatrix->childAtIndex(i); resultMatrix->replaceOperand(entryI, m, false); m->addOperand(entryI); - m->shallowReduce(context, complexFormat, angleUnit, target); + m->shallowReduce(reductionContext); } - return replaceWith(resultMatrix, true)->shallowReduce(context, complexFormat, angleUnit, target); + return replaceWith(resultMatrix, true)->shallowReduce(reductionContext); } #endif #endif @@ -356,7 +356,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: while (i < numberOfChildren()-1) { Expression oi = childAtIndex(i); Expression oi1 = childAtIndex(i+1); - if (oi.recursivelyMatches(Expression::IsRandom, context, true)) { + if (oi.recursivelyMatches(Expression::IsRandom, reductionContext.context(), true)) { // Do not factorize random or randint i++; continue; @@ -371,11 +371,11 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: shouldFactorizeBase = oi.type() == ExpressionNode::Type::Power && oi1.type() == ExpressionNode::Type::Power; } if (shouldFactorizeBase) { - factorizeBase(i, i+1, context, complexFormat, angleUnit, target); + factorizeBase(i, i+1, reductionContext); continue; } } else if (TermHasNumeralBase(oi) && TermHasNumeralBase(oi1) && TermsHaveIdenticalExponent(oi, oi1)) { - factorizeExponent(i, i+1, context, complexFormat, angleUnit, target); + factorizeExponent(i, i+1, reductionContext); continue; } i++; @@ -385,7 +385,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: * opposite signs. We replace them by either: * - tan(x)^p*cos(x)^(p+q) if |p|<|q| * - tan(x)^(-q)*sin(x)^(p+q) otherwise */ - if (target == ExpressionNode::ReductionTarget::User) { + if (reductionContext.target() == ExpressionNode::ReductionTarget::User) { for (int i = 0; i < numberOfChildren(); i++) { Expression o1 = childAtIndex(i); if (Base(o1).type() == ExpressionNode::Type::Sine && TermHasNumeralExponent(o1)) { @@ -395,7 +395,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: for (int j = i+1; j < numberOfChildren(); j++) { Expression o2 = childAtIndex(j); if (Base(o2).type() == ExpressionNode::Type::Cosine && TermHasNumeralExponent(o2) && Base(o2).childAtIndex(0).isIdenticalTo(x)) { - factorizeSineAndCosine(i, j, context, complexFormat, angleUnit); + factorizeSineAndCosine(i, j, reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); break; } } @@ -404,7 +404,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: /* Replacing sin/cos by tan factors may have mixed factors and factors are * guaranteed to be sorted (according ot SimplificationOrder) at the end of * shallowReduce */ - sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, true, canBeInterrupted); }, true); + sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, true, canBeInterrupted); }, true); } /* Step 5: We remove rational children that appeared in the middle of sorted @@ -450,7 +450,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: // Check that other children don't match inf bool infiniteFactor = false; for (int i = 1; i < numberOfChildren(); i++) { - infiniteFactor = childAtIndex(i).recursivelyMatches(Expression::IsInfinity, context); + infiniteFactor = childAtIndex(i).recursivelyMatches(Expression::IsInfinity, reductionContext.context()); if (infiniteFactor) { break; } @@ -473,14 +473,14 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: * reduce expressions such as (x+y)^(-1)*(x+y)(a+b). * If there is a random somewhere, do not expand. */ Expression p = parent(); - bool hasRandom = recursivelyMatches(Expression::IsRandom, context, true); + bool hasRandom = recursivelyMatches(Expression::IsRandom, reductionContext.context(), true); if (shouldExpand && (p.isUninitialized() || p.type() != ExpressionNode::Type::Multiplication) && !hasRandom) { for (int i = 0; i < numberOfChildren(); i++) { if (childAtIndex(i).type() == ExpressionNode::Type::Addition) { - return distributeOnOperandAtIndex(i, context, complexFormat, angleUnit, target); + return distributeOnOperandAtIndex(i, reductionContext); } } } @@ -500,7 +500,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: * - All children are either real or ComplexCartesian (allChildrenAreReal == 0) * We can bubble up ComplexCartesian nodes. * Do not simplify if there are randoms !*/ - if (!hasRandom && allChildrenAreReal(context) == 0) { + if (!hasRandom && allChildrenAreReal(reductionContext.context()) == 0) { int nbChildren = numberOfChildren(); int i = nbChildren-1; // Children are sorted so ComplexCartesian nodes are at the end @@ -515,7 +515,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: // the Multiplication is sorted so ComplexCartesian nodes are the last ones break; } - child = child.multiply(static_cast(e), context, complexFormat, angleUnit, target); + child = child.multiply(static_cast(e), reductionContext); removeChildAtIndexInPlace(i); i--; } @@ -528,8 +528,8 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: replaceWithInPlace(newComplexCartesian); newComplexCartesian.replaceChildAtIndexInPlace(0, real); newComplexCartesian.replaceChildAtIndexInPlace(1, imag); - real.shallowReduce(context, complexFormat, angleUnit, target); - imag.shallowReduce(context, complexFormat, angleUnit, target); + real.shallowReduce(reductionContext); + imag.shallowReduce(reductionContext); return newComplexCartesian.shallowReduce(); } @@ -549,7 +549,7 @@ void Multiplication::mergeMultiplicationChildrenInPlace() { } } -void Multiplication::factorizeBase(int i, int j, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +void Multiplication::factorizeBase(int i, int j, ExpressionNode::ReductionContext reductionContext) { /* This function factorizes two children which have a common base. For example * if this is Multiplication::Builder(pi^2, pi^3), then pi^2 and pi^3 could be merged * and this turned into Multiplication::Builder(pi^5). */ @@ -558,10 +558,10 @@ void Multiplication::factorizeBase(int i, int j, Context & context, Preferences: // Step 1: Get rid of the child j removeChildAtIndexInPlace(j); // Step 2: Merge child j in child i by factorizing base - mergeInChildByFactorizingBase(i, e, context, complexFormat, angleUnit, target); + mergeInChildByFactorizingBase(i, e, reductionContext); } -void Multiplication::mergeInChildByFactorizingBase(int i, Expression e, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +void Multiplication::mergeInChildByFactorizingBase(int i, Expression e, ExpressionNode::ReductionContext reductionContext) { /* This function replace the child at index i by its factorization with e. e * and childAtIndex(i) are supposed to have a common base. */ @@ -569,10 +569,10 @@ void Multiplication::mergeInChildByFactorizingBase(int i, Expression e, Context Expression s = Addition::Builder(CreateExponent(childAtIndex(i)), CreateExponent(e)); // pi^2*pi^3 -> pi^(2+3) -> pi^5 // Step 2: Create the new Power Expression p = Power::Builder(Base(childAtIndex(i)), s); // pi^2*pi^-2 -> pi^0 -> 1 - s.shallowReduce(context, complexFormat, angleUnit, target); + s.shallowReduce(reductionContext); // Step 3: Replace one of the child replaceChildAtIndexInPlace(i, p); - p = p.shallowReduce(context, complexFormat, angleUnit, target); + p = p.shallowReduce(reductionContext); /* Step 4: Reducing the new power might have turned it into a multiplication, * ie: 12^(1/2) -> 2*3^(1/2). In that case, we need to merge the multiplication * node with this. */ @@ -581,7 +581,7 @@ void Multiplication::mergeInChildByFactorizingBase(int i, Expression e, Context } } -void Multiplication::factorizeExponent(int i, int j, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +void Multiplication::factorizeExponent(int i, int j, ExpressionNode::ReductionContext reductionContext) { /* This function factorizes children which share a common exponent. For * example, it turns Multiplication::Builder(2^x,3^x) into Multiplication::Builder(6^x). */ @@ -592,8 +592,8 @@ void Multiplication::factorizeExponent(int i, int j, Context & context, Preferen // Step 3: Replace the other child childAtIndex(i).replaceChildAtIndexInPlace(0, m); // Step 4: Reduce expressions - m.shallowReduce(context, complexFormat, angleUnit, target); - Expression p = childAtIndex(i).shallowReduce(context, complexFormat, angleUnit, target); // 2^x*(1/2)^x -> (2*1/2)^x -> 1 + m.shallowReduce(reductionContext); + Expression p = childAtIndex(i).shallowReduce(reductionContext); // 2^x*(1/2)^x -> (2*1/2)^x -> 1 /* Step 5: Reducing the new power might have turned it into a multiplication, * ie: 12^(1/2) -> 2*3^(1/2). In that case, we need to merge the multiplication * node with this. */ @@ -602,7 +602,7 @@ void Multiplication::factorizeExponent(int i, int j, Context & context, Preferen } } -Expression Multiplication::distributeOnOperandAtIndex(int i, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Multiplication::distributeOnOperandAtIndex(int i, ExpressionNode::ReductionContext reductionContext) { /* This method creates a*...*b*y... + a*...*c*y... + ... from * a*...*(b+c+...)*y... */ assert(i >= 0 && i < numberOfChildren()); @@ -616,13 +616,13 @@ Expression Multiplication::distributeOnOperandAtIndex(int i, Context & context, m.replaceChildAtIndexInPlace(i, childI.childAtIndex(j)); // Reduce m: pi^(-1)*(pi + x) -> pi^(-1)*pi + pi^(-1)*x -> 1 + pi^(-1)*x a.addChildAtIndexInPlace(m, a.numberOfChildren(), a.numberOfChildren()); - m.shallowReduce(context, complexFormat, angleUnit, target); + m.shallowReduce(reductionContext); } replaceWithInPlace(a); - return a.shallowReduce(context, complexFormat, angleUnit, target); // Order terms, put under a common denominator if needed + return a.shallowReduce(reductionContext); // Order terms, put under a common denominator if needed } -void Multiplication::addMissingFactors(Expression factor, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { +void Multiplication::addMissingFactors(Expression factor, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { if (factor.type() == ExpressionNode::Type::Multiplication) { for (int j = 0; j < factor.numberOfChildren(); j++) { addMissingFactors(factor.childAtIndex(j), context, complexFormat, angleUnit); @@ -646,20 +646,21 @@ void Multiplication::addMissingFactors(Expression factor, Context & context, Pre if (factor.type() != ExpressionNode::Type::Rational) { /* If factor is not a rational, we merge it with the child of identical * base if any. Otherwise, we add it as an new child. */ + ExpressionNode::ReductionContext reductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); for (int i = 0; i < numberOfChildren(); i++) { if (TermsHaveIdenticalBase(childAtIndex(i), factor)) { - Expression sub = Subtraction::Builder(CreateExponent(childAtIndex(i)), CreateExponent(factor)).deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); - if (sub.sign(&context) == ExpressionNode::Sign::Negative) { // index[0] < index[1] + Expression sub = Subtraction::Builder(CreateExponent(childAtIndex(i)), CreateExponent(factor)).deepReduce(reductionContext); + if (sub.sign(reductionContext.context()) == ExpressionNode::Sign::Negative) { // index[0] < index[1] sub = Opposite::Builder(sub); if (factor.type() == ExpressionNode::Type::Power) { factor.replaceChildAtIndexInPlace(1, sub); } else { factor = Power::Builder(factor, sub); } - sub.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); - mergeInChildByFactorizingBase(i, factor, context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); - } else if (sub.sign(&context) == ExpressionNode::Sign::Unknown) { - mergeInChildByFactorizingBase(i, factor, context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + sub.shallowReduce(reductionContext); + mergeInChildByFactorizingBase(i, factor, reductionContext); + } else if (sub.sign(reductionContext.context()) == ExpressionNode::Sign::Unknown) { + mergeInChildByFactorizingBase(i, factor, reductionContext); } return; } @@ -669,7 +670,7 @@ void Multiplication::addMissingFactors(Expression factor, Context & context, Pre sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, true, canBeInterrupted); }, true); } -void Multiplication::factorizeSineAndCosine(int i, int j, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { +void Multiplication::factorizeSineAndCosine(int i, int j, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { /* This function turn sin(x)^p * cos(x)^q into either: * - tan(x)^p*cos(x)^(p+q) if |p|<|q| * - tan(x)^(-q)*sin(x)^(p+q) otherwise */ @@ -685,6 +686,7 @@ void Multiplication::factorizeSineAndCosine(int i, int j, Context & context, Pre Number absP = p.clone().convert().setSign(ExpressionNode::Sign::Positive); Number absQ = q.clone().convert().setSign(ExpressionNode::Sign::Positive); Expression tan = Tangent::Builder(x.clone()); + ExpressionNode::ReductionContext userReductionContext = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); if (Number::NaturalOrder(absP, absQ) < 0) { // Replace sin(x) by tan(x) or sin(x)^p by tan(x)^p if (p.isRationalOne()) { @@ -692,19 +694,19 @@ void Multiplication::factorizeSineAndCosine(int i, int j, Context & context, Pre } else { replaceChildAtIndexInPlace(i, Power::Builder(tan, p)); } - childAtIndex(i).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + childAtIndex(i).shallowReduce(userReductionContext); // Replace cos(x)^q by cos(x)^(p+q) replaceChildAtIndexInPlace(j, Power::Builder(Base(childAtIndex(j)), sumPQ)); - childAtIndex(j).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + childAtIndex(j).shallowReduce(userReductionContext); } else { // Replace cos(x)^q by tan(x)^(-q) Expression newPower = Power::Builder(tan, Number::Multiplication(q, Rational::Builder(-1))); - newPower.childAtIndex(1).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + newPower.childAtIndex(1).shallowReduce(userReductionContext); replaceChildAtIndexInPlace(j, newPower); - newPower.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + newPower.shallowReduce(userReductionContext); // Replace sin(x)^p by sin(x)^(p+q) replaceChildAtIndexInPlace(i, Power::Builder(Base(childAtIndex(i)), sumPQ)); - childAtIndex(i).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + childAtIndex(i).shallowReduce(userReductionContext); } } @@ -758,7 +760,7 @@ bool Multiplication::TermHasNumeralExponent(const Expression & e) { return false; } -Expression Multiplication::mergeNegativePower(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { +Expression Multiplication::mergeNegativePower(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { /* mergeNegativePower groups all factors that are power of form a^(-b) together * for instance, a^(-1)*b^(-c)*c = c*(a*b^c)^(-1) */ Multiplication m = Multiplication::Builder(); @@ -777,7 +779,7 @@ Expression Multiplication::mergeNegativePower(Context & context, Preferences::Co while (i < numberOfChildren()) { if (childAtIndex(i).type() == ExpressionNode::Type::Power) { Expression p = childAtIndex(i); - Expression positivePIndex = p.childAtIndex(1).makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + Expression positivePIndex = p.childAtIndex(1).makePositiveAnyNegativeNumeralFactor( ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User)); if (!positivePIndex.isUninitialized()) { // Remove a^(-b) from the Multiplication removeChildAtIndexInPlace(i); diff --git a/poincare/src/n_ary_expression.cpp b/poincare/src/n_ary_expression.cpp index c57ae085b..133d1bb01 100644 --- a/poincare/src/n_ary_expression.cpp +++ b/poincare/src/n_ary_expression.cpp @@ -28,7 +28,7 @@ void NAryExpressionNode::sortChildrenInPlace(ExpressionOrder order, bool canBeIn } } -bool NAryExpressionNode::isReal(Context & context) const { +bool NAryExpressionNode::isReal(Context * context) const { return NAryExpression(this).allChildrenAreReal(context) == 1; } @@ -80,7 +80,7 @@ int NAryExpressionNode::simplificationOrderGreaterType(const ExpressionNode * e, return 0; } -int NAryExpression::allChildrenAreReal(Context & context) const { +int NAryExpression::allChildrenAreReal(Context * context) const { int i = 0; int result = 1; while (i < numberOfChildren()) { @@ -95,7 +95,7 @@ int NAryExpression::allChildrenAreReal(Context & context) const { return result; } -bool NAryExpression::SortedIsMatrix(Expression e, Context & context) { +bool NAryExpression::SortedIsMatrix(Expression e, Context * context) { assert(IsNAry(e, context)); int childrenCount = e.numberOfChildren(); if (childrenCount > 0) { diff --git a/poincare/src/naperian_logarithm.cpp b/poincare/src/naperian_logarithm.cpp index 184070a72..88522f1b3 100644 --- a/poincare/src/naperian_logarithm.cpp +++ b/poincare/src/naperian_logarithm.cpp @@ -18,12 +18,12 @@ int NaperianLogarithmNode::serialize(char * buffer, int bufferSize, Preferences: return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NaperianLogarithm::s_functionHelper.name()); } -Expression NaperianLogarithmNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return NaperianLogarithm(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression NaperianLogarithmNode::shallowReduce(ReductionContext reductionContext) { + return NaperianLogarithm(this).shallowReduce(reductionContext); } -Expression NaperianLogarithm::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression NaperianLogarithm::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -32,11 +32,11 @@ Expression NaperianLogarithm::shallowReduce(Context & context, Preferences::Comp } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } Logarithm l = Logarithm::Builder(c, Constant::Builder(UCodePointScriptSmallE)); replaceWithInPlace(l); - return l.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + return l.shallowReduce(reductionContext); } } diff --git a/poincare/src/nth_root.cpp b/poincare/src/nth_root.cpp index c212bb5f4..02becd1f8 100644 --- a/poincare/src/nth_root.cpp +++ b/poincare/src/nth_root.cpp @@ -28,12 +28,12 @@ int NthRootNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloa return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NthRoot::s_functionHelper.name()); } -Expression NthRootNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return NthRoot(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression NthRootNode::shallowReduce(ReductionContext reductionContext) { + return NthRoot(this).shallowReduce(reductionContext); } template -Evaluation NthRootNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation NthRootNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation base = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation index = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); Complex result = Complex::Undefined(); @@ -64,7 +64,7 @@ Evaluation NthRootNode::templatedApproximate(Context& context, Preferences::C } -Expression NthRoot::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression NthRoot::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -78,9 +78,9 @@ Expression NthRoot::shallowReduce(Context & context, Preferences::ComplexFormat #endif Expression invIndex = Power::Builder(childAtIndex(1), Rational::Builder(-1)); Power p = Power::Builder(childAtIndex(0), invIndex); - invIndex.shallowReduce(context, complexFormat, angleUnit, target); + invIndex.shallowReduce(reductionContext); replaceWithInPlace(p); - return p.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + return p.shallowReduce(reductionContext); } } diff --git a/poincare/src/opposite.cpp b/poincare/src/opposite.cpp index bd26b5a45..0ad9d5b3b 100644 --- a/poincare/src/opposite.cpp +++ b/poincare/src/opposite.cpp @@ -16,7 +16,7 @@ extern "C" { namespace Poincare { -int OppositeNode::polynomialDegree(Context & context, const char * symbolName) const { +int OppositeNode::polynomialDegree(Context * context, const char * symbolName) const { return childAtIndex(0)->polynomialDegree(context, symbolName); } @@ -67,13 +67,13 @@ int OppositeNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo return numberOfChar; } -Expression OppositeNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Opposite(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression OppositeNode::shallowReduce(ReductionContext reductionContext) { + return Opposite(this).shallowReduce(reductionContext); } /* Simplification */ -Expression Opposite::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Opposite::shallowReduce(ExpressionNode::ReductionContext reductionContext) { Expression result = Expression::defaultShallowReduce(); if (result.isUndefined()) { return result; @@ -81,7 +81,7 @@ Expression Opposite::shallowReduce(Context & context, Preferences::ComplexFormat Expression child = result.childAtIndex(0); result = Multiplication::Builder(Rational::Builder(-1), child); replaceWithInPlace(result); - return result.shallowReduce(context, complexFormat, angleUnit, target); + return result.shallowReduce(reductionContext); } } diff --git a/poincare/src/parenthesis.cpp b/poincare/src/parenthesis.cpp index e55d013b7..81b7fddb7 100644 --- a/poincare/src/parenthesis.cpp +++ b/poincare/src/parenthesis.cpp @@ -4,7 +4,7 @@ namespace Poincare { -int ParenthesisNode::polynomialDegree(Context & context, const char * symbolName) const { +int ParenthesisNode::polynomialDegree(Context * context, const char * symbolName) const { return childAtIndex(0)->polynomialDegree(context, symbolName); } @@ -16,12 +16,12 @@ int ParenthesisNode::serialize(char * buffer, int bufferSize, Preferences::Print return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ""); } -Expression ParenthesisNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression ParenthesisNode::shallowReduce(ReductionContext reductionContext) { return Parenthesis(this).shallowReduce(); } template -Evaluation ParenthesisNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation ParenthesisNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); } diff --git a/poincare/src/permute_coefficient.cpp b/poincare/src/permute_coefficient.cpp index f974a8983..ba99709b7 100644 --- a/poincare/src/permute_coefficient.cpp +++ b/poincare/src/permute_coefficient.cpp @@ -23,12 +23,12 @@ int PermuteCoefficientNode::serialize(char * buffer, int bufferSize, Preferences return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, PermuteCoefficient::s_functionHelper.name()); } -Expression PermuteCoefficientNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression PermuteCoefficientNode::shallowReduce(ReductionContext reductionContext) { return PermuteCoefficient(this).shallowReduce(); } template -Evaluation PermuteCoefficientNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation PermuteCoefficientNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation nInput = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation kInput = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T n = nInput.toScalar(); diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index b1c474141..6e072299b 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -48,12 +48,12 @@ ExpressionNode::Sign PowerNode::sign(Context * context) const { return Sign::Unknown; } -Expression PowerNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression PowerNode::setSign(Sign s, ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive); - return Power(this).setSign(s, context, complexFormat, angleUnit, target); + return Power(this).setSign(s, reductionContext); } -int PowerNode::polynomialDegree(Context & context, const char * symbolName) const { +int PowerNode::polynomialDegree(Context * context, const char * symbolName) const { int deg = ExpressionNode::polynomialDegree(context, symbolName); if (deg == 0) { return deg; @@ -77,11 +77,11 @@ int PowerNode::polynomialDegree(Context & context, const char * symbolName) cons return -1; } -int PowerNode::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { +int PowerNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { return Power(this).getPolynomialCoefficients(context, symbolName, coefficients); } -bool PowerNode::isReal(Context & context) const { +bool PowerNode::isReal(Context * context) const { ExpressionNode * base = childAtIndex(0); ExpressionNode * index = childAtIndex(1); // Both base and index are real and: @@ -89,7 +89,7 @@ bool PowerNode::isReal(Context & context) const { // - or index is an integer if (base->isReal(context) && index->isReal(context) && - (base->sign(&context) == Sign::Positive || + (base->sign(context) == Sign::Positive || (index->type() == ExpressionNode::Type::Rational && static_cast(index)->denominator().isOne()))) { return true; } @@ -164,12 +164,12 @@ int PowerNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatM // Simplify -Expression PowerNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Power(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression PowerNode::shallowReduce(ReductionContext reductionContext) { + return Power(this).shallowReduce(reductionContext); } -Expression PowerNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { - return Power(this).shallowBeautify(context, complexFormat, angleUnit, target); +Expression PowerNode::shallowBeautify(ReductionContext reductionContext) { + return Power(this).shallowBeautify(reductionContext); } int PowerNode::simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { @@ -191,7 +191,7 @@ int PowerNode::simplificationOrderSameType(const ExpressionNode * e, bool ascend return SimplificationOrder(childAtIndex(1), e->childAtIndex(1), ascending, canBeInterrupted); } -Expression PowerNode::denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression PowerNode::denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return Power(this).denominator(context, complexFormat, angleUnit); } @@ -234,17 +234,17 @@ template MatrixComplex PowerNode::computeOnMatrices(const MatrixC // Power -Expression Power::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Power::setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive); - if (childAtIndex(0).sign(context) == ExpressionNode::Sign::Negative) { - Expression result = Power::Builder(childAtIndex(0).setSign(ExpressionNode::Sign::Positive, context, complexFormat, angleUnit, target), childAtIndex(1)); + if (childAtIndex(0).sign(reductionContext.context()) == ExpressionNode::Sign::Negative) { + Expression result = Power::Builder(childAtIndex(0).setSign(ExpressionNode::Sign::Positive, reductionContext), childAtIndex(1)); replaceWithInPlace(result); - return result.shallowReduce(*context, complexFormat, angleUnit, target); + return result.shallowReduce(reductionContext); } return *this; } -int Power::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { +int Power::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { int deg = polynomialDegree(context, symbolName); if (deg <= 0) { return Expression::defaultGetPolynomialCoefficients(context, symbolName, coefficients); @@ -275,7 +275,7 @@ int Power::getPolynomialCoefficients(Context & context, const char * symbolName, return -1; } -Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Power::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); @@ -301,7 +301,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co } if (exponent.isNegative()) { childAtIndex(1)->setSign(Sign::Positive, context, complexFormat, angleUnit); - Expression * newMatrix = shallowReduce(context, complexFormat, angleUnit, target); + Expression * newMatrix = shallowReduce(reductionContext); Expression * parent = newMatrix->parent(); MatrixInverse * inv = new MatrixInverse(newMatrix, false); parent->replaceOperand(newMatrix, inv, false); @@ -321,7 +321,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co result->addOperand(mat->clone()); } replaceWith(result, true); - return result->shallowReduce(context, complexFormat, angleUnit, target); + return result->shallowReduce(reductionContext); } #endif #endif @@ -330,7 +330,11 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co Expression base = childAtIndex(0); Expression index = childAtIndex(1); /* Step 0: if both children are true unresolved complexes, the result is not simplified. TODO? */ - if (!base.isReal(context) && base.type() != ExpressionNode::Type::ComplexCartesian && !index.isReal(context) && index.type() != ExpressionNode::Type::ComplexCartesian) { + if (!base.isReal(reductionContext.context()) + && base.type() != ExpressionNode::Type::ComplexCartesian + && !index.isReal(reductionContext.context()) + && index.type() != ExpressionNode::Type::ComplexCartesian) + { return *this; } @@ -349,7 +353,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co return result; } // x^0 - if (target == ExpressionNode::ReductionTarget::User || childAtIndex(0).isNumber()) { + if (reductionContext.target() == ExpressionNode::ReductionTarget::User || childAtIndex(0).isNumber()) { /* Warning: if the ReductionTarget is User, in all other cases but 0^0, * we replace x^0 by one. This is almost always true except when x = 0. * However, not substituting x^0 by one would prevent from simplifying @@ -371,20 +375,20 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co // 0^x if (a.isZero()) { // 0^x with x > 0 = 0 - if (childAtIndex(1).sign(&context) == ExpressionNode::Sign::Positive) { + if (childAtIndex(1).sign(reductionContext.context()) == ExpressionNode::Sign::Positive) { Expression result = Rational::Builder(0); replaceWithInPlace(result); return result; } // 0^x with x < 0 = undef - if (childAtIndex(1).sign(&context) == ExpressionNode::Sign::Negative) { + if (childAtIndex(1).sign(reductionContext.context()) == ExpressionNode::Sign::Negative) { Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } } // 1^x = 1 if x != ±inf - if (a.isOne() && !childAtIndex(1).recursivelyMatches(Expression::IsInfinity, context)) { + if (a.isOne() && !childAtIndex(1).recursivelyMatches(Expression::IsInfinity, reductionContext.context())) { Expression result = Rational::Builder(1); replaceWithInPlace(result); return result; @@ -414,21 +418,21 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co Rational r = static_cast(index); if (r.isMinusOne()) { // (x+iy)^(-1) - result = complexBase.inverse(context, complexFormat, angleUnit, target); + result = complexBase.inverse(reductionContext); } else if (r.isHalf()) { // (x+iy)^(1/2) - result = complexBase.squareRoot(context, complexFormat, angleUnit, target); + result = complexBase.squareRoot(reductionContext); } else if (r.isMinusHalf()) { // (x+iy)^(-1/2) - result = complexBase.squareRoot(context, complexFormat, angleUnit, target).inverse(context, complexFormat, angleUnit, target); + result = complexBase.squareRoot(reductionContext).inverse(reductionContext); } else if (r.integerDenominator().isOne() && r.unsignedIntegerNumerator().isLowerThan(ten)) { if (r.sign() == ExpressionNode::Sign::Positive) { // (x+iy)^n, n integer positive n < 10 - result = complexBase.powerInteger(r.unsignedIntegerNumerator().extractedInt(), context, complexFormat, angleUnit, target, symbolicComputation); + result = complexBase.powerInteger(r.unsignedIntegerNumerator().extractedInt(), reductionContext); } else { // (x+iy)^(-n), n integer positive n < 10 assert(r.sign() == ExpressionNode::Sign::Negative); - result = complexBase.powerInteger(r.unsignedIntegerNumerator().extractedInt(), context, complexFormat, angleUnit, target, symbolicComputation).inverse(context, complexFormat, angleUnit, target); + result = complexBase.powerInteger(r.unsignedIntegerNumerator().extractedInt(), reductionContext).inverse(reductionContext); } } if (!result.isUninitialized()) { @@ -438,20 +442,25 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co } } // All other cases where one child at least is a ComplexCartesian - if ((!letPowerAtRoot && base.isReal(context) && index.type() == ExpressionNode::Type::ComplexCartesian) || - (!letPowerAtRoot && base.type() == ExpressionNode::Type::ComplexCartesian && index.isReal(context)) || - (!letPowerAtRoot && base.type() == ExpressionNode::Type::ComplexCartesian && index.type() == ExpressionNode::Type::ComplexCartesian)) { + if (!letPowerAtRoot + && ((base.isReal(reductionContext.context()) + && index.type() == ExpressionNode::Type::ComplexCartesian) + || (base.type() == ExpressionNode::Type::ComplexCartesian + && index.isReal(reductionContext.context())) + || (base.type() == ExpressionNode::Type::ComplexCartesian + && index.type() == ExpressionNode::Type::ComplexCartesian))) + { complexBase = base.type() == ExpressionNode::Type::ComplexCartesian ? static_cast(base) : ComplexCartesian::Builder(base, Rational::Builder(0)); complexIndex = index.type() == ExpressionNode::Type::ComplexCartesian ? static_cast(index) : ComplexCartesian::Builder(index, Rational::Builder(0)); - result = complexBase.power(complexIndex, context, complexFormat, angleUnit, target, symbolicComputation); + result = complexBase.power(complexIndex, reductionContext); replaceWithInPlace(result); return result.shallowReduce(); } /* Step 3: We look for square root and sum of square roots (two terms maximum * so far) at the denominator and move them to the numerator. */ - if (target == ExpressionNode::ReductionTarget::User) { - Expression r = removeSquareRootsFromDenominator(context, complexFormat, angleUnit, symbolicComputation); + if (reductionContext.target() == ExpressionNode::ReductionTarget::User) { + Expression r = removeSquareRootsFromDenominator(reductionContext); if (!r.isUninitialized()) { return r; } @@ -463,31 +472,31 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co // i^(p/q) if (childAtIndex(0).type() == ExpressionNode::Type::Constant && childAtIndex(0).convert().isIComplex()) { Number r = Number::Multiplication(b, Rational::Builder(1, 2)); - Expression result = CreateComplexExponent(r, context, complexFormat, angleUnit, target); + Expression result = CreateComplexExponent(r, reductionContext); replaceWithInPlace(result); - return result.shallowReduce(context, complexFormat, angleUnit, target); + return result.shallowReduce(reductionContext); } } // Step 5: (±inf)^x = 0 or ±inf if (childAtIndex(0).type() == ExpressionNode::Type::Infinity) { Expression result; - if (childAtIndex(1).sign(&context) == ExpressionNode::Sign::Negative) { + if (childAtIndex(1).sign(reductionContext.context()) == ExpressionNode::Sign::Negative) { // --> 0 if x < 0 result = Rational::Builder(0); - } else if (childAtIndex(1).sign(&context) == ExpressionNode::Sign::Positive) { + } else if (childAtIndex(1).sign(reductionContext.context()) == ExpressionNode::Sign::Positive) { // --> (±inf) if x > 0 result = Infinity::Builder(false); - if (childAtIndex(0).sign(&context) == ExpressionNode::Sign::Negative) { + if (childAtIndex(0).sign(reductionContext.context()) == ExpressionNode::Sign::Negative) { // (-inf)^x --> (-1)^x*inf Power p = Power::Builder(Rational::Builder(-1), childAtIndex(1)); result = Multiplication::Builder(p, result); - p.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + p.shallowReduce(reductionContext); } } if (!result.isUninitialized()) { replaceWithInPlace(result); - return result.shallowReduce(context, complexFormat, angleUnit, target); + return result.shallowReduce(reductionContext); } } @@ -501,7 +510,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co if (RationalExponentShouldNotBeReduced(a, exp)) { return *this; } - return simplifyRationalRationalPower(context, complexFormat, angleUnit, target); + return simplifyRationalRationalPower(reductionContext); } } // Step 7: (a)^(1/2) --> i*(-a)^(1/2) @@ -514,7 +523,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co && childAtIndex(1).type() == ExpressionNode::Type::Rational && childAtIndex(1).convert().isHalf()) { - Expression m0 = childAtIndex(0).makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target); + Expression m0 = childAtIndex(0).makePositiveAnyNegativeNumeralFactor(reductionContext); if (!m0.isUninitialized()) { replaceChildAtIndexInPlace(0, m0); // m0 doest not need to be shallowReduce as makePositiveAnyNegativeNumeralFactor returns a reduced expression @@ -523,10 +532,10 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co // Multiply m1 by i complex Constant i = Constant::Builder(UCodePointMathematicalBoldSmallI); m1.addChildAtIndexInPlace(i, 0, 0); - i.shallowReduce(context, complexFormat, angleUnit, target); + i.shallowReduce(reductionContext); m1.addChildAtIndexInPlace(*this, 1, 1); - shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); - return m1.shallowReduce(context, complexFormat, angleUnit, target); + shallowReduce(reductionContext); + return m1.shallowReduce(reductionContext); } } // Step 8: e^(r*i*Pi) with r rational --> cos(pi*r) + i*sin(pi*r) @@ -534,25 +543,25 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co Expression m = childAtIndex(1); Expression i = m.childAtIndex(m.numberOfChildren()-2); static_cast(m).removeChildAtIndexInPlace(m.numberOfChildren()-2); - if (angleUnit == Preferences::AngleUnit::Degree) { + if (reductionContext.angleUnit() == Preferences::AngleUnit::Degree) { m.replaceChildAtIndexInPlace(m.numberOfChildren()-1, Rational::Builder(180)); } Expression cos = Cosine::Builder(m); - m = m.shallowReduce(context, complexFormat, angleUnit, target); + m = m.shallowReduce(reductionContext); Expression sin = Sine::Builder(m.clone()); Expression complexPart = Multiplication::Builder(sin, i); - sin.shallowReduce(context, complexFormat, angleUnit, target); + sin.shallowReduce(reductionContext); Expression a = Addition::Builder(cos, complexPart); - cos.shallowReduce(context, complexFormat, angleUnit, target); - complexPart.shallowReduce(context, complexFormat, angleUnit, target); + cos.shallowReduce(reductionContext); + complexPart.shallowReduce(reductionContext); replaceWithInPlace(a); - return a.shallowReduce(context, complexFormat, angleUnit, target); + return a.shallowReduce(reductionContext); } // Step 9: x^log(y,x)->y if y > 0 if (childAtIndex(1).type() == ExpressionNode::Type::Logarithm) { if (childAtIndex(1).numberOfChildren() == 2 && childAtIndex(0).isIdenticalTo(childAtIndex(1).childAtIndex(1))) { // y > 0 - if (childAtIndex(1).childAtIndex(0).sign(&context) == ExpressionNode::Sign::Positive) { + if (childAtIndex(1).childAtIndex(0).sign(reductionContext.context()) == ExpressionNode::Sign::Positive) { Expression result = childAtIndex(1).childAtIndex(0); replaceWithInPlace(result); return result; @@ -592,21 +601,21 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co if (childAtIndex(0).type() == ExpressionNode::Type::Power) { Power p = childAtIndex(0).convert(); // Check if a > 0 or c is Integer - bool aPositive = p.childAtIndex(0).sign(&context) == ExpressionNode::Sign::Positive; + bool aPositive = p.childAtIndex(0).sign(reductionContext.context()) == ExpressionNode::Sign::Positive; bool cInteger = (childAtIndex(1).type() == ExpressionNode::Type::Rational && childAtIndex(1).convert().integerDenominator().isOne()); if (aPositive || cInteger) { /* If the complexFormat is real, we check that the inner power is defined * before applying the rule (a^b)^c -> a^(b*c). Otherwise, we return * 'unreal'. */ - if (complexFormat == Preferences::ComplexFormat::Real) { - Expression approximation = p.approximate(context, complexFormat, angleUnit); + if (reductionContext.complexFormat() == Preferences::ComplexFormat::Real) { + Expression approximation = p.approximate(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); if (approximation.type() == ExpressionNode::Type::Unreal) { replaceWithInPlace(approximation); return approximation; } } - return simplifyPowerPower(context, complexFormat, angleUnit, target, symbolicComputation); + return simplifyPowerPower(reductionContext); } } // Step 11: (a*b*c*...)^r ? @@ -614,12 +623,12 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co Multiplication m = childAtIndex(0).convert(); // Case 1: (a*b*c*...)^n = a^n*b^n*c^n*... if n integer if (childAtIndex(1).type() == ExpressionNode::Type::Rational && childAtIndex(1).convert().integerDenominator().isOne()) { - return simplifyPowerMultiplication(context, complexFormat, angleUnit, target, symbolicComputation); + return simplifyPowerMultiplication(reductionContext); } // Case 2: (a*b*...)^r -> |a|^r*(sign(a)*b*...)^r if a not -1 for (int i = 0; i < m.numberOfChildren(); i++) { // a is signed and a != -1 - if (m.childAtIndex(i).sign(&context) != ExpressionNode::Sign::Unknown + if (m.childAtIndex(i).sign(reductionContext.context()) != ExpressionNode::Sign::Unknown && (m.childAtIndex(i).type() != ExpressionNode::Type::Rational || !m.childAtIndex(i).convert().isMinusOne())) { @@ -628,13 +637,13 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co Expression factor = m.childAtIndex(i); // (sign(a)*b*...)^r - if (factor.sign(&context) == ExpressionNode::Sign::Negative) { + if (factor.sign(reductionContext.context()) == ExpressionNode::Sign::Negative) { m.replaceChildAtIndexInPlace(i, Rational::Builder(-1)); - factor = factor.setSign(ExpressionNode::Sign::Positive, &context, complexFormat, angleUnit, target); + factor = factor.setSign(ExpressionNode::Sign::Positive, reductionContext); } else { m.removeChildAtIndexInPlace(i); } - m.shallowReduce(context, complexFormat, angleUnit, target); + m.shallowReduce(reductionContext); // |a|^r Power p = Power::Builder(factor, rCopy); @@ -644,9 +653,9 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co Multiplication root = Multiplication::Builder(p); replaceWithInPlace(root); root.addChildAtIndexInPlace(thisRef, 1, 1); - p.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); - thisRef.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); - return root.shallowReduce(context, complexFormat, angleUnit, target); + p.shallowReduce(reductionContext); + thisRef.shallowReduce(reductionContext); + return root.shallowReduce(reductionContext); } } } @@ -686,8 +695,8 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co Multiplication m = Multiplication::Builder(p1); replaceWithInPlace(m); m.addChildAtIndexInPlace(thisRef, 1, 1); - p1.simplifyRationalRationalPower(context, complexFormat, angleUnit, target); - return m.shallowReduce(context, complexFormat, angleUnit, target); + p1.simplifyRationalRationalPower(reductionContext); + return m.shallowReduce(reductionContext); } } @@ -726,28 +735,28 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co // We need a 'double' distribution and newA will hold the new expanded form Expression newA = Addition::Builder(); for (int j = 0; j < a.numberOfChildren(); j++) { - Expression m = Multiplication::Builder(result.clone(), a.childAtIndex(j).clone()).distributeOnOperandAtIndex(0, context, complexFormat, angleUnit, target); + Expression m = Multiplication::Builder(result.clone(), a.childAtIndex(j).clone()).distributeOnOperandAtIndex(0, reductionContext); if (newA.type() == ExpressionNode::Type::Addition) { static_cast(newA).addChildAtIndexInPlace(m, newA.numberOfChildren(), newA.numberOfChildren()); } else { newA = Addition::Builder(newA, m); } - newA = newA.shallowReduce(context, complexFormat, angleUnit, target); + newA = newA.shallowReduce(reductionContext); } result.replaceWithInPlace(newA); result = newA; } else { // Just distribute result on a Multiplication m = Multiplication::Builder(a.clone(), result.clone()); - Expression distributedM = m.distributeOnOperandAtIndex(0, context, complexFormat, angleUnit, target); + Expression distributedM = m.distributeOnOperandAtIndex(0, reductionContext); result.replaceWithInPlace(distributedM); result = distributedM; - result = result.shallowReduce(context, complexFormat, angleUnit, target); + result = result.shallowReduce(reductionContext); } } if (nr.sign() == ExpressionNode::Sign::Negative) { nr.replaceWithInPlace(Rational::Builder(-1)); - return shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + return shallowReduce(reductionContext); } else { replaceWithInPlace(result); return result; @@ -774,32 +783,32 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co Power * p1 = new Power::Builder(x1->clone(), new Rational::Builder(clippedN-i), false); const Expression * operands[3] = {r, p0, p1}; Multiplication * m = new Multiplication::Builder(operands, 3, false); - p0->shallowReduce(context, complexFormat, angleUnit, target); - p1->shallowReduce(context, complexFormat, angleUnit, target); + p0->shallowReduce(reductionContext); + p1->shallowReduce(reductionContext); a->addOperand(m); - m->shallowReduce(context, complexFormat, angleUnit, target); + m->shallowReduce(reductionContext); } if (nr->sign(&context) == Sign::Negative) { nr->replaceWith(new Rational::Builder(-1), true); - childAtIndex(0)->replaceWith(a, true)->shallowReduce(context, complexFormat, angleUnit, target); - return shallowReduce(context, complexFormat, angleUnit, target); + childAtIndex(0)->replaceWith(a, true)->shallowReduce(reductionContext); + return shallowReduce(reductionContext); } else { - return replaceWith(a, true)->shallowReduce(context, complexFormat, angleUnit, target); + return replaceWith(a, true)->shallowReduce(reductionContext); } } #endif return *this; } -Expression Power::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Power::shallowBeautify(ExpressionNode::ReductionContext reductionContext) { // Step 1: X^-y -> 1/(X->shallowBeautify)^y - Expression p = denominator(context, complexFormat, angleUnit); + Expression p = denominator(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); // If the denominator is initialized, the index of the power is of form -y if (!p.isUninitialized()) { Division d = Division::Builder(Rational::Builder(1), p); - p.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + p.shallowReduce(reductionContext); replaceWithInPlace(d); - return d.shallowBeautify(context, complexFormat, angleUnit, target); + return d.shallowBeautify(reductionContext); } // Step 2: Turn a^(1/n) into root(a, n) if (childAtIndex(1).type() == ExpressionNode::Type::Rational && childAtIndex(1).convert().signedIntegerNumerator().isOne()) { @@ -820,7 +829,7 @@ Expression Power::shallowBeautify(Context & context, Preferences::ComplexFormat * Indeed, root(a, q) can have a real root which is not the principale angle * but that we want to return in real complex format. This special case is * handled in NthRoot approximation but not in Power approximation. */ - if (target == ExpressionNode::ReductionTarget::System && childAtIndex(1).type() == ExpressionNode::Type::Rational) { + if (reductionContext.target() == ExpressionNode::ReductionTarget::System && childAtIndex(1).type() == ExpressionNode::Type::Rational) { Integer p = childAtIndex(1).convert().signedIntegerNumerator(); Integer q = childAtIndex(1).convert().integerDenominator(); Expression nthRoot = q.isOne() ? childAtIndex(0) : NthRoot::Builder(childAtIndex(0), Rational::Builder(q)); @@ -842,11 +851,11 @@ Expression Power::shallowBeautify(Context & context, Preferences::ComplexFormat // Private // Simplification -Expression Power::denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression Power::denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { // Clone the power Expression clone = Power::Builder(childAtIndex(0).clone(), childAtIndex(1).clone()); // If the power is of form x^(-y), denominator should be x^y - Expression positiveIndex = clone.childAtIndex(1).makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + Expression positiveIndex = clone.childAtIndex(1).makePositiveAnyNegativeNumeralFactor(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User)); if (!positiveIndex.isUninitialized()) { // if y was -1, clone is now x^1, denominator is then only x // we cannot shallowReduce the clone as it is not attached to its parent yet @@ -858,30 +867,30 @@ Expression Power::denominator(Context & context, Preferences::ComplexFormat comp return Expression(); } -Expression Power::simplifyPowerPower(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Power::simplifyPowerPower(ExpressionNode::ReductionContext reductionContext) { // this is p^e = (a^b)^e, we want a^(b*e) Expression p = childAtIndex(0); Multiplication m = Multiplication::Builder(p.childAtIndex(1), childAtIndex(1)); replaceChildAtIndexInPlace(0, p.childAtIndex(0)); replaceChildAtIndexInPlace(1, m); - m.shallowReduce(context, complexFormat, angleUnit, target); - return shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + m.shallowReduce(reductionContext); + return shallowReduce(reductionContext); } -Expression Power::simplifyPowerMultiplication(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Power::simplifyPowerMultiplication(ExpressionNode::ReductionContext reductionContext) { // this is m^r= (a*b*c*...)^r, we want a^r * b^r *c^r * ... Expression m = childAtIndex(0); Expression r = childAtIndex(1); for (int index = 0; index < m.numberOfChildren(); index++) { Power p = Power::Builder(m.childAtIndex(index).clone(), r.clone()); // We copy r and factor to avoid inheritance issues m.replaceChildAtIndexInPlace(index, p); - p.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + p.shallowReduce(reductionContext); } replaceWithInPlace(m); - return m.shallowReduce(context, complexFormat, angleUnit, target); + return m.shallowReduce(reductionContext); } -Expression Power::simplifyRationalRationalPower(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Power::simplifyRationalRationalPower(ExpressionNode::ReductionContext reductionContext) { // this is a^b with a, b rationals Rational a = childAtIndex(0).convert(); Rational b = childAtIndex(1).convert(); @@ -897,18 +906,18 @@ Expression Power::simplifyRationalRationalPower(Context& context, Preferences::C Expression d; if (b.sign() == ExpressionNode::Sign::Negative) { b.setSign(ExpressionNode::Sign::Positive); - n = CreateSimplifiedIntegerRationalPower(a.integerDenominator(), b, false, context, complexFormat, angleUnit, target); - d = CreateSimplifiedIntegerRationalPower(a.signedIntegerNumerator(), b, true, context, complexFormat, angleUnit, target); + n = CreateSimplifiedIntegerRationalPower(a.integerDenominator(), b, false, reductionContext); + d = CreateSimplifiedIntegerRationalPower(a.signedIntegerNumerator(), b, true, reductionContext); } else { - n = CreateSimplifiedIntegerRationalPower(a.signedIntegerNumerator(), b, false, context, complexFormat, angleUnit, target); - d = CreateSimplifiedIntegerRationalPower(a.integerDenominator(), b, true, context, complexFormat, angleUnit, target); + n = CreateSimplifiedIntegerRationalPower(a.signedIntegerNumerator(), b, false, reductionContext); + d = CreateSimplifiedIntegerRationalPower(a.integerDenominator(), b, true, reductionContext); } Multiplication m = Multiplication::Builder(n, d); replaceWithInPlace(m); - return m.shallowReduce(context, complexFormat, angleUnit, target); + return m.shallowReduce(reductionContext); } -Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bool isDenominator, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bool isDenominator, ExpressionNode::ReductionContext reductionContext) { assert(!i.isZero()); assert(r.sign() == ExpressionNode::Sign::Positive); if (i.isOne()) { @@ -920,7 +929,7 @@ Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bo if (numberOfPrimeFactors < 0) { /* We could not break i in prime factors (it might take either too many * factors or too much time). */ - Expression rClone = r.clone().setSign(isDenominator ? ExpressionNode::Sign::Negative : ExpressionNode::Sign::Positive, &context, complexFormat, angleUnit, target); + Expression rClone = r.clone().setSign(isDenominator ? ExpressionNode::Sign::Negative : ExpressionNode::Sign::Positive, reductionContext); return Power::Builder(Rational::Builder(i), rClone); } @@ -952,7 +961,7 @@ Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bo m.addChildAtIndexInPlace(p, 1, 1); } if (i.isNegative()) { - if (complexFormat == Preferences::ComplexFormat::Real) { + if (reductionContext.complexFormat() == Preferences::ComplexFormat::Real) { /* On real numbers (-1)^(p/q) = * - 1 if p is even * - -1 if p and q are odd @@ -966,15 +975,16 @@ Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bo } } else { /* On complex numbers, we pick the first root (-1)^(p/q) = e^(i*pi*p/q) */ - Expression exp = CreateComplexExponent(r, context, complexFormat, angleUnit, target); + Expression exp = CreateComplexExponent(r, reductionContext); m.addChildAtIndexInPlace(exp, m.numberOfChildren(), m.numberOfChildren()); - exp.shallowReduce(context, complexFormat, angleUnit, target); + exp.shallowReduce(reductionContext); } } - return m.shallowReduce(context, complexFormat, angleUnit, target); + return m.shallowReduce(reductionContext); } -Expression Power::removeSquareRootsFromDenominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation) { +Expression Power::removeSquareRootsFromDenominator(ExpressionNode::ReductionContext reductionContext) { + assert(reductionContext.target() == ExpressionNode::ReductionTarget::User); Expression result; if (childAtIndex(0).type() == ExpressionNode::Type::Rational && childAtIndex(1).type() == ExpressionNode::Type::Rational @@ -1001,7 +1011,7 @@ Expression Power::removeSquareRootsFromDenominator(Context & context, Preference } else { result = Multiplication::Builder(Rational::Builder(one, p), sqrt); // We use here the assertion that p != 0 } - sqrt.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicComputation); + sqrt.shallowReduce(reductionContext); } } else if (childAtIndex(1).type() == ExpressionNode::Type::Rational && childAtIndex(1).convert().isMinusOne() @@ -1069,14 +1079,14 @@ Expression Power::removeSquareRootsFromDenominator(Context & context, Preference if (denominator.isOverflow() || factor1.isOverflow() || factor2.isOverflow() || pq1.isOverflow() || pq2.isOverflow()) { return result; // Escape } - numerator = numerator.deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + numerator = numerator.deepReduce(reductionContext); Integer one(1); result = Multiplication::Builder(numerator, Rational::Builder(one, denominator)); } if (!result.isUninitialized()) { replaceWithInPlace(result); - result = result.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); + result = result.shallowReduce(reductionContext); } return result; } @@ -1152,15 +1162,15 @@ Expression Power::equivalentExpressionUsingStandardExpression() const { return Expression(); } -Expression Power::CreateComplexExponent(const Expression & r, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Power::CreateComplexExponent(const Expression & r, ExpressionNode::ReductionContext reductionContext) { // Returns e^(i*pi*r) const Constant exp = Constant::Builder(UCodePointScriptSmallE); Constant iComplex = Constant::Builder(UCodePointMathematicalBoldSmallI); const Constant pi = Constant::Builder(UCodePointGreekSmallLetterPi); Multiplication mExp = Multiplication::Builder(iComplex, pi, r.clone()); - iComplex.shallowReduce(context, complexFormat, angleUnit, target); + iComplex.shallowReduce(reductionContext); Power p = Power::Builder(exp, mExp); - mExp.shallowReduce(context, complexFormat, angleUnit, target); + mExp.shallowReduce(reductionContext); return p; #if 0 const Constant iComplex = Constant::Builder(UCodePointMathematicalBoldSmallI); diff --git a/poincare/src/prediction_interval.cpp b/poincare/src/prediction_interval.cpp index 9a78e0956..d2a0b2916 100644 --- a/poincare/src/prediction_interval.cpp +++ b/poincare/src/prediction_interval.cpp @@ -27,12 +27,12 @@ int PredictionIntervalNode::serialize(char * buffer, int bufferSize, Preferences } -Expression PredictionIntervalNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return PredictionInterval(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression PredictionIntervalNode::shallowReduce(ReductionContext reductionContext) { + return PredictionInterval(this).shallowReduce(reductionContext); } template -Evaluation PredictionIntervalNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation PredictionIntervalNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation pInput = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation nInput = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T p = static_cast &>(pInput).toScalar(); @@ -47,7 +47,7 @@ Evaluation PredictionIntervalNode::templatedApproximate(Context& context, Pre } -Expression PredictionInterval::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression PredictionInterval::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -103,7 +103,7 @@ Expression PredictionInterval::shallowReduce(Context & context, Preferences::Com matrix.addChildAtIndexInPlace(Addition::Builder(r0.clone(), m), 1, 1); matrix.setDimensions(1, 2); replaceWithInPlace(matrix); - matrix.deepReduceChildren(context, complexFormat, angleUnit, target); + matrix.deepReduceChildren(reductionContext); return matrix; } diff --git a/poincare/src/randint.cpp b/poincare/src/randint.cpp index eee3afb1f..c0eac4100 100644 --- a/poincare/src/randint.cpp +++ b/poincare/src/randint.cpp @@ -28,7 +28,7 @@ int RandintNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloa return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Randint::s_functionHelper.name()); } -template Evaluation RandintNode::templateApproximate(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +template Evaluation RandintNode::templateApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation aInput = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation bInput = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T a = aInput.toScalar(); @@ -41,16 +41,16 @@ template Evaluation RandintNode::templateApproximate(Context & c return Complex::Builder(result); } -Expression RandintNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Randint(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression RandintNode::shallowReduce(ReductionContext reductionContext) { + return Randint(this).shallowReduce(reductionContext); } -Expression Randint::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Randint::shallowReduce(ExpressionNode::ReductionContext reductionContext) { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { return e; } - float eval = approximateToScalar(context, complexFormat, angleUnit); + float eval = approximateToScalar(reductionContext.context() , reductionContext.complexFormat() , reductionContext.angleUnit() ); Expression result; if (std::isnan(eval)) { result = Undefined::Builder(); diff --git a/poincare/src/random.cpp b/poincare/src/random.cpp index cd5e309a0..72445ac8d 100644 --- a/poincare/src/random.cpp +++ b/poincare/src/random.cpp @@ -12,9 +12,9 @@ constexpr Expression::FunctionHelper Random::s_functionHelper; int RandomNode::numberOfChildren() const { return Random::s_functionHelper.numberOfChildren(); } -Expression RandomNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression RandomNode::setSign(Sign s, ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive); - return Random(this).setSign(s, context, complexFormat, angleUnit); + return Random(this); } Layout RandomNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { @@ -29,11 +29,6 @@ template Evaluation RandomNode::templateApproximate() const { return Complex::Builder(Random::random()); } -Expression Random::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { - assert(s == ExpressionNode::Sign::Positive); - return *this; -} - template T Random::random() { if (sizeof(T) == sizeof(float)) { uint32_t r = Ion::random(); diff --git a/poincare/src/rational.cpp b/poincare/src/rational.cpp index d2b6dd9f8..5785e3c4e 100644 --- a/poincare/src/rational.cpp +++ b/poincare/src/rational.cpp @@ -88,7 +88,7 @@ int RationalNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo // Expression subclassing -Expression RationalNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression RationalNode::setSign(Sign s, ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); return Rational(this).setSign(s); } @@ -137,16 +137,16 @@ int RationalNode::simplificationOrderSameType(const ExpressionNode * e, bool asc // Simplification -Expression RationalNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression RationalNode::shallowReduce(ReductionContext reductionContext) { return Rational(this).shallowReduce(); } -Expression RationalNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression RationalNode::shallowBeautify(ReductionContext reductionContext) { return Rational(this).shallowBeautify(); } -Expression RationalNode::denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { - return Rational(this).denominator(context, complexFormat, angleUnit); +Expression RationalNode::denominator(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { + return Rational(this).denominator(); } /* Rational */ @@ -264,7 +264,7 @@ Expression Rational::shallowBeautify() { return *this; } -Expression Rational::denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression Rational::denominator() const { Integer d = integerDenominator(); if (d.isOne()) { return Expression(); diff --git a/poincare/src/real_part.cpp b/poincare/src/real_part.cpp index 3ce0754d0..35140833b 100644 --- a/poincare/src/real_part.cpp +++ b/poincare/src/real_part.cpp @@ -20,11 +20,11 @@ int RealPartNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, RealPart::s_functionHelper.name()); } -Expression RealPartNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return RealPart(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression RealPartNode::shallowReduce(ReductionContext reductionContext) { + return RealPart(this).shallowReduce(reductionContext); } -Expression RealPart::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression RealPart::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -33,9 +33,9 @@ Expression RealPart::shallowReduce(Context & context, Preferences::ComplexFormat } Expression c = childAtIndex(0); if (c.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - if (c.isReal(context)) { + if (c.isReal(reductionContext.context())) { replaceWithInPlace(c); return c; } @@ -43,7 +43,7 @@ Expression RealPart::shallowReduce(Context & context, Preferences::ComplexFormat ComplexCartesian complexChild = static_cast(c); Expression r = complexChild.real(); replaceWithInPlace(r); - return r.shallowReduce(context, complexFormat, angleUnit, target); + return r.shallowReduce(reductionContext); } return *this; } diff --git a/poincare/src/round.cpp b/poincare/src/round.cpp index 3fd3f813b..939e6f59c 100644 --- a/poincare/src/round.cpp +++ b/poincare/src/round.cpp @@ -21,12 +21,12 @@ int RoundNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatM return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Round::s_functionHelper.name()); } -Expression RoundNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { +Expression RoundNode::shallowReduce(ReductionContext reductionContext) { return Round(this).shallowReduce(); } template -Evaluation RoundNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation RoundNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation f1Input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation f2Input = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T f1 = f1Input.toScalar(); diff --git a/poincare/src/sequence.cpp b/poincare/src/sequence.cpp index 5e09b9732..1622ea840 100644 --- a/poincare/src/sequence.cpp +++ b/poincare/src/sequence.cpp @@ -20,7 +20,7 @@ Layout SequenceNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, } template -Evaluation SequenceNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation SequenceNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation aInput = childAtIndex(2)->approximate(T(), context, complexFormat, angleUnit); Evaluation bInput = childAtIndex(3)->approximate(T(), context, complexFormat, angleUnit); T start = aInput.toScalar(); @@ -28,14 +28,14 @@ Evaluation SequenceNode::templatedApproximate(Context& context, Preferences:: if (std::isnan(start) || std::isnan(end) || start != (int)start || end != (int)end || end - start > k_maxNumberOfSteps) { return Complex::Undefined(); } - VariableContext nContext = VariableContext(static_cast(childAtIndex(1))->name(), &context); + VariableContext nContext = VariableContext(static_cast(childAtIndex(1))->name(), context); Evaluation result = Complex::Builder((T)emptySequenceValue()); for (int i = (int)start; i <= (int)end; i++) { if (Expression::ShouldStopProcessing()) { return Complex::Undefined(); } nContext.setApproximationForVariable((T)i); - result = evaluateWithNextTerm(T(), result, childAtIndex(0)->approximate(T(), nContext, complexFormat, angleUnit), complexFormat); + result = evaluateWithNextTerm(T(), result, childAtIndex(0)->approximate(T(), &nContext, complexFormat, angleUnit), complexFormat); if (result.isUndefined()) { return Complex::Undefined(); } @@ -43,7 +43,7 @@ Evaluation SequenceNode::templatedApproximate(Context& context, Preferences:: return result; } -template Evaluation SequenceNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; -template Evaluation SequenceNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; +template Evaluation SequenceNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; +template Evaluation SequenceNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; } diff --git a/poincare/src/sign_function.cpp b/poincare/src/sign_function.cpp index 4d468c159..4c2fbe5df 100644 --- a/poincare/src/sign_function.cpp +++ b/poincare/src/sign_function.cpp @@ -18,7 +18,7 @@ ExpressionNode::Sign SignFunctionNode::sign(Context * context) const { return childAtIndex(0)->sign(context); } -Expression SignFunctionNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression SignFunctionNode::setSign(Sign s, ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); SignFunction sign(this); Rational r = Rational::Builder(s == ExpressionNode::Sign::Positive ? 1 : -1); @@ -34,8 +34,8 @@ int SignFunctionNode::serialize(char * buffer, int bufferSize, Preferences::Prin return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SignFunction::s_functionHelper.name()); } -Expression SignFunctionNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return SignFunction(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression SignFunctionNode::shallowReduce(ReductionContext reductionContext) { + return SignFunction(this).shallowReduce(reductionContext); } template @@ -53,7 +53,7 @@ Complex SignFunctionNode::computeOnComplex(const std::complex c, Preferenc } -Expression SignFunction::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression SignFunction::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -62,23 +62,23 @@ Expression SignFunction::shallowReduce(Context & context, Preferences::ComplexFo } Expression child = childAtIndex(0); if (child.type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } Rational resultSign = Rational::Builder(1); - ExpressionNode::Sign s = child.sign(&context); + ExpressionNode::Sign s = child.sign(reductionContext.context()); if (s == ExpressionNode::Sign::Negative) { resultSign = Rational::Builder(-1); } else { - Evaluation childApproximated = child.node()->approximate(1.0f, context, complexFormat, angleUnit); + Evaluation childApproximated = child.node()->approximate(1.0f, reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); assert(childApproximated.type() == EvaluationNode::Type::Complex); Complex c = static_cast&>(childApproximated); if (std::isnan(c.imag()) || std::isnan(c.real()) || c.imag() != 0) { // c's approximation has no sign (c is complex or NAN) - if (target == ExpressionNode::ReductionTarget::User && s == ExpressionNode::Sign::Positive) { + if (reductionContext.target() == ExpressionNode::ReductionTarget::User && s == ExpressionNode::Sign::Positive) { // For the user, we want sign(abs(x)) = 1 } else { // sign(-x) = -sign(x) - Expression oppChild = child.makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target); + Expression oppChild = child.makePositiveAnyNegativeNumeralFactor(reductionContext); if (oppChild.isUninitialized()) { return *this; } diff --git a/poincare/src/sine.cpp b/poincare/src/sine.cpp index 8732933de..f43482635 100644 --- a/poincare/src/sine.cpp +++ b/poincare/src/sine.cpp @@ -11,7 +11,7 @@ constexpr Expression::FunctionHelper Sine::s_functionHelper; int SineNode::numberOfChildren() const { return Sine::s_functionHelper.numberOfChildren(); } -float SineNode::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { +float SineNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const { return Trigonometry::characteristicXRange(Sine(this), context, angleUnit); } @@ -30,12 +30,12 @@ int SineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMo return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Sine::s_functionHelper.name()); } -Expression SineNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Sine(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression SineNode::shallowReduce(ReductionContext reductionContext) { + return Sine(this).shallowReduce(reductionContext); } -Expression Sine::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Sine::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -43,9 +43,9 @@ Expression Sine::shallowReduce(Context & context, Preferences::ComplexFormat com } } if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - return Trigonometry::shallowReduceDirectFunction(*this, context, complexFormat, angleUnit, target); + return Trigonometry::shallowReduceDirectFunction(*this, reductionContext); } } diff --git a/poincare/src/square_root.cpp b/poincare/src/square_root.cpp index 471f14dce..874b02f6d 100644 --- a/poincare/src/square_root.cpp +++ b/poincare/src/square_root.cpp @@ -38,11 +38,11 @@ Complex SquareRootNode::computeOnComplex(const std::complex c, Preferences return Complex::Builder(ApproximationHelper::TruncateRealOrImaginaryPartAccordingToArgument(result)); } -Expression SquareRootNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return SquareRoot(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression SquareRootNode::shallowReduce(ReductionContext reductionContext) { + return SquareRoot(this).shallowReduce(reductionContext); } -Expression SquareRoot::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression SquareRoot::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -56,7 +56,7 @@ Expression SquareRoot::shallowReduce(Context & context, Preferences::ComplexForm #endif Power p = Power::Builder(childAtIndex(0), Rational::Builder(1, 2)); replaceWithInPlace(p); - return p.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + return p.shallowReduce(reductionContext); } } diff --git a/poincare/src/store.cpp b/poincare/src/store.cpp index 9d25f0a50..3ba7ed706 100644 --- a/poincare/src/store.cpp +++ b/poincare/src/store.cpp @@ -15,15 +15,15 @@ extern "C" { namespace Poincare { -void StoreNode::deepReduceChildren(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +void StoreNode::deepReduceChildren(ExpressionNode::ReductionContext reductionContext) { // Interrupt simplification if the expression stored contains a matrix - if (Expression(childAtIndex(0)).recursivelyMatches([](const Expression e, Context & context) { return Expression::IsMatrix(e, context); }, context, true)) { + if (Expression(childAtIndex(0)).recursivelyMatches([](const Expression e, Context * context) { return Expression::IsMatrix(e, context); }, reductionContext.context(), true)) { Expression::SetInterruption(true); } } -Expression StoreNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Store(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression StoreNode::shallowReduce(ReductionContext reductionContext) { + return Store(this).shallowReduce(reductionContext); } int StoreNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { @@ -42,7 +42,7 @@ Layout StoreNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int } template -Evaluation StoreNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation StoreNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { /* If we are here, it means that the store node was not shallowReduced. * Otherwise, it would have been replaced by its symbol. We thus have to * setExpressionForSymbol. */ @@ -51,9 +51,9 @@ Evaluation StoreNode::templatedApproximate(Context& context, Preferences::Com return storedExpression.node()->approximate(T(), context, complexFormat, angleUnit); } -Expression Store::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Store::shallowReduce(ExpressionNode::ReductionContext reductionContext) { // Store the expression. - Expression storedExpression = storeValueForSymbol(context, complexFormat, angleUnit); + Expression storedExpression = storeValueForSymbol(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); if (symbol().type() == ExpressionNode::Type::Symbol) { /* If the symbol is not a function, we want to replace the store with its @@ -62,7 +62,7 @@ Expression Store::shallowReduce(Context & context, Preferences::ComplexFormat co * The simplification fails for [1+2]->a for instance, because we do not * have exact simplification of matrices yet. */ bool interruptedSimplification = SimplificationHasBeenInterrupted(); - Expression reducedE = storedExpression.clone().deepReduce(context, complexFormat, angleUnit, target, symbolicComputation); + Expression reducedE = storedExpression.clone().deepReduce(reductionContext); if (!reducedE.isUninitialized() && !SimplificationHasBeenInterrupted()) { storedExpression = reducedE; } @@ -74,7 +74,7 @@ Expression Store::shallowReduce(Context & context, Preferences::ComplexFormat co return storedExpression; } -Expression Store::storeValueForSymbol(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Expression Store::storeValueForSymbol(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Expression finalValue; if (symbol().type() == ExpressionNode::Type::Function) { // In tata + 2 ->f(tata), replace tata with xUnknown symbol @@ -87,8 +87,8 @@ Expression Store::storeValueForSymbol(Context& context, Preferences::ComplexForm finalValue = childAtIndex(0); } assert(!finalValue.isUninitialized()); - context.setExpressionForSymbol(finalValue, symbol(), context); - Expression storedExpression = context.expressionForSymbol(symbol(), true); + context->setExpressionForSymbol(finalValue, symbol(), context); + Expression storedExpression = context->expressionForSymbol(symbol(), true); if (storedExpression.isUninitialized()) { return Undefined::Builder(); diff --git a/poincare/src/subtraction.cpp b/poincare/src/subtraction.cpp index 9fd547aa8..cdb083ef1 100644 --- a/poincare/src/subtraction.cpp +++ b/poincare/src/subtraction.cpp @@ -9,7 +9,7 @@ namespace Poincare { -int SubtractionNode::polynomialDegree(Context & context, const char * symbolName) const { +int SubtractionNode::polynomialDegree(Context * context, const char * symbolName) const { int degree = 0; for (ExpressionNode * e : children()) { int d = e->polynomialDegree(context, symbolName); @@ -52,20 +52,20 @@ template MatrixComplex SubtractionNode::computeOnComplexAndMatrix return result; } -Expression SubtractionNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Subtraction(this).shallowReduce(context, complexFormat, angleUnit, target); +Expression SubtractionNode::shallowReduce(ReductionContext reductionContext) { + return Subtraction(this).shallowReduce(reductionContext); } -Expression Subtraction::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Subtraction::shallowReduce(ExpressionNode::ReductionContext reductionContext) { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { return e; } Expression m = Multiplication::Builder(Rational::Builder(-1), childAtIndex(1)); Addition a = Addition::Builder(childAtIndex(0), m); - m = m.shallowReduce(context, complexFormat, angleUnit, target); + m = m.shallowReduce(reductionContext); replaceWithInPlace(a); - return a.shallowReduce(context, complexFormat, angleUnit, target); + return a.shallowReduce(reductionContext); } } diff --git a/poincare/src/symbol.cpp b/poincare/src/symbol.cpp index 95fde8e38..1f7a507fe 100644 --- a/poincare/src/symbol.cpp +++ b/poincare/src/symbol.cpp @@ -30,18 +30,18 @@ Expression SymbolNode::replaceUnknown(const Symbol & symbol, const Symbol & unkn return Symbol(this).replaceUnknown(symbol, unknownSymbol); } -int SymbolNode::polynomialDegree(Context & context, const char * symbolName) const { +int SymbolNode::polynomialDegree(Context * context, const char * symbolName) const { if (strcmp(m_name, symbolName) == 0) { return 1; } return 0; } -int SymbolNode::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { +int SymbolNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { return Symbol(this).getPolynomialCoefficients(context, symbolName, coefficients); } -int SymbolNode::getVariables(Context & context, isVariableTest isVariable, char * variables, int maxSizeVariable) const { +int SymbolNode::getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const { // variables is in fact of type char[k_maxNumberOfVariables][maxSizeVariable] size_t variablesIndex = 0; while(variables[variablesIndex] != 0) { @@ -68,11 +68,11 @@ int SymbolNode::getVariables(Context & context, isVariableTest isVariable, char return variablesIndex/maxSizeVariable; } -float SymbolNode::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { +float SymbolNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const { return isUnknown(UCodePointUnknownX) ? NAN : 0.0f; } -bool SymbolNode::isReal(Context & context) const { +bool SymbolNode::isReal(Context * context) const { Symbol s(this); return SymbolAbstract::isReal(s, context); } @@ -123,16 +123,16 @@ int SymbolNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat return strlcpy(buffer, m_name, bufferSize); } -Expression SymbolNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Symbol(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression SymbolNode::shallowReduce(ReductionContext reductionContext) { + return Symbol(this).shallowReduce(reductionContext); } -Expression SymbolNode::shallowReplaceReplaceableSymbols(Context & context) { +Expression SymbolNode::shallowReplaceReplaceableSymbols(Context * context) { return Symbol(this).shallowReplaceReplaceableSymbols(context); } template -Evaluation SymbolNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +Evaluation SymbolNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Symbol s(this); Expression e = SymbolAbstract::Expand(s, context, false); if (e.isUninitialized()) { @@ -183,7 +183,7 @@ bool Symbol::isRegressionSymbol(const char * c) { return false; } -Expression Symbol::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Symbol::shallowReduce(ExpressionNode::ReductionContext reductionContext) { Expression parentExpression = parent(); { Expression current = *this; @@ -211,9 +211,9 @@ Expression Symbol::shallowReduce(Context & context, Preferences::ComplexFormat c } Symbol s = *this; - Expression result = SymbolAbstract::Expand(s, context, true); + Expression result = SymbolAbstract::Expand(s, reductionContext.context(), true); if (result.isUninitialized()) { - if (symbolicComputation) { + if (reductionContext.symbolicComputation()) { return *this; } result = Undefined::Builder(); @@ -222,7 +222,7 @@ Expression Symbol::shallowReduce(Context & context, Preferences::ComplexFormat c parentExpression.replaceChildInPlace(*this, result); } // The stored expression is as entered by the user, so we need to call reduce - return result.deepReduce(context, complexFormat, angleUnit, target, symbolicComputation); + return result.deepReduce(reductionContext); } Expression Symbol::replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { @@ -245,7 +245,7 @@ Expression Symbol::replaceUnknown(const Symbol & symbol, const Symbol & unknownS return replaceSymbolWithExpression(symbol, unknownSymbol); } -int Symbol::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { +int Symbol::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { if (strcmp(name(), symbolName) == 0) { coefficients[0] = Rational::Builder(0); coefficients[1] = Rational::Builder(1); @@ -255,11 +255,11 @@ int Symbol::getPolynomialCoefficients(Context & context, const char * symbolName return 0; } -Expression Symbol::shallowReplaceReplaceableSymbols(Context & context) { +Expression Symbol::shallowReplaceReplaceableSymbols(Context * context) { if (isSystemSymbol()) { return *this; } - Expression e = context.expressionForSymbol(*this, true); + Expression e = context->expressionForSymbol(*this, true); if (e.isUninitialized()) { return *this; } diff --git a/poincare/src/symbol_abstract.cpp b/poincare/src/symbol_abstract.cpp index 83044b051..1f4b1871d 100644 --- a/poincare/src/symbol_abstract.cpp +++ b/poincare/src/symbol_abstract.cpp @@ -18,19 +18,19 @@ size_t SymbolAbstractNode::size() const { ExpressionNode::Sign SymbolAbstractNode::sign(Context * context) const { SymbolAbstract s(this); - Expression e = SymbolAbstract::Expand(s, *context, false); + Expression e = SymbolAbstract::Expand(s, context, false); if (e.isUninitialized()) { return Sign::Unknown; } return e.sign(context); } -Expression SymbolAbstractNode::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { +Expression SymbolAbstractNode::setSign(ExpressionNode::Sign s, ReductionContext reductionContext) { SymbolAbstract sa(this); - Expression e = SymbolAbstract::Expand(sa, *context, true); + Expression e = SymbolAbstract::Expand(sa, reductionContext.context(), true); assert(!e.isUninitialized()); sa.replaceWithInPlace(e); - return e.setSign(s, context, complexFormat, angleUnit, target); + return e.setSign(s, reductionContext); } int SymbolAbstractNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { @@ -51,16 +51,16 @@ size_t SymbolAbstract::TruncateExtension(char * dst, const char * src, size_t le return UTF8Helper::CopyUntilCodePoint(dst, len, src, '.'); } -bool SymbolAbstract::matches(const SymbolAbstract & symbol, ExpressionTest test, Context & context) { +bool SymbolAbstract::matches(const SymbolAbstract & symbol, ExpressionTest test, Context * context) { Expression e = SymbolAbstract::Expand(symbol, context, false); return !e.isUninitialized() && e.recursivelyMatches(test, context, false); } -Expression SymbolAbstract::Expand(const SymbolAbstract & symbol, Context & context, bool clone) { +Expression SymbolAbstract::Expand(const SymbolAbstract & symbol, Context * context, bool clone) { bool isFunction = symbol.type() == ExpressionNode::Type::Function; /* Always clone the expression for Function because we are going to alter e * by replacing all UnknownX in it. */ - Expression e = context.expressionForSymbol(symbol, clone || isFunction); + Expression e = context->expressionForSymbol(symbol, clone || isFunction); /* Replace all the symbols iteratively. This prevents a memory failure when * symbols are defined circularly. */ e = Expression::ExpressionWithoutSymbols(e, context); @@ -71,7 +71,7 @@ Expression SymbolAbstract::Expand(const SymbolAbstract & symbol, Context & conte return e; } -bool SymbolAbstract::isReal(const SymbolAbstract & symbol, Context & context) { +bool SymbolAbstract::isReal(const SymbolAbstract & symbol, Context * context) { Expression e = SymbolAbstract::Expand(symbol, context, false); if (e.isUninitialized()) { return false; diff --git a/poincare/src/tangent.cpp b/poincare/src/tangent.cpp index 0ab38d391..14f8bccd2 100644 --- a/poincare/src/tangent.cpp +++ b/poincare/src/tangent.cpp @@ -14,7 +14,7 @@ constexpr Expression::FunctionHelper Tangent::s_functionHelper; int TangentNode::numberOfChildren() const { return Tangent::s_functionHelper.numberOfChildren(); } -float TangentNode::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { +float TangentNode::characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const { return Trigonometry::characteristicXRange(Tangent(this), context, angleUnit); } @@ -33,12 +33,12 @@ Complex TangentNode::computeOnComplex(const std::complex c, Preferences::C return Complex::Builder(Trigonometry::RoundToMeaningfulDigits(res, angleInput)); } -Expression TangentNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) { - return Tangent(this).shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); +Expression TangentNode::shallowReduce(ReductionContext reductionContext) { + return Tangent(this).shallowReduce(reductionContext); } -Expression Tangent::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) { +Expression Tangent::shallowReduce(ExpressionNode::ReductionContext reductionContext) { { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { @@ -47,18 +47,18 @@ Expression Tangent::shallowReduce(Context & context, Preferences::ComplexFormat } if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) { - return mapOnMatrixChild(context, complexFormat, angleUnit, target, symbolicComputation); + return mapOnMatrixChild(reductionContext); } - Expression newExpression = Trigonometry::shallowReduceDirectFunction(*this, context, complexFormat, angleUnit, target); + Expression newExpression = Trigonometry::shallowReduceDirectFunction(*this, reductionContext); if (newExpression.type() == ExpressionNode::Type::Tangent) { Sine s = Sine::Builder(newExpression.childAtIndex(0).clone()); Cosine c = Cosine::Builder(newExpression.childAtIndex(0)); Division d = Division::Builder(s, c); - s.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); - c.shallowReduce(context, complexFormat, angleUnit, target, symbolicComputation); + s.shallowReduce(reductionContext); + c.shallowReduce(reductionContext); newExpression.replaceWithInPlace(d); - return d.shallowReduce(context, complexFormat, angleUnit, target); + return d.shallowReduce(reductionContext); } return newExpression; } diff --git a/poincare/src/trigonometry.cpp b/poincare/src/trigonometry.cpp index c54d4b12f..7ae73d855 100644 --- a/poincare/src/trigonometry.cpp +++ b/poincare/src/trigonometry.cpp @@ -21,7 +21,7 @@ namespace Poincare { -float Trigonometry::characteristicXRange(const Expression & e, Context & context, Preferences::AngleUnit angleUnit) { +float Trigonometry::characteristicXRange(const Expression & e, Context * context, Preferences::AngleUnit angleUnit) { assert(e.numberOfChildren() == 1); constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; @@ -48,11 +48,15 @@ float Trigonometry::characteristicXRange(const Expression & e, Context & context } bool Trigonometry::isDirectTrigonometryFunction(const Expression & e) { - return e.type() == ExpressionNode::Type::Cosine || e.type() == ExpressionNode::Type::Sine || e.type() == ExpressionNode::Type::Tangent; + return e.type() == ExpressionNode::Type::Cosine + || e.type() == ExpressionNode::Type::Sine + || e.type() == ExpressionNode::Type::Tangent; } bool Trigonometry::isInverseTrigonometryFunction(const Expression & e) { - return e.type() == ExpressionNode::Type::ArcCosine || e.type() == ExpressionNode::Type::ArcSine || e.type() == ExpressionNode::Type::ArcTangent; + return e.type() == ExpressionNode::Type::ArcCosine + || e.type() == ExpressionNode::Type::ArcSine + || e.type() == ExpressionNode::Type::ArcTangent; } bool Trigonometry::AreInverseFunctions(const Expression & directFunction, const Expression & inverseFunction) { @@ -89,11 +93,11 @@ bool Trigonometry::ExpressionIsEquivalentToTangent(const Expression & e) { return false; } -Expression Trigonometry::shallowReduceDirectFunction(Expression & e, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression Trigonometry::shallowReduceDirectFunction(Expression & e, ExpressionNode::ReductionContext reductionContext) { assert(isDirectTrigonometryFunction(e)); // Step 1. Try finding an easy standard calculation reduction - Expression lookup = TrigonometryCheatTable::Table()->simplify(e.childAtIndex(0), e.type(), context, complexFormat, angleUnit, target); + Expression lookup = TrigonometryCheatTable::Table()->simplify(e.childAtIndex(0), e.type(), reductionContext); if (!lookup.isUninitialized()) { e.replaceWithInPlace(lookup); return lookup; @@ -121,14 +125,14 @@ Expression Trigonometry::shallowReduceDirectFunction(Expression & e, Context& co Rational::Builder(1,2) ); // reduce x^2 - sqrt.childAtIndex(0).childAtIndex(1).childAtIndex(1).shallowReduce(context, complexFormat, angleUnit, target); + sqrt.childAtIndex(0).childAtIndex(1).childAtIndex(1).shallowReduce(reductionContext); // reduce -1*x^2 - sqrt.childAtIndex(0).childAtIndex(1).shallowReduce(context, complexFormat, angleUnit, target); + sqrt.childAtIndex(0).childAtIndex(1).shallowReduce(reductionContext); // reduce 1-1*x^2 - sqrt.childAtIndex(0).shallowReduce(context, complexFormat, angleUnit, target); + sqrt.childAtIndex(0).shallowReduce(reductionContext); e.replaceWithInPlace(sqrt); // reduce sqrt(1+(-1)*x^2) - return sqrt.shallowReduce(context, complexFormat, angleUnit, target); + return sqrt.shallowReduce(reductionContext); } // Step 4. Look for an expression of type "cos(atan(x))" or "sin(atan(x))" @@ -150,33 +154,33 @@ Expression Trigonometry::shallowReduceDirectFunction(Expression & e, Context& co ); // reduce x^2 - res.childAtIndex(0).childAtIndex(1).shallowReduce(context, complexFormat, angleUnit, target); + res.childAtIndex(0).childAtIndex(1).shallowReduce(reductionContext); // reduce 1+*x^2 - res.childAtIndex(0).shallowReduce(context, complexFormat, angleUnit, target); + res.childAtIndex(0).shallowReduce(reductionContext); if (e.type() == ExpressionNode::Type::Sine) { res = Multiplication::Builder(x, res); // reduce (1+x^2)^(-1/2) - res.childAtIndex(0).shallowReduce(context, complexFormat, angleUnit, target); + res.childAtIndex(0).shallowReduce(reductionContext); } e.replaceWithInPlace(res); // reduce (1+x^2)^(-1/2) or x*(1+x^2)^(-1/2) - return res.shallowReduce(context, complexFormat, angleUnit, target); + return res.shallowReduce(reductionContext); } // Step 5. Look for an expression of type "cos(-a)", return "+/-cos(a)" - Expression positiveArg = e.childAtIndex(0).makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target); + Expression positiveArg = e.childAtIndex(0).makePositiveAnyNegativeNumeralFactor(reductionContext); if (!positiveArg.isUninitialized()) { // The argument was of form cos(-a) if (e.type() == ExpressionNode::Type::Cosine) { // cos(-a) = cos(a) - return e.shallowReduce(context, complexFormat, angleUnit, target); + return e.shallowReduce(reductionContext); } else { // sin(-a) = -sin(a) or tan(-a) = -tan(a) Multiplication m = Multiplication::Builder(Rational::Builder(-1)); e.replaceWithInPlace(m); m.addChildAtIndexInPlace(e, 1, 1); - e.shallowReduce(context, complexFormat, angleUnit, target); - return m.shallowReduce(context, complexFormat, angleUnit, target); + e.shallowReduce(reductionContext); + return m.shallowReduce(reductionContext); } } @@ -184,21 +188,21 @@ Expression Trigonometry::shallowReduceDirectFunction(Expression & e, Context& co * "cos(p/q)" in degrees, put the argument in [0, π/2[ or [0, 90[ and * multiply the cos/sin/tan by -1 if needed. * We know thanks to Step 3 that p/q > 0. */ - if ((angleUnit == Preferences::AngleUnit::Radian + if ((reductionContext.angleUnit() == Preferences::AngleUnit::Radian && e.childAtIndex(0).type() == ExpressionNode::Type::Multiplication && e.childAtIndex(0).numberOfChildren() == 2 && e.childAtIndex(0).childAtIndex(1).type() == ExpressionNode::Type::Constant && e.childAtIndex(0).childAtIndex(1).convert().isPi() && e.childAtIndex(0).childAtIndex(0).type() == ExpressionNode::Type::Rational) - || (angleUnit == Preferences::AngleUnit::Degree + || (reductionContext.angleUnit() == Preferences::AngleUnit::Degree && e.childAtIndex(0).type() == ExpressionNode::Type::Rational)) { - Rational r = angleUnit == Preferences::AngleUnit::Radian ? e.childAtIndex(0).childAtIndex(0).convert() : e.childAtIndex(0).convert(); + Rational r = reductionContext.angleUnit() == Preferences::AngleUnit::Radian ? e.childAtIndex(0).childAtIndex(0).convert() : e.childAtIndex(0).convert(); /* Step 4.1. In radians: * We first check if p/q * π is already in the right quadrant: * p/q * π < π/2 => p/q < 2 => 2p < q */ - Integer dividand = angleUnit == Preferences::AngleUnit::Radian ? Integer::Addition(r.unsignedIntegerNumerator(), r.unsignedIntegerNumerator()) : r.unsignedIntegerNumerator(); - Integer divisor = angleUnit == Preferences::AngleUnit::Radian ? r.integerDenominator() : Integer::Multiplication(r.integerDenominator(), Integer(90)); + Integer dividand = reductionContext.angleUnit() == Preferences::AngleUnit::Radian ? Integer::Addition(r.unsignedIntegerNumerator(), r.unsignedIntegerNumerator()) : r.unsignedIntegerNumerator(); + Integer divisor = reductionContext.angleUnit() == Preferences::AngleUnit::Radian ? r.integerDenominator() : Integer::Multiplication(r.integerDenominator(), Integer(90)); if (divisor.isLowerThan(dividand)) { /* Step 4.2. p/q * π is not in the wanted trigonometrical quadrant. * We could subtract n*π to p/q with n an integer. @@ -206,9 +210,9 @@ Expression Trigonometry::shallowReduceDirectFunction(Expression & e, Context& co * (p/q * π - q'*π) < π/2 => r'/q < 1/2 => 2*r'approximate(float(), context, complexFormat, angleUnit).toScalar(); + float trigoOp = e.childAtIndex(0).childAtIndex(0).node()->approximate(float(), reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()).toScalar(); if ((e.type() == ExpressionNode::Type::ArcCosine && trigoOp >= 0.0f && trigoOp <= pi) || (e.type() == ExpressionNode::Type::ArcSine && trigoOp >= -pi/2.0f && trigoOp <= pi/2.0f) || (e.type() == ExpressionNode::Type::ArcTangent && trigoOp >= -pi/2.0f && trigoOp <= pi/2.0f)) { @@ -266,7 +270,7 @@ Expression Trigonometry::shallowReduceInverseFunction(Expression & e, Context& c // Step 2. Special case for atan(sin(x)/cos(x)) if (e.type() == ExpressionNode::Type::ArcTangent && ExpressionIsEquivalentToTangent(e.childAtIndex(0))) { - float trigoOp = e.childAtIndex(0).childAtIndex(1).childAtIndex(0).node()->approximate(float(), context, complexFormat, angleUnit).toScalar(); + float trigoOp = e.childAtIndex(0).childAtIndex(1).childAtIndex(0).node()->approximate(float(), reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()).toScalar(); if (trigoOp >= -pi/2.0f && trigoOp <= pi/2.0f) { Expression result = e.childAtIndex(0).childAtIndex(1).childAtIndex(0); e.replaceWithInPlace(result); @@ -281,22 +285,22 @@ Expression Trigonometry::shallowReduceInverseFunction(Expression & e, Context& c * - the reduction target is the user * - x is numeral (which means that x != 0 otherwise 0^(-1) would have been * reduced to undef) */ - if (target == ExpressionNode::ReductionTarget::User || x.isNumber()) { + if (reductionContext.target() == ExpressionNode::ReductionTarget::User || x.isNumber()) { Expression sign = SignFunction::Builder(x.clone()); Multiplication m0 = Multiplication::Builder(Rational::Builder(1,2), sign, Constant::Builder(UCodePointGreekSmallLetterPi)); - sign.shallowReduce(context, complexFormat, angleUnit, target); + sign.shallowReduce(reductionContext); e.replaceChildAtIndexInPlace(0, x); Addition a = Addition::Builder(m0); e.replaceWithInPlace(a); Multiplication m1 = Multiplication::Builder(Rational::Builder(-1), e); - e.shallowReduce(context, complexFormat, angleUnit, target); + e.shallowReduce(reductionContext); a.addChildAtIndexInPlace(m1, 1, 1); - return a.shallowReduce(context, complexFormat, angleUnit, target); + return a.shallowReduce(reductionContext); } } // Step 4. Try finding an easy standard calculation reduction - Expression lookup = TrigonometryCheatTable::Table()->simplify(e.childAtIndex(0), e.type(), context, complexFormat, angleUnit, target); + Expression lookup = TrigonometryCheatTable::Table()->simplify(e.childAtIndex(0), e.type(), reductionContext); if (!lookup.isUninitialized()) { e.replaceWithInPlace(lookup); return lookup; @@ -314,25 +318,25 @@ Expression Trigonometry::shallowReduceInverseFunction(Expression & e, Context& c * asin(-x) = -asin(x), atan(-x)= -atan(x) * */ if (!letArcFunctionAtRoot) { - Expression positiveArg = e.childAtIndex(0).makePositiveAnyNegativeNumeralFactor(context, complexFormat, angleUnit, target); + Expression positiveArg = e.childAtIndex(0).makePositiveAnyNegativeNumeralFactor(reductionContext); if (!positiveArg.isUninitialized()) { // The argument was made positive // acos(-x) = π-acos(x) if (e.type() == ExpressionNode::Type::ArcCosine) { - Expression pi = angleUnit == Preferences::AngleUnit::Radian ? static_cast(Constant::Builder(UCodePointGreekSmallLetterPi)) : static_cast(Rational::Builder(180)); + Expression pi = reductionContext.angleUnit() == Preferences::AngleUnit::Radian ? static_cast(Constant::Builder(UCodePointGreekSmallLetterPi)) : static_cast(Rational::Builder(180)); Subtraction s = Subtraction::Builder(); e.replaceWithInPlace(s); s.replaceChildAtIndexInPlace(0, pi); s.replaceChildAtIndexInPlace(1, e); - e.shallowReduce(context, complexFormat, angleUnit, target); - return s.shallowReduce(context, complexFormat, angleUnit, target); + e.shallowReduce(reductionContext); + return s.shallowReduce(reductionContext); } else { // asin(-x) = -asin(x) or atan(-x) = -atan(x) Multiplication m = Multiplication::Builder(Rational::Builder(-1)); e.replaceWithInPlace(m); m.addChildAtIndexInPlace(e, 1, 1); - e.shallowReduce(context, complexFormat, angleUnit, target); - return m.shallowReduce(context, complexFormat, angleUnit, target); + e.shallowReduce(reductionContext); + return m.shallowReduce(reductionContext); } } } diff --git a/poincare/src/trigonometry_cheat_table.cpp b/poincare/src/trigonometry_cheat_table.cpp index 58b2cba17..0fb6e71e8 100644 --- a/poincare/src/trigonometry_cheat_table.cpp +++ b/poincare/src/trigonometry_cheat_table.cpp @@ -2,7 +2,7 @@ namespace Poincare { -Expression TrigonometryCheatTable::Row::Pair::reducedExpression(bool assertNotUninitialized, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) const { +Expression TrigonometryCheatTable::Row::Pair::reducedExpression(bool assertNotUninitialized, ExpressionNode::ReductionContext reductionContext) const { Expression e = Expression::Parse(m_expression); if (assertNotUninitialized) { assert(!e.isUninitialized()); @@ -11,10 +11,10 @@ Expression TrigonometryCheatTable::Row::Pair::reducedExpression(bool assertNotUn return Expression(); } } - return e.deepReduce(context, complexFormat, angleUnit, target); + return e.deepReduce(reductionContext); } -Expression TrigonometryCheatTable::simplify(const Expression e, ExpressionNode::Type type, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) const { +Expression TrigonometryCheatTable::simplify(const Expression e, ExpressionNode::Type type, ExpressionNode::ReductionContext reductionContext) const { assert(type == ExpressionNode::Type::Sine || type == ExpressionNode::Type::Cosine || type == ExpressionNode::Type::Tangent @@ -23,7 +23,7 @@ Expression TrigonometryCheatTable::simplify(const Expression e, ExpressionNode:: || type == ExpressionNode::Type::ArcTangent); // Compute the input and output types - Type angleUnitType = angleUnit == Preferences::AngleUnit::Radian ? Type::AngleInRadians : Type::AngleInDegrees; + Type angleUnitType = reductionContext.angleUnit() == Preferences::AngleUnit::Radian ? Type::AngleInRadians : Type::AngleInDegrees; Type trigonometricFunctionType; if (type == ExpressionNode::Type::Cosine || type == ExpressionNode::Type::ArcCosine) { trigonometricFunctionType = Type::Cosine; @@ -53,7 +53,7 @@ Expression TrigonometryCheatTable::simplify(const Expression e, ExpressionNode:: } // Approximate e to quickly compare it to cheat table entries - float eValue = e.node()->approximate(float(), context, complexFormat, angleUnit).toScalar(); + float eValue = e.node()->approximate(float(), reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()).toScalar(); if (std::isnan(eValue) || std::isinf(eValue)) { return Expression(); } @@ -64,9 +64,9 @@ Expression TrigonometryCheatTable::simplify(const Expression e, ExpressionNode:: } /* e's approximation matches a table entry, check that both expressions are * identical */ - Expression input = expressionForTypeAtIndex(inputType, i, true, context, complexFormat, angleUnit, target); + Expression input = expressionForTypeAtIndex(inputType, i, true, reductionContext); if (input.isIdenticalTo(e)) { - return expressionForTypeAtIndex(outputType, i, false, context, complexFormat, angleUnit, target); + return expressionForTypeAtIndex(outputType, i, false, reductionContext); } } return Expression(); diff --git a/poincare/src/undefined.cpp b/poincare/src/undefined.cpp index c45bd2663..7075a18b3 100644 --- a/poincare/src/undefined.cpp +++ b/poincare/src/undefined.cpp @@ -11,11 +11,11 @@ namespace Poincare { static inline int minInt(int x, int y) { return x < y ? x : y; } -int UndefinedNode::polynomialDegree(Context & context, const char * symbolName) const { +int UndefinedNode::polynomialDegree(Context * context, const char * symbolName) const { return -1; } -Expression UndefinedNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { +Expression UndefinedNode::setSign(Sign s, ExpressionNode::ReductionContext reductionContext) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); return Undefined(this); } diff --git a/poincare/src/variable_context.cpp b/poincare/src/variable_context.cpp index fb36c9fc2..ac16b2049 100644 --- a/poincare/src/variable_context.cpp +++ b/poincare/src/variable_context.cpp @@ -18,7 +18,7 @@ void VariableContext::setApproximationForVariable(T value) { m_value = Float::Builder(value); } -void VariableContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) { +void VariableContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context * context) { if (strcmp(symbol.name(), m_name) == 0) { if (expression.isUninitialized()) { return; diff --git a/poincare/test/addition.cpp b/poincare/test/addition.cpp index c80d40c43..65ed09973 100644 --- a/poincare/test/addition.cpp +++ b/poincare/test/addition.cpp @@ -12,7 +12,7 @@ using namespace Poincare; static inline void assert_approximation_equals(const Expression i, float f) { Shared::GlobalContext c; - quiz_assert(i.approximateToScalar(c, Cartesian, Degree) == f); + quiz_assert(i.approximateToScalar(&c, Cartesian, Degree) == f); } static inline void assert_parsed_expression_is_equal_to(const char * exp, Expression e) { diff --git a/poincare/test/float.cpp b/poincare/test/float.cpp index 756327396..39bbd61df 100644 --- a/poincare/test/float.cpp +++ b/poincare/test/float.cpp @@ -16,7 +16,7 @@ void assert_float_evaluates_to(Float f, const char * result) { Shared::GlobalContext globalContext; int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits; char buffer[500]; - f.template approximate(globalContext, Cartesian, Radian).serialize(buffer, sizeof(buffer), DecimalMode, numberOfDigits); + f.template approximate(&globalContext, Cartesian, Radian).serialize(buffer, sizeof(buffer), DecimalMode, numberOfDigits); quiz_assert(strcmp(buffer, result) == 0); } diff --git a/poincare/test/function.cpp b/poincare/test/function.cpp index 5214ff815..233d77b53 100644 --- a/poincare/test/function.cpp +++ b/poincare/test/function.cpp @@ -11,7 +11,7 @@ using namespace Poincare; template void assert_exp_is_bounded(Expression exp, T lowBound, T upBound, bool upBoundIncluded = false) { Shared::GlobalContext globalContext; - T result = exp.approximateToScalar(globalContext, Cartesian, Radian); + T result = exp.approximateToScalar(&globalContext, Cartesian, Radian); quiz_assert(result >= lowBound); quiz_assert(result < upBound || (result == upBound && upBoundIncluded)); } diff --git a/poincare/test/helper.cpp b/poincare/test/helper.cpp index 9cb7fc05a..620e9c9cd 100644 --- a/poincare/test/helper.cpp +++ b/poincare/test/helper.cpp @@ -90,11 +90,11 @@ void assert_parsed_expression_is(const char * expression, Poincare::Expression r void assert_parsed_expression_polynomial_degree(const char * expression, int degree, const char * symbolName, Preferences::ComplexFormat complexFormat) { Shared::GlobalContext globalContext; Expression e = parse_expression(expression); - Expression result = e.clone().reduce(globalContext, complexFormat, Radian); + Expression result = e.clone().reduce(&globalContext, complexFormat, Radian); if (result.isUninitialized()) { result = e; } - quiz_assert(result.polynomialDegree(globalContext, symbolName) == degree); + quiz_assert(result.polynomialDegree(&globalContext, symbolName) == degree); } @@ -102,14 +102,14 @@ Expression parse_and_simplify(const char * expression) { Shared::GlobalContext globalContext; Expression e = parse_expression(expression); quiz_assert(!e.isUninitialized()); - return e.simplify(globalContext, Cartesian, Radian); + return e.simplify(&globalContext, Cartesian, Radian); } void assert_simplify(const char * expression) { quiz_assert(!(parse_and_simplify(expression).isUninitialized())); } -typedef Expression (*ProcessExpression)(Expression, Context & context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); +typedef Expression (*ProcessExpression)(Expression, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); void assert_parsed_expression_process_to(const char * expression, const char * result, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ProcessExpression process, int numberOfSignifiantDigits = PrintFloat::k_numberOfStoredSignificantDigits) { Shared::GlobalContext globalContext; @@ -119,7 +119,7 @@ void assert_parsed_expression_process_to(const char * expression, const char * r cout << " Entry expression: " << expression << "----" << endl; print_expression(e, 0); #endif - Expression m = process(e, globalContext, target, complexFormat, angleUnit); + Expression m = process(e, &globalContext, target, complexFormat, angleUnit); constexpr int bufferSize = 500; char buffer[bufferSize]; m.serialize(buffer, bufferSize, DecimalMode, numberOfSignifiantDigits); @@ -138,7 +138,7 @@ void assert_parsed_expression_evaluates_to(const char * expression, const char * int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits; numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : numberOfDigits; - assert_parsed_expression_process_to(expression, approximation, target, complexFormat, angleUnit, [](Expression e, Context & context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { + assert_parsed_expression_process_to(expression, approximation, target, complexFormat, angleUnit, [](Expression e, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { Expression simplified = e.clone(); Expression result; if (target == ExpressionNode::ReductionTarget::User) { @@ -161,7 +161,7 @@ template void assert_parsed_expression_evaluates_without_simplifying_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) { int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits; numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : numberOfDigits; - assert_parsed_expression_process_to(expression, approximation, ExpressionNode::ReductionTarget::System, complexFormat, angleUnit, [](Expression e, Context & context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { + assert_parsed_expression_process_to(expression, approximation, ExpressionNode::ReductionTarget::System, complexFormat, angleUnit, [](Expression e, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { return e.approximate(context, complexFormat, angleUnit); }, numberOfDigits); } @@ -170,7 +170,7 @@ void assert_parsed_expression_evaluates_without_simplifying_to(const char * expr template void assert_parsed_expression_approximates_with_value_for_symbol(Expression expression, const char * symbol, T value, T approximation, Poincare::Preferences::ComplexFormat complexFormat, Poincare::Preferences::AngleUnit angleUnit) { Shared::GlobalContext globalContext; - T result = expression.approximateWithValueForSymbol(symbol, value, globalContext, complexFormat, angleUnit); + T result = expression.approximateWithValueForSymbol(symbol, value, &globalContext, complexFormat, angleUnit); quiz_assert((std::isnan(result) && std::isnan(approximation)) || std::fabs(result - approximation) < 10.0*Expression::Epsilon()); } @@ -178,7 +178,7 @@ void assert_parsed_expression_simplify_to(const char * expression, const char * #if POINCARE_TESTS_PRINT_EXPRESSIONS cout << "--------- Simplification ---------" << endl; #endif - assert_parsed_expression_process_to(expression, simplifiedExpression, target, complexFormat, angleUnit, [](Expression e, Context & context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { + assert_parsed_expression_process_to(expression, simplifiedExpression, target, complexFormat, angleUnit, [](Expression e, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { Expression copy = e.clone(); if (target == ExpressionNode::ReductionTarget::User) { copy.simplifyAndApproximate(©, nullptr, context, complexFormat, angleUnit); diff --git a/poincare/test/layouts.cpp b/poincare/test/layouts.cpp index 5509a0fdd..c54870902 100644 --- a/poincare/test/layouts.cpp +++ b/poincare/test/layouts.cpp @@ -15,14 +15,14 @@ void assert_parsed_layout_is(Layout l, Poincare::Expression r) { l.serializeForParsing(buffer, bufferSize); Expression e = parse_expression(buffer); Expression eSimplified; - e.clone().simplifyAndApproximate(&eSimplified, nullptr, context, Cartesian, Degree); + e.clone().simplifyAndApproximate(&eSimplified, nullptr, &context, Cartesian, Degree); if (eSimplified.isUninitialized()) { /* In case the simplification is impossible (if there are matrices for * instance), use the non simplified expression */ eSimplified = e; } Expression rSimplified; - r.clone().simplifyAndApproximate(&rSimplified, nullptr, context, Cartesian, Degree); + r.clone().simplifyAndApproximate(&rSimplified, nullptr, &context, Cartesian, Degree); if (rSimplified.isUninitialized()) { /* In case the simplification is impossible (if there are matrices for * instance), use the non simplified expression */ diff --git a/poincare/test/properties.cpp b/poincare/test/properties.cpp index 4f1cea9e4..8fb8a7d16 100644 --- a/poincare/test/properties.cpp +++ b/poincare/test/properties.cpp @@ -15,7 +15,7 @@ void assert_parsed_expression_sign(const char * expression, Poincare::Expression Shared::GlobalContext globalContext; Expression e = parse_expression(expression); quiz_assert(!e.isUninitialized()); - e = e.reduce(globalContext, complexFormat, Degree); + e = e.reduce(&globalContext, complexFormat, Degree); quiz_assert(e.sign(&globalContext) == sign); } @@ -67,11 +67,11 @@ QUIZ_CASE(poincare_polynomial_degree) { void assert_expression_has_characteristic_range(Expression e, float range, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) { Shared::GlobalContext globalContext; quiz_assert(!e.isUninitialized()); - e = e.reduce(globalContext, Preferences::ComplexFormat::Cartesian, angleUnit); + e = e.reduce(&globalContext, Preferences::ComplexFormat::Cartesian, angleUnit); if (std::isnan(range)) { - quiz_assert(std::isnan(e.characteristicXRange(globalContext, angleUnit))); + quiz_assert(std::isnan(e.characteristicXRange(&globalContext, angleUnit))); } else { - quiz_assert(std::fabs(e.characteristicXRange(globalContext, angleUnit) - range) < 0.0000001f); + quiz_assert(std::fabs(e.characteristicXRange(&globalContext, angleUnit) - range) < 0.0000001f); } } @@ -97,7 +97,7 @@ void assert_parsed_expression_has_variables(const char * expression, const char constexpr static int k_maxVariableSize = Poincare::SymbolAbstract::k_maxNameSize; char variableBuffer[Expression::k_maxNumberOfVariables+1][k_maxVariableSize] = {{0}}; Shared::GlobalContext globalContext; - int numberOfVariables = e.getVariables(globalContext, [](const char * symbol) { return true; }, (char *)variableBuffer, k_maxVariableSize); + int numberOfVariables = e.getVariables(&globalContext, [](const char * symbol) { return true; }, (char *)variableBuffer, k_maxVariableSize); quiz_assert(trueNumberOfVariables == numberOfVariables); if (numberOfVariables < 0) { // Too many variables @@ -133,14 +133,14 @@ void assert_parsed_expression_has_polynomial_coefficient(const char * expression Shared::GlobalContext globalContext; Expression e = parse_expression(expression); quiz_assert(!e.isUninitialized()); - e = e.reduce(globalContext, complexFormat, angleUnit); + e = e.reduce(&globalContext, complexFormat, angleUnit); Expression coefficientBuffer[Poincare::Expression::k_maxNumberOfPolynomialCoefficients]; - int d = e.getPolynomialReducedCoefficients(symbolName, coefficientBuffer, globalContext, complexFormat, Radian); + int d = e.getPolynomialReducedCoefficients(symbolName, coefficientBuffer, &globalContext, complexFormat, Radian); for (int i = 0; i <= d; i++) { Expression f = parse_expression(coefficients[i]); quiz_assert(!f.isUninitialized()); - coefficientBuffer[i] = coefficientBuffer[i].reduce(globalContext, complexFormat, angleUnit); - f = f.reduce(globalContext, complexFormat, angleUnit); + coefficientBuffer[i] = coefficientBuffer[i].reduce(&globalContext, complexFormat, angleUnit); + f = f.reduce(&globalContext, complexFormat, angleUnit); quiz_assert(coefficientBuffer[i].isIdenticalTo(f)); } quiz_assert(coefficients[d+1] == 0); diff --git a/poincare/test/user_variable.cpp b/poincare/test/user_variable.cpp index e19b81a66..19786c56c 100644 --- a/poincare/test/user_variable.cpp +++ b/poincare/test/user_variable.cpp @@ -185,19 +185,19 @@ QUIZ_CASE(poincare_user_variable_properties) { Shared::GlobalContext context; assert_parsed_expression_evaluates_to("[[1]]→a", "[[1]]"); - quiz_assert(Symbol::Builder('a').recursivelyMatches(Expression::IsMatrix, context)); + quiz_assert(Symbol::Builder('a').recursivelyMatches(Expression::IsMatrix, &context)); assert_parsed_expression_evaluates_to("1.2→b", "1.2"); - quiz_assert(Symbol::Builder('b').recursivelyMatches(Expression::IsApproximate, context, true)); + quiz_assert(Symbol::Builder('b').recursivelyMatches(Expression::IsApproximate, &context, true)); /* [[x]]→f(x) expression contains a matrix, so its simplification is going * to be interrupted. We thus rather approximate it instead of simplifying it. * TODO: use parse_and_simplify when matrix are simplified. */ assert_parsed_expression_evaluates_to("[[x]]→f(x)", "[[undef]]"); - quiz_assert(Function::Builder("f", 1, Symbol::Builder('x')).recursivelyMatches(Poincare::Expression::IsMatrix, context)); + quiz_assert(Function::Builder("f", 1, Symbol::Builder('x')).recursivelyMatches(Poincare::Expression::IsMatrix, &context)); assert_parsed_expression_evaluates_to("0.2*x→g(x)", "undef"); - quiz_assert(Function::Builder("g", 1, Rational::Builder(2)).recursivelyMatches(Expression::IsApproximate, context, true)); + quiz_assert(Function::Builder("g", 1, Rational::Builder(2)).recursivelyMatches(Expression::IsApproximate, &context, true)); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();