mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare] More matrix simplification when map/undefined
This commit is contained in:
@@ -43,7 +43,7 @@ public:
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("binomial", 2, &UntypedBuilderTwoChildren<BinomialCoefficient>);
|
||||
|
||||
// Expression
|
||||
Expression shallowReduce();
|
||||
Expression shallowReduce(Context & context);
|
||||
private:
|
||||
constexpr static int k_maxNValue = 300;
|
||||
};
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ceil", 1, &UntypedBuilderOneChild<Ceiling>);
|
||||
|
||||
Expression shallowReduce();
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
static Expression UntypedBuilder(Expression children);
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("diff", 3, &UntypedBuilder);
|
||||
|
||||
Expression shallowReduce();
|
||||
Expression shallowReduce(Context & context);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -133,9 +133,11 @@ public:
|
||||
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);
|
||||
/* 'characteristicXRange' tries to assess the range on x where the expression
|
||||
* (considered as a function on x) has an interesting evolution. For example,
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
Factorial(const FactorialNode * n) : Expression(n) {}
|
||||
static Factorial Builder(Expression child) { return TreeHandle::FixedArityBuilder<Factorial, FactorialNode>(&child, 1); }
|
||||
|
||||
Expression shallowReduce();
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression shallowBeautify();
|
||||
private:
|
||||
constexpr static int k_maxOperandValue = 100;
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("floor", 1, &UntypedBuilderOneChild<Floor>);
|
||||
|
||||
Expression shallowReduce();
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("frac", 1, &UntypedBuilderOneChild<FracPart>);
|
||||
|
||||
Expression shallowReduce();
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ private:
|
||||
class HyperbolicTrigonometricFunction : public Expression {
|
||||
public:
|
||||
HyperbolicTrigonometricFunction(const HyperbolicTrigonometricFunctionNode * n) : Expression(n) {}
|
||||
Expression shallowReduce();
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("int", 4, &UntypedBuilder);
|
||||
|
||||
// Expression
|
||||
Expression shallowReduce();
|
||||
Expression shallowReduce(Context & context);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ 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; }
|
||||
@@ -58,6 +59,7 @@ public:
|
||||
* - 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
|
||||
protected:
|
||||
NAryExpressionNode * node() const { return static_cast<NAryExpressionNode *>(Expression::node()); }
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ 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();
|
||||
return BinomialCoefficient(this).shallowReduce(context);
|
||||
}
|
||||
|
||||
Layout BinomialCoefficientNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
@@ -54,7 +54,7 @@ T BinomialCoefficientNode::compute(T k, T n) {
|
||||
}
|
||||
|
||||
|
||||
Expression BinomialCoefficient::shallowReduce() {
|
||||
Expression BinomialCoefficient::shallowReduce(Context & context) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
if (e.isUndefined()) {
|
||||
@@ -63,11 +63,11 @@ Expression BinomialCoefficient::shallowReduce() {
|
||||
}
|
||||
Expression c0 = childAtIndex(0);
|
||||
Expression c1 = childAtIndex(1);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c0.type() == ExpressionNode::Type::Matrix || c1.type() == ExpressionNode::Type::Matrix) {
|
||||
|
||||
if (SortedIsMatrix(c0, context) || SortedIsMatrix(c1, context)) {
|
||||
return Undefined::Builder();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (c0.type() == ExpressionNode::Type::Rational) {
|
||||
Rational r0 = static_cast<Rational&>(c0);
|
||||
if (!r0.integerDenominator().isOne() || r0.isNegative()) {
|
||||
|
||||
@@ -32,11 +32,11 @@ Complex<T> CeilingNode::computeOnComplex(const std::complex<T> c, Preferences::C
|
||||
}
|
||||
|
||||
Expression CeilingNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) {
|
||||
return Ceiling(this).shallowReduce();
|
||||
return Ceiling(this).shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
|
||||
Expression Ceiling::shallowReduce() {
|
||||
Expression Ceiling::shallowReduce(Context & context, Preferences::AngleUnit angleUnit) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
if (e.isUndefined()) {
|
||||
@@ -44,11 +44,9 @@ Expression Ceiling::shallowReduce() {
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
if (c.type() == ExpressionNode::Type::Constant) {
|
||||
Constant s = static_cast<Constant&>(c);
|
||||
Expression result;
|
||||
|
||||
@@ -42,11 +42,9 @@ Expression ComplexArgument::shallowReduce(Context & context, Preferences::Comple
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
bool real = c.isReal(context);
|
||||
if (real) {
|
||||
float app = c.node()->approximate(float(), context, complexFormat, angleUnit).toScalar();
|
||||
|
||||
@@ -265,7 +265,7 @@ 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();
|
||||
binom.shallowReduce(context);
|
||||
apow.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
bpow.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
if (i/2%2 == 1) {
|
||||
|
||||
@@ -62,11 +62,9 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Com
|
||||
}
|
||||
Expression c0 = childAtIndex(0);
|
||||
Expression c1 = childAtIndex(1);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c0.type() == ExpressionNode::Type::Matrix || c1.type() == ExpressionNode::Type::Matrix) {
|
||||
if (SortedIsMatrix(c0, context) || SortedIsMatrix(c1, context)) {
|
||||
return Undefined::Builder();
|
||||
}
|
||||
#endif
|
||||
if (c0.type() == ExpressionNode::Type::Rational) {
|
||||
Rational r0 = static_cast<Rational&>(c0);
|
||||
if (r0.signedIntegerNumerator().isNegative() || Integer::NaturalOrder(r0.signedIntegerNumerator(), r0.integerDenominator()) > 0) {
|
||||
|
||||
@@ -40,11 +40,9 @@ Expression Conjugate::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
if (c.isReal(context)) {
|
||||
replaceWithInPlace(c);
|
||||
return c;
|
||||
|
||||
@@ -41,12 +41,10 @@ Expression Cosine::shallowReduce(Context & context, Preferences::ComplexFormat c
|
||||
return e;
|
||||
}
|
||||
}
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
Expression op = childAtIndex(0);
|
||||
if (op.type() == ExpressionNode::Type::Matrix) {
|
||||
Expression c = childAtIndex(0);
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
return Trigonometry::shallowReduceDirectFunction(*this, context, complexFormat, angleUnit, target);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ int DerivativeNode::serialize(char * buffer, int bufferSize, Preferences::PrintF
|
||||
}
|
||||
|
||||
Expression DerivativeNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) {
|
||||
return Derivative(this).shallowReduce();
|
||||
return Derivative(this).shallowReduce(context);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -135,18 +135,19 @@ T DerivativeNode::riddersApproximation(Context & context, Preferences::ComplexFo
|
||||
return ans;
|
||||
}
|
||||
|
||||
Expression Derivative::shallowReduce() {
|
||||
Expression Derivative::shallowReduce(Context & context) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
if (e.isUndefined()) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Matrix || || childAtIndex(1).type() == ExpressionNode::Type::Matrix || childAtIndex(2).type() == ExpressionNode::Type::Matrix) {
|
||||
if (SortedIsMatrix(childAtIndex(0), context)
|
||||
|| SortedIsMatrix(childAtIndex(1), context)
|
||||
|| SortedIsMatrix(childAtIndex(2), context))
|
||||
{
|
||||
return Undefined::Builder();
|
||||
}
|
||||
#endif
|
||||
// TODO: to be implemented diff(+) -> +diff() etc
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -41,19 +41,12 @@ Expression Determinant::shallowReduce(Context & context) {
|
||||
}
|
||||
}
|
||||
Expression c0 = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
#if 0
|
||||
if (!op.recursivelyMatches(Expression::IsMatrix)) {
|
||||
return replaceWith(op, true);
|
||||
}
|
||||
return this;
|
||||
#endif
|
||||
#endif
|
||||
// det(A) = A if A is not a matrix
|
||||
if (!c0.recursivelyMatches(Expression::IsMatrix, context, true)) {
|
||||
if (!SortedIsMatrix(c0, context)) {
|
||||
replaceWithInPlace(c0);
|
||||
return c0;
|
||||
}
|
||||
//TODO LEA for matrix
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,10 @@ bool Expression::IsRandom(const Expression e, Context & context) {
|
||||
return e.isRandom();
|
||||
}
|
||||
|
||||
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) {
|
||||
return e.type() == ExpressionNode::Type::Matrix
|
||||
|| e.type() == ExpressionNode::Type::ConfidenceInterval
|
||||
@@ -116,6 +120,17 @@ bool Expression::IsMatrix(const Expression e, Context & context) {
|
||||
|| e.type() == ExpressionNode::Type::MatrixTranspose;
|
||||
}
|
||||
|
||||
bool Expression::SortedIsMatrix(const Expression e, Context & context) {
|
||||
// TODO should we replace symbols?
|
||||
if (IsMatrix(e, context)) {
|
||||
return true;
|
||||
}
|
||||
if (IsNAry(e, context)) {
|
||||
return NAryExpression::SortedIsMatrix(e, context);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Expression::IsInfinity(const Expression e, Context & context) {
|
||||
return e.type() == ExpressionNode::Type::Infinity;
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat
|
||||
}
|
||||
|
||||
Multiplication Factor::createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
||||
//TODO LEA Matrices?
|
||||
assert(!i.isZero());
|
||||
assert(!i.isNegative());
|
||||
Multiplication m = Multiplication::Builder();
|
||||
|
||||
@@ -35,7 +35,7 @@ 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();
|
||||
return Factorial(this).shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
Expression FactorialNode::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) {
|
||||
@@ -77,20 +77,19 @@ int FactorialNode::serialize(char * buffer, int bufferSize, Preferences::PrintFl
|
||||
}
|
||||
|
||||
|
||||
Expression Factorial::shallowReduce() {
|
||||
Expression Factorial::shallowReduce(Context & context, Preferences::AngleUnit angleUnit) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
if (e.isUndefined()) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) {
|
||||
Expression c = childAtIndex(0);
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Rational) {
|
||||
Rational r = childAtIndex(0).convert<Rational>();
|
||||
if (c.type() == ExpressionNode::Type::Rational) {
|
||||
Rational r = c.convert<Rational>();
|
||||
if (!r.integerDenominator().isOne() || r.sign() == ExpressionNode::Sign::Negative) {
|
||||
Expression result = Undefined::Builder();
|
||||
replaceWithInPlace(result);
|
||||
@@ -104,7 +103,7 @@ Expression Factorial::shallowReduce() {
|
||||
replaceWithInPlace(fact);
|
||||
return fact;
|
||||
}
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Constant) {
|
||||
if (c.type() == ExpressionNode::Type::Constant) {
|
||||
// e! = undef, i! = undef, pi! = undef
|
||||
Expression result = Undefined::Builder();
|
||||
replaceWithInPlace(result);
|
||||
|
||||
@@ -32,11 +32,10 @@ Complex<T> FloorNode::computeOnComplex(const std::complex<T> c, Preferences::Com
|
||||
}
|
||||
|
||||
Expression FloorNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) {
|
||||
return Floor(this).shallowReduce();
|
||||
return Floor(this).shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
|
||||
Expression Floor::shallowReduce() {
|
||||
Expression Floor::shallowReduce(Context & context, Preferences::AngleUnit angleUnit) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
if (e.isUndefined()) {
|
||||
@@ -44,11 +43,9 @@ Expression Floor::shallowReduce() {
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
if (c.type() == ExpressionNode::Type::Constant) {
|
||||
Constant s = static_cast<Constant &>(c);
|
||||
Expression result;
|
||||
|
||||
@@ -20,7 +20,7 @@ int FracPartNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo
|
||||
}
|
||||
|
||||
Expression FracPartNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) {
|
||||
return FracPart(this).shallowReduce();
|
||||
return FracPart(this).shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -32,7 +32,7 @@ Complex<T> FracPartNode::computeOnComplex(const std::complex<T> c, Preferences::
|
||||
}
|
||||
|
||||
|
||||
Expression FracPart::shallowReduce() {
|
||||
Expression FracPart::shallowReduce(Context & context, Preferences::AngleUnit angleUnit) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
if (e.isUndefined()) {
|
||||
@@ -40,11 +40,9 @@ Expression FracPart::shallowReduce() {
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
if (c.type() != ExpressionNode::Type::Rational) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ Complex<T> HyperbolicArcCosineNode::computeOnComplex(const std::complex<T> c, Pr
|
||||
return Complex<T>::Builder(Trigonometry::RoundToMeaningfulDigits(result, c));
|
||||
}
|
||||
|
||||
|
||||
template Complex<float> Poincare::HyperbolicArcCosineNode::computeOnComplex<float>(std::complex<float>, Preferences::ComplexFormat, Preferences::AngleUnit);
|
||||
template Complex<double> Poincare::HyperbolicArcCosineNode::computeOnComplex<double>(std::complex<double>, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ constexpr Expression::FunctionHelper HyperbolicArcSine::s_functionHelper;
|
||||
Layout HyperbolicArcSineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return LayoutHelper::Prefix(HyperbolicArcSine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicArcSine::s_functionHelper.name());
|
||||
}
|
||||
|
||||
int HyperbolicArcSineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicArcSine::s_functionHelper.name());
|
||||
}
|
||||
@@ -29,7 +30,6 @@ Complex<T> HyperbolicArcSineNode::computeOnComplex(const std::complex<T> c, Pref
|
||||
return Complex<T>::Builder(Trigonometry::RoundToMeaningfulDigits(result, c));
|
||||
}
|
||||
|
||||
|
||||
template Complex<float> Poincare::HyperbolicArcSineNode::computeOnComplex<float>(std::complex<float>, Preferences::ComplexFormat, Preferences::AngleUnit);
|
||||
template Complex<double> Poincare::HyperbolicArcSineNode::computeOnComplex<double>(std::complex<double>, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit);
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ Complex<T> HyperbolicArcTangentNode::computeOnComplex(const std::complex<T> c, P
|
||||
return Complex<T>::Builder(Trigonometry::RoundToMeaningfulDigits(result, c));
|
||||
}
|
||||
|
||||
|
||||
template Complex<float> Poincare::HyperbolicArcTangentNode::computeOnComplex<float>(std::complex<float>, Preferences::ComplexFormat, Preferences::AngleUnit);
|
||||
template Complex<double> Poincare::HyperbolicArcTangentNode::computeOnComplex<double>(std::complex<double>, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ constexpr Expression::FunctionHelper HyperbolicCosine::s_functionHelper;
|
||||
Layout HyperbolicCosineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return LayoutHelper::Prefix(HyperbolicCosine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicCosine::s_functionHelper.name());
|
||||
}
|
||||
|
||||
int HyperbolicCosineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicCosine::s_functionHelper.name());
|
||||
}
|
||||
@@ -18,7 +19,6 @@ Complex<T> HyperbolicCosineNode::computeOnComplex(const std::complex<T> c, Prefe
|
||||
return Complex<T>::Builder(Trigonometry::RoundToMeaningfulDigits(std::cosh(c), c));
|
||||
}
|
||||
|
||||
|
||||
template Complex<float> Poincare::HyperbolicCosineNode::computeOnComplex<float>(std::complex<float>, Preferences::ComplexFormat, Preferences::AngleUnit);
|
||||
template Complex<double> Poincare::HyperbolicCosineNode::computeOnComplex<double>(std::complex<double>, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ constexpr Expression::FunctionHelper HyperbolicSine::s_functionHelper;
|
||||
Layout HyperbolicSineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return LayoutHelper::Prefix(HyperbolicSine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicSine::s_functionHelper.name());
|
||||
}
|
||||
|
||||
int HyperbolicSineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicSine::s_functionHelper.name());
|
||||
}
|
||||
@@ -18,7 +19,6 @@ Complex<T> HyperbolicSineNode::computeOnComplex(const std::complex<T> c, Prefere
|
||||
return Complex<T>::Builder(Trigonometry::RoundToMeaningfulDigits(std::sinh(c), c));
|
||||
}
|
||||
|
||||
|
||||
template Complex<float> Poincare::HyperbolicSineNode::computeOnComplex<float>(std::complex<float>, Preferences::ComplexFormat, Preferences::AngleUnit);
|
||||
template Complex<double> Poincare::HyperbolicSineNode::computeOnComplex<double>(std::complex<double>, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ constexpr Expression::FunctionHelper HyperbolicTangent::s_functionHelper;
|
||||
Layout HyperbolicTangentNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return LayoutHelper::Prefix(HyperbolicTangent(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicTangent::s_functionHelper.name());
|
||||
}
|
||||
|
||||
int HyperbolicTangentNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicTangent::s_functionHelper.name());
|
||||
}
|
||||
@@ -18,7 +19,6 @@ Complex<T> HyperbolicTangentNode::computeOnComplex(const std::complex<T> c, Pref
|
||||
return Complex<T>::Builder(Trigonometry::RoundToMeaningfulDigits(std::tanh(c), c));
|
||||
}
|
||||
|
||||
|
||||
template Complex<float> Poincare::HyperbolicTangentNode::computeOnComplex<float>(std::complex<float>, Preferences::ComplexFormat, Preferences::AngleUnit);
|
||||
template Complex<double> Poincare::HyperbolicTangentNode::computeOnComplex<double>(std::complex<double>, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit);
|
||||
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
#include <poincare/hyperbolic_trigonometric_function.h>
|
||||
#include <poincare/simplification_helper.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
Expression HyperbolicTrigonometricFunctionNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) {
|
||||
return HyperbolicTrigonometricFunction(this).shallowReduce();
|
||||
return HyperbolicTrigonometricFunction(this).shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
Expression HyperbolicTrigonometricFunction::shallowReduce() {
|
||||
Expression HyperbolicTrigonometricFunction::shallowReduce(Context & context, Preferences::AngleUnit angleUnit) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
if (e.isUndefined()) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
Expression c = childAtIndex(0);
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,11 +32,9 @@ Expression ImaginaryPart::shallowReduce(Context & context, Preferences::ComplexF
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
if (c.isReal(context)) {
|
||||
Expression result = Rational::Builder(0);
|
||||
replaceWithInPlace(result);
|
||||
|
||||
@@ -40,7 +40,7 @@ int IntegralNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo
|
||||
}
|
||||
|
||||
Expression IntegralNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, bool symbolicComputation) {
|
||||
return Integral(this).shallowReduce();
|
||||
return Integral(this).shallowReduce(context);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -213,22 +213,20 @@ Expression Integral::UntypedBuilder(Expression children) {
|
||||
return Builder(children.childAtIndex(0), children.childAtIndex(1).convert<Symbol>(), children.childAtIndex(2), children.childAtIndex(3));
|
||||
}
|
||||
|
||||
Expression Integral::shallowReduce() {
|
||||
Expression Integral::shallowReduce(Context & context) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
if (e.isUndefined()) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Matrix
|
||||
|| childAtIndex(1).type() == ExpressionNode::Type::Matrix
|
||||
|| childAtIndex(2).type() == ExpressionNode::Type::Matrix
|
||||
|| childAtIndex(3).type() == ExpressionNode::Type::Matrix)
|
||||
if (SortedIsMatrix(childAtIndex(0), context)
|
||||
|| SortedIsMatrix(childAtIndex(1), context)
|
||||
|| SortedIsMatrix(childAtIndex(2), context)
|
||||
|| SortedIsMatrix(childAtIndex(3), context))
|
||||
{
|
||||
return Undefined::Builder();
|
||||
}
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,13 +94,9 @@ Expression CommonLogarithm::shallowReduce(Context & context, Preferences::Comple
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
#if 0
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(this, context, angleUnit);
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Logarithm log = Logarithm::Builder(childAtIndex(0), Rational::Builder(10));
|
||||
replaceWithInPlace(log);
|
||||
return log.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
@@ -113,14 +109,12 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
return e;
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
#if 0
|
||||
if (c.type() == ExpressionNode::Type::Matrix || childAtIndex(1).type() == ExpressionNode::Type::Matrix) {
|
||||
|
||||
if (SortedIsMatrix(childAtIndex(1), context)) {
|
||||
return Undefined::Builder();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Expression c = childAtIndex(0);
|
||||
if (c.sign(&context) == ExpressionNode::Sign::Negative || childAtIndex(1).sign(&context) == ExpressionNode::Sign::Negative) {
|
||||
return *this;
|
||||
}
|
||||
@@ -136,9 +130,12 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
* information on the parent which could later be a power of b.
|
||||
*/
|
||||
bool letLogAtRoot = parentIsAPowerOfSameBase();
|
||||
if (letLogAtRoot) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// log(+inf, a) ?
|
||||
if (!letLogAtRoot && c.type() == ExpressionNode::Type::Infinity && c.sign(&context) == ExpressionNode::Sign::Positive) {
|
||||
if (c.type() == ExpressionNode::Type::Infinity && c.sign(&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<Rational&>(base).isNegative() && !static_cast<Rational&>(base).isZero()) {
|
||||
@@ -156,7 +153,7 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
}
|
||||
|
||||
// log(x^y, b)->y*log(x, b) if x>0
|
||||
if (!letLogAtRoot && c.type() == ExpressionNode::Type::Power && c.childAtIndex(0).sign(&context) == ExpressionNode::Sign::Positive) {
|
||||
if (c.type() == ExpressionNode::Type::Power && c.childAtIndex(0).sign(&context) == ExpressionNode::Sign::Positive) {
|
||||
Power p = static_cast<Power &>(c);
|
||||
Expression x = p.childAtIndex(0);
|
||||
Expression y = p.childAtIndex(1);
|
||||
@@ -168,7 +165,7 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
return mult.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
// log(x*y, b)->log(x,b)+log(y, b) if x,y>0
|
||||
if (!letLogAtRoot && c.type() == ExpressionNode::Type::Multiplication) {
|
||||
if (c.type() == ExpressionNode::Type::Multiplication) {
|
||||
Addition a = Addition::Builder();
|
||||
for (int i = 0; i < c.numberOfChildren()-1; i++) {
|
||||
Expression factor = c.childAtIndex(i);
|
||||
@@ -189,7 +186,7 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
}
|
||||
}
|
||||
// log(r) with r Rational
|
||||
if (!letLogAtRoot && c.type() == ExpressionNode::Type::Rational) {
|
||||
if (c.type() == ExpressionNode::Type::Rational) {
|
||||
Rational r = static_cast<Rational &>(c);
|
||||
Addition a = Addition::Builder();
|
||||
// if the log base is Integer: log_b(r) = c + log_b(r') with r = b^c*r'
|
||||
@@ -205,6 +202,12 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma
|
||||
replaceWithInPlace(a);
|
||||
return a.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
|
||||
// log(m) with m Matrix
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -95,4 +95,13 @@ int NAryExpression::allChildrenAreReal(Context & context) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NAryExpression::SortedIsMatrix(Expression e, Context & context) {
|
||||
assert(IsNAry(e, context));
|
||||
int childrenCount = e.numberOfChildren();
|
||||
if (childrenCount > 0) {
|
||||
return SortedIsMatrix(e.childAtIndex(childrenCount - 1), context);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,12 +30,11 @@ Expression NaperianLogarithm::shallowReduce(Context & context, Preferences::Comp
|
||||
return e;
|
||||
}
|
||||
}
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) {
|
||||
Expression c = childAtIndex(0);
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
Logarithm l = Logarithm::Builder(childAtIndex(0), Constant::Builder(UCodePointScriptSmallE));
|
||||
Logarithm l = Logarithm::Builder(c, Constant::Builder(UCodePointScriptSmallE));
|
||||
replaceWithInPlace(l);
|
||||
return l.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
}
|
||||
|
||||
@@ -79,8 +79,6 @@ Expression Opposite::shallowReduce(Context & context, Preferences::ComplexFormat
|
||||
return result;
|
||||
}
|
||||
Expression child = result.childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
#endif
|
||||
result = Multiplication::Builder(Rational::Builder(-1), child);
|
||||
replaceWithInPlace(result);
|
||||
return result.shallowReduce(context, complexFormat, angleUnit, target);
|
||||
|
||||
@@ -33,11 +33,9 @@ Expression RealPart::shallowReduce(Context & context, Preferences::ComplexFormat
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
if (c.isReal(context)) {
|
||||
replaceWithInPlace(c);
|
||||
return c;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/serialization_helper.h>
|
||||
#include <poincare/simplification_helper.h>
|
||||
#include <ion.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
@@ -59,13 +60,11 @@ Expression SignFunction::shallowReduce(Context & context, Preferences::ComplexFo
|
||||
return e;
|
||||
}
|
||||
}
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
Expression child = childAtIndex(0);
|
||||
if (child.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
Rational resultSign = Rational::Builder(1);
|
||||
Expression child = childAtIndex(0);
|
||||
ExpressionNode::Sign s = child.sign(&context);
|
||||
if (s == ExpressionNode::Sign::Negative) {
|
||||
resultSign = Rational::Builder(-1);
|
||||
|
||||
@@ -42,12 +42,9 @@ Expression Sine::shallowReduce(Context & context, Preferences::ComplexFormat com
|
||||
return e;
|
||||
}
|
||||
}
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
Expression op = childAtIndex(0);
|
||||
if (op.type() == ExpressionNode::Type::Matrix) {
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
return Trigonometry::shallowReduceDirectFunction(*this, context, complexFormat, angleUnit, target);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,7 @@ Expression Tangent::shallowReduce(Context & context, Preferences::ComplexFormat
|
||||
}
|
||||
}
|
||||
|
||||
Expression op = childAtIndex(0);
|
||||
if (op.type() == ExpressionNode::Type::Matrix) {
|
||||
if (childAtIndex(0).type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user