mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-25 16:50:50 +01:00
[poincare] First version of Simplification with matrix (no tests yet!)
Change-Id: I28ad4750ad31995836b23725f7d715669fcb7ae2
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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\
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
16
poincare/include/poincare/simplification_engine.h
Normal file
16
poincare/include/poincare/simplification_engine.h
Normal 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
|
||||
@@ -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:
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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); }
|
||||
};
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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>;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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))));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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; }
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user