[poincare] More matrix simplification when map/undefined

This commit is contained in:
Léa Saviot
2019-07-01 10:50:21 +02:00
committed by Émilie Feral
parent 476d4f0046
commit 51ee5d8e21
41 changed files with 107 additions and 114 deletions

View File

@@ -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;
};

View File

@@ -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);
};
}

View File

@@ -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);
};
}

View File

@@ -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,

View File

@@ -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;

View File

@@ -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);
};
}

View File

@@ -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);
};
}

View File

@@ -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);
};
}

View File

@@ -60,7 +60,7 @@ public:
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("int", 4, &UntypedBuilder);
// Expression
Expression shallowReduce();
Expression shallowReduce(Context & context);
};
}

View File

@@ -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()); }
};

View File

@@ -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()) {

View File

@@ -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;

View File

@@ -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();

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);
}