mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Add SymbolicComputation parameter to the reduction context
This way, in solver, we can reduce expression without expanding symbols
This commit is contained in:
@@ -97,7 +97,7 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
|
||||
// Outputs hold exact output, approximate output and its duplicate
|
||||
constexpr static int numberOfOutputs = Calculation::k_numberOfExpressions - 1;
|
||||
Expression outputs[numberOfOutputs] = {Expression(), Expression(), Expression()};
|
||||
PoincareHelpers::ParseAndSimplifyAndApproximate(inputSerialization, &(outputs[0]), &(outputs[1]), context, false);
|
||||
PoincareHelpers::ParseAndSimplifyAndApproximate(inputSerialization, &(outputs[0]), &(outputs[1]), context, Poincare::ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
|
||||
outputs[2] = outputs[1];
|
||||
int numberOfSignificantDigits = Poincare::PrintFloat::k_numberOfStoredSignificantDigits;
|
||||
for (int i = 0; i < numberOfOutputs; i++) {
|
||||
|
||||
@@ -50,25 +50,26 @@ inline T ApproximateWithValueForSymbol(const Poincare::Expression e, const char
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T ApproximateToScalar(const char * text, Poincare::Context * context, bool symbolicComputation = true) {
|
||||
inline T ApproximateToScalar(const char * text, Poincare::Context * context, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition) {
|
||||
Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences();
|
||||
Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), text);
|
||||
return Poincare::Expression::ApproximateToScalar<T>(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, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition) {
|
||||
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, Poincare::ExpressionNode::ReductionTarget target, bool symbolicComputation = true) {
|
||||
inline void Simplify(Poincare::Expression * e, Poincare::Context * context, Poincare::ExpressionNode::ReductionTarget target, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition) {
|
||||
Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences();
|
||||
Poincare::Preferences::ComplexFormat complexFormat = Poincare::Expression::UpdatedComplexFormatWithExpressionInput(preferences->complexFormat(), *e, context);
|
||||
*e = e->simplify(context, complexFormat, preferences->angleUnit(), target, symbolicComputation);
|
||||
|
||||
*e = e->simplify(Poincare::ExpressionNode::ReductionContext(context, complexFormat, preferences->angleUnit(), target, 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, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition) {
|
||||
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);
|
||||
|
||||
@@ -168,7 +168,7 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context, bool
|
||||
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, replaceFunctionsButNotSymbols).getLinearCoefficients((char *)m_variables, Poincare::SymbolAbstract::k_maxNameSize, coefficients[i], &constants[i], context, updatedComplexFormat(context), preferences->angleUnit());
|
||||
isLinear = isLinear && modelForRecord(definedRecordAtIndex(i))->standardForm(context, replaceFunctionsButNotSymbols).getLinearCoefficients((char *)m_variables, Poincare::SymbolAbstract::k_maxNameSize, coefficients[i], &constants[i], context, updatedComplexFormat(context), preferences->angleUnit(), replaceFunctionsButNotSymbols ? ExpressionNode::SymbolicComputation::ReplaceDefinedFunctionsWithDefinitions : ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
|
||||
if (!isLinear) {
|
||||
// TODO: should we clean pool allocated memory if the system is not linear
|
||||
#if 0
|
||||
@@ -199,7 +199,7 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context, bool
|
||||
// Step 3. Polynomial & Monovariable?
|
||||
assert(numberOfVariables == 1 && numberOfDefinedModels() == 1);
|
||||
Expression polynomialCoefficients[Expression::k_maxNumberOfPolynomialCoefficients];
|
||||
int degree = modelForRecord(definedRecordAtIndex(0))->standardForm(context, replaceFunctionsButNotSymbols).getPolynomialReducedCoefficients(m_variables[0], polynomialCoefficients, context, updatedComplexFormat(context), preferences->angleUnit());
|
||||
int degree = modelForRecord(definedRecordAtIndex(0))->standardForm(context, replaceFunctionsButNotSymbols).getPolynomialReducedCoefficients(m_variables[0], polynomialCoefficients, context, updatedComplexFormat(context), preferences->angleUnit(), replaceFunctionsButNotSymbols ? ExpressionNode::SymbolicComputation::ReplaceDefinedFunctionsWithDefinitions : ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
|
||||
if (degree == 2) {
|
||||
// Polynomial degree <= 2
|
||||
m_type = Type::PolynomialMonovariable;
|
||||
@@ -299,7 +299,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(), ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
delta = delta.simplify(ExpressionNode::ReductionContext(context, updatedComplexFormat(context), Poincare::Preferences::sharedPreferences()->angleUnit(), ExpressionNode::ReductionTarget::SystemForApproximation));
|
||||
if (delta.isUninitialized()) {
|
||||
delta = Poincare::Undefined::Builder();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ 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 getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
||||
|
||||
// Evaluation
|
||||
template<typename T> static Complex<T> compute(const std::complex<T> c, const std::complex<T> d, Preferences::ComplexFormat complexFormat) { return Complex<T>::Builder(c+d); }
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
// Expression
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const;
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
void sortChildrenInPlace(NAryExpressionNode::ExpressionOrder order, Context * context, bool canBeInterrupted) {
|
||||
NAryExpression::sortChildrenInPlace(order, context, true, canBeInterrupted);
|
||||
}
|
||||
|
||||
@@ -187,14 +187,14 @@ public:
|
||||
* the variables hold in 'variables'. Otherwise, it fills 'coefficients' with
|
||||
* the coefficients of the variables hold in 'variables' (following the same
|
||||
* order) and 'constant' with the constant of the expression. */
|
||||
bool getLinearCoefficients(char * variables, 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, ExpressionNode::SymbolicComputation symbolicComputation) 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, ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { return node()->replaceSymbolWithExpression(symbol, expression); }
|
||||
|
||||
/* Complex */
|
||||
@@ -231,12 +231,12 @@ 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, ExpressionNode::ReductionTarget target, bool symbolicComputation = true);
|
||||
static Expression ParseAndSimplify(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
|
||||
Expression simplify(ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
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, ExpressionNode::ReductionTarget target = ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
static void ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
|
||||
void simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
|
||||
Expression reduce(ExpressionNode::ReductionContext context);
|
||||
|
||||
Expression mapOnMatrixFirstChild(ExpressionNode::ReductionContext reductionContext);
|
||||
/* 'ExpressionWithoutSymbols' returns an uninitialized expression if it is
|
||||
@@ -251,7 +251,7 @@ public:
|
||||
template<typename U> static U Epsilon();
|
||||
template<typename U> Expression approximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename U> U approximateToScalar(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename U> static U ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation = true);
|
||||
template<typename U> static U ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
|
||||
template<typename U> U approximateWithValueForSymbol(const char * symbol, U x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
/* Expression roots/extrema solver */
|
||||
Coordinate2D<double> nextMinimum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
@@ -337,7 +337,7 @@ protected:
|
||||
void removeChildrenInPlace(int currentNumberOfChildren) = delete;
|
||||
|
||||
/* Properties */
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const { return node()->getPolynomialCoefficients(context, symbolName, coefficients); }
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const { return node()->getPolynomialCoefficients(context, symbolName, coefficients, symbolicComputation); }
|
||||
Expression defaultReplaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression expression);
|
||||
/* 'deepReplaceReplaceableSymbols' returns an uninitialized expression if it
|
||||
* is circularly defined. Same convention as for 'ExpressionWithoutSymbols'.*/
|
||||
|
||||
@@ -123,6 +123,11 @@ public:
|
||||
* - identifying tangent in cos/sin polynoms ... */
|
||||
User
|
||||
};
|
||||
enum class SymbolicComputation {
|
||||
ReplaceAllSymbolsWithDefinitionsOrUndefined = 0,
|
||||
ReplaceAllDefinedSymbolsWithDefinition = 1,
|
||||
ReplaceDefinedFunctionsWithDefinitions = 2
|
||||
};
|
||||
enum class Sign {
|
||||
Negative = -1,
|
||||
Unknown = 0,
|
||||
@@ -131,7 +136,7 @@ public:
|
||||
|
||||
class ReductionContext {
|
||||
public:
|
||||
ReductionContext(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation = true) :
|
||||
ReductionContext(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, SymbolicComputation symbolicComputation = SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition) :
|
||||
m_context(context),
|
||||
m_complexFormat(complexFormat),
|
||||
m_angleUnit(angleUnit),
|
||||
@@ -142,13 +147,13 @@ public:
|
||||
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; }
|
||||
SymbolicComputation symbolicComputation() const { return m_symbolicComputation; }
|
||||
private:
|
||||
Context * m_context;
|
||||
Preferences::ComplexFormat m_complexFormat;
|
||||
Preferences::AngleUnit m_angleUnit;
|
||||
ReductionTarget m_target;
|
||||
bool m_symbolicComputation;
|
||||
SymbolicComputation m_symbolicComputation;
|
||||
};
|
||||
|
||||
virtual Sign sign(Context * context) const { return Sign::Unknown; }
|
||||
@@ -163,7 +168,7 @@ public:
|
||||
/*!*/ virtual Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression);
|
||||
/*!*/ 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 int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
/*!*/ virtual Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly);
|
||||
typedef bool (*isVariableTest)(const char * c, Poincare::Context * context);
|
||||
virtual int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const;
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
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 getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
||||
int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const override;
|
||||
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
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 getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
||||
bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override;
|
||||
|
||||
// Approximation
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
static Multiplication Builder(Expression * children, size_t numberOfChildren) { return TreeHandle::NAryBuilder<Multiplication, MultiplicationNode>(children, numberOfChildren); }
|
||||
|
||||
// Properties
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const;
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
// Approximation
|
||||
template<typename T> static void computeOnArrays(T * m, T * n, T * result, int mNumberOfColumns, int mNumberOfRows, int nNumberOfColumns);
|
||||
// Simplification
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override;
|
||||
|
||||
int polynomialDegree(Context * context, const char * symbolName) const override;
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const override;
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
||||
|
||||
template<typename T> static Complex<T> compute(const std::complex<T> c, const std::complex<T> d, Preferences::ComplexFormat complexFormat);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
Type type() const override { return Type::Symbol; }
|
||||
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 getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
||||
int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const override;
|
||||
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
// Expression
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression);
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const;
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly);
|
||||
private:
|
||||
SymbolNode * node() const { return static_cast<SymbolNode *>(Expression::node()); }
|
||||
|
||||
@@ -25,8 +25,8 @@ int AdditionNode::polynomialDegree(Context * context, const char * symbolName) c
|
||||
return degree;
|
||||
}
|
||||
|
||||
int AdditionNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const {
|
||||
return Addition(this).getPolynomialCoefficients(context, symbolName, coefficients);
|
||||
int AdditionNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
return Addition(this).getPolynomialCoefficients(context, symbolName, coefficients, symbolicComputation);
|
||||
}
|
||||
|
||||
// Layout
|
||||
@@ -59,7 +59,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[], ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
int deg = polynomialDegree(context, symbolName);
|
||||
if (deg < 0 || deg > Expression::k_maxPolynomialDegree) {
|
||||
return -1;
|
||||
@@ -69,7 +69,7 @@ int Addition::getPolynomialCoefficients(Context * context, const char * symbolNa
|
||||
}
|
||||
Expression intermediateCoefficients[Expression::k_maxNumberOfPolynomialCoefficients];
|
||||
for (int i = 0; i < numberOfChildren(); i++) {
|
||||
int d = childAtIndex(i).getPolynomialCoefficients(context, symbolName, intermediateCoefficients);
|
||||
int d = childAtIndex(i).getPolynomialCoefficients(context, symbolName, intermediateCoefficients, symbolicComputation);
|
||||
assert(d < Expression::k_maxNumberOfPolynomialCoefficients);
|
||||
for (int j = 0; j < d+1; j++) {
|
||||
static_cast<Addition&>(coefficients[j]).addChildAtIndexInPlace(intermediateCoefficients[j], coefficients[j].numberOfChildren(), coefficients[j].numberOfChildren());
|
||||
@@ -394,8 +394,8 @@ Expression Addition::factorizeOnCommonDenominator(ExpressionNode::ReductionConte
|
||||
|
||||
/* To simplify the numerator and the denominator, we allow symbolic
|
||||
* computation: all unwanted symbols should have already disappeared by now,
|
||||
* and if we checked again for symbols we might find "paramter" symbols
|
||||
* disconnected from the parametered expression, which would be replaed with
|
||||
* and if we checked again for symbols we might find "parameter" symbols
|
||||
* disconnected from the parametered expression, which would be replaced with
|
||||
* undef.
|
||||
* Example: int((ℯ^(-x))-x^(0.5), x, 0, 3), when creating the common
|
||||
* denominator for the integrand. */
|
||||
@@ -404,7 +404,7 @@ Expression Addition::factorizeOnCommonDenominator(ExpressionNode::ReductionConte
|
||||
reductionContext.complexFormat(),
|
||||
reductionContext.angleUnit(),
|
||||
reductionContext.target(),
|
||||
true);
|
||||
ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
|
||||
|
||||
// Step 4: Simplify the numerator
|
||||
numerator.shallowReduce(contextWithSymbolicComputation);
|
||||
|
||||
@@ -50,7 +50,7 @@ Expression Equal::standardEquation(Context * context, Preferences::ComplexFormat
|
||||
* SystemForAnalysis. This enables to expand Newton multinom to be able to
|
||||
* detect polynom correctly ("(x+2)^2" in this form won't be detected
|
||||
* unless expanded). */
|
||||
return sub.reduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForAnalysis);
|
||||
return sub.reduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForAnalysis));
|
||||
}
|
||||
|
||||
Expression Equal::shallowReduce() {
|
||||
|
||||
@@ -196,7 +196,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, ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
assert(!recursivelyMatches(IsMatrix, context, true));
|
||||
// variables is in fact of type char[k_maxNumberOfVariables][maxVariableSize]
|
||||
int index = 0;
|
||||
@@ -211,7 +211,7 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex
|
||||
index = 0;
|
||||
Expression polynomialCoefficients[k_maxNumberOfPolynomialCoefficients];
|
||||
while (variables[index*maxVariableSize] != 0) {
|
||||
int degree = equation.getPolynomialReducedCoefficients(&variables[index*maxVariableSize], polynomialCoefficients, context, complexFormat, angleUnit);
|
||||
int degree = equation.getPolynomialReducedCoefficients(&variables[index*maxVariableSize], polynomialCoefficients, context, complexFormat, angleUnit, symbolicComputation);
|
||||
switch (degree) {
|
||||
case 0:
|
||||
coefficients[index] = Rational::Builder(0);
|
||||
@@ -232,7 +232,7 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex
|
||||
equation = polynomialCoefficients[0];
|
||||
index++;
|
||||
}
|
||||
constant[0] = Opposite::Builder(equation.clone()).reduce(context, complexFormat, angleUnit);
|
||||
constant[0] = Opposite::Builder(equation.clone()).reduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForApproximation, symbolicComputation));
|
||||
/* The expression can be linear on all coefficients taken one by one but
|
||||
* non-linear (ex: xy = 2). We delete the results and return false if one of
|
||||
* the coefficients contains a variable. */
|
||||
@@ -444,11 +444,11 @@ 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, ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
// Reset interrupting flag because we use deepReduce
|
||||
int degree = getPolynomialCoefficients(context, symbolName, coefficients);
|
||||
int degree = getPolynomialCoefficients(context, symbolName, coefficients, symbolicComputation);
|
||||
for (int i = 0; i <= degree; i++) {
|
||||
coefficients[i] = coefficients[i].reduce(context, complexFormat, angleUnit);
|
||||
coefficients[i] = coefficients[i].reduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::SystemForApproximation, symbolicComputation));
|
||||
}
|
||||
return degree;
|
||||
}
|
||||
@@ -525,8 +525,8 @@ bool Expression::isIdenticalTo(const Expression e) const {
|
||||
}
|
||||
|
||||
bool Expression::ParsedExpressionsAreEqual(const char * e0, const char * e1, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) {
|
||||
Expression exp0 = Expression::ParseAndSimplify(e0, context, complexFormat, angleUnit, false);
|
||||
Expression exp1 = Expression::ParseAndSimplify(e1, context, complexFormat, angleUnit, false);
|
||||
Expression exp0 = Expression::ParseAndSimplify(e0, context, complexFormat, angleUnit, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
|
||||
Expression exp1 = Expression::ParseAndSimplify(e1, context, complexFormat, angleUnit, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
|
||||
if (exp0.isUninitialized() || exp1.isUninitialized()) {
|
||||
return false;
|
||||
}
|
||||
@@ -543,12 +543,12 @@ 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, ExpressionNode::SymbolicComputation symbolicComputation) {
|
||||
Expression exp = Parse(text, context, false);
|
||||
if (exp.isUninitialized()) {
|
||||
return Undefined::Builder();
|
||||
}
|
||||
exp = exp.simplify(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicSimplification);
|
||||
exp = exp.simplify(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User, symbolicComputation));
|
||||
/* simplify might have been interrupted, in which case the resulting
|
||||
* expression is uninitialized, so we need to check that. */
|
||||
if (exp.isUninitialized()) {
|
||||
@@ -557,7 +557,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, ExpressionNode::SymbolicComputation symbolicComputation) {
|
||||
assert(simplifiedExpression);
|
||||
Expression exp = Parse(text, context, false);
|
||||
if (exp.isUninitialized()) {
|
||||
@@ -576,12 +576,11 @@ void Expression::ParseAndSimplifyAndApproximate(const char * text, Expression *
|
||||
}
|
||||
}
|
||||
|
||||
Expression Expression::simplify(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool symbolicComputation) {
|
||||
Expression Expression::simplify(ExpressionNode::ReductionContext reductionContext) {
|
||||
sSimplificationHasBeenInterrupted = false;
|
||||
ExpressionNode::ReductionContext c = ExpressionNode::ReductionContext(context, complexFormat, angleUnit, target, symbolicComputation);
|
||||
Expression e = deepReduce(c);
|
||||
Expression e = deepReduce(reductionContext);
|
||||
if (!sSimplificationHasBeenInterrupted) {
|
||||
e = e.deepBeautify(c);
|
||||
e = e.deepBeautify(reductionContext);
|
||||
}
|
||||
return sSimplificationHasBeenInterrupted ? Expression() : e;
|
||||
}
|
||||
@@ -647,7 +646,7 @@ void Expression::beautifyAndApproximateScalar(Expression * simplifiedExpression,
|
||||
}
|
||||
}
|
||||
|
||||
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, ExpressionNode::SymbolicComputation symbolicComputation) {
|
||||
assert(simplifiedExpression);
|
||||
sSimplificationHasBeenInterrupted = false;
|
||||
// Step 1: we reduce the expression
|
||||
@@ -772,9 +771,9 @@ Expression Expression::angleUnitToRadian(Preferences::AngleUnit angleUnit) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Expression Expression::reduce(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) {
|
||||
Expression Expression::reduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
sSimplificationHasBeenInterrupted = false;
|
||||
return deepReduce(ExpressionNode::ReductionContext(context, complexFormat, angleUnit, target, true));
|
||||
return deepReduce(reductionContext);
|
||||
}
|
||||
|
||||
Expression Expression::deepReduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
@@ -824,8 +823,8 @@ U Expression::approximateToScalar(Context * context, Preferences::ComplexFormat
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
U Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicSimplification) {
|
||||
Expression exp = ParseAndSimplify(text, context, complexFormat, angleUnit, symbolicSimplification);
|
||||
U Expression::ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation) {
|
||||
Expression exp = ParseAndSimplify(text, context, complexFormat, angleUnit, symbolicComputation);
|
||||
assert(!exp.isUninitialized());
|
||||
return exp.approximateToScalar<U>(context, complexFormat, angleUnit);
|
||||
}
|
||||
@@ -1147,8 +1146,8 @@ template Expression Expression::approximate<double>(Context * context, Preferenc
|
||||
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<float>(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation);
|
||||
template double Expression::ApproximateToScalar<double>(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool symbolicComputation);
|
||||
template float Expression::ApproximateToScalar<float>(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation);
|
||||
template double Expression::ApproximateToScalar<double>(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation);
|
||||
|
||||
template Evaluation<float> Expression::approximateToEvaluation(Context * context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template Evaluation<double> Expression::approximateToEvaluation(Context * context, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
@@ -32,7 +32,7 @@ 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[], ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
return Expression(this).defaultGetPolynomialCoefficients(context, symbolName, coefficients);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ 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[], ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
Function f(this);
|
||||
Expression e = SymbolAbstract::Expand(f, context, true);
|
||||
if (e.isUninitialized()) {
|
||||
return -1;
|
||||
}
|
||||
return e.getPolynomialCoefficients(context, symbolName, coefficients);
|
||||
return e.getPolynomialCoefficients(context, symbolName, coefficients, symbolicComputation);
|
||||
}
|
||||
|
||||
int FunctionNode::getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const {
|
||||
@@ -120,7 +120,7 @@ Expression Function::shallowReduce(ExpressionNode::ReductionContext reductionCon
|
||||
}
|
||||
Expression result = SymbolAbstract::Expand(*this, reductionContext.context(), true);
|
||||
if (result.isUninitialized()) {
|
||||
if (reductionContext.symbolicComputation()) {
|
||||
if (reductionContext.symbolicComputation() != ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined) {
|
||||
return *this;
|
||||
}
|
||||
result = Undefined::Builder();
|
||||
|
||||
@@ -699,7 +699,7 @@ Expression Integer::CreateEuclideanDivision(const Integer & num, const Integer &
|
||||
Expression quo = DivisionQuotient::Reduce(num, denom);
|
||||
Expression rem = DivisionRemainder::Reduce(num, denom);
|
||||
Expression e = Equal::Builder(Rational::Builder(num), Addition::Builder(Multiplication::Builder(Rational::Builder(denom), quo), rem));
|
||||
ExpressionNode::ReductionContext defaultReductionContext = ExpressionNode::ReductionContext(nullptr, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Radian, ExpressionNode::ReductionTarget::User, false);
|
||||
ExpressionNode::ReductionContext defaultReductionContext = ExpressionNode::ReductionContext(nullptr, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Radian, ExpressionNode::ReductionTarget::User, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
|
||||
e = e.deepBeautify(defaultReductionContext);
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ int MultiplicationNode::polynomialDegree(Context * context, const char * symbolN
|
||||
return degree;
|
||||
}
|
||||
|
||||
int MultiplicationNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const {
|
||||
return Multiplication(this).getPolynomialCoefficients(context, symbolName, coefficients);
|
||||
int MultiplicationNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
return Multiplication(this).getPolynomialCoefficients(context, symbolName, coefficients, symbolicComputation);
|
||||
}
|
||||
|
||||
bool MultiplicationNode::childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const {
|
||||
@@ -217,7 +217,7 @@ Expression MultiplicationNode::denominator(ReductionContext reductionContext) co
|
||||
|
||||
/* Multiplication */
|
||||
|
||||
int Multiplication::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const {
|
||||
int Multiplication::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
int deg = polynomialDegree(context, symbolName);
|
||||
if (deg < 0 || deg > Expression::k_maxPolynomialDegree) {
|
||||
return -1;
|
||||
@@ -232,7 +232,7 @@ int Multiplication::getPolynomialCoefficients(Context * context, const char * sy
|
||||
// Let's note result = a(0)+a(1)*X+a(2)*X^2+a(3)*x^3+..
|
||||
for (int i = 0; i < numberOfChildren(); i++) {
|
||||
// childAtIndex(i) = b(0)+b(1)*X+b(2)*X^2+b(3)*x^3+...
|
||||
int degI = childAtIndex(i).getPolynomialCoefficients(context, symbolName, intermediateCoefficients);
|
||||
int degI = childAtIndex(i).getPolynomialCoefficients(context, symbolName, intermediateCoefficients, symbolicComputation);
|
||||
assert(degI <= Expression::k_maxPolynomialDegree);
|
||||
for (int j = deg; j > 0; j--) {
|
||||
// new coefficients[j] = b(0)*a(j)+b(1)*a(j-1)+b(2)*a(j-2)+...
|
||||
|
||||
@@ -81,7 +81,7 @@ 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[], ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
return Power(this).getPolynomialCoefficients(context, symbolName, coefficients);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ int SymbolNode::polynomialDegree(Context * context, const char * symbolName) con
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SymbolNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const {
|
||||
return Symbol(this).getPolynomialCoefficients(context, symbolName, coefficients);
|
||||
int SymbolNode::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
return Symbol(this).getPolynomialCoefficients(context, symbolName, coefficients, symbolicComputation);
|
||||
}
|
||||
|
||||
int SymbolNode::getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable) const {
|
||||
@@ -151,6 +151,9 @@ bool Symbol::isRegressionSymbol(const char * c, Poincare::Context * context) {
|
||||
}
|
||||
|
||||
Expression Symbol::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
if (reductionContext.symbolicComputation() == ExpressionNode::SymbolicComputation::ReplaceDefinedFunctionsWithDefinitions) {
|
||||
return *this;
|
||||
}
|
||||
{
|
||||
Expression current = *this;
|
||||
Expression p = parent();
|
||||
@@ -177,7 +180,7 @@ Expression Symbol::shallowReduce(ExpressionNode::ReductionContext reductionConte
|
||||
|
||||
Expression result = SymbolAbstract::Expand(*this, reductionContext.context(), true);
|
||||
if (result.isUninitialized()) {
|
||||
if (reductionContext.symbolicComputation()) {
|
||||
if (reductionContext.symbolicComputation() != ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined) {
|
||||
return *this;
|
||||
}
|
||||
result = Undefined::Builder();
|
||||
@@ -200,7 +203,7 @@ Expression Symbol::replaceSymbolWithExpression(const SymbolAbstract & symbol, co
|
||||
return *this;
|
||||
}
|
||||
|
||||
int Symbol::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const {
|
||||
int Symbol::getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const {
|
||||
if (strcmp(name(), symbolName) == 0) {
|
||||
coefficients[0] = Rational::Builder(0);
|
||||
coefficients[1] = Rational::Builder(1);
|
||||
|
||||
Reference in New Issue
Block a user