mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[poincare] Better simplification of sequences
This commit is contained in:
@@ -24,6 +24,7 @@ public:
|
|||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
Type type() const override { return Type::Addition; }
|
Type type() const override { return Type::Addition; }
|
||||||
|
virtual ExpressionNode::IntegerStatus integerStatus(Context * context) const override;
|
||||||
int polynomialDegree(Context * context, const char * symbolName) const override;
|
int polynomialDegree(Context * context, const char * symbolName) const override;
|
||||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
||||||
|
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ public:
|
|||||||
bool isOfType(ExpressionNode::Type * types, int length) const { return node()->isOfType(types, length); }
|
bool isOfType(ExpressionNode::Type * types, int length) const { return node()->isOfType(types, length); }
|
||||||
ExpressionNode::Sign sign(Context * context) const { return node()->sign(context); }
|
ExpressionNode::Sign sign(Context * context) const { return node()->sign(context); }
|
||||||
ExpressionNode::NullStatus nullStatus(Context * context) const { return node()->nullStatus(context); }
|
ExpressionNode::NullStatus nullStatus(Context * context) const { return node()->nullStatus(context); }
|
||||||
|
ExpressionNode::IntegerStatus integerStatus(Context * context) const { return node()->integerStatus(context); }
|
||||||
bool isStrictly(ExpressionNode::Sign s, Context * context) const { return s == node()->sign(context) && node()->nullStatus(context) == ExpressionNode::NullStatus::NonNull; }
|
bool isStrictly(ExpressionNode::Sign s, Context * context) const { return s == node()->sign(context) && node()->nullStatus(context) == ExpressionNode::NullStatus::NonNull; }
|
||||||
bool isUndefined() const { return node()->type() == ExpressionNode::Type::Undefined || node()->type() == ExpressionNode::Type::Unreal; }
|
bool isUndefined() const { return node()->type() == ExpressionNode::Type::Undefined || node()->type() == ExpressionNode::Type::Unreal; }
|
||||||
bool isNumber() const { return node()->isNumber(); }
|
bool isNumber() const { return node()->isNumber(); }
|
||||||
|
|||||||
@@ -162,7 +162,10 @@ public:
|
|||||||
NonNull = 0,
|
NonNull = 0,
|
||||||
Null = 1,
|
Null = 1,
|
||||||
};
|
};
|
||||||
|
enum class IntegerStatus {
|
||||||
|
Unknown = -1,
|
||||||
|
Integer = 1,
|
||||||
|
};
|
||||||
class ComputationContext {
|
class ComputationContext {
|
||||||
public:
|
public:
|
||||||
ComputationContext(
|
ComputationContext(
|
||||||
@@ -233,6 +236,7 @@ public:
|
|||||||
|
|
||||||
virtual Sign sign(Context * context) const { return Sign::Unknown; }
|
virtual Sign sign(Context * context) const { return Sign::Unknown; }
|
||||||
virtual NullStatus nullStatus(Context * context) const { return NullStatus::Unknown; }
|
virtual NullStatus nullStatus(Context * context) const { return NullStatus::Unknown; }
|
||||||
|
virtual IntegerStatus integerStatus(Context * context) const { return IntegerStatus::Unknown; }
|
||||||
virtual bool isNumber() const { return false; }
|
virtual bool isNumber() const { return false; }
|
||||||
virtual bool isRandom() const { return false; }
|
virtual bool isRandom() const { return false; }
|
||||||
virtual bool isParameteredExpression() const { return false; }
|
virtual bool isParameteredExpression() const { return false; }
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public:
|
|||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
Type type() const override { return Type::Multiplication; }
|
Type type() const override { return Type::Multiplication; }
|
||||||
|
virtual IntegerStatus integerStatus(Context * context) const override;
|
||||||
Sign sign(Context * context) const override;
|
Sign sign(Context * context) const override;
|
||||||
int polynomialDegree(Context * context, const char * symbolName) const override;
|
int polynomialDegree(Context * context, const char * symbolName) const override;
|
||||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public:
|
|||||||
void setNegative(bool negative) { m_negative = negative; }
|
void setNegative(bool negative) { m_negative = negative; }
|
||||||
bool isInteger() const { return denominator().isOne(); }
|
bool isInteger() const { return denominator().isOne(); }
|
||||||
NullStatus nullStatus(Context * context) const override { return isZero() ? NullStatus::Null : NullStatus::NonNull; }
|
NullStatus nullStatus(Context * context) const override { return isZero() ? NullStatus::Null : NullStatus::NonNull; }
|
||||||
|
virtual IntegerStatus integerStatus(Context * context) const { return isInteger() ? IntegerStatus::Integer : IntegerStatus::Unknown; }
|
||||||
|
|
||||||
// TreeNode
|
// TreeNode
|
||||||
size_t size() const override;
|
size_t size() const override;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public:
|
|||||||
|
|
||||||
// Expression Properties
|
// Expression Properties
|
||||||
Type type() const override { return Type::Symbol; }
|
Type type() const override { return Type::Symbol; }
|
||||||
|
virtual IntegerStatus integerStatus(Context * context) const { return context->expressionTypeForIdentifier(m_name, strlen(m_name)) == Context::SymbolAbstractType::Integer ? IntegerStatus::Integer : IntegerStatus::Unknown; }
|
||||||
Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) override;
|
Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) override;
|
||||||
int polynomialDegree(Context * context, const char * symbolName) const override;
|
int polynomialDegree(Context * context, const char * symbolName) const override;
|
||||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
||||||
|
|||||||
@@ -57,6 +57,16 @@ bool AdditionNode::derivate(ReductionContext reductionContext, Expression symbol
|
|||||||
|
|
||||||
// Addition
|
// Addition
|
||||||
|
|
||||||
|
ExpressionNode::IntegerStatus AdditionNode::integerStatus(Context * context) const {
|
||||||
|
int nbOfChildren = numberOfChildren();
|
||||||
|
for (int i = 0; i < nbOfChildren; i++) {
|
||||||
|
if (childAtIndex(i)->integerStatus(context) != IntegerStatus::Integer) {
|
||||||
|
return IntegerStatus::Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return IntegerStatus::Integer;
|
||||||
|
}
|
||||||
|
|
||||||
const Number Addition::NumeralFactor(const Expression & e) {
|
const Number Addition::NumeralFactor(const Expression & e) {
|
||||||
if (e.type() == ExpressionNode::Type::Multiplication && e.childAtIndex(0).isNumber()) {
|
if (e.type() == ExpressionNode::Type::Multiplication && e.childAtIndex(0).isNumber()) {
|
||||||
Number result = e.childAtIndex(0).convert<Number>();
|
Number result = e.childAtIndex(0).convert<Number>();
|
||||||
|
|||||||
@@ -42,6 +42,16 @@ ExpressionNode::Sign MultiplicationNode::sign(Context * context) const {
|
|||||||
return (Sign)sign;
|
return (Sign)sign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExpressionNode::IntegerStatus MultiplicationNode::integerStatus(Context * context) const {
|
||||||
|
int nbOfChildren = numberOfChildren();
|
||||||
|
for (int i = 0; i < nbOfChildren; i++) {
|
||||||
|
if (childAtIndex(i)->integerStatus(context) != IntegerStatus::Integer) {
|
||||||
|
return IntegerStatus::Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return IntegerStatus::Integer;
|
||||||
|
}
|
||||||
|
|
||||||
int MultiplicationNode::polynomialDegree(Context * context, const char * symbolName) const {
|
int MultiplicationNode::polynomialDegree(Context * context, const char * symbolName) const {
|
||||||
int degree = 0;
|
int degree = 0;
|
||||||
for (ExpressionNode * c : children()) {
|
for (ExpressionNode * c : children()) {
|
||||||
|
|||||||
@@ -166,21 +166,8 @@ Expression Sequence::deepReplaceReplaceableSymbols(Context * context, bool * did
|
|||||||
|
|
||||||
Expression Sequence::replacedByDefinitionIfPossible(Context * context) {
|
Expression Sequence::replacedByDefinitionIfPossible(Context * context) {
|
||||||
// We try to replace the sequence by his definition ONLY if the index is an integer
|
// We try to replace the sequence by his definition ONLY if the index is an integer
|
||||||
bool canBeReplacedByExpression = false;
|
|
||||||
|
|
||||||
if (childAtIndex(0).type() == ExpressionNode::Type::Symbol) {
|
if (childAtIndex(0).integerStatus(context) != ExpressionNode::IntegerStatus::Integer) {
|
||||||
const char * symbolName = (childAtIndex(0).convert<SymbolAbstract>()).name();
|
|
||||||
if (context->expressionTypeForIdentifier(symbolName, strlen(symbolName)) == Context::SymbolAbstractType::Integer) {
|
|
||||||
canBeReplacedByExpression = true;
|
|
||||||
}
|
|
||||||
} else if (childAtIndex(0).type() == ExpressionNode::Type::Rational) {
|
|
||||||
Rational r = childAtIndex(0).convert<Rational>();
|
|
||||||
if (r.isInteger()) {
|
|
||||||
canBeReplacedByExpression = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!canBeReplacedByExpression) {
|
|
||||||
return Expression();
|
return Expression();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,12 +45,6 @@ Evaluation<T> SumAndProductNode::templatedApproximate(ApproximationContext appro
|
|||||||
}
|
}
|
||||||
nContext.setApproximationForVariable<T>((T)i);
|
nContext.setApproximationForVariable<T>((T)i);
|
||||||
Expression child = Expression(childAtIndex(0)).clone();
|
Expression child = Expression(childAtIndex(0)).clone();
|
||||||
if (child.type() == ExpressionNode::Type::Sequence) {
|
|
||||||
/* Since we cannot get the expression of a sequence term like we would for
|
|
||||||
* a function, we replace its potential abstract rank by the value it should
|
|
||||||
* have. We can then evaluate its value */
|
|
||||||
child.childAtIndex(0).replaceSymbolWithExpression(symbol, Float<T>::Builder(i));
|
|
||||||
}
|
|
||||||
approximationContext.setContext(&nContext);
|
approximationContext.setContext(&nContext);
|
||||||
result = evaluateWithNextTerm(T(), result, child.node()->approximate(T(), approximationContext), approximationContext.complexFormat());
|
result = evaluateWithNextTerm(T(), result, child.node()->approximate(T(), approximationContext), approximationContext.complexFormat());
|
||||||
if (result.isUndefined()) {
|
if (result.isUndefined()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user