[poincare] First version of Simplification with matrix (no tests yet!)

Change-Id: I28ad4750ad31995836b23725f7d715669fcb7ae2
This commit is contained in:
Émilie Feral
2017-11-09 11:14:38 +01:00
parent 8aa4444337
commit d5fc8d139f
145 changed files with 1972 additions and 1331 deletions

View File

@@ -1,4 +1,4 @@
include apps/calculation/Makefile
#include apps/calculation/Makefile
include apps/graph/Makefile
include apps/home/Makefile
include apps/hardware_test/Makefile

View File

@@ -14,7 +14,6 @@ objs += $(addprefix poincare/src/,\
ceiling.o\
complex.o\
complex_argument.o\
complex_matrix.o\
confidence_interval.o\
conjugate.o\
cosine.o\
@@ -25,7 +24,6 @@ objs += $(addprefix poincare/src/,\
division_quotient.o\
division_remainder.o\
dynamic_hierarchy.o\
evaluation.o\
evaluation_engine.o\
expression.o\
expression_lexer.o\
@@ -33,7 +31,6 @@ objs += $(addprefix poincare/src/,\
factorial.o\
floor.o\
frac_part.o\
expression_matrix.o\
global_context.o\
great_common_divisor.o\
hierarchy.o\
@@ -70,6 +67,7 @@ objs += $(addprefix poincare/src/,\
real_part.o\
round.o\
sequence.o\
simplification_engine.o\
sine.o\
square_root.o\
static_hierarchy.o\

View File

@@ -12,7 +12,6 @@
#include <poincare/ceiling.h>
#include <poincare/complex.h>
#include <poincare/complex_argument.h>
#include <poincare/complex_matrix.h>
#include <poincare/confidence_interval.h>
#include <poincare/conjugate.h>
#include <poincare/context.h>
@@ -23,13 +22,11 @@
#include <poincare/division.h>
#include <poincare/division_quotient.h>
#include <poincare/division_remainder.h>
#include <poincare/evaluation.h>
#include <poincare/expression.h>
#include <poincare/expression_layout.h>
#include <poincare/factorial.h>
#include <poincare/floor.h>
#include <poincare/frac_part.h>
#include <poincare/expression_matrix.h>
#include <poincare/global_context.h>
#include <poincare/great_common_divisor.h>
#include <poincare/hyperbolic_arc_cosine.h>

View File

@@ -15,17 +15,20 @@ public:
Sign sign() const override { return Sign::Positive; }
private:
Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override {
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "abs");
}
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
virtual Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit, computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
virtual Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};

View File

@@ -18,12 +18,6 @@ public:
Expression * clone() const override;
/* Evaluation */
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
template<typename T> static Evaluation<T> * computeOnMatrices(Evaluation<T> * m, Evaluation<T> * n) {
return EvaluationEngine::elementWiseOnComplexMatrices(m, n, compute<T>);
}
template<typename T> static Evaluation<T> * computeOnComplexAndMatrix(const Complex<T> * c, Evaluation<T> * m) {
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
}
private:
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
@@ -42,14 +36,11 @@ private:
static const Rational RationalFactor(Expression * e);
static bool TermsHaveIdenticalNonRationalFactors(const Expression * e1, const Expression * e2);
/* Evaluation */
template<typename T> static Evaluation<T> * computeOnMatrixAndComplex(Evaluation<T> * m, const Complex<T> * c) {
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>);
}
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>);
}
};

View File

@@ -27,11 +27,11 @@ private:
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
virtual Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
virtual Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};

View File

@@ -25,11 +25,11 @@ private:
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};

View File

@@ -25,11 +25,11 @@ private:
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};

View File

@@ -12,13 +12,17 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override {
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "binomial");
}
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};
}

View File

@@ -13,13 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +21,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "ceil"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit, computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -1,8 +1,8 @@
#ifndef POINCARE_COMPLEX_H
#define POINCARE_COMPLEX_H
#include <poincare/evaluation.h>
#include <poincare/preferences.h>
#include <poincare/static_hierarchy.h>
#include <assert.h>
namespace Poincare {
@@ -23,7 +23,7 @@ namespace PrintFloat {
}
template<typename T>
class Complex : public Evaluation<T> {
class Complex : public StaticHierarchy<0> {
public:
Complex() : m_a(0), m_b(0) {}
static Complex<T> Float(T x);
@@ -32,33 +32,21 @@ public:
Complex(const char * integralPart, int integralPartLength, bool integralNegative,
const char * fractionalPart, int fractionalPartLength,
const char * exponent, int exponentLength, bool exponentNegative);
Complex(const Complex & other);
Complex& operator=(const Complex& other);
T a() const;
T b() const;
T r() const;
T th() const;
Complex<T> conjugate() const;
T toScalar() const;
/* Expression */
Expression::Type type() const override;
Complex<T> * clone() const override;
void replaceOperand(const Expression * oldOperand, Expression * newOperand, bool deleteOldOperand) override {
assert(false);
}
void swapOperands(int i, int j) override { assert(false); }
/* Evaluation */
T toScalar() const override;
int numberOfRows() const override;
int numberOfColumns() const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override;
Evaluation<T> * createDeterminant() const override {
return clone();
}
Evaluation<T> * createInverse() const override;
Evaluation<T> * createTrace() const override {
return clone();
}
/* The parameter 'DisplayMode' refers to the way to display float 'scientific'
* or 'auto'. The scientific mode returns float with style -1.2E2 whereas
* the auto mode tries to return 'natural' float like (0.021) and switches
@@ -73,12 +61,11 @@ public:
static int convertFloatToText(T d, char * buffer, int bufferSize, int numberOfSignificantDigits, Expression::FloatDisplayMode mode = Expression::FloatDisplayMode::Default);
private:
Complex(T a, T b);
const Complex<T> * complexOperand(int i) const override;
constexpr static int k_numberOfSignificantDigits = 7;
ExpressionLayout * privateCreateLayout(Expression::FloatDisplayMode floatDisplayMode, Expression::ComplexFormat complexFormat) const override;
Evaluation<float> * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename U> Evaluation<U> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
Complex<float> * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename U> Complex<U> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
/* We here define the buffer size to write the lengthest float possible.
* At maximum, the number has 7 significant digits so, in the worst case it
* has the form -1.999999e-308 (7+7+1 char) (the auto mode is always

View File

@@ -13,13 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +21,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "arg"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -1,50 +0,0 @@
#ifndef POINCARE_COMPLEX_MATRIX_H
#define POINCARE_COMPLEX_MATRIX_H
#include <poincare/evaluation.h>
#include <assert.h>
namespace Poincare {
template<typename T>
class ComplexMatrix : public Evaluation<T> {
public:
ComplexMatrix(const Complex<T> * complexes, int numberOfRows, int numberOfColumns);
~ComplexMatrix();
ComplexMatrix(const ComplexMatrix& other) = delete;
ComplexMatrix(ComplexMatrix&& other) = delete;
ComplexMatrix& operator=(const ComplexMatrix& other) = delete;
ComplexMatrix& operator=(ComplexMatrix&& other) = delete;
/* Expression */
Expression::Type type() const override;
ComplexMatrix<T> * clone() const override;
// TODO: Remove these 2 functions
void replaceOperand(const Expression * oldOperand, Expression * newOperand, bool deleteOldOperand) override {
assert(false);
}
void swapOperands(int i, int j) override { assert(false); }
/* Evaluation */
T toScalar() const override;
int numberOfRows() const override;
int numberOfColumns() const override;
const Complex<T> * complexOperand(int i) const override;
/* If the buffer is too small, the function fills the buffer until reaching
* buffer size */
static Evaluation<T> * createIdentity(int dim);
private:
Evaluation<float> * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename U> Evaluation<U> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
Complex<T> * m_values;
int m_numberOfRows;
int m_numberOfColumns;
};
}
#endif

View File

@@ -12,9 +12,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -22,6 +20,11 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "confidence"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { assert(false); return nullptr; }
Complex<double> * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { assert(false); return nullptr; }
};
}

View File

@@ -13,17 +13,21 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override {
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "conjugate");
}
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -16,13 +16,7 @@ public:
Expression * clone() const override;
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit = AngleUnit::Radian);
private:
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -30,6 +24,15 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "cos"; }
/* Simplication */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -21,15 +21,17 @@ public:
Expression * clone() const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int numberOfDigitsInMantissa() const;
/* Sorting */
/* Comparison */
int simplificationOrderSameType(const Expression * e) const override;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
constexpr static int k_maxLength = 10;
Integer m_mantissa;

View File

@@ -13,11 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
template<typename T> T growthRateAroundAbscissa(T x, T h, VariableContext<T> variableContext, AngleUnit angleUnit) const;
template<typename T> T approximateDerivate2(T x, T h, VariableContext<T> xContext, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -25,6 +21,14 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "diff"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
template<typename T> T growthRateAroundAbscissa(T x, T h, VariableContext<T> variableContext, AngleUnit angleUnit) const;
template<typename T> T approximateDerivate2(T x, T h, VariableContext<T> xContext, AngleUnit angleUnit) const;
// TODO: Change coefficients?
constexpr static double k_maxErrorRateOnApproximation = 0.001;
constexpr static double k_minInitialRate = 0.01;

View File

@@ -3,6 +3,7 @@
#include <poincare/layout_engine.h>
#include <poincare/static_hierarchy.h>
#include <poincare/complex.h>
namespace Poincare {
@@ -12,9 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -22,6 +21,11 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "det"; }
/* Simplification */
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { assert(false); return nullptr; }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { assert(false); return nullptr; }
};
}

View File

@@ -16,22 +16,18 @@ public:
Expression * clone() const override;
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
private:
template<typename T> static Evaluation<T> * computeOnMatrixAndComplex(Evaluation<T> * m, const Complex<T> * c) {
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
}
template<typename T> static Evaluation<T> * computeOnComplexAndMatrix(const Complex<T> * c, Evaluation<T> * n);
template<typename T> static Evaluation<T> * computeOnMatrices(Evaluation<T> * m, Evaluation<T> * n);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
}
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override;
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
virtual Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>);
}
virtual Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>);
}
};
}

View File

@@ -12,9 +12,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -22,6 +20,12 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "quo"; }
/* Simplification */
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};
}

View File

@@ -12,9 +12,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -22,6 +20,13 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "rem"; }
/* Simplification */
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};
}

View File

@@ -28,12 +28,13 @@ public:
typedef int (*ExpressionOrder)(const Expression * e1, const Expression * e2);
void sortOperands(ExpressionOrder order);
Expression * squashUnaryHierarchy();
protected:
const Expression ** m_operands;
int m_numberOfOperands;
private:
void removeOperandAtIndex(int i, bool deleteAfterRemoval);
int simplificationOrderSameType(const Expression * e) const override;
int simplificationOrderGreaterType(const Expression * e) const override;
const Expression ** m_operands;
int m_numberOfOperands;
};
}

View File

@@ -1,26 +0,0 @@
#ifndef POINCARE_EVALUATION_H
#define POINCARE_EVALUATION_H
#include <poincare/matrix.h>
namespace Poincare {
template<class T>
class Complex;
template<typename T>
class Evaluation : public Matrix {
public:
virtual T toScalar() const = 0;
virtual const Expression * operand(int i) const override;
virtual const Complex<T> * complexOperand(int i) const = 0;
virtual Evaluation<T> * clone() const override = 0;
virtual Evaluation<T> * createTrace() const;
virtual Evaluation<T> * createDeterminant() const;
virtual Evaluation<T> * createInverse() const;
Evaluation<T> * createTranspose() const;
};
}
#endif

View File

@@ -2,25 +2,17 @@
#define POINCARE_EVALUATION_ENGINE_H
#include <poincare/expression.h>
#include <poincare/evaluation.h>
#include <poincare/complex.h>
namespace Poincare {
class EvaluationEngine {
public:
template <typename T> using ExpressionToComplexMap = Complex<T>(*)(const Complex<T>, Expression::AngleUnit angleUnit);
template<typename T> static Evaluation<T> * map(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ExpressionToComplexMap<T> compute);
template <typename T> using ComplexCompute = Complex<T> (*)(const Complex<T>, Expression::AngleUnit angleUnit);
template<typename T> static Complex<T> * approximate(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexCompute<T> compute);
template <typename T> using ComplexAndComplexReduction = Complex<T>(*)(const Complex<T>, const Complex<T>);
template <typename T> using ComplexAndMatrixReduction = Evaluation<T> * (*)(const Complex<T> * c, Evaluation<T> * m);
template <typename T> using MatrixAndComplexReduction = Evaluation<T> * (*)(Evaluation<T> * m, const Complex<T> * c);
template <typename T> using MatrixAndMatrixReduction = Evaluation<T> * (*)(Evaluation<T> * m, Evaluation<T> * n);
template<typename T> static Evaluation<T> * mapReduce(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices);
template<typename T> static Evaluation<T> * elementWiseOnComplexAndComplexMatrix(const Complex<T> * c, Evaluation<T> * n, ComplexAndComplexReduction<T> computeOnComplexes);
template<typename T> static Evaluation<T> * elementWiseOnComplexMatrices(Evaluation<T> * m, Evaluation<T> * n, ComplexAndComplexReduction<T> computeOnComplexes);
template<typename T> static Complex<T> * mapReduce(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes);
};
}

View File

@@ -9,8 +9,7 @@ extern "C" {
namespace Poincare {
class Context;
template<class T>
class Evaluation;
template<class T> class Complex;
class Rational;
class Expression {
@@ -85,6 +84,8 @@ public:
Power,
Addition,
Factorial,
Division,
Store,
Sine,
Cosine,
Tangent,
@@ -99,7 +100,6 @@ public:
Conjugate,
Derivative,
Determinant,
Division,
DivisionQuotient,
DivisionRemainder,
Floor,
@@ -129,14 +129,12 @@ public:
RealPart,
Round,
SquareRoot,
Store,
Subtraction,
Sum,
Symbol,
Complex,
ComplexMatrix,
ExpressionMatrix,
Matrix,
SimplificationRoot,
};
enum class FloatDisplayMode {
@@ -209,7 +207,7 @@ public:
/* Evaluation Engine
* The function evaluate creates a new expression and thus mallocs memory.
* Do not forget to delete the new expression to avoid leaking. */
template<typename T> Evaluation<T> * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Default) const;
template<typename T> Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Default) const;
template<typename T> T approximate(Context& context, AngleUnit angleUnit = AngleUnit::Default) const;
template<typename T> static T approximate(const char * text, Context& context, AngleUnit angleUnit = AngleUnit::Default);
protected:
@@ -219,6 +217,7 @@ protected:
typedef float SinglePrecision;
typedef double DoublePrecision;
template<typename T> static T epsilon();
constexpr static float k_maxNumberOfSteps = 10000.0f;
/* Simplification */
/* SimplificationOrder returns:
@@ -247,7 +246,7 @@ private:
/* Layout Engine */
virtual ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const = 0;
/* Simplification */
static void Reduce(Expression ** expressionAddress, Context & context, AngleUnit angleUnit);
static void Reduce(Expression ** expressionAddress, Context & context, AngleUnit angleUnit, bool recursively = true);
Expression * deepBeautify(Context & context, AngleUnit angleUnit);
Expression * deepReduce(Context & context, AngleUnit angleUnit);
// TODO: should be virtual pure
@@ -262,8 +261,8 @@ private:
static const Rational * RadicandInExpression(const Expression * e);
static const Rational * RationalFactorInExpression(const Expression * e);
/* Evaluation Engine */
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const = 0;
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const = 0;
virtual Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const = 0;
virtual Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const = 0;
Expression * m_parent;
};

View File

@@ -1,42 +0,0 @@
#ifndef POINCARE_EXPRESSION_MATRIX_H
#define POINCARE_EXPRESSION_MATRIX_H
#include <poincare/matrix.h>
#include <assert.h>
namespace Poincare {
class ExpressionMatrix : public Matrix {
public:
ExpressionMatrix(MatrixData * matrixData);
ExpressionMatrix(Expression ** newOperands, int numberOfOperands, int m_numberOfRows, int m_numberOfColumns, bool cloneOperands);
~ExpressionMatrix();
ExpressionMatrix(const Matrix& other) = delete;
ExpressionMatrix(Matrix&& other) = delete;
ExpressionMatrix& operator=(const ExpressionMatrix& other) = delete;
ExpressionMatrix& operator=(ExpressionMatrix&& other) = delete;
/* Expression */
Type type() const override;
Expression * clone() const override;
// TODO: Remove these 2 functions
void replaceOperand(const Expression * oldOperand, Expression * newOperand, bool deleteOldOperand) override {
assert(false);
}
void swapOperands(int i, int j) override { assert(false); }
/* Evaluation */
int numberOfRows() const override;
int numberOfColumns() const override;
const Expression * operand(int i) const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
MatrixData * m_matrixData;
};
}
#endif

View File

@@ -12,12 +12,13 @@ public:
Type type() const override;
Expression * clone() const override;
private:
constexpr static int k_maxOperandValue = 100;
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;

View File

@@ -13,13 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +21,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "floor"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit, computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -13,13 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +21,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "frac"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit, computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -2,8 +2,8 @@
#define POINCARE_GLOBAL_CONTEXT_H
#include <poincare/context.h>
#include <poincare/matrix.h>
#include <poincare/complex.h>
#include <poincare/complex_matrix.h>
namespace Poincare {
@@ -21,10 +21,7 @@ public:
GlobalContext& operator=(GlobalContext&& other) = delete;
/* The expression recorded in global context is already a expression.
* Otherwise, we would need the context and the angle unit to evaluate it */
const Expression * expressionForSymbol(const Symbol * symbol) override {
return evaluationForSymbol(symbol);
}
const Evaluation<double> * evaluationForSymbol(const Symbol * symbol);
const Expression * expressionForSymbol(const Symbol * symbol) override;
void setExpressionForSymbolName(const Expression * expression, const Symbol * symbol) override;
static constexpr uint16_t k_maxNumberOfScalarExpressions = 26;
static constexpr uint16_t k_maxNumberOfListExpressions = 10;
@@ -33,7 +30,7 @@ public:
private:
int symbolIndex(const Symbol * symbol) const;
Complex<double> * m_expressions[k_maxNumberOfScalarExpressions];
ComplexMatrix<double> * m_matrixExpressions[k_maxNumberOfMatrixExpressions];
Matrix * m_matrixExpressions[k_maxNumberOfMatrixExpressions];
Complex<double> m_pi;
Complex<double> m_e;
};

View File

@@ -12,9 +12,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -22,6 +20,12 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "gcd"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};
}

View File

@@ -13,13 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +21,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "acosh"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -13,13 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +21,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "asinh"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -13,13 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +21,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "atanh"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -14,12 +14,7 @@ public:
Expression * clone() const override;
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
private:
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +22,15 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "cosh"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -14,12 +14,7 @@ public:
Expression * clone() const override;
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
private:
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +22,15 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "sinh"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -14,12 +14,7 @@ public:
Expression * clone() const override;
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
private:
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +22,15 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "tanh"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -13,13 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +21,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "im"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -40,6 +40,7 @@ public:
// Getter & Setter
bool isNegative() const { return m_negative; }
void setNegative(bool negative);
int extractedInt() { assert(m_numberOfDigits == 1 && m_digit <= 0x7FFFFFFF); return m_negative ? -m_digit : m_digit; }
// Comparison
static int NaturalOrder(const Integer & i, const Integer & j);

View File

@@ -13,13 +13,17 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override {
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "int");
}
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
template<typename T>
struct DetailedResult
{

View File

@@ -12,9 +12,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -22,6 +20,12 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "lcm"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};
}

View File

@@ -17,6 +17,7 @@ public:
Expression ** operands() const;
const Expression * operand(int i) const;
void pushExpression(Expression * operand);
void detachOperands();
private:
int m_numberOfOperands;
Expression ** m_operands;

View File

@@ -3,7 +3,6 @@
#include <poincare/layout_engine.h>
#include <poincare/bounded_static_hierarchy.h>
#include <poincare/evaluation_engine.h>
#include <poincare/integer.h>
namespace Poincare {
@@ -15,10 +14,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override {
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "log");
@@ -27,6 +23,11 @@ private:
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override;
Expression * splitInteger(Integer i, bool isDenominator, Context & context, AngleUnit angleUnit);
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};
}

View File

@@ -1,18 +1,35 @@
#ifndef POINCARE_MATRIX_H
#define POINCARE_MATRIX_H
#include <poincare/dynamic_hierarchy.h>
#include <poincare/matrix_data.h>
namespace Poincare {
class Matrix : public Expression {
class Matrix : public DynamicHierarchy {
public:
int numberOfOperands() const override;
virtual int numberOfRows() const = 0;
virtual int numberOfColumns() const = 0;
Matrix(MatrixData * matrixData); // pilfer the operands of matrixData
Matrix(const Expression * const * operands, int numberOfRows, int numberOfColumns, bool cloneOperands = true);
int numberOfRows() const;
int numberOfColumns() const;
/* Expression */
Type type() const override;
Expression * clone() const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override;
/* Operation on matrix */
template<typename T> Complex<T> * createDeterminant() const;
template<typename T> Expression * createInverse() const;
Matrix * createTranspose() const;
static Matrix * createIdentity(int dim);
private:
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
/* Evaluation */
Complex<float> * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { assert(false); return nullptr; }
Complex<double> * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { assert(false); return nullptr; }
int m_numberOfRows;
};
}

View File

@@ -12,7 +12,6 @@ class Complex;
class MatrixData {
public:
MatrixData(ListData * listData, bool clone);
MatrixData(Expression ** newOperands, int numberOfOperands, int m_numberOfRows, int m_numberOfColumns, bool cloneOperands, Expression * parent);
~MatrixData();
MatrixData(const MatrixData& other) = delete;
MatrixData(MatrixData&& other) = delete;
@@ -21,11 +20,11 @@ public:
void pushListData(ListData * listData, bool clone);
int numberOfRows();
int numberOfColumns();
Expression ** operands() const;
void pilferOperands(const Expression *** newStorageAddress);
private:
int m_numberOfRows;
int m_numberOfColumns;
Expression ** m_operands;
const Expression ** m_operands;
static Complex<double> * defaultExpression();
};

View File

@@ -4,7 +4,6 @@
#include <poincare/layout_engine.h>
#include <poincare/static_hierarchy.h>
#include <poincare/complex.h>
#include <poincare/complex_matrix.h>
namespace Poincare {
@@ -14,9 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -24,6 +21,11 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "dimension"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { assert(false); return nullptr; }
Complex<double> * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { assert(false); return nullptr; }
};
}

View File

@@ -4,7 +4,6 @@
#include <poincare/layout_engine.h>
#include <poincare/static_hierarchy.h>
#include <poincare/complex.h>
#include <poincare/complex_matrix.h>
namespace Poincare {
@@ -14,9 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Evaluation */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -24,6 +21,11 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "inverse"; }
/* Simplification */
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { assert(false); return nullptr; }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { assert(false); return nullptr; }
};
}

View File

@@ -4,7 +4,6 @@
#include <poincare/layout_engine.h>
#include <poincare/static_hierarchy.h>
#include <poincare/complex.h>
#include <poincare/complex_matrix.h>
namespace Poincare {
@@ -14,9 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -24,6 +21,11 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "trace"; }
/* Simplification */
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { assert(false); return nullptr; }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { assert(false); return nullptr; }
};
}

View File

@@ -4,7 +4,6 @@
#include <poincare/layout_engine.h>
#include <poincare/static_hierarchy.h>
#include <poincare/complex.h>
#include <poincare/complex_matrix.h>
namespace Poincare {
@@ -14,9 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -24,6 +21,11 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "transpose"; }
/* Simplification */
Expression * shallowReduce(Context & context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { assert(false); return nullptr; }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { assert(false); return nullptr; }
};
}

View File

@@ -19,11 +19,8 @@ public:
Type type() const override;
Expression * clone() const override;
Sign sign() const override;
/* Evaluation */
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
template<typename T> static Evaluation<T> * computeOnComplexAndMatrix(const Complex<T> * c, Evaluation<T> * m) {
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
}
template<typename T> static Evaluation<T> * computeOnMatrices(Evaluation<T> * m, Evaluation<T> * n);
private:
/* Property */
Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override;
@@ -49,14 +46,11 @@ private:
// Warning: mergeNegativePower not always returns a multiplication: *(b^-1,c^-1) -> (bc)^-1
Expression * mergeNegativePower(Context & context, AngleUnit angleUnit);
/* Evaluation */
template<typename T> static Evaluation<T> * computeOnMatrixAndComplex(Evaluation<T> * m, const Complex<T> * c) {
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>);
}
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>);
}
};

View File

@@ -13,13 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,8 +21,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "ln"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -13,15 +13,18 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override {
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "root");
}
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};

View File

@@ -14,15 +14,18 @@ public:
Type type() const override;
template<typename T> static Complex<T> compute(const Complex<T> c, AngleUnit angleUnit);
private:
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit, compute<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, compute<double>);
}
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override;
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit, compute<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, compute<double>);
}
};
}

View File

@@ -13,15 +13,17 @@ public:
Expression * clone() const override;
Type type() const override;
private:
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override {
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "");
}
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};

View File

@@ -12,9 +12,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -22,6 +20,12 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "permute"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};
}

View File

@@ -20,7 +20,6 @@ public:
Sign sign() const override;
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
private:
constexpr static float k_maxNumberOfSteps = 10000.0f;
/* Property */
Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override;
/* Layout */
@@ -41,14 +40,11 @@ private:
Expression * removeSquareRootsFromDenominator(Context & context, AngleUnit angleUnit);
static Expression * CreateSimplifiedIntegerRationalPower(Integer i, Rational * r, bool isDenominator);
/* Evaluation */
template<typename T> static Evaluation<T> * computeOnComplexAndMatrix(const Complex<T> * c, Evaluation<T> * n);
template<typename T> static Evaluation<T> * computeOnMatrixAndComplex(Evaluation<T> * m, const Complex<T> * d);
template<typename T> static Evaluation<T> * computeOnMatrices(Evaluation<T> * m, Evaluation<T> * n);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>);
}
};

View File

@@ -12,9 +12,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -22,6 +20,11 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "prediction95"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(Expression::SinglePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { assert(false); return nullptr; }
Complex<double> * privateEvaluate(Expression::DoublePrecision p, Context& context, Expression::AngleUnit angleUnit) const override { assert(false); return nullptr; }
};
}

View File

@@ -14,13 +14,13 @@ private:
const char * name() const override;
int emptySequenceValue() const override;
ExpressionLayout * createSequenceLayoutWithArgumentLayouts(ExpressionLayout * subscriptLayout, ExpressionLayout * superscriptLayout, ExpressionLayout * argumentLayout) const override;
Evaluation<float> * evaluateWithNextTerm(Evaluation<float> * a, Evaluation<float> * b) const override {
Complex<float> * evaluateWithNextTerm(Complex<float> * a, Complex<float> * b) const override {
return templatedEvaluateWithNextTerm(a, b);
}
Evaluation<double> * evaluateWithNextTerm(Evaluation<double> * a, Evaluation<double> * b) const override {
Complex<double> * evaluateWithNextTerm(Complex<double> * a, Complex<double> * b) const override {
return templatedEvaluateWithNextTerm(a, b);
}
template<typename T> Evaluation<T> * templatedEvaluateWithNextTerm(Evaluation<T> * a, Evaluation<T> * b) const;
template<typename T> Complex<T> * templatedEvaluateWithNextTerm(Complex<T> * a, Complex<T> * b) const;
};
}

View File

@@ -14,11 +14,9 @@ public:
Rational(const Integer numerator, const Integer denominator);
Rational(const Integer numerator);
Rational(Integer::native_int_t i) : Rational(Integer(i)) {}
Rational(Integer::native_int_t i, Integer::native_int_t j) : Rational(Integer(i), Integer(j)) {}
Rational(const Rational & other);
/*Rational(Rational && other) = default;
Rational& operator=(const Rational & other) = default;
Rational& operator=(Rational && other) = default;*/
// Getter
const Integer numerator() const;
@@ -44,9 +42,9 @@ public:
private:
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override;
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename U> Evaluation<U> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename U> Complex<U> * templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const;
Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override;
Expression * setSign(Sign s);
Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override {

View File

@@ -13,13 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -27,6 +21,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "re"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -4,7 +4,6 @@
#include <poincare/layout_engine.h>
#include <poincare/static_hierarchy.h>
#include <poincare/complex.h>
#include <poincare/complex_matrix.h>
namespace Poincare {
@@ -14,9 +13,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -24,6 +21,12 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "round"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Complex */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};
}

View File

@@ -10,19 +10,21 @@ namespace Poincare {
class Sequence : public StaticHierarchy<3> {
using StaticHierarchy<3>::StaticHierarchy;
private:
constexpr static float k_maxNumberOfSteps = 10000.0f;
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override {
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
virtual ExpressionLayout * createSequenceLayoutWithArgumentLayouts(ExpressionLayout * subscriptLayout, ExpressionLayout * superscriptLayout, ExpressionLayout * argumentLayout) const = 0;
virtual const char * name() const = 0;
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
virtual int emptySequenceValue() const = 0;
virtual Evaluation<float> * evaluateWithNextTerm(Evaluation<float> * a, Evaluation<float> * b) const = 0;
virtual Evaluation<double> * evaluateWithNextTerm(Evaluation<double> * a, Evaluation<double> * b) const = 0;
virtual Complex<float> * evaluateWithNextTerm(Complex<float> * a, Complex<float> * b) const = 0;
virtual Complex<double> * evaluateWithNextTerm(Complex<double> * a, Complex<double> * b) const = 0;
};
}

View File

@@ -0,0 +1,16 @@
#ifndef POINCARE_SIMPLIFICATION_ENGINE_H
#define POINCARE_SIMPLIFICATION_ENGINE_H
#include <poincare/expression.h>
namespace Poincare {
class SimplificationEngine {
public:
static Expression * map(Expression * e, Context & context, Expression::AngleUnit angleUnit);
};
}
#endif

View File

@@ -23,10 +23,12 @@ public:
return nullptr;
}
int writeTextInBuffer(char * buffer, int bufferSize) const override { return 0; }
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
assert(false);
return nullptr;
}
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
assert(false);
return nullptr;
}
private:

View File

@@ -16,13 +16,7 @@ public:
Expression * clone() const override;
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit = AngleUnit::Radian);
private:
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -30,6 +24,15 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "sin"; }
/* Simplication */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -13,17 +13,19 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override;
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};

View File

@@ -14,11 +14,15 @@ public:
Type type() const override;
Expression * clone() const override;
private:
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override;
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evalutation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { assert(false); return nullptr; }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { assert(false); return nullptr; }
const Symbol * symbol() const { return static_cast<const Symbol *>(operand(0)); }
const Expression * value() const { return operand(1); }
};

View File

@@ -14,21 +14,7 @@ public:
Expression * clone() const override;
template<typename T> static Complex<T> compute(const Complex<T> c, const Complex<T> d);
private:
template<typename T> static Evaluation<T> * computeOnMatrixAndComplex(Evaluation<T> * m, const Complex<T> * c) {
return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute<T>);
}
template<typename T> static Evaluation<T> * computeOnComplexAndMatrix(const Complex<T> * c, Evaluation<T> * n);
template<typename T> static Evaluation<T> * computeOnMatrices(Evaluation<T> * m, Evaluation<T> * n) {
return EvaluationEngine::elementWiseOnComplexMatrices(m, n, compute<T>);
}
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
}
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createInfixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -36,6 +22,16 @@ private:
return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
static const char * name() { return "-"; }
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<float>(this, context, angleUnit, compute<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::mapReduce<double>(this, context, angleUnit, compute<double>);
}
};
}

View File

@@ -14,13 +14,13 @@ private:
const char * name() const override;
int emptySequenceValue() const override;
ExpressionLayout * createSequenceLayoutWithArgumentLayouts(ExpressionLayout * subscriptLayout, ExpressionLayout * superscriptLayout, ExpressionLayout * argumentLayout) const override;
Evaluation<float> * evaluateWithNextTerm(Evaluation<float> * a, Evaluation<float> * b) const override {
Complex<float> * evaluateWithNextTerm(Complex<float> * a, Complex<float> * b) const override {
return templatedEvaluateWithNextTerm(a, b);
}
Evaluation<double> * evaluateWithNextTerm(Evaluation<double> * a, Evaluation<double> * b) const override {
Complex<double> * evaluateWithNextTerm(Complex<double> * a, Complex<double> * b) const override {
return templatedEvaluateWithNextTerm(a, b);
}
template<typename T> Evaluation<T> * templatedEvaluateWithNextTerm(Evaluation<T> * a, Evaluation<T> * b) const;
template<typename T> Complex<T> * templatedEvaluateWithNextTerm(Complex<T> * a, Complex<T> * b) const;
};
}

View File

@@ -37,12 +37,17 @@ public:
Sign sign() const override;
bool isMatrixSymbol() const;
private:
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Evaluation<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
/* Comparison */
int simplificationOrderSameType(const Expression * e) const override;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override;
int simplificationOrderSameType(const Expression * e) const override;
/* Simplification */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
const char m_name;
};

View File

@@ -14,14 +14,7 @@ public:
Type type() const override;
Expression * clone() const override;
private:
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit = AngleUnit::Radian);
virtual Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
}
virtual Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
}
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override {
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name());
}
@@ -29,6 +22,16 @@ private:
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name());
}
const char * name() const { return "tan"; }
/* Simplication */
Expression * shallowReduce(Context& context, AngleUnit angleUnit) override;
/* Evaluation */
template<typename T> static Complex<T> computeOnComplex(const Complex<T> c, AngleUnit angleUnit = AngleUnit::Radian);
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<float>(this, context, angleUnit,computeOnComplex<float>);
}
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override {
return EvaluationEngine::approximate<double>(this, context, angleUnit, computeOnComplex<double>);
}
};
}

View File

@@ -11,9 +11,12 @@ public:
Expression * clone() const override;
int writeTextInBuffer(char * buffer, int bufferSize) const override;
private:
/* Layout */
ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override;
Evaluation<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override;
Evaluation<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override;
/* Evaluation */
Complex<float> * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<float>(context, angleUnit); }
Complex<double> * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedEvaluate<double>(context, angleUnit); }
template<typename T> Complex<T> * templatedEvaluate(Context& context, AngleUnit angleUnit) const;
};
}

View File

@@ -1,5 +1,6 @@
#include <poincare/absolute_value.h>
#include <poincare/complex.h>
#include <poincare/simplification_engine.h>
#include "layout/absolute_value_layout.h"
extern "C" {
@@ -34,11 +35,14 @@ Expression * AbsoluteValue::shallowReduce(Context& context, AngleUnit angleUnit)
if (e != this) {
return e;
}
if (operand(0)->sign() == Sign::Positive) {
return replaceWith(editableOperand(0), true);
Expression * op = editableOperand(0);
if (op->type() == Type::Matrix) {
return SimplificationEngine::map(this, context, angleUnit);
}
if (operand(0)->sign() == Sign::Negative) {
Expression * op = editableOperand(0);
if (op->sign() == Sign::Positive) {
return replaceWith(op, true);
}
if (op->sign() == Sign::Negative) {
Expression * newOp = op->setSign(Sign::Positive, context, angleUnit);
return replaceWith(newOp, true);
}

View File

@@ -1,10 +1,10 @@
#include <poincare/addition.h>
#include <poincare/complex_matrix.h>
#include <poincare/multiplication.h>
#include <poincare/subtraction.h>
#include <poincare/power.h>
#include <poincare/opposite.h>
#include <poincare/undefined.h>
#include <poincare/matrix.h>
extern "C" {
#include <assert.h>
#include <stdlib.h>
@@ -43,6 +43,53 @@ Expression * Addition::shallowReduce(Context& context, AngleUnit angleUnit) {
// Step 2: Sort the operands
sortOperands(Expression::SimplificationOrder);
/* Step 2bis: get rid of matrix */
int n = 1;
int m = 1;
/* All operands have been simplified so if any operand contains a matrix, it
* is at the root node of the operand. Moreover, thanks to the simplification
* order, all matrix operands (if any) are the last operands. */
Expression * lastOperand = editableOperand(numberOfOperands()-1);
if (lastOperand->type() == Type::Matrix) {
// Create in-place the matrix of addition M (in place of the last operand)
Matrix * resultMatrix = static_cast<Matrix *>(lastOperand);
n = resultMatrix->numberOfRows();
m = resultMatrix->numberOfColumns();
removeOperand(resultMatrix, false);
/* Scan (starting at the end) accross the addition operands to find any
* other matrix */
int i = numberOfOperands()-1;
while (i >= 0 && operand(i)->type() == Type::Matrix) {
Matrix * currentMatrix = static_cast<Matrix *>(editableOperand(i));
int on = currentMatrix->numberOfRows();
int om = currentMatrix->numberOfColumns();
if (on != n || om != m) {
return replaceWith(new Undefined(), true);
}
// Dispatch the current matrix operands in the created additions matrix
for (int j = 0; j < n*m; j++) {
Addition * a = new Addition();
Expression * resultMatrixEntryJ = resultMatrix->editableOperand(j);
resultMatrix->replaceOperand(resultMatrixEntryJ, a, false);
a->addOperand(currentMatrix->editableOperand(j));
a->addOperand(resultMatrixEntryJ);
a->shallowReduce(context, angleUnit);
}
currentMatrix->detachOperands();
removeOperand(currentMatrix, true);
i--;
}
// Distribute the remaining addition on matrix operands
for (int i = 0; i < n*m; i++) {
Addition * a = static_cast<Addition *>(clone());
Expression * entryI = resultMatrix->editableOperand(i);
resultMatrix->replaceOperand(entryI, a, false);
a->addOperand(entryI);
a->shallowReduce(context, angleUnit);
}
return replaceWith(resultMatrix, true)->shallowReduce(context, angleUnit);
}
/* Step 3: Factorize like terms. Thanks to the simplification order, those are
* next to each other at this point. */
i = 0;
@@ -257,13 +304,7 @@ Complex<T> Addition::compute(const Complex<T> c, const Complex<T> d) {
return Complex<T>::Cartesian(c.a()+d.a(), c.b()+d.b());
}
template Poincare::Complex<float> Poincare::Addition::compute<float>(Poincare::Complex<float>, Poincare::Complex<float>);
template Poincare::Complex<double> Poincare::Addition::compute<double>(Poincare::Complex<double>, Poincare::Complex<double>);
template Poincare::Evaluation<float>* Poincare::Addition::computeOnMatrices<float>(Poincare::Evaluation<float>*, Poincare::Evaluation<float>*);
template Poincare::Evaluation<double>* Poincare::Addition::computeOnMatrices<double>(Poincare::Evaluation<double>*, Poincare::Evaluation<double>*);
template Poincare::Evaluation<float>* Poincare::Addition::computeOnComplexAndMatrix<float>(Poincare::Complex<float> const*, Poincare::Evaluation<float>*);
template Poincare::Evaluation<double>* Poincare::Addition::computeOnComplexAndMatrix<double>(Poincare::Complex<double> const*, Poincare::Evaluation<double>*);
template Complex<float> Poincare::Addition::compute<float>(Poincare::Complex<float>, Poincare::Complex<float>);
template Complex<double> Poincare::Addition::compute<double>(Poincare::Complex<double>, Poincare::Complex<double>);
}

View File

@@ -1,5 +1,6 @@
#include <poincare/arc_cosine.h>
#include <poincare/trigonometry.h>
#include <poincare/simplification_engine.h>
extern "C" {
#include <assert.h>
}
@@ -21,6 +22,9 @@ Expression * ArcCosine::shallowReduce(Context& context, AngleUnit angleUnit) {
if (e != this) {
return e;
}
if (operand(0)->type() == Type::Matrix) {
return SimplificationEngine::map(this, context, angleUnit);
}
return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit);
}

View File

@@ -1,5 +1,6 @@
#include <poincare/arc_sine.h>
#include <poincare/trigonometry.h>
#include <poincare/simplification_engine.h>
extern "C" {
#include <assert.h>
}
@@ -21,6 +22,9 @@ Expression * ArcSine::shallowReduce(Context& context, AngleUnit angleUnit) {
if (e != this) {
return e;
}
if (operand(0)->type() == Type::Matrix) {
return SimplificationEngine::map(this, context, angleUnit);
}
return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit);
}

View File

@@ -1,5 +1,6 @@
#include <poincare/arc_tangent.h>
#include <poincare/trigonometry.h>
#include <poincare/simplification_engine.h>
extern "C" {
#include <assert.h>
}
@@ -21,6 +22,9 @@ Expression * ArcTangent::shallowReduce(Context& context, AngleUnit angleUnit) {
if (e != this) {
return e;
}
if (operand(0)->type() == Type::Matrix) {
return SimplificationEngine::map(this, context, angleUnit);
}
return Trigonometry::shallowReduceInverseFunction(this, context, angleUnit);
}

View File

@@ -1,6 +1,7 @@
#include <poincare/binomial_coefficient.h>
#include <poincare/evaluation.h>
#include <poincare/complex.h>
#include <poincare/undefined.h>
#include <poincare/rational.h>
#include "layout/parenthesis_layout.h"
#include "layout/grid_layout.h"
@@ -21,22 +22,52 @@ Expression * BinomialCoefficient::clone() const {
return b;
}
template<typename T>
Evaluation<T> * BinomialCoefficient::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
Evaluation<T> * nInput = operand(0)->evaluate<T>(context, angleUnit);
Evaluation<T> * kInput = operand(1)->evaluate<T>(context, angleUnit);
T n = nInput->toScalar();
T k = kInput->toScalar();
delete nInput;
delete kInput;
if (isnan(n) || isnan(k) || n != (int)n || k != (int)k || k > n || k < 0 || n < 0) {
return new Complex<T>(Complex<T>::Float(NAN));
Expression * BinomialCoefficient::shallowReduce(Context& context, AngleUnit angleUnit) {
Expression * e = Expression::shallowReduce(context, angleUnit);
if (e != this) {
return e;
}
T result = 1;
for (int i = 0; i < (int)k; i++) {
result *= (n-(T)i)/(k-(T)i);
Expression * op0 = editableOperand(0);
Expression * op1 = editableOperand(1);
if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) {
return replaceWith(new Undefined(), true);
}
return new Complex<T>(Complex<T>::Float(std::round(result)));
if (op0->type() == Type::Rational) {
Rational * r0 = static_cast<Rational *>(op0);
if (!r0->denominator().isOne() || r0->numerator().isNegative()) {
return replaceWith(new Undefined(), true);
}
}
if (op1->type() == Type::Rational) {
Rational * r1 = static_cast<Rational *>(op1);
if (!r1->denominator().isOne() || r1->numerator().isNegative()) {
return replaceWith(new Undefined(), true);
}
}
if (op0->type() != Type::Rational || op1->type() != Type::Rational) {
return this;
}
Rational * r0 = static_cast<Rational *>(op0);
Rational * r1 = static_cast<Rational *>(op1);
Integer n = r0->numerator();
Integer k = r1->numerator();
if (n.isLowerThan(k)) {
return replaceWith(new Undefined(), true);
}
Integer result(1);
Integer kBis = Integer::Subtraction(n, k);
k = kBis.isLowerThan(k) ? kBis : k;
// Out of bounds
if (Integer(k_maxNumberOfSteps).isLowerThan(k)) {
return replaceWith(new Undefined(), true);
}
int clippedK = k.extractedInt(); // Authorized because k < k_maxNumberOfSteps
for (int i = 0; i < clippedK; i++) {
Integer factor = Integer::Division(Integer::Subtraction(n, Integer(i)), Integer::Subtraction(k, Integer(i))).quotient;
result = Integer::Multiplication(result, factor);
}
return replaceWith(new Rational(result), true);
}
ExpressionLayout * BinomialCoefficient::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
@@ -48,5 +79,24 @@ ExpressionLayout * BinomialCoefficient::privateCreateLayout(FloatDisplayMode flo
return new ParenthesisLayout(new GridLayout(childrenLayouts, 2, 1));
}
template<typename T>
Complex<T> * BinomialCoefficient::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
Complex<T> * nInput = operand(0)->privateEvaluate(T(), context, angleUnit);
Complex<T> * kInput = operand(1)->privateEvaluate(T(), context, angleUnit);
T n = nInput->toScalar();
T k = kInput->toScalar();
delete nInput;
delete kInput;
k = k > (n-k) ? n-k : k;
if (isnan(n) || isnan(k) || n != std::round(n) || k != std::round(k) || k > n || k < 0 || n < 0 || k > k_maxNumberOfSteps) {
return new Complex<T>(Complex<T>::Float(NAN));
}
T result = 1;
for (int i = 0; i < k; i++) {
result *= (n-(T)i)/(k-(T)i);
}
return new Complex<T>(Complex<T>::Float(std::round(result)));
}
}

View File

@@ -1,5 +1,8 @@
#include <poincare/ceiling.h>
#include <poincare/symbol.h>
#include <poincare/simplification_engine.h>
#include <poincare/rational.h>
#include <ion.h>
extern "C" {
#include <assert.h>
}
@@ -16,6 +19,35 @@ Expression * Ceiling::clone() const {
return c;
}
Expression * Ceiling::shallowReduce(Context& context, AngleUnit angleUnit) {
Expression * e = Expression::shallowReduce(context, angleUnit);
if (e != this) {
return e;
}
Expression * op = editableOperand(0);
if (op->type() == Type::Matrix) {
return SimplificationEngine::map(this, context, angleUnit);
}
if (op->type() == Type::Symbol) {
Symbol * s = static_cast<Symbol *>(op);
if (s->name() == Ion::Charset::SmallPi) {
return replaceWith(new Rational(4), true);
}
if (s->name() == Ion::Charset::Exponential) {
return replaceWith(new Rational(3), true);
}
}
if (op->type() != Type::Rational) {
return this;
}
Rational * r = static_cast<Rational *>(op);
IntegerDivision div = Integer::Division(r->numerator(), r->denominator());
if (div.remainder.isZero()) {
return replaceWith(new Rational(div.quotient), true);
}
return replaceWith(new Rational(Integer::Addition(div.quotient, Integer(1))), true);
}
template<typename T>
Complex<T> Ceiling::computeOnComplex(const Complex<T> c, AngleUnit angleUnit) {
if (c.b() != 0) {

View File

@@ -7,7 +7,6 @@ extern "C" {
}
#include <cmath>
#include <math.h>
#include <poincare/complex_matrix.h>
#include "layout/string_layout.h"
#include "layout/baseline_relative_layout.h"
#include <ion.h>
@@ -71,7 +70,20 @@ Complex<T> Complex<T>::Polar(T r, T th) {
}
template<typename T>
static inline T setSign(T f, bool negative) {
Complex<T>::Complex(const Complex<T> & other) {
m_a = other.m_a;
m_b = other.m_b;
}
template<typename T>
Complex<T> & Complex<T>::operator=(const Complex& other) {
m_a = other.m_a;
m_b = other.m_b;
return *this;
}
template<typename T>
static inline T setSignOnScalar(T f, bool negative) {
if (negative) {
return -f;
}
@@ -99,9 +111,9 @@ Complex<T>::Complex(const char * integralPart, int integralPartLength, bool inte
const char * exponent, int exponentLength, bool exponentNegative) {
T i = digitsToFloat<T>(integralPart, integralPartLength);
T j = digitsToFloat<T>(fractionalPart, fractionalPartLength);
T l = setSign<T>(digitsToFloat<T>(exponent, exponentLength), exponentNegative);
T l = setSignOnScalar<T>(digitsToFloat<T>(exponent, exponentLength), exponentNegative);
m_a = setSign((i + j*std::pow(10, -std::ceil((T)fractionalPartLength)))* std::pow(10, l), integralNegative);
m_a = setSignOnScalar((i + j*std::pow(10, -std::ceil((T)fractionalPartLength)))* std::pow(10, l), integralNegative);
m_b = 0;
}
@@ -159,26 +171,11 @@ T Complex<T>::toScalar() const {
return m_a;
}
template<typename T>
int Complex<T>::numberOfRows() const {
return 1;
}
template<typename T>
int Complex<T>::numberOfColumns() const {
return 1;
}
template <class T>
int Complex<T>::writeTextInBuffer(char * buffer, int bufferSize) const {
return convertComplexToText(buffer, bufferSize, Preferences::sharedPreferences()->displayMode(), Preferences::sharedPreferences()->complexFormat());
}
template <class T>
Evaluation<T> * Complex<T>::createInverse() const {
return new Complex<T>(Cartesian(1/m_a, -1/m_b));
}
template <class T>
int Complex<T>::convertFloatToText(T f, char * buffer, int bufferSize,
int numberOfSignificantDigits, Expression::FloatDisplayMode mode) {
@@ -213,11 +210,6 @@ Complex<T>::Complex(T a, T b) :
{
}
template <class T>
const Complex<T> * Complex<T>::complexOperand(int i) const {
return this;
}
template <class T>
ExpressionLayout * Complex<T>::privateCreateLayout(Expression::FloatDisplayMode floatDisplayMode, Expression::ComplexFormat complexFormat) const {
assert(floatDisplayMode != Expression::FloatDisplayMode::Default);
@@ -229,7 +221,7 @@ ExpressionLayout * Complex<T>::privateCreateLayout(Expression::FloatDisplayMode
template<typename T>
template<typename U>
Evaluation<U> * Complex<T>::templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const {
Complex<U> * Complex<T>::templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const {
return new Complex<U>(Complex<U>::Cartesian((U)m_a, (U)m_b));
}
@@ -453,12 +445,12 @@ ExpressionLayout * Complex<T>::createCartesianLayout(Expression::FloatDisplayMod
return new StringLayout(buffer, numberOfChars);
}
template class Poincare::Complex<float>;
template class Poincare::Complex<double>;
template Poincare::Evaluation<double>* Poincare::Complex<double>::templatedEvaluate<double>(Poincare::Context&, Poincare::Expression::AngleUnit) const;
template Poincare::Evaluation<float>* Poincare::Complex<double>::templatedEvaluate<float>(Poincare::Context&, Poincare::Expression::AngleUnit) const;
template Poincare::Evaluation<double>* Poincare::Complex<float>::templatedEvaluate<double>(Poincare::Context&, Poincare::Expression::AngleUnit) const;
template Poincare::Evaluation<float>* Poincare::Complex<float>::templatedEvaluate<float>(Poincare::Context&, Poincare::Expression::AngleUnit) const;
template class Complex<float>;
template class Complex<double>;
template Complex<double>* Complex<double>::templatedEvaluate<double>(Context&, Expression::AngleUnit) const;
template Complex<float>* Complex<double>::templatedEvaluate<float>(Context&, Expression::AngleUnit) const;
template Complex<double>* Complex<float>::templatedEvaluate<double>(Context&, Expression::AngleUnit) const;
template Complex<float>* Complex<float>::templatedEvaluate<float>(Context&, Expression::AngleUnit) const;
}

View File

@@ -1,6 +1,6 @@
#include <poincare/complex_argument.h>
#include <poincare/complex.h>
#include <poincare/simplification_engine.h>
extern "C" {
#include <assert.h>
}
@@ -17,6 +17,18 @@ Expression * ComplexArgument::clone() const {
return a;
}
Expression * ComplexArgument::shallowReduce(Context& context, AngleUnit angleUnit) {
Expression * e = Expression::shallowReduce(context, angleUnit);
if (e != this) {
return e;
}
Expression * op = editableOperand(0);
if (op->type() == Type::Matrix) {
return SimplificationEngine::map(this, context, angleUnit);
}
return this;
}
template<typename T>
Complex<T> ComplexArgument::computeOnComplex(const Complex<T> c, AngleUnit angleUnit) {
return Complex<T>::Float(c.th());

View File

@@ -1,102 +0,0 @@
extern "C" {
#include <assert.h>
#include <stdlib.h>
}
#include <poincare/complex_matrix.h>
#include <poincare/complex.h>
#include "layout/grid_layout.h"
#include "layout/bracket_layout.h"
#include <cmath>
#include <float.h>
#include <string.h>
namespace Poincare {
template<typename T>
ComplexMatrix<T>::ComplexMatrix(const Complex<T> * complexes, int numberOfRows, int numberOfColumns) :
m_numberOfRows(numberOfRows),
m_numberOfColumns(numberOfColumns)
{
assert(complexes != nullptr);
m_values = new Complex<T>[numberOfRows*numberOfColumns];
for (int i = 0; i < numberOfRows*numberOfColumns; i++) {
m_values[i] = complexes[i];
m_values[i].setParent(this);
}
}
template<typename T>
ComplexMatrix<T>::~ComplexMatrix() {
delete[] m_values;
}
template<typename T>
Expression::Type ComplexMatrix<T>::type() const {
return Expression::Type::ComplexMatrix;
}
template<typename T>
ComplexMatrix<T> * ComplexMatrix<T>::clone() const {
return new ComplexMatrix<T>(m_values, m_numberOfRows, m_numberOfColumns);
}
template<typename T>
T ComplexMatrix<T>::toScalar() const {
if (m_numberOfRows != 1 || m_numberOfColumns != 1) {
return NAN;
}
if (m_values[0].b() != 0) {
return NAN;
}
return m_values[0].a();
}
template<typename T>
int ComplexMatrix<T>::numberOfRows() const {
return m_numberOfRows;
}
template<typename T>
int ComplexMatrix<T>::numberOfColumns() const {
return m_numberOfColumns;
}
template<typename T>
const Complex<T> * ComplexMatrix<T>::complexOperand(int i) const {
return &m_values[i];
}
template<typename T>
Evaluation<T> * ComplexMatrix<T>::createIdentity(int dim) {
Complex<T> * operands = new Complex<T> [dim*dim];
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++) {
if (i == j) {
operands[i*dim+j] = Complex<T>::Float(1.0);
} else {
operands[i*dim+j] = Complex<T>::Float(0.0);
}
}
}
Evaluation<T> * matrix = new ComplexMatrix<T>(operands, dim, dim);
delete [] operands;
return matrix;
}
template<typename T>
template <class U>
Evaluation<U> * ComplexMatrix<T>::templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const {
Complex<U> * values = new Complex<U>[m_numberOfRows*m_numberOfColumns];
for (int i = 0; i < m_numberOfRows*m_numberOfColumns; i++) {
values[i] = Complex<U>::Cartesian(m_values[i].a(), m_values[i].b());
}
Evaluation<U> * result = new ComplexMatrix<U>(values, m_numberOfRows, m_numberOfColumns);
delete [] values;
return result;
}
template class Poincare::ComplexMatrix<float>;
template class Poincare::ComplexMatrix<double>;
}

View File

@@ -1,7 +1,10 @@
#include <poincare/confidence_interval.h>
#include <poincare/matrix.h>
#include <poincare/complex_matrix.h>
#include <poincare/complex.h>
#include <poincare/addition.h>
#include <poincare/multiplication.h>
#include <poincare/power.h>
#include <poincare/undefined.h>
extern "C" {
#include <assert.h>
}
@@ -18,21 +21,28 @@ Expression * ConfidenceInterval::clone() const {
return a;
}
template<typename T>
Evaluation<T> * ConfidenceInterval::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
Evaluation<T> * fInput = operand(0)->evaluate<T>(context, angleUnit);
Evaluation<T> * nInput = operand(1)->evaluate<T>(context, angleUnit);
T f = fInput->toScalar();
T n = nInput->toScalar();
delete fInput;
delete nInput;
if (isnan(f) || isnan(n) || n != (int)n || n < 0 || f < 0 || f > 1) {
return new Complex<T>(Complex<T>::Float(NAN));
Expression * ConfidenceInterval::shallowReduce(Context& context, AngleUnit angleUnit) {
Expression * e = Expression::shallowReduce(context, angleUnit);
if (e != this) {
return e;
}
Complex<T> operands[2];
operands[0] = Complex<T>::Float(f - 1/std::sqrt(n));
operands[1] = Complex<T>::Float(f + 1/std::sqrt(n));
return new ComplexMatrix<T>(operands, 2, 1);
Expression * op0 = editableOperand(0);
Expression * op1 = editableOperand(1);
if (op0->type() != Type::Rational || op1->type() != Type::Rational) {
return replaceWith(new Undefined(), true);
}
Rational * r0 = static_cast<Rational *>(op0);
Rational * r1 = static_cast<Rational *>(op1);
if (!r1->denominator().isOne() || r1->numerator().isNegative() || r0->numerator().isNegative() || Integer::NaturalOrder(r0->numerator(), r0->denominator()) <= 0) {
return replaceWith(new Undefined(), true);
}
detachOperand(r0);
detachOperand(r1);
Expression * sqr = new Power(r1, new Rational(-1, 2), false);
const Expression * newOperands[2] = {new Addition(r0, sqr, true),
new Addition(r0, new Multiplication(new Rational(-1), sqr, false), false)};
Expression * matrix = replaceWith(new Matrix(newOperands, 1, 2, false), true);
return matrix->deepReduce(context, angleUnit);
}
}

View File

@@ -1,5 +1,6 @@
#include <poincare/conjugate.h>
#include <poincare/complex.h>
#include <poincare/simplification_engine.h>
#include "layout/conjugate_layout.h"
extern "C" {
@@ -18,16 +19,28 @@ Expression * Conjugate::clone() const {
return a;
}
template<typename T>
Complex<T> Conjugate::computeOnComplex(const Complex<T> c, AngleUnit angleUnit) {
return c.conjugate();
}
ExpressionLayout * Conjugate::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
assert(floatDisplayMode != FloatDisplayMode::Default);
assert(complexFormat != ComplexFormat::Default);
return new ConjugateLayout(operand(0)->createLayout(floatDisplayMode, complexFormat));
}
Expression * Conjugate::shallowReduce(Context& context, AngleUnit angleUnit) {
Expression * e = Expression::shallowReduce(context, angleUnit);
if (e != this) {
return e;
}
Expression * op = editableOperand(0);
if (op->type() == Type::Matrix) {
return SimplificationEngine::map(this, context, angleUnit);
}
return this;
}
template<typename T>
Complex<T> Conjugate::computeOnComplex(const Complex<T> c, AngleUnit angleUnit) {
return c.conjugate();
}
}

View File

@@ -4,6 +4,7 @@
#include <poincare/symbol.h>
#include <poincare/rational.h>
#include <poincare/multiplication.h>
#include <poincare/simplification_engine.h>
#include <ion.h>
extern "C" {
#include <assert.h>
@@ -26,6 +27,10 @@ Expression * Cosine::shallowReduce(Context& context, AngleUnit angleUnit) {
if (e != this) {
return e;
}
Expression * op = editableOperand(0);
if (op->type() == Type::Matrix) {
return SimplificationEngine::map(this, context, angleUnit);
}
return Trigonometry::shallowReduceDirectFunction(this, context, angleUnit);
}

View File

@@ -79,7 +79,7 @@ Expression * Decimal::clone() const {
return new Decimal(m_mantissa, m_exponent);
}
template<typename T> Evaluation<T> * Decimal::templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const {
template<typename T> Complex<T> * Decimal::templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const {
T m = m_mantissa.approximate<T>();
int numberOfDigits = numberOfDigitsInMantissa();
return new Complex<T>(Complex<T>::Float(m*std::pow((T)10.0, (T)(m_exponent-numberOfDigits+1))));

View File

@@ -1,6 +1,8 @@
#include <poincare/derivative.h>
#include <poincare/symbol.h>
#include <poincare/complex.h>
#include <poincare/simplification_engine.h>
#include <poincare/undefined.h>
#include <cmath>
extern "C" {
#include <assert.h>
@@ -18,18 +20,30 @@ Expression * Derivative::clone() const {
return a;
}
Expression * Derivative::shallowReduce(Context& context, AngleUnit angleUnit) {
Expression * e = Expression::shallowReduce(context, angleUnit);
if (e != this) {
return e;
}
if (operand(0)->type() == Type::Matrix || operand(1)->type() == Type::Matrix) {
return replaceWith(new Undefined(), true);
}
// TODO: to be implemented diff(+) -> +diff() etc
return this;
}
template<typename T>
Evaluation<T> * Derivative::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
Complex<T> * Derivative::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
static T min = sizeof(T) == sizeof(double) ? DBL_MIN : FLT_MIN;
static T max = sizeof(T) == sizeof(double) ? DBL_MAX : FLT_MAX;
VariableContext<T> xContext = VariableContext<T>('x', &context);
Symbol xSymbol('x');
Evaluation<T> * xInput = operand(1)->evaluate<T>(context, angleUnit);
Complex<T> * xInput = operand(1)->privateEvaluate(T(), context, angleUnit);
T x = xInput->toScalar();
delete xInput;
Complex<T> e = Complex<T>::Float(x);
xContext.setExpressionForSymbolName(&e, &xSymbol);
Evaluation<T> * fInput = operand(1)->evaluate<T>(xContext, angleUnit);
Complex<T> * fInput = operand(1)->privateEvaluate(T(), xContext, angleUnit);
T functionValue = fInput->toScalar();
delete fInput;
@@ -107,12 +121,12 @@ T Derivative::growthRateAroundAbscissa(T x, T h, VariableContext<T> xContext, An
Symbol xSymbol('x');
Complex<T> e = Complex<T>::Float(x + h);
xContext.setExpressionForSymbolName(&e, &xSymbol);
Evaluation<T> * fInput = operand(0)->evaluate<T>(xContext, angleUnit);
Complex<T> * fInput = operand(0)->privateEvaluate(T(), xContext, angleUnit);
T expressionPlus = fInput->toScalar();
delete fInput;
e = Complex<T>::Float(x-h);
xContext.setExpressionForSymbolName(&e, &xSymbol);
fInput = operand(0)->evaluate<T>(xContext, angleUnit);
fInput = operand(0)->privateEvaluate(T(), xContext, angleUnit);
T expressionMinus = fInput->toScalar();
delete fInput;
return (expressionPlus - expressionMinus)/(2*h);
@@ -123,17 +137,17 @@ T Derivative::approximateDerivate2(T x, T h, VariableContext<T> xContext, AngleU
Symbol xSymbol('x');
Complex<T> e = Complex<T>::Float(x + h);
xContext.setExpressionForSymbolName(&e, &xSymbol);
Evaluation<T> * fInput = operand(0)->evaluate<T>(xContext, angleUnit);
Complex<T> * fInput = operand(0)->privateEvaluate(T(), xContext, angleUnit);
T expressionPlus = fInput->toScalar();
delete fInput;
e = Complex<T>::Float(x);
xContext.setExpressionForSymbolName(&e, &xSymbol);
fInput = operand(0)->evaluate<T>(xContext, angleUnit);
fInput = operand(0)->privateEvaluate(T(), xContext, angleUnit);
T expression = fInput->toScalar();
delete fInput;
e = Complex<T>::Float(x-h);
xContext.setExpressionForSymbolName(&e, &xSymbol);
fInput = operand(0)->evaluate<T>(xContext, angleUnit);
fInput = operand(0)->privateEvaluate(T(), xContext, angleUnit);
T expressionMinus = fInput->toScalar();
delete fInput;
return expressionPlus - 2.0*expression + expressionMinus;

View File

@@ -1,6 +1,5 @@
#include <poincare/determinant.h>
#include <poincare/matrix.h>
#include <poincare/evaluation.h>
extern "C" {
#include <assert.h>
}
@@ -17,13 +16,21 @@ Expression * Determinant::clone() const {
return a;
}
template<typename T>
Evaluation<T> * Determinant::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
Evaluation<T> * input = operand(0)->evaluate<T>(context, angleUnit);
Evaluation<T> * result = input->createDeterminant();
delete input;
return result;
Expression * Determinant::shallowReduce(Context& context, AngleUnit angleUnit) {
Expression * e = Expression::shallowReduce(context, angleUnit);
if (e != this) {
return e;
}
Expression * op = editableOperand(0);
if (op->type() == Type::Matrix) {
// TODO: handle this exactly ; now, we approximate the operand and compute the determinant on real only.
Expression * approxMatrix = op->evaluate<double>(context, angleUnit);
assert(approxMatrix->type() == Type::Matrix);
Complex<double> * det = static_cast<Matrix *>(approxMatrix)->createDeterminant<double>();
delete approxMatrix;
return replaceWith(det, true);
}
return replaceWith(op, true);
}
}

View File

@@ -48,23 +48,6 @@ Complex<T> Division::compute(const Complex<T> c, const Complex<T> d) {
return Complex<T>::Cartesian((c.a()*d.a()+c.b()*d.b())/norm, (d.a()*c.b()-c.a()*d.b())/norm);
}
template<typename T> Evaluation<T> * Division::computeOnComplexAndMatrix(const Complex<T> * c, Evaluation<T> * n) {
Evaluation<T> * inverse = n->createInverse();
Evaluation<T> * result = Multiplication::computeOnComplexAndMatrix(c, inverse);
delete inverse;
return result;
}
template<typename T> Evaluation<T> * Division::computeOnMatrices(Evaluation<T> * m, Evaluation<T> * n) {
if (m->numberOfColumns() != n->numberOfColumns()) {
return nullptr;
}
Evaluation<T> * inverse = n->createInverse();
Evaluation<T> * result = Multiplication::computeOnMatrices(m, inverse);
delete inverse;
return result;
}
ExpressionLayout * Division::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const {
assert(floatDisplayMode != FloatDisplayMode::Default);
assert(complexFormat != ComplexFormat::Default);

View File

@@ -1,5 +1,7 @@
#include <poincare/division_quotient.h>
#include <poincare/complex.h>
#include <poincare/rational.h>
#include <poincare/undefined.h>
extern "C" {
#include <assert.h>
@@ -17,10 +19,44 @@ Expression * DivisionQuotient::clone() const {
return a;
}
Expression * DivisionQuotient::shallowReduce(Context& context, AngleUnit angleUnit) {
Expression * e = Expression::shallowReduce(context, angleUnit);
if (e != this) {
return e;
}
Expression * op0 = editableOperand(0);
Expression * op1 = editableOperand(1);
if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) {
return replaceWith(new Undefined(), true);
}
if (op0->type() == Type::Rational) {
Rational * r0 = static_cast<Rational *>(op0);
if (!r0->denominator().isOne()) {
return replaceWith(new Undefined(), true);
}
}
if (op1->type() == Type::Rational) {
Rational * r1 = static_cast<Rational *>(op1);
if (!r1->denominator().isOne()) {
return replaceWith(new Undefined(), true);
}
}
if (op0->type() != Type::Rational || op1->type() != Type::Rational) {
return this;
}
Rational * r0 = static_cast<Rational *>(op0);
Rational * r1 = static_cast<Rational *>(op1);
Integer a = r0->numerator();
Integer b = r1->numerator();
Integer result = Integer::Division(a, b).quotient;
return replaceWith(new Rational(result), true);
}
template<typename T>
Evaluation<T> * DivisionQuotient::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
Evaluation<T> * f1Input = operand(0)->evaluate<T>(context, angleUnit);
Evaluation<T> * f2Input = operand(1)->evaluate<T>(context, angleUnit);
Complex<T> * DivisionQuotient::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
Complex<T> * f1Input = operand(0)->privateEvaluate(T(), context, angleUnit);
Complex<T> * f2Input = operand(1)->privateEvaluate(T(), context, angleUnit);
T f1 = f1Input->toScalar();
T f2 = f2Input->toScalar();
delete f1Input;

View File

@@ -1,5 +1,7 @@
#include <poincare/division_remainder.h>
#include <poincare/complex.h>
#include <poincare/rational.h>
#include <poincare/undefined.h>
extern "C" {
#include <assert.h>
@@ -17,10 +19,44 @@ Expression * DivisionRemainder::clone() const {
return a;
}
Expression * DivisionRemainder::shallowReduce(Context& context, AngleUnit angleUnit) {
Expression * e = Expression::shallowReduce(context, angleUnit);
if (e != this) {
return e;
}
Expression * op0 = editableOperand(0);
Expression * op1 = editableOperand(1);
if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) {
return replaceWith(new Undefined(), true);
}
if (op0->type() == Type::Rational) {
Rational * r0 = static_cast<Rational *>(op0);
if (!r0->denominator().isOne()) {
return replaceWith(new Undefined(), true);
}
}
if (op1->type() == Type::Rational) {
Rational * r1 = static_cast<Rational *>(op1);
if (!r1->denominator().isOne()) {
return replaceWith(new Undefined(), true);
}
}
if (op0->type() != Type::Rational || op1->type() != Type::Rational) {
return this;
}
Rational * r0 = static_cast<Rational *>(op0);
Rational * r1 = static_cast<Rational *>(op1);
Integer a = r0->numerator();
Integer b = r1->numerator();
Integer result = Integer::Division(a, b).remainder;
return replaceWith(new Rational(result), true);
}
template<typename T>
Evaluation<T> * DivisionRemainder::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
Evaluation<T> * f1Input = operand(0)->evaluate<T>(context, angleUnit);
Evaluation<T> * f2Input = operand(1)->evaluate<T>(context, angleUnit);
Complex<T> * DivisionRemainder::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
Complex<T> * f1Input = operand(0)->privateEvaluate(T(), context, angleUnit);
Complex<T> * f2Input = operand(1)->privateEvaluate(T(), context, angleUnit);
T f1 = f1Input->toScalar();
T f2 = f2Input->toScalar();
delete f1Input;

View File

@@ -91,7 +91,9 @@ void DynamicHierarchy::sortOperands(ExpressionOrder order) {
for (int i = numberOfOperands()-1; i > 0; i--) {
bool isSorted = true;
for (int j = 0; j < numberOfOperands()-1; j++) {
if (order(operand(j), operand(j+1)) > 0) {
/* Warning: Matrix operations are not always commutative (ie,
* multiplication) so we never swap 2 matrices. */
if (order(operand(j), operand(j+1)) > 0 && (operand(j)->type() != Type::Matrix || operand(j+1)->type() != Type::Matrix)) {
swapOperands(j, j+1);
isSorted = false;
}

View File

@@ -1,191 +0,0 @@
#include <poincare/evaluation.h>
extern "C" {
#include <assert.h>
#include <stdlib.h>
}
#include <poincare/complex_matrix.h>
#include <poincare/addition.h>
#include <poincare/complex.h>
#include "layout/grid_layout.h"
#include "layout/bracket_layout.h"
#include <cmath>
#include <float.h>
#include <string.h>
namespace Poincare {
template<typename T>
const Expression * Evaluation<T>::operand(int i) const {
return complexOperand(i);
}
template<typename T>
Evaluation<T> * Evaluation<T>::createTrace() const {
if (numberOfRows() != numberOfColumns()) {
return new Complex<T>(Complex<T>::Float(NAN));
}
int dim = numberOfRows();
Complex<T> c = Complex<T>::Float(0);
for (int i = 0; i < dim; i++) {
c = Addition::compute(c, *complexOperand(i*dim+i));
}
return new Complex<T>(c);
}
template<typename T>
// TODO: implement determinant for complex matrix?
Evaluation<T> * Evaluation<T>::createDeterminant() const {
if (numberOfRows() != numberOfColumns()) {
return new Complex<T>(Complex<T>::Float(NAN));
}
int dim = numberOfRows();
T ** tempMat = new T*[dim];
for (int i = 0; i < dim; i++) {
tempMat[i] = new T[dim];
}
T det = 1;
/* Copy the matrix */
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++) {
tempMat[i][j] = complexOperand(i*dim+ j)->toScalar();
}
}
/* Main Loop: Gauss pivot */
for (int i = 0; i < dim-1; i++) {
/* Search for pivot */
int rowWithPivot = i;
for (int row = i+1; row < dim; row++) {
if (std::fabs(tempMat[rowWithPivot][i]) < std::fabs(tempMat[row][i])) {
rowWithPivot = row;
}
}
T valuePivot = tempMat[rowWithPivot][i];
/* if the pivot is null, det = 0. */
if (std::fabs(valuePivot) <= FLT_EPSILON) {
for (int i = 0; i < dim; i++) {
free(tempMat[i]);
}
free(tempMat);
return new Complex<T>(Complex<T>::Float(0.0f));
}
/* Switch rows to have the pivot row as first row */
if (rowWithPivot != i) {
for (int col = i; col < dim; col++) {
T temp = tempMat[i][col];
tempMat[i][col] = tempMat[rowWithPivot][col];
tempMat[rowWithPivot][col] = temp;
}
det *= -1;
}
det *= valuePivot;
/* Set to 0 all A[][i] by linear combination */
for (int row = i+1; row < dim; row++) {
T factor = tempMat[row][i]/valuePivot;
for (int col = i; col < dim; col++) {
tempMat[row][col] -= factor*tempMat[i][col];
}
}
}
det *= tempMat[dim-1][dim-1];
for (int i = 0; i < dim; i++) {
delete[] tempMat[i];
}
delete[] tempMat;
return new Complex<T>(Complex<T>::Float(det));
}
template<typename T>
Evaluation<T> * Evaluation<T>::createInverse() const {
if (numberOfRows() != numberOfColumns()) {
return new Complex<T>(Complex<T>::Float(NAN));
}
int dim = numberOfRows();
/* Create the matrix inv = (A|I) with A the input matrix and I the dim identity matrix */
T ** inv = new T*[dim];
for (int i = 0; i < dim; i++) {
inv[i] = new T [2*dim];
}
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++) {
inv[i][j] = complexOperand(i*dim+j)->toScalar();
}
for (int j = dim; j < 2*dim; j++) {
inv[i][j] = (i+dim == j);
}
}
/* Main Loop: Gauss pivot */
for (int i = 0; i < dim; i++) {
/* Search for pivot */
int rowWithPivot = i;
for (int row = i+1; row < dim; row++) {
if (std::fabs(inv[rowWithPivot][i]) < std::fabs(inv[row][i])) {
rowWithPivot = row;
}
}
T valuePivot = inv[rowWithPivot][i];
/* if the pivot is null, the matrix in not invertible. */
if (std::fabs(valuePivot) <= FLT_EPSILON) {
for (int i = 0; i < dim; i++) {
free(inv[i]);
}
free(inv);
return new Complex<T>(Complex<T>::Float(NAN));
}
/* Switch rows to have the pivot row as first row */
if (rowWithPivot != i) {
for (int col = i; col < 2*dim; col++) {
T temp = inv[i][col];
inv[i][col] = inv[rowWithPivot][col];
inv[rowWithPivot][col] = temp;
}
}
/* A[pivot][] = A[pivot][]/valuePivot */
for (int col = 0; col < 2*dim; col++) {
inv[i][col] /= valuePivot;
}
/* Set to 0 all A[][row] by linear combination */
for (int row = 0; row < dim; row++) {
if (row == i) {
continue;
}
T factor = inv[row][i];
for (int col = 0; col < 2*dim; col++) {
inv[row][col] -= factor*inv[i][col];
}
}
}
Complex<T> * operands = new Complex<T>[numberOfOperands()];
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++) {
operands[i*dim+j] = Complex<T>(Complex<T>::Float(inv[i][j+dim]));
}
}
for (int i = 0; i < dim; i++) {
delete[] inv[i];
}
delete[] inv;
// Intentionally swapping dimensions for inverse, although it doesn't make a difference because it is square
Evaluation<T> * matrix = new ComplexMatrix<T>(operands, numberOfColumns(), numberOfRows());
delete[] operands;
return matrix;
}
template<typename T>
Evaluation<T> * Evaluation<T>::createTranspose() const {
Complex<T> * operands = new Complex<T>[numberOfOperands()];
for (int i = 0; i < numberOfRows(); i++) {
for (int j = 0; j < numberOfColumns(); j++) {
operands[j*numberOfRows()+i] = *(complexOperand(i*numberOfColumns()+j));
}
}
// Intentionally swapping dimensions for transpose
Evaluation<T> * matrix = new ComplexMatrix<T>(operands, numberOfColumns(), numberOfRows());
delete[] operands;
return matrix;
}
template class Poincare::Evaluation<float>;
template class Poincare::Evaluation<double>;
}

View File

@@ -1,5 +1,5 @@
#include <poincare/evaluation_engine.h>
#include <poincare/complex_matrix.h>
#include <poincare/matrix.h>
#include <cmath>
extern "C" {
#include <assert.h>
@@ -7,38 +7,19 @@ extern "C" {
namespace Poincare {
template<typename T> Evaluation<T> * EvaluationEngine::map(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ExpressionToComplexMap<T> compute) {
template<typename T> Complex<T> * EvaluationEngine::approximate(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexCompute<T> compute) {
assert(expression->numberOfOperands() == 1);
Evaluation<T> * input = expression->operand(0)->evaluate<T>(context, angleUnit);
Complex<T> * operands = new Complex<T>[input->numberOfRows()*input->numberOfColumns()];
for (int i = 0; i < input->numberOfOperands(); i++) {
operands[i] = compute(*input->complexOperand(i), angleUnit);
}
Evaluation<T> * result = nullptr;
if (input->numberOfOperands() == 1) {
result = new Complex<T>(operands[0]);
} else {
result = new ComplexMatrix<T>(operands, input->numberOfRows(), input->numberOfColumns());
}
Complex<T> * input = expression->operand(0)->privateEvaluate(T(), context, angleUnit);
Complex<T> * result = new Complex<T>(compute(*input, angleUnit));
delete input;
delete[] operands;
return result;
}
template<typename T> Evaluation<T> * EvaluationEngine::mapReduce(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices) {
Evaluation<T> * result = expression->operand(0)->evaluate<T>(context, angleUnit);
template<typename T> Complex<T> * EvaluationEngine::mapReduce(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes) {
Complex<T> * result = expression->operand(0)->privateEvaluate(T(), context, angleUnit);
for (int i = 1; i < expression->numberOfOperands(); i++) {
Evaluation<T> * intermediateResult = nullptr;
Evaluation<T> * nextOperandEvaluation = expression->operand(i)->evaluate<T>(context, angleUnit);
if (result->numberOfRows() == 1 && result->numberOfColumns() == 1 && nextOperandEvaluation->numberOfRows() == 1 && nextOperandEvaluation->numberOfColumns() == 1) {
intermediateResult = new Complex<T>(computeOnComplexes(*(result->complexOperand(0)), *(nextOperandEvaluation->complexOperand(0))));
} else if (result->numberOfRows() == 1 && result->numberOfColumns() == 1) {
intermediateResult = computeOnComplexAndMatrix(result->complexOperand(0), nextOperandEvaluation);
} else if (nextOperandEvaluation->numberOfRows() == 1 && nextOperandEvaluation->numberOfColumns() == 1) {
intermediateResult = computeOnMatrixAndComplex(result, nextOperandEvaluation->complexOperand(0));
} else {
intermediateResult = computeOnMatrices(result, nextOperandEvaluation);
}
Complex<T> * nextOperandEvaluation = expression->operand(i)->privateEvaluate(T(), context, angleUnit);
Complex<T> * intermediateResult = new Complex<T>(computeOnComplexes(*result, *nextOperandEvaluation));
delete result;
delete nextOperandEvaluation;
result = intermediateResult;
@@ -49,36 +30,9 @@ template<typename T> Evaluation<T> * EvaluationEngine::mapReduce(const Expressio
return result;
}
template<typename T> Evaluation<T> * EvaluationEngine::elementWiseOnComplexAndComplexMatrix(const Complex<T> * c, Evaluation<T> * m, ComplexAndComplexReduction<T> computeOnComplexes) {
Complex<T> * operands = new Complex<T>[m->numberOfRows()*m->numberOfColumns()];
for (int i = 0; i < m->numberOfOperands(); i++) {
operands[i] = computeOnComplexes(*(m->complexOperand(i)), *c);
}
Evaluation<T> * result = new ComplexMatrix<T>(operands, m->numberOfRows(), m->numberOfColumns());
delete[] operands;
return result;
}
template<typename T> Evaluation<T> * EvaluationEngine::elementWiseOnComplexMatrices(Evaluation<T> * m, Evaluation<T> * n, ComplexAndComplexReduction<T> computeOnComplexes) {
if (m->numberOfRows() != n->numberOfRows() && m->numberOfColumns() != n->numberOfColumns()) {
return nullptr;
}
Complex<T> * operands = new Complex<T>[m->numberOfRows()*m->numberOfColumns()];
for (int i = 0; i < m->numberOfOperands(); i++) {
operands[i] = computeOnComplexes(*(m->complexOperand(i)), *(n->complexOperand(i)));
}
Evaluation<T> * result = new ComplexMatrix<T>(operands, m->numberOfRows(), m->numberOfColumns());
delete[] operands;
return result;
}
template Poincare::Evaluation<float> * Poincare::EvaluationEngine::map(const Poincare::Expression * expression, Poincare::Context& context, Poincare::Expression::AngleUnit angleUnit, Poincare::EvaluationEngine::ExpressionToComplexMap<float> compute);
template Poincare::Evaluation<double> * Poincare::EvaluationEngine::map(const Poincare::Expression * expression, Poincare::Context& context, Poincare::Expression::AngleUnit angleUnit, Poincare::EvaluationEngine::ExpressionToComplexMap<double> compute);
template Poincare::Evaluation<float> * Poincare::EvaluationEngine::mapReduce(const Poincare::Expression * expression, Poincare::Context& context, Poincare::Expression::AngleUnit angleUnit, Poincare::EvaluationEngine::ComplexAndComplexReduction<float> computeOnComplexes, Poincare::EvaluationEngine::ComplexAndMatrixReduction<float> computeOnComplexAndMatrix, Poincare::EvaluationEngine::MatrixAndComplexReduction<float> computeOnMatrixAndComplex, Poincare::EvaluationEngine::MatrixAndMatrixReduction<float> computeOnMatrices);
template Poincare::Evaluation<double> * Poincare::EvaluationEngine::mapReduce(const Poincare::Expression * expression, Poincare::Context& context, Poincare::Expression::AngleUnit angleUnit, Poincare::EvaluationEngine::ComplexAndComplexReduction<double> computeOnComplexes, Poincare::EvaluationEngine::ComplexAndMatrixReduction<double> computeOnComplexAndMatrix, Poincare::EvaluationEngine::MatrixAndComplexReduction<double> computeOnMatrixAndComplex, Poincare::EvaluationEngine::MatrixAndMatrixReduction<double> computeOnMatrices);
template Poincare::Evaluation<float>* Poincare::EvaluationEngine::elementWiseOnComplexAndComplexMatrix<float>(Poincare::Complex<float> const*, Poincare::Evaluation<float>*, Poincare::Complex<float> (*)(Poincare::Complex<float>, Poincare::Complex<float>));
template Poincare::Evaluation<double>* Poincare::EvaluationEngine::elementWiseOnComplexAndComplexMatrix<double>(Poincare::Complex<double> const*, Poincare::Evaluation<double>*, Poincare::Complex<double> (*)(Poincare::Complex<double>, Poincare::Complex<double>));
template Poincare::Evaluation<float>* Poincare::EvaluationEngine::elementWiseOnComplexMatrices<float>(Poincare::Evaluation<float>*, Poincare::Evaluation<float>*, Poincare::Complex<float> (*)(Poincare::Complex<float>, Poincare::Complex<float>));
template Poincare::Evaluation<double>* Poincare::EvaluationEngine::elementWiseOnComplexMatrices<double>(Poincare::Evaluation<double>*, Poincare::Evaluation<double>*, Poincare::Complex<double> (*)(Poincare::Complex<double>, Poincare::Complex<double>));
template Complex<float> * Poincare::EvaluationEngine::approximate(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, EvaluationEngine::ComplexCompute<float> compute);
template Complex<double> * EvaluationEngine::approximate(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, EvaluationEngine::ComplexCompute<double> compute);
template Complex<float> * EvaluationEngine::mapReduce(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, EvaluationEngine::ComplexAndComplexReduction<float> computeOnComplexes);
template Complex<double> * EvaluationEngine::mapReduce(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, EvaluationEngine::ComplexAndComplexReduction<double> computeOnComplexes);
}

View File

@@ -5,10 +5,11 @@
#include <poincare/static_hierarchy.h>
#include <poincare/list_data.h>
#include <poincare/matrix_data.h>
#include <poincare/evaluation.h>
#include <poincare/undefined.h>
#include <poincare/simplification_root.h>
#include <poincare/rational.h>
#include <poincare/matrix.h>
#include <poincare/complex.h>
#include <cmath>
#include "expression_parser.hpp"
#include "expression_lexer.hpp"
@@ -132,9 +133,13 @@ void Expression::Simplify(Expression ** expressionAddress, Context & context, An
*expressionAddress = root.editableOperand(0);
}
void Expression::Reduce(Expression ** expressionAddress, Context & context, AngleUnit angleUnit) {
void Expression::Reduce(Expression ** expressionAddress, Context & context, AngleUnit angleUnit, bool recursively) {
SimplificationRoot root(*expressionAddress);
root.editableOperand(0)->deepReduce(context, angleUnit);
if (recursively) {
root.editableOperand(0)->deepReduce(context, angleUnit);
} else {
root.editableOperand(0)->shallowReduce(context,angleUnit);
}
*expressionAddress = root.editableOperand(0);
}
@@ -166,30 +171,51 @@ Expression * Expression::deepBeautify(Context & context, AngleUnit angleUnit) {
/* Evaluation */
template<typename T> Evaluation<T> * Expression::evaluate(Context& context, AngleUnit angleUnit) const {
switch (angleUnit) {
case AngleUnit::Default:
return privateEvaluate(T(), context, Preferences::sharedPreferences()->angleUnit());
default:
return privateEvaluate(T(), context, angleUnit);
template<typename T> Expression * Expression::evaluate(Context& context, AngleUnit angleUnit) const {
for (int i = 0; i < numberOfOperands(); i++) {
assert(operand(i)->type() != Type::Matrix);
}
AngleUnit au = angleUnit == AngleUnit::Default ? Preferences::sharedPreferences()->angleUnit() : angleUnit;
if (type() == Type::Matrix) {
const Matrix * inputMatrix = static_cast<const Matrix *>(this);
Expression ** operands = new Expression *[numberOfOperands()];
for (int i = 0; i < numberOfOperands(); i++) {
operands[i] = operand(i)->privateEvaluate(T(), context, au);
}
Expression * matrix = new Matrix(operands, inputMatrix->numberOfRows(), inputMatrix->numberOfColumns(), false);
delete[] operands;
return matrix;
}
return privateEvaluate(T(), context, au);
}
template<typename T> T Expression::approximate(Context& context, AngleUnit angleUnit) const {
Evaluation<T> * evaluation = evaluate<T>(context, angleUnit);
T result = evaluation->toScalar();
Expression * evaluation = evaluate<T>(context, angleUnit);
assert(evaluation->type() == Type::Complex || evaluation->type() == Type::Matrix);
T result = NAN;
if (evaluation->type() == Type::Complex) {
result = static_cast<const Complex<T> *>(evaluation)->toScalar();
}
if (evaluation->type() == Type::Matrix) {
if (numberOfOperands() == 1) {
result = static_cast<const Complex<T> *>(operand(0))->toScalar();
}
}
delete evaluation;
return result;
}
template<typename T> T Expression::approximate(const char * text, Context& context, AngleUnit angleUnit) {
Expression * exp = parse(text);
T result = NAN;
if (exp == nullptr) {
return NAN;
return result;
}
Evaluation<T> * evaluation = exp->evaluate<T>(context, angleUnit);
Expression * evaluation = exp->evaluate<T>(context, angleUnit);
delete exp;
T result = evaluation->toScalar();
if (evaluation->type() == Type::Complex) {
result = static_cast<Complex<T> *>(evaluation)->toScalar();
}
delete evaluation;
return result;
}
@@ -241,8 +267,8 @@ const Rational * Expression::RationalFactorInExpression(const Expression * e) {
}
template Poincare::Evaluation<double> * Poincare::Expression::evaluate<double>(Context& context, AngleUnit angleUnit) const;
template Poincare::Evaluation<float> * Poincare::Expression::evaluate<float>(Context& context, AngleUnit angleUnit) const;
template Poincare::Expression * Poincare::Expression::evaluate<double>(Context& context, AngleUnit angleUnit) const;
template Poincare::Expression * Poincare::Expression::evaluate<float>(Context& context, AngleUnit angleUnit) const;
template double Poincare::Expression::approximate<double>(char const*, Poincare::Context&, Poincare::Expression::AngleUnit);
template float Poincare::Expression::approximate<float>(char const*, Poincare::Context&, Poincare::Expression::AngleUnit);
template double Poincare::Expression::approximate<double>(Poincare::Context&, Poincare::Expression::AngleUnit) const;

View File

@@ -3,6 +3,7 @@
#include <poincare/symbol.h>
#include <poincare/integer.h>
#include <poincare/rational.h>
#include <poincare/complex.h>
#include <ion.h>
#include <iostream>
@@ -17,6 +18,9 @@ void print_expression(const Expression * e, int indentationLevel) {
}
GlobalContext context;
switch (e->type()) {
case Expression::Type::AbsoluteValue:
std::cout << "AbsoluteValue";
break;
case Expression::Type::Addition:
std::cout << "Addition";
break;
@@ -29,35 +33,133 @@ void print_expression(const Expression * e, int indentationLevel) {
case Expression::Type::ArcTangent:
std::cout << "ArcTangent";
break;
case Expression::Type::Multiplication:
std::cout << "Multiplication";
case Expression::Type::BinomialCoefficient:
std::cout << "BinomialCoefficient";
break;
case Expression::Type::NthRoot:
std::cout << "NthRoot";
case Expression::Type::Ceiling:
std::cout << "Ceiling";
break;
case Expression::Type::Complex:
std::cout << "Complex(";
std::cout << static_cast<const Complex<double> *>(e)->a();
std::cout << ", ";
std::cout << static_cast<const Complex<double> *>(e)->b();
std::cout << ")";
break;
case Expression::Type::ComplexArgument:
std::cout << "ComplexArgument";
break;
case Expression::Type::ConfidenceInterval:
std::cout << "ConfidenceInterval";
break;
case Expression::Type::Conjugate:
std::cout << "Conjugate";
break;
case Expression::Type::Cosine:
std::cout << "Cosine";
break;
case Expression::Type::Logarithm:
std::cout << "Log";
case Expression::Type::Decimal:
std::cout << "Decimal(";
std::cout << e->approximate<double>(context, Expression::AngleUnit::Radian);
std::cout << ")";
break;
case Expression::Type::NaperianLogarithm:
std::cout << "Ln";
case Expression::Type::Derivative:
std::cout << "Derivative";
break;
case Expression::Type::Determinant:
std::cout << "Determinant";
break;
case Expression::Type::Division:
std::cout << "Division";
break;
case Expression::Type::DivisionQuotient:
std::cout << "DivisionQuotient";
break;
case Expression::Type::DivisionRemainder:
std::cout << "DivisionRemainder";
break;
case Expression::Type::Factorial:
std::cout << "Factorial";
break;
case Expression::Type::Floor:
std::cout << "Floor";
break;
case Expression::Type::FracPart:
std::cout << "FracPart";
break;
case Expression::Type::GreatCommonDivisor:
std::cout << "GreatCommonDivisor";
break;
case Expression::Type::HyperbolicArcCosine:
std::cout << "HyperbolicArcCosine";
break;
case Expression::Type::HyperbolicArcSine:
std::cout << "HyperbolicArcSine";
break;
case Expression::Type::HyperbolicArcTangent:
std::cout << "HyperbolicArcTangent";
break;
case Expression::Type::HyperbolicCosine:
std::cout << "HyperbolicCosine";
break;
case Expression::Type::HyperbolicSine:
std::cout << "HyperbolicSine";
break;
case Expression::Type::HyperbolicTangent:
std::cout << "HyperbolicTangent";
break;
case Expression::Type::ImaginaryPart:
std::cout << "ImaginaryPart";
break;
case Expression::Type::Integral:
std::cout << "Integral";
break;
case Expression::Type::LeastCommonMultiple:
std::cout << "LeastCommonMultiple";
break;
case Expression::Type::Logarithm:
std::cout << "Logarithm";
break;
case Expression::Type::Matrix:
std::cout << "Matrix(Rows: ";
std::cout << static_cast<const Matrix *>(e)->numberOfRows();
std::cout << ", Columns: ";
std::cout << static_cast<const Matrix *>(e)->numberOfColumns();
std::cout << ")";
break;
case Expression::Type::MatrixDimension:
std::cout << "MatrixDimension";
break;
case Expression::Type::MatrixInverse:
std::cout << "MatrixInverse";
break;
case Expression::Type::MatrixTrace:
std::cout << "MatrixTrace";
break;
case Expression::Type::MatrixTranspose:
std::cout << "MatrixTranspose";
break;
case Expression::Type::Multiplication:
std::cout << "Multiplication";
break;
case Expression::Type::NaperianLogarithm:
std::cout << "NaperianLogarithm";
break;
case Expression::Type::NthRoot:
std::cout << "NthRoot";
break;
case Expression::Type::Opposite:
std::cout << "Opposite";
break;
/*
case Expression::Type::Matrix:
std::cout << "Matrix";
break;
*/
case Expression::Type::Parenthesis:
std::cout << "Parenthesis";
break;
case Expression::Type::PermuteCoefficient:
std::cout << "PermuteCoefficient";
break;
case Expression::Type::PredictionInterval:
std::cout << "PredictionInterval";
break;
case Expression::Type::Power:
std::cout << "Power";
break;
@@ -71,17 +173,32 @@ void print_expression(const Expression * e, int indentationLevel) {
std::cout << static_cast<const Rational * >(e)->denominator().approximate<double>();
std::cout << ")";
break;
case Expression::Type::RealPart:
std::cout << "RealPart";
break;
case Expression::Type::Round:
std::cout << "Round";
break;
case Expression::Type::SimplificationRoot:
std::cout << "SimplificationRoot";
break;
case Expression::Type::Sine:
std::cout << "Sine";
break;
case Expression::Type::SquareRoot:
std::cout << "SquareRoot";
break;
case Expression::Type::Store:
std::cout << "Store";
break;
case Expression::Type::Subtraction:
std::cout << "Subtraction";
break;
case Expression::Type::Sum:
std::cout << "Sum";
break;
case Expression::Type::Symbol:
std::cout << "Symbol(";
std::cout << "Symbol(";
switch (((Symbol*)e)->name()) {
case Ion::Charset::SmallPi:
std::cout << "PI";

View File

@@ -1,67 +0,0 @@
extern "C" {
#include <assert.h>
#include <stdlib.h>
}
#include <poincare/expression_matrix.h>
#include <poincare/complex_matrix.h>
#include <poincare/complex.h>
#include <cmath>
#include <float.h>
#include <string.h>
namespace Poincare {
ExpressionMatrix::ExpressionMatrix(MatrixData * matrixData) :
m_matrixData(matrixData)
{
}
ExpressionMatrix::ExpressionMatrix(Expression ** newOperands, int numberOfOperands, int numberOfRows, int numberOfColumns, bool cloneOperands)
{
m_matrixData = new MatrixData(newOperands, numberOfOperands, numberOfRows, numberOfColumns, cloneOperands, this);
}
ExpressionMatrix::~ExpressionMatrix() {
delete m_matrixData;
}
Expression::Type ExpressionMatrix::type() const {
return Type::ExpressionMatrix;
}
Expression * ExpressionMatrix::clone() const {
return new ExpressionMatrix(m_matrixData->operands(), numberOfOperands(), numberOfRows(), numberOfColumns(), true);
}
int ExpressionMatrix::numberOfRows() const {
return m_matrixData->numberOfRows();
}
int ExpressionMatrix::numberOfColumns() const {
return m_matrixData->numberOfColumns();
}
const Expression * ExpressionMatrix::operand(int i) const {
assert(i >= 0);
assert(i < numberOfOperands());
return m_matrixData->operands()[i];
}
template<typename T>
Evaluation<T> * ExpressionMatrix::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
Complex<T> * operands = new Complex<T>[numberOfOperands()];
for (int i = 0; i < numberOfOperands(); i++) {
Evaluation<T> * operandEvaluation = operand(i)->evaluate<T>(context, angleUnit);
if (operandEvaluation->numberOfOperands() != 1) {
operands[i] = Complex<T>::Float(NAN);
} else {
operands[i] = *(operandEvaluation->complexOperand(0));
}
delete operandEvaluation;
}
Evaluation<T> * matrix = new ComplexMatrix<T>(operands, numberOfRows(), numberOfColumns());
delete[] operands;
return matrix;
}
}

View File

@@ -143,8 +143,8 @@ lstData:
| lstData COMMA exp { $$ = $1; $$->pushExpression($3); }
/* MATRICES_ARE_DEFINED */
mtxData:
LEFT_BRACKET lstData RIGHT_BRACKET { $$ = new Poincare::MatrixData($2, true); delete $2; }
| mtxData LEFT_BRACKET lstData RIGHT_BRACKET { $$ = $1; $$->pushListData($3, true); delete $3; }
LEFT_BRACKET lstData RIGHT_BRACKET { $$ = new Poincare::MatrixData($2, false); $2->detachOperands(); delete $2; }
| mtxData LEFT_BRACKET lstData RIGHT_BRACKET { $$ = $1; $$->pushListData($3, false); $3->detachOperands(); delete $3; }
number:
DIGITS { $$ = new Poincare::Rational(Poincare::Integer($1.address, false)); }
@@ -180,8 +180,8 @@ exp:
| MINUS exp %prec UNARY_MINUS { Poincare::Expression * terms[1] = {$2}; $$ = new Poincare::Opposite(terms, false); }
| LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { Poincare::Expression * terms[1] = {$2}; $$ = new Poincare::Parenthesis(terms, false); }
/* MATRICES_ARE_DEFINED */
| LEFT_BRACKET mtxData RIGHT_BRACKET { $$ = new Poincare::ExpressionMatrix($2); }
| FUNCTION LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { $$ = $1; if (!$1->hasValidNumberOfOperands($3->numberOfOperands())) { delete $1; delete $3; YYERROR; } ; $1->setArgument($3, $3->numberOfOperands(), true); delete $3; }
| LEFT_BRACKET mtxData RIGHT_BRACKET { $$ = new Poincare::Matrix($2); delete $2; }
| FUNCTION LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { $$ = $1; if (!$1->hasValidNumberOfOperands($3->numberOfOperands())) { delete $1; delete $3; YYERROR; } ; $1->setArgument($3, $3->numberOfOperands(), false); $3->detachOperands(); delete $3; }
final_exp:
exp { $$ = $1; }

View File

@@ -4,6 +4,7 @@
#include <poincare/rational.h>
#include <poincare/undefined.h>
#include <poincare/symbol.h>
#include <poincare/simplification_engine.h>
#include <ion.h>
extern "C" {
#include <assert.h>
@@ -31,11 +32,17 @@ Expression * Factorial::shallowReduce(Context& context, AngleUnit angleUnit) {
if (e != this) {
return e;
}
if (operand(0)->type() == Type::Matrix) {
return SimplificationEngine::map(this, context, angleUnit);
}
if (operand(0)->type() == Type::Rational) {
Rational * r = static_cast<Rational *>(editableOperand(0));
if (!r->denominator().isOne()) {
return replaceWith(new Undefined(), true);
}
if (Integer(k_maxOperandValue).isLowerThan(r->numerator())) {
return this;
}
Rational * fact = new Rational(Integer::Factorial(r->numerator()));
return replaceWith(fact, true);
}

Some files were not shown because too many files have changed in this diff Show More