mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Redesign of Expression: first attempt
This commit is contained in:
@@ -40,7 +40,7 @@ Expression * Equation::standardForm(Context * context) const {
|
||||
m_standardForm = static_cast<const Equal *>(e)->standardEquation(*context, Preferences::sharedPreferences()->angleUnit());
|
||||
} else if (e->type() == Expression::Type::Rational && static_cast<Rational *>(e)->isOne()) {
|
||||
// The equality was reduced which means the equality was always true.
|
||||
m_standardForm = new Rational(0);
|
||||
m_standardForm = RationalReference(0);
|
||||
} else {
|
||||
// The equality has an undefined operand
|
||||
assert(e->type() == Expression::Type::Undefined);
|
||||
|
||||
@@ -11,23 +11,22 @@ class AbsoluteValue : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
Sign sign() const override { return Sign::Positive; }
|
||||
private:
|
||||
Expression * setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "abs");
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,7 +18,6 @@ class Addition : public DynamicHierarchy {
|
||||
friend class Complex<double>;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
int privateGetPolynomialCoefficients(char symbolName, Expression * coefficients[]) const override;
|
||||
/* Evaluation */
|
||||
@@ -31,7 +30,7 @@ public:
|
||||
}
|
||||
private:
|
||||
/* Layout */
|
||||
bool needParenthesisWithParent(const Expression * e) const override;
|
||||
bool needsParenthesisWithParent(SerializableNode * parentNode) const override;
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutEngine::createInfixLayout(this, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
@@ -41,7 +40,7 @@ private:
|
||||
static const char * name() { return "+"; }
|
||||
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
Expression * shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
Expression * factorizeOnCommonDenominator(Context & context, Preferences::AngleUnit angleUnit);
|
||||
void factorizeOperands(Expression * e1, Expression * e2, Context & context, Preferences::AngleUnit angleUnit);
|
||||
@@ -51,10 +50,10 @@ private:
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrixAndComplex(const MatrixComplex<T> m, const std::complex<T> c) {
|
||||
return ApproximationEngine::elementWiseOnMatrixComplexAndComplex(m, c, compute<T>);
|
||||
}
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
39
poincare/include/poincare/allocation_failed_evaluation.h
Normal file
39
poincare/include/poincare/allocation_failed_evaluation.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef POINCARE_ALLOCATION_FAILED_EVALUATION_H
|
||||
#define POINCARE_ALLOCATION_FAILED_EVALUATION_H
|
||||
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<typename T>
|
||||
class AllocationFailedEvaluationNode : public EvaluationNode<T> {
|
||||
public:
|
||||
// EvaluationNode
|
||||
typename EvaluationNode<T>::Type type() const override { return EvaluationNode<T>::Type::AllocationFailure; }
|
||||
bool isUndefined() const override { return true; }
|
||||
T toScalar() const override{ return NAN; }
|
||||
ExpressionReference complexToExpression(Preferences::Preferences::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> trace() const override { return std::complex<T>(NAN); }
|
||||
std::complex<T> determinant() const override { return std::complex<T>(NAN); }
|
||||
EvaluationReference<T> inverse() const override { return ComplexReference<T>::Undefined(); }
|
||||
virtual EvaluationReference<T> transpose() const override { return ComplexReference<T>::Undefined(); }
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(AllocationFailedEvaluationNode); }
|
||||
const char * description() const override { return "Allocation Failed"; }
|
||||
bool isAllocationFailure() const override { return true; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class AllocationFailedEvaluationReference : public EvaluationReference<T> {
|
||||
public:
|
||||
AllocationFailedEvaluationReference() : EvaluationReference<T>() {
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<AllocationFailedEvaluationNode<T>>();
|
||||
this->m_identifier = node->identifier();
|
||||
}
|
||||
AllocationFailedEvaluationReference(TreeNode * n) : EvaluationReference<T>(n) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef POINCARE_ALLOCATION_FAILED_EXPRESSION_NODE_H
|
||||
#define POINCARE_ALLOCATION_FAILED_EXPRESSION_NODE_H
|
||||
|
||||
#include <poincare/expression_node.h>
|
||||
#include <poincare/expression_reference.h>
|
||||
#include <poincare/complex.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class AllocationFailedExpressionNode : public ExpressionNode {
|
||||
public:
|
||||
// ExpressionNode
|
||||
Type type() const override { return Type::AllocationFailure; }
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return ComplexReference<float>::Undefined(); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return ComplexReference<double>::Undefined(); }
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(AllocationFailedExpressionNode); }
|
||||
const char * description() const override { return "Allocation Failed"; }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
bool isAllocationFailure() const override { return true; }
|
||||
};
|
||||
|
||||
class AllocationFailedExpressionRef : public ExpressionReference {
|
||||
public:
|
||||
AllocationFailedExpressionRef() : ExpressionReference() {
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<AllocationFailedExpressionNode>();
|
||||
m_identifier = node->identifier();
|
||||
}
|
||||
AllocationFailedExpressionRef(TreeNode * n) : ExpressionReference(n) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
#ifndef POINCARE_APPROXIMATION_H
|
||||
#define POINCARE_APPROXIMATION_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
/* Approximation reprensents an approximated complex. This class is
|
||||
* theoritecally unecessary as it can be reprensented by an Addition of Decimals
|
||||
* and I Symbol for example. However, performances are dramatically affected if
|
||||
* we keep turning float/double into Decimal back and forth (for instance, when
|
||||
* plotting a graph, we need to set a float/double value for a symbol and
|
||||
* approximate an expression containing the symbol for each dot displayed). We
|
||||
* thus use the Approximation class that hold an std::complex<T> and can only
|
||||
* be approximated. Indeed, the usual methods of expression are not implemented
|
||||
* to avoid code duplication with Decimal. */
|
||||
|
||||
template<typename T>
|
||||
class Approximation : public Expression {
|
||||
public:
|
||||
Approximation(T a, T b = 0.0) :
|
||||
Expression(),
|
||||
m_complex(a, b)
|
||||
{}
|
||||
Type type() const override {
|
||||
return Expression::Type::Approximation;
|
||||
}
|
||||
Expression * clone() const override {
|
||||
return new Approximation(m_complex.real(), m_complex.imag());
|
||||
}
|
||||
const Expression * const * operands() const override {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
int numberOfOperands() const override {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename U> Complex<U> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
return new Complex<U>((U)m_complex.real(), (U)m_complex.imag());
|
||||
}
|
||||
std::complex<T> m_complex;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef POINCARE_APPROXIMATION_ENGINE_H
|
||||
#define POINCARE_APPROXIMATION_ENGINE_H
|
||||
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/complex.h>
|
||||
#include <poincare/matrix_complex.h>
|
||||
#include <poincare/expression_node.h>
|
||||
#include <complex>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -11,17 +12,17 @@ class ApproximationEngine {
|
||||
public:
|
||||
template <typename T> static std::complex<T> truncateRealOrImaginaryPartAccordingToArgument(std::complex<T> c);
|
||||
|
||||
template <typename T> using ComplexCompute = std::complex<T>(*)(const std::complex<T>, Preferences::AngleUnit angleUnit);
|
||||
template<typename T> static Evaluation<T> * map(const Expression * expression, Context& context, Preferences::AngleUnit angleUnit, ComplexCompute<T> compute);
|
||||
template <typename T> using ComplexCompute = ComplexReference<T>(*)(const std::complex<T>, Preferences::AngleUnit angleUnit);
|
||||
template<typename T> static EvaluationReference<T> map(const ExpressionNode * expression, Context& context, Preferences::AngleUnit angleUnit, ComplexCompute<T> compute);
|
||||
|
||||
template <typename T> using ComplexAndComplexReduction = std::complex<T>(*)(const std::complex<T>, const std::complex<T>);
|
||||
template <typename T> using ComplexAndMatrixReduction = MatrixComplex<T>(*)(const std::complex<T> c, const MatrixComplex<T> m);
|
||||
template <typename T> using MatrixAndComplexReduction = MatrixComplex<T>(*)(const MatrixComplex<T> m, const std::complex<T> c);
|
||||
template <typename T> using MatrixAndMatrixReduction = MatrixComplex<T>(*)(const MatrixComplex<T> m, const MatrixComplex<T> n);
|
||||
template<typename T> static Evaluation<T> * mapReduce(const Expression * expression, Context& context, Preferences::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices);
|
||||
template <typename T> using ComplexAndComplexReduction = ComplexReference<T>(*)(const std::complex<T>, const std::complex<T>);
|
||||
template <typename T> using ComplexAndMatrixReduction = MatrixComplexReference<T>(*)(const std::complex<T> c, const MatrixComplexReference<T> m);
|
||||
template <typename T> using MatrixAndComplexReduction = MatrixComplexReference<T>(*)(const MatrixComplexReference<T> m, const std::complex<T> c);
|
||||
template <typename T> using MatrixAndMatrixReduction = MatrixComplexReference<T>(*)(const MatrixComplexReference<T> m, const MatrixComplexReference<T> n);
|
||||
template<typename T> static EvaluationReference<T> mapReduce(const ExpressionNode * expression, Context& context, Preferences::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices);
|
||||
|
||||
template<typename T> static MatrixComplex<T> elementWiseOnMatrixComplexAndComplex(const MatrixComplex<T> n, const std::complex<T> c, ComplexAndComplexReduction<T> computeOnComplexes);
|
||||
template<typename T> static MatrixComplex<T> elementWiseOnComplexMatrices(const MatrixComplex<T> m, const MatrixComplex<T> n, ComplexAndComplexReduction<T> computeOnComplexes);
|
||||
template<typename T> static MatrixComplexReference<T> elementWiseOnMatrixComplexAndComplex(const MatrixComplexReference<T> n, std::complex<T> c, ComplexAndComplexReduction<T> computeOnComplexes);
|
||||
template<typename T> static MatrixComplexReference<T> elementWiseOnComplexMatrices(const MatrixComplexReference<T> m, const MatrixComplexReference<T> n, ComplexAndComplexReduction<T> computeOnComplexes);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ class ArcCosine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -25,13 +24,13 @@ private:
|
||||
return "acos";
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,7 +12,6 @@ class ArcSine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -23,13 +22,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "asin"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,7 +12,6 @@ class ArcTangent : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -23,13 +22,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "atan"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,11 +6,11 @@ namespace Poincare {
|
||||
|
||||
class Arithmetic {
|
||||
public:
|
||||
static Integer LCM(const Integer * i, const Integer * j);
|
||||
static Integer GCD(const Integer * i, const Integer * j);
|
||||
static IntegerReference LCM(const IntegerReference i, const IntegerReference j);
|
||||
static IntegerReference GCD(const IntegerReference i, const IntegerReference j);
|
||||
/* When outputCoefficients[0] is set to -1, that indicates a special case:
|
||||
* i could not be factorized. */
|
||||
static void PrimeFactorization(const Integer * i, Integer * outputFactors, Integer * outputCoefficients, int outputLength);
|
||||
static void PrimeFactorization(const IntegerReference i, IntegerReference outputFactors[], IntegerReference outputCoefficients[], int outputLength);
|
||||
constexpr static int k_numberOfPrimeFactors = 1000;
|
||||
constexpr static int k_maxNumberOfPrimeFactors = 32;
|
||||
private:
|
||||
|
||||
@@ -11,7 +11,6 @@ class BinomialCoefficient : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
template<typename T> static T compute(T k, T n);
|
||||
private:
|
||||
constexpr static int k_maxNValue = 300;
|
||||
@@ -21,11 +20,11 @@ private:
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "binomial");
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ class Ceiling : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
@@ -20,13 +19,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "ceil"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
46
poincare/include/poincare/complex.h
Normal file
46
poincare/include/poincare/complex.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef POINCARE_COMPLEX_H
|
||||
#define POINCARE_COMPLEX_H
|
||||
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<typename T>
|
||||
class ComplexReference;
|
||||
|
||||
template<typename T>
|
||||
class ComplexNode : public std::complex<T>, public EvaluationNode<T> {
|
||||
public:
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(ComplexNode<T>); }
|
||||
const char * description() const override { return "Evaluation complex"; }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
|
||||
void setComplex(std::complex<T> c);
|
||||
typename Poincare::EvaluationNode<T>::Type type() const override { return Poincare::EvaluationNode<T>::Type::Complex; }
|
||||
bool isUndefined() const override {
|
||||
return (std::isnan(this->real()) && std::isnan(this->imag()));
|
||||
}
|
||||
T toScalar() const override;
|
||||
ExpressionReference complexToExpression(Preferences::Preferences::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> trace() const override { return *this; }
|
||||
std::complex<T> determinant() const override { return *this; }
|
||||
EvaluationReference<T> inverse() const override;
|
||||
EvaluationReference<T> transpose() const override { return ComplexReference<T>(*this); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ComplexReference : public std::complex<T>, public EvaluationReference<T> {
|
||||
public:
|
||||
ComplexReference(TreeNode * t) : EvaluationReference<T>(t) {}
|
||||
ComplexReference(T a, T b = 0.0) : ComplexReference(std::complex<T>(a, b)) {}
|
||||
ComplexReference(std::complex<T> c);
|
||||
static ComplexReference<T> Undefined() {
|
||||
return ComplexReference<T>(NAN, NAN);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -11,7 +11,6 @@ class ComplexArgument : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,13 +21,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "arg"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,7 +10,6 @@ class ConfidenceInterval : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -22,11 +21,11 @@ private:
|
||||
}
|
||||
virtual const char * name() const { return "confidence"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(Expression::SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<float> approximate(Expression::SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(Expression::DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
class SimplePredictionInterval : public ConfidenceInterval {
|
||||
|
||||
@@ -11,7 +11,6 @@ class Conjugate : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
@@ -19,13 +18,13 @@ private:
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "conj");
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#ifndef POINCARE_CONTEXT_H
|
||||
#define POINCARE_CONTEXT_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/symbol.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class ExpressionReference;
|
||||
class SymbolReference;
|
||||
|
||||
class Context {
|
||||
public:
|
||||
virtual const Expression * expressionForSymbol(const Symbol * symbol) = 0;
|
||||
virtual void setExpressionForSymbolName(const Expression * expression, const Symbol * symbol, Context & context) = 0;
|
||||
virtual const ExpressionReference expressionForSymbol(const SymbolReference symbol) = 0;
|
||||
virtual void setExpressionForSymbolName(const ExpressionReference expression, const SymbolReference symbol, Context & context) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ class Cosine : public StaticHierarchy<1>::StaticHierarchy {
|
||||
friend class Tangent;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian);
|
||||
private:
|
||||
@@ -27,12 +26,12 @@ private:
|
||||
}
|
||||
const char * name() const { return "cos"; }
|
||||
/* Simplication */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,24 +21,24 @@ public:
|
||||
Integer mantissa() const { return m_mantissa; }
|
||||
// Expression subclassing
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
Sign sign() const override { return m_mantissa.isNegative() ? Sign::Negative : Sign::Positive; }
|
||||
constexpr static int k_maxExponentLength = 4;
|
||||
private:
|
||||
constexpr static double k_biggestMantissaFromDouble = 999999999999999;
|
||||
constexpr static int k_maxDoubleExponent = 308;
|
||||
/* Comparison */
|
||||
int simplificationOrderSameType(const Expression * e, bool canBeInterrupted) const override;
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
/* Layout */
|
||||
bool needParenthesisWithParent(const Expression * e) const override;
|
||||
bool needsParenthesisWithParent(SerializableNode * parentNode) const override;
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
Expression * shallowBeautify(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowBeautify(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
int convertToText(char * buffer, int bufferSize, Preferences::PrintFloatMode mode, int numberOfSignificantDigits) const;
|
||||
// Worst case is -1.2345678901234E-1000
|
||||
|
||||
@@ -11,7 +11,6 @@ class Derivative : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -23,11 +22,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "diff"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> T growthRateAroundAbscissa(T x, T h, Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> T riddersApproximation(Context & context, Preferences::AngleUnit angleUnit, T x, T h, T * error) const;
|
||||
// TODO: Change coefficients?
|
||||
|
||||
@@ -10,7 +10,6 @@ class Determinant : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -21,11 +20,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "det"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -14,28 +14,27 @@ class Division : public StaticHierarchy<2> {
|
||||
friend class Power;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
template<typename T> static std::complex<T> compute(const std::complex<T> c, const std::complex<T> d);
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
private:
|
||||
/* Layout */
|
||||
bool needParenthesisWithParent(const Expression * e) const override;
|
||||
bool needsParenthesisWithParent(SerializableNode * parentNode) const override;
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "/");
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrixAndComplex(const MatrixComplex<T> m, const std::complex<T> c) {
|
||||
return ApproximationEngine::elementWiseOnMatrixComplexAndComplex(m, c, compute<T>);
|
||||
}
|
||||
template<typename T> static MatrixComplex<T> computeOnComplexAndMatrix(const std::complex<T> c, const MatrixComplex<T> n);
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrices(const MatrixComplex<T> m, const MatrixComplex<T> n);
|
||||
virtual Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
virtual EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
virtual Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
virtual EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,7 +12,6 @@ class DivisionQuotient : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -23,11 +22,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "quo"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ class DivisionRemainder : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,11 +21,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "rem"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ protected:
|
||||
int m_numberOfOperands;
|
||||
private:
|
||||
void removeOperandAtIndex(int i, bool deleteAfterRemoval);
|
||||
int simplificationOrderSameType(const Expression * e, bool canBeInterrupted) const override;
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
int simplificationOrderGreaterType(const Expression * e, bool canBeInterrupted) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,15 +13,14 @@ public:
|
||||
Type type() const override {
|
||||
return Type::EmptyExpression;
|
||||
}
|
||||
Expression * clone() const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,22 +11,21 @@ class Equal : public StaticHierarchy<2> {
|
||||
public:
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
// For the equation A = B, create the reduced expression A-B
|
||||
Expression * standardEquation(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "=");
|
||||
}
|
||||
/* Evalutation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -5,111 +5,58 @@
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
}
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/preferences.h>
|
||||
#include <poincare/tree_node.h>
|
||||
#include <poincare/tree_reference.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
/* acos, asin, arctan, acosh, asinh, arctanh and log have branch cuts on the
|
||||
* complex plan.
|
||||
* - acos, asin, atanh: ]-inf, -1[U]1, +inf[
|
||||
* - atan, asinh: ]-inf*i, -i[U]i, +inf*i[
|
||||
* - acosh: ]-inf, 1]
|
||||
* - log: ]-inf, 0]
|
||||
* They are then multivalued on these cuts. We followed the convention chosen
|
||||
* by the lib c++ of llvm but it might differ from a calculator to another
|
||||
* (ie acos(2) = -1.3169578969248*I or 1.3169578969248*I). */
|
||||
class ExpressionReference;
|
||||
template<typename T>
|
||||
class EvaluationReference;
|
||||
|
||||
template<typename T>
|
||||
class Evaluation {
|
||||
class EvaluationNode : public TreeNode {
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
AllocationFailure,
|
||||
Complex,
|
||||
MatrixComplex
|
||||
};
|
||||
EvaluationNode<T> * childAtIndex(int index) const override { return static_cast<EvaluationNode<T> *>(TreeNode::childAtIndex(index)); }
|
||||
virtual Type type() const = 0;
|
||||
virtual ~Evaluation() {}
|
||||
virtual ~EvaluationNode() = default;
|
||||
virtual bool isUndefined() const = 0;
|
||||
virtual T toScalar() const { return NAN; }
|
||||
virtual Expression * complexToExpression(Preferences::ComplexFormat complexFormat) const = 0;
|
||||
virtual std::complex<T> createTrace() const = 0;
|
||||
virtual std::complex<T> createDeterminant() const = 0;
|
||||
virtual Evaluation * createInverse() const = 0;
|
||||
virtual Evaluation * createTranspose() const = 0;
|
||||
};
|
||||
virtual ExpressionReference complexToExpression(Preferences::ComplexFormat complexFormat) const = 0;
|
||||
virtual std::complex<T> trace() const = 0;
|
||||
virtual std::complex<T> determinant() const = 0;
|
||||
virtual EvaluationReference<T> inverse() const = 0;
|
||||
virtual EvaluationReference<T> transpose() const = 0;
|
||||
|
||||
template <typename T>
|
||||
using ComplexFunction = std::complex<T> (*)(const std::complex<T>&);
|
||||
// TreeNode
|
||||
static TreeNode * FailedAllocationStaticNode();
|
||||
TreeNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
|
||||
|
||||
template<typename T>
|
||||
class Complex : public std::complex<T>, public Evaluation<T> {
|
||||
public:
|
||||
Complex(T a, T b = 0.0) : std::complex<T>(a, b) {}
|
||||
Complex(std::complex<T> c) : std::complex<T>(c) {
|
||||
if (this->real() == -0) {
|
||||
this->real(0);
|
||||
}
|
||||
if (this->imag() == -0) {
|
||||
this->imag(0);
|
||||
}
|
||||
}
|
||||
static Complex Undefined() {
|
||||
return Complex(NAN, NAN);
|
||||
}
|
||||
virtual ~Complex() {}
|
||||
typename Poincare::Evaluation<T>::Type type() const override { return Poincare::Evaluation<T>::Type::Complex; }
|
||||
bool isUndefined() const override {
|
||||
return (std::isnan(this->real()) && std::isnan(this->imag()));
|
||||
}
|
||||
T toScalar() const override;
|
||||
Expression * complexToExpression(Preferences::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> createTrace() const override { return *this; }
|
||||
std::complex<T> createDeterminant() const override { return *this; }
|
||||
Complex<T> * createInverse() const override;
|
||||
Complex<T> * createTranspose() const override { return new Complex<T>(*this); }
|
||||
/* Complex functions */
|
||||
static std::complex<T> pow(const std::complex<T> &c, const std::complex<T> &d);
|
||||
static std::complex<T> sqrt(const std::complex<T> &c) {
|
||||
return approximate(c, std::sqrt);
|
||||
}
|
||||
static std::complex<T> cos(const std::complex<T> &c) {
|
||||
return approximate(c, std::cos);
|
||||
}
|
||||
static std::complex<T> sin(const std::complex<T> &c) {
|
||||
return approximate(c, std::sin);
|
||||
}
|
||||
static std::complex<T> tan(const std::complex<T> &c) {
|
||||
return approximate(c, std::tan);
|
||||
}
|
||||
static std::complex<T> approximate(const std::complex<T>& c, ComplexFunction<T> approximation);
|
||||
// Tree
|
||||
//LayoutNode * childAtIndex(int i) { return static_cast<LayoutNode *>(TreeNode::childAtIndex(i)); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class MatrixComplex : public Evaluation<T> {
|
||||
class EvaluationReference : public TreeReference {
|
||||
public:
|
||||
MatrixComplex(std::complex<T> * operands, int numberOfRows, int numberOfColumns);
|
||||
static MatrixComplex Undefined() {
|
||||
std::complex<T> undef = std::complex<T>(NAN, NAN);
|
||||
return MatrixComplex<T>(&undef, 1, 1);
|
||||
}
|
||||
virtual ~MatrixComplex() {}
|
||||
typename Poincare::Evaluation<T>::Type type() const override { return Poincare::Evaluation<T>::Type::MatrixComplex; }
|
||||
const std::complex<T> complexOperand(int i) const { return m_operands[i]; }
|
||||
int numberOfComplexOperands() const { return m_numberOfRows*m_numberOfColumns; }
|
||||
int numberOfRows() const { return m_numberOfRows; }
|
||||
int numberOfColumns() const { return m_numberOfColumns; }
|
||||
bool isUndefined() const override {
|
||||
return (numberOfRows() == 1 && numberOfColumns() == 1 && std::isnan(complexOperand(0).real()) && std::isnan(complexOperand(0).imag()));
|
||||
}
|
||||
Expression * complexToExpression(Preferences::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> createTrace() const override;
|
||||
std::complex<T> createDeterminant() const override;
|
||||
MatrixComplex<T> * createInverse() const override;
|
||||
MatrixComplex<T> * createTranspose() const override;
|
||||
static MatrixComplex<T> createIdentity(int dim);
|
||||
private:
|
||||
std::complex<T> * m_operands;
|
||||
int m_numberOfRows;
|
||||
int m_numberOfColumns;
|
||||
EvaluationReference(TreeNode * t) : TreeReference(t) {}
|
||||
EvaluationNode<T> * node() const override{ return static_cast<EvaluationNode<T> *>(TreeReference::node()); }
|
||||
typename Poincare::EvaluationNode<T>::Type type() const { return node()->type(); }
|
||||
bool isUndefined() const { return node()->isUndefined(); }
|
||||
T toScalar() const { return node()->toScalar(); }
|
||||
ExpressionReference complexToExpression(Preferences::ComplexFormat complexFormat) const;
|
||||
std::complex<T> trace() const { return node()->trace(); }
|
||||
std::complex<T> determinant() const { return node()->determinant(); }
|
||||
EvaluationReference inverse() const { return node()->inverse(); }
|
||||
EvaluationReference transpose() const { return node()->transpose(); }
|
||||
protected:
|
||||
EvaluationReference() : TreeReference() {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -292,9 +292,9 @@ protected:
|
||||
private:
|
||||
virtual Expression * replaceSymbolWithExpression(char symbol, Expression * expression);
|
||||
/* Properties */
|
||||
virtual Expression * setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) { assert(false); return nullptr; }
|
||||
virtual ExpressionReference setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) { assert(false); return nullptr; }
|
||||
bool isOfType(Type * types, int length) const;
|
||||
virtual bool needParenthesisWithParent(const Expression * e) const;
|
||||
virtual bool needsParenthesisWithParent(SerializableNode * parentNode) const;
|
||||
virtual int privateGetPolynomialCoefficients(char symbolName, Expression * coefficients[]) const;
|
||||
/* Comparison */
|
||||
/* In the simplification order, most expressions are compared by only
|
||||
@@ -310,7 +310,7 @@ private:
|
||||
Expression * deepBeautify(Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression * deepReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
// TODO: should be virtual pure
|
||||
virtual Expression * shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
virtual ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
virtual Expression * shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) { return this; };
|
||||
|
||||
// Private methods used in simplification process
|
||||
@@ -318,8 +318,8 @@ private:
|
||||
return nullptr;
|
||||
}
|
||||
/* Evaluation Engine */
|
||||
virtual Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const = 0;
|
||||
virtual Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const = 0;
|
||||
virtual EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const = 0;
|
||||
virtual EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const = 0;
|
||||
|
||||
/* Expression roots/extrema solver*/
|
||||
constexpr static double k_solverPrecision = 1.0E-5;
|
||||
|
||||
165
poincare/include/poincare/expression_node.h
Normal file
165
poincare/include/poincare/expression_node.h
Normal file
@@ -0,0 +1,165 @@
|
||||
#ifndef POINCARE_EXPRESSION_NODE_H
|
||||
#define POINCARE_EXPRESSION_NODE_H
|
||||
|
||||
#include <poincare/serializable_node.h>
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/layout_reference.h>
|
||||
#include <poincare/context.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
/* Methods preceded by a '*!*' interfere with the expression pools which can
|
||||
* make 'this' outdated. They should only be call only be call in a wrapper on
|
||||
* ExpressionRef. */
|
||||
|
||||
class ExpressionNode : public SerializableNode {
|
||||
friend class ApproximationEngine;
|
||||
friend class SymbolNode;
|
||||
friend class NAryExpressionNode;
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
AllocationFailure = 0,
|
||||
Undefined = 1,
|
||||
Integer = 2,
|
||||
Rational,
|
||||
Decimal,
|
||||
Float,
|
||||
Infinity,
|
||||
Multiplication,
|
||||
Power,
|
||||
Addition,
|
||||
Factorial,
|
||||
Division,
|
||||
Store,
|
||||
Equal,
|
||||
Sine,
|
||||
Cosine,
|
||||
Tangent,
|
||||
AbsoluteValue,
|
||||
ArcCosine,
|
||||
ArcSine,
|
||||
ArcTangent,
|
||||
BinomialCoefficient,
|
||||
Ceiling,
|
||||
ComplexArgument,
|
||||
Conjugate,
|
||||
Derivative,
|
||||
Determinant,
|
||||
DivisionQuotient,
|
||||
DivisionRemainder,
|
||||
Factor,
|
||||
Floor,
|
||||
FracPart,
|
||||
GreatCommonDivisor,
|
||||
HyperbolicArcCosine,
|
||||
HyperbolicArcSine,
|
||||
HyperbolicArcTangent,
|
||||
HyperbolicCosine,
|
||||
HyperbolicSine,
|
||||
HyperbolicTangent,
|
||||
ImaginaryPart,
|
||||
Integral,
|
||||
LeastCommonMultiple,
|
||||
Logarithm,
|
||||
MatrixTrace,
|
||||
NaperianLogarithm,
|
||||
NthRoot,
|
||||
Opposite,
|
||||
Parenthesis,
|
||||
PermuteCoefficient,
|
||||
Product,
|
||||
Random,
|
||||
Randint,
|
||||
RealPart,
|
||||
Round,
|
||||
SquareRoot,
|
||||
Subtraction,
|
||||
Sum,
|
||||
Symbol,
|
||||
|
||||
Matrix,
|
||||
ConfidenceInterval,
|
||||
MatrixDimension,
|
||||
MatrixInverse,
|
||||
MatrixTranspose,
|
||||
PredictionInterval,
|
||||
EmptyExpression
|
||||
};
|
||||
/* Allocation failure */
|
||||
static TreeNode * FailedAllocationStaticNode();
|
||||
TreeNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
|
||||
|
||||
/* Poor man's RTTI */
|
||||
virtual Type type() const = 0;
|
||||
|
||||
/* Properties */
|
||||
enum class Sign {
|
||||
Negative = -1,
|
||||
Unknown = 0,
|
||||
Positive = 1
|
||||
};
|
||||
virtual Sign sign() const { return Sign::Unknown; }
|
||||
virtual bool isNumber() const { return false; }
|
||||
/*!*/ virtual ExpressionReference replaceSymbolWithExpression(char symbol, ExpressionReference expression);
|
||||
/*!*/ virtual ExpressionReference setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit);
|
||||
virtual int polynomialDegree(char symbolName) const;
|
||||
/*!*/ virtual int getPolynomialCoefficients(char symbolName, ExpressionReference coefficients[]) const;
|
||||
typedef bool (*isVariableTest)(char c);
|
||||
virtual int getVariables(isVariableTest isVariable, char * variables) const;
|
||||
virtual float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
bool isOfType(Type * types, int length) const;
|
||||
|
||||
// Useful to avoid parsing incorrect expressions as cos(2,3,4)
|
||||
virtual bool hasValidNumberOfOperands(int numberOfOperands) const { return numberOfChildren() == numberOfOperands; }
|
||||
|
||||
/* Comparison */
|
||||
|
||||
/* Simplification */
|
||||
/* SimplificationOrder returns:
|
||||
* 1 if e1 > e2
|
||||
* -1 if e1 < e2
|
||||
* 0 if e1 == e
|
||||
* The order groups like terms together to avoid quadratic complexity when
|
||||
* factorizing addition or multiplication. For example, it groups terms with
|
||||
* same bases together (ie Pi, Pi^3) and with same non-rational factors
|
||||
* together (ie Pi, 2*Pi).
|
||||
* Because SimplificationOrder is a recursive call, we sometimes enable its
|
||||
* interruption to avoid freezing in the simplification process. */
|
||||
static int SimplificationOrder(const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted = false);
|
||||
/* In the simplification order, most expressions are compared by only
|
||||
* comparing their types. However hierarchical expressions of same type would
|
||||
* compare their operands and thus need to reimplement
|
||||
* simplificationOrderSameType. Besides, operations that can be simplified
|
||||
* (ie +, *, ^, !) have specific rules to group like terms together and thus
|
||||
* reimplement simplificationOrderGreaterType. */
|
||||
virtual int simplificationOrderGreaterType(const ExpressionNode * e, bool canBeInterrupted) const { return -1; }
|
||||
//TODO: What should be the implementation for complex?
|
||||
virtual int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const { return 0; }
|
||||
|
||||
/* Layout Engine */
|
||||
virtual LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const = 0;
|
||||
|
||||
/* Evaluation Engine */
|
||||
typedef float SinglePrecision;
|
||||
typedef double DoublePrecision;
|
||||
constexpr static int k_maxNumberOfSteps = 10000;
|
||||
virtual EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const = 0;
|
||||
virtual EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const = 0;
|
||||
|
||||
/* Simplification */
|
||||
/*!*/ virtual ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
/*!*/ virtual ExpressionReference shallowBeautify(Context & context, Preferences::AngleUnit angleUnit);
|
||||
|
||||
protected:
|
||||
// Private methods used in simplification process
|
||||
/*!*/ virtual ExpressionReference cloneDenominator(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
/* Hierarchy */
|
||||
ExpressionNode * childAtIndex(int i) const override { return static_cast<ExpressionNode *>(SerializableNode::childAtIndex(i)); }
|
||||
ExpressionNode * parent() const override { return static_cast<ExpressionNode *>(SerializableNode::parent()); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
234
poincare/include/poincare/expression_reference.h
Normal file
234
poincare/include/poincare/expression_reference.h
Normal file
@@ -0,0 +1,234 @@
|
||||
#ifndef POINCARE_EXPRESSION_REFERENCE_H
|
||||
#define POINCARE_EXPRESSION_REFERENCE_H
|
||||
|
||||
#include <poincare/serializable_reference.h>
|
||||
#include <poincare/preferences.h>
|
||||
#include <poincare/print_float.h>
|
||||
#include <poincare/expression_node.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Context;
|
||||
|
||||
class ExpressionReference : public SerializableReference {
|
||||
friend class ExpressionNode;
|
||||
friend class NAryExpressionNode;
|
||||
friend class SymbolNode;
|
||||
public:
|
||||
using SerializableReference::SerializableReference;
|
||||
|
||||
/* Constructor & Destructor */
|
||||
virtual ~ExpressionReference() = default;
|
||||
static ExpressionReference parse(char const * string);
|
||||
static void ReplaceSymbolWithExpression(ExpressionReference * expressionAddress, char symbol, ExpressionReference expression);
|
||||
ExpressionReference clone() const;
|
||||
|
||||
/* Reference */
|
||||
ExpressionNode * node() const override { return static_cast<ExpressionNode *>(SerializableReference::node()); }
|
||||
|
||||
/* Circuit breaker */
|
||||
typedef bool (*CircuitBreaker)();
|
||||
static void setCircuitBreaker(CircuitBreaker cb);
|
||||
static bool shouldStopProcessing();
|
||||
|
||||
/* Properties */
|
||||
ExpressionNode::Sign sign() const { return node()->sign(); }
|
||||
ExpressionReference setSign(ExpressionNode::Sign s, Context & context, Preferences::AngleUnit angleUnit) { return node()->setSign(s, context, angleUnit); }
|
||||
bool isNumber() const { return node()->isNumber(); }
|
||||
bool isRationalZero() const;
|
||||
typedef bool (*ExpressionTest)(const ExpressionReference e, Context & context);
|
||||
bool recursivelyMatches(ExpressionTest test, Context & context) const;
|
||||
bool isApproximate(Context & context) const;
|
||||
static bool IsMatrix(const ExpressionReference e, Context & context);
|
||||
/* 'characteristicXRange' tries to assess the range on x where the expression
|
||||
* (considered as a function on x) has an interesting evolution. For example,
|
||||
* the period of the function on 'x' if it is periodic. If
|
||||
* the function is x-independent, the return value is 0.0f (because any
|
||||
* x-range is equivalent). If the function does not have an interesting range,
|
||||
* the return value is NAN.
|
||||
* NB: so far, we consider that the only way of building a periodic function
|
||||
* is to use sin/tan/cos(f(x)) with f a linear function. */
|
||||
float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { return this->node()->characteristicXRange(context, angleUnit); }
|
||||
/* polynomialDegree returns:
|
||||
* - (-1) if the expression is not a polynome
|
||||
* - the degree of the polynome otherwise */
|
||||
int polynomialDegree(char symbolName) const { return this->node()->polynomialDegree(symbolName); }
|
||||
/* getVariables fills the table variables with the variable present in the
|
||||
* expression and returns the number of entries in filled in variables.
|
||||
* For instance getVariables('x+y+2*w/cos(4)') would result in
|
||||
* variables = « xyw » and would return 3. If the final number of
|
||||
* variables would overflow the maxNumberOfVariables, getVariables return -1 */
|
||||
static constexpr int k_maxNumberOfVariables = 6;
|
||||
int getVariables(ExpressionNode::isVariableTest isVariable, char * variables) const { return this->node()->getVariables(isVariable, variables); }
|
||||
/* getLinearCoefficients return false if the expression is not linear with
|
||||
* the variables hold in 'variables'. Otherwise, it fills 'coefficients' with
|
||||
* the coefficients of the variables hold in 'variables' (following the same
|
||||
* order) and 'constant' with the constant of the expression. */
|
||||
bool getLinearCoefficients(char * variables, ExpressionReference coefficients[], ExpressionReference constant[], Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
/* getPolynomialCoefficients fills the table coefficients with the expressions
|
||||
* of the first 3 polynomial coefficients and return polynomialDegree.
|
||||
* coefficients has up to 3 entries. It supposed to be called on Reduced
|
||||
* expression. */
|
||||
static constexpr int k_maxPolynomialDegree = 2;
|
||||
static constexpr int k_maxNumberOfPolynomialCoefficients = k_maxPolynomialDegree+1;
|
||||
int getPolynomialCoefficients(char symbolName, ExpressionReference coefficients[], Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
/* Comparison */
|
||||
/* isIdenticalTo is the "easy" equality, it returns true if both trees have
|
||||
* same structures and all their nodes have same types and values (ie,
|
||||
* sqrt(pi^2) is NOT identical to pi). */
|
||||
bool isIdenticalTo(const ExpressionReference e) const {
|
||||
/* We use the simplification order only because it is a already-coded total
|
||||
* order on expresssions. */
|
||||
return ExpressionNode::SimplificationOrder(this->node(), e.node(), true) == 0;
|
||||
}
|
||||
bool isEqualToItsApproximationLayout(ExpressionReference approximation, int bufferSize, Preferences::AngleUnit angleUnit, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, Context & context);
|
||||
|
||||
/* Layout Engine */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return this->node()->createLayout(floatDisplayMode, numberOfSignificantDigits); }
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const { return this->node()->writeTextInBuffer(buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits); }
|
||||
|
||||
/* Simplification */
|
||||
static ExpressionReference ParseAndSimplify(const char * text, Context & context, Preferences::AngleUnit angleUnit);
|
||||
static void Simplify(ExpressionReference * expressionAddress, Context & context, Preferences::AngleUnit angleUnit);
|
||||
|
||||
/* Approximation Engine */
|
||||
template<typename U> ExpressionReference approximate(Context& context, Preferences::AngleUnit angleUnit, Preferences::Preferences::ComplexFormat complexFormat) const;
|
||||
template<typename U> U approximateToScalar(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename U> static U approximateToScalar(const char * text, Context& context, Preferences::AngleUnit angleUnit);
|
||||
template<typename U> U approximateWithValueForSymbol(char symbol, U x, Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
/* Expression roots/extrema solver*/
|
||||
struct Coordinate2D {
|
||||
double abscissa;
|
||||
double value;
|
||||
};
|
||||
Coordinate2D nextMinimum(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
Coordinate2D nextMaximum(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
double nextRoot(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
Coordinate2D nextIntersection(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit, const ExpressionReference expression) const;
|
||||
|
||||
private:
|
||||
/* Hierarchy */
|
||||
ExpressionReference childAtIndex(int i) const {
|
||||
return ExpressionReference(TreeReference::treeChildAtIndex(i).node());
|
||||
}
|
||||
|
||||
/* Simplification */
|
||||
ExpressionReference deepBeautify(Context & context, Preferences::AngleUnit angleUnit);
|
||||
ExpressionReference deepReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
// TODO: should be virtual pure
|
||||
virtual ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) { return this->node()->shallowReduce(context, angleUnit); }
|
||||
virtual ExpressionReference shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) { return this->node()->shallowBeautify(context, angleUnit); };
|
||||
|
||||
/* Approximation */
|
||||
template<typename U> static U epsilon();
|
||||
|
||||
/* Expression roots/extrema solver*/
|
||||
constexpr static double k_solverPrecision = 1.0E-5;
|
||||
constexpr static double k_sqrtEps = 1.4901161193847656E-8; // sqrt(DBL_EPSILON)
|
||||
constexpr static double k_goldenRatio = 0.381966011250105151795413165634361882279690820194237137864; // (3-sqrt(5))/2
|
||||
constexpr static double k_maxFloat = 1e100;
|
||||
typedef double (*EvaluationAtAbscissa)(char symbol, double abscissa, Context & context, Preferences::AngleUnit angleUnit, const ExpressionReference expression0, const ExpressionReference expression1);
|
||||
Coordinate2D nextMinimumOfExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const ExpressionReference expression = ExpressionReference(nullptr), bool lookForRootMinimum = false) const;
|
||||
void bracketMinimum(char symbol, double start, double step, double max, double result[3], EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const ExpressionReference expression = ExpressionReference(nullptr)) const;
|
||||
Coordinate2D brentMinimum(char symbol, double ax, double bx, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const ExpressionReference expression = ExpressionReference(nullptr)) const;
|
||||
double nextIntersectionWithExpression(char symbol, double start, double step, double max, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const ExpressionReference expression) const;
|
||||
void bracketRoot(char symbol, double start, double step, double max, double result[2], EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const ExpressionReference expression) const;
|
||||
double brentRoot(char symbol, double ax, double bx, double precision, EvaluationAtAbscissa evaluation, Context & context, Preferences::AngleUnit angleUnit, const ExpressionReference expression) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
class UndefinedNode : public ExpressionNode {
|
||||
public:
|
||||
// ExpressionNode
|
||||
Type type() const override { return Type::Undefined; }
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return Complex<float>::Undefined().storeEvaluation(); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return Complex<double>::Undefined().storeEvaluation(); }
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(UndefinedNode); }
|
||||
const char * description() const override { return "Allocation Failed"; }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
bool isAllocationFailure() const override { return true; }
|
||||
};
|
||||
|
||||
class SymbolNode : public ExpressionNode {
|
||||
public:
|
||||
bool isApproximate(Context & context) const;
|
||||
bool isMatrixSymbol() const;
|
||||
char name() const;
|
||||
// ExpressionNode
|
||||
Type type() const override { return Type::Undefined; }
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return Complex<float>::Undefined().storeEvaluation(); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return Complex<double>::Undefined().storeEvaluation(); }
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(UndefinedNode); }
|
||||
const char * description() const override { return "Allocation Failed"; }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
bool isAllocationFailure() const override { return true; }
|
||||
};
|
||||
|
||||
class RationalNode : public ExpressionNode {
|
||||
public:
|
||||
// ExpressionNode
|
||||
Type type() const override { return Type::Rational; }
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return Complex<float>::Undefined().storeEvaluation(); }
|
||||
Evaluation<double> * approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return Complex<double>::Undefined().storeEvaluation(); }
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(UndefinedNode); }
|
||||
const char * description() const override { return "Allocation Failed"; }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
bool isAllocationFailure() const override { return true; }
|
||||
};
|
||||
|
||||
class OppositeNode : public ExpressionNode {
|
||||
public:
|
||||
// ExpressionNode
|
||||
Type type() const override { return Type::Opposite; }
|
||||
Evaluation<float> * approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return Complex<float>::Undefined().storeEvaluation(); }
|
||||
Evaluation<double> * approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return Complex<double>::Undefined().storeEvaluation(); }
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(UndefinedNode); }
|
||||
const char * description() const override { return "Allocation Failed"; }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
bool isAllocationFailure() const override { return true; }
|
||||
};
|
||||
|
||||
|
||||
typedef ExpressionReference UndefinedRef;
|
||||
typedef ExpressionReference SymbolRef;
|
||||
class RationalRef : public ExpressionReference {
|
||||
public:
|
||||
RationalRef(int i) :
|
||||
ExpressionReference()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class OppositeRef : public ExpressionReference {
|
||||
public:
|
||||
OppositeRef(ExpressionReference child) :
|
||||
ExpressionReference()
|
||||
{
|
||||
}
|
||||
};
|
||||
*/
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,6 @@ class Factor : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -24,12 +23,12 @@ private:
|
||||
}
|
||||
const char * name() const { return "factor"; }
|
||||
/* Simplification */
|
||||
Expression * shallowBeautify(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowBeautify(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
Expression * createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context & context, Preferences::AngleUnit angleUnit);
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
return operand(0)->privateApproximate(T(), context, angleUnit);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,22 +10,21 @@ class Factorial : public StaticHierarchy<1> {
|
||||
public:
|
||||
Factorial(const Expression * argument, bool clone = true);
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
constexpr static int k_maxOperandValue = 100;
|
||||
/* Layout */
|
||||
bool needParenthesisWithParent(const Expression * e) const override;
|
||||
bool needsParenthesisWithParent(SerializableNode * parentNode) const override;
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Simplication */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
Expression * shallowBeautify(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowBeautify(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
|
||||
|
||||
68
poincare/include/poincare/float.h
Normal file
68
poincare/include/poincare/float.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef POINCARE_FLOAT_H
|
||||
#define POINCARE_FLOAT_H
|
||||
|
||||
#include <poincare/number.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
/* Float reprensents an approximated number. This class is use when:
|
||||
* - a rational overflows
|
||||
* - to avoid turning float/double into Decimal back and forth because
|
||||
* performances are dramatically affected when doing so. For instance, when
|
||||
* plotting a graph, we need to set a float/double value for a symbol and
|
||||
* approximate an expression containing the symbol for each dot displayed).
|
||||
* We thus use the Float class that hold a float/double.
|
||||
* Float can only be approximated ; Float is an INTERNAL node only. Indeed,
|
||||
* they are always turned back into Decimal when beautifying. Thus, the usual
|
||||
* methods of expression are not implemented to avoid code duplication with
|
||||
* Decimal. */
|
||||
|
||||
template<typename T>
|
||||
class FloatNode : public NumberNode {
|
||||
public:
|
||||
void setFloat(T a) { m_value = a; }
|
||||
T value() const { return m_value; }
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(FloatNode<T>); }
|
||||
const char * description() const override { return "Float"; }
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::Float; }
|
||||
|
||||
// Layout
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
/* Evaluation */
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
private:
|
||||
template<typename U> EvaluationReference<U> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
return ComplexReference<U>((U)m_value);
|
||||
}
|
||||
T m_value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class FloatReference : public NumberReference {
|
||||
public:
|
||||
FloatReference(T value) : NumberReference() {
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<RationalNode>();
|
||||
m_identifier = node->identifier();
|
||||
if (!node->isAllocationFailure()) {
|
||||
static_cast<FloatNode<T> *>(node)->setFloat(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -11,7 +11,6 @@ class Floor : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
@@ -20,13 +19,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "floor"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@ class FracPart : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,13 +21,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "frac"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -15,24 +15,19 @@ class Integer;
|
||||
class GlobalContext : public Context {
|
||||
public:
|
||||
GlobalContext();
|
||||
~GlobalContext();
|
||||
GlobalContext(const GlobalContext& other) = delete;
|
||||
GlobalContext(GlobalContext&& other) = delete;
|
||||
GlobalContext& operator=(const GlobalContext& other) = delete;
|
||||
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;
|
||||
LayoutRef layoutForSymbol(const Symbol * symbol, int numberOfSignificantDigits);
|
||||
void setExpressionForSymbolName(const Expression * expression, const Symbol * symbol, Context & context) override;
|
||||
const ExpressionReference expressionForSymbol(const SymbolReference symbol) override;
|
||||
LayoutRef layoutForSymbol(const SymbolReference symbol, int numberOfSignificantDigits);
|
||||
void setExpressionForSymbolName(const ExpressionReference expression, const SymbolReference symbol, Context & context) override;
|
||||
static constexpr uint16_t k_maxNumberOfScalarExpressions = 26;
|
||||
static constexpr uint16_t k_maxNumberOfListExpressions = 10;
|
||||
static constexpr uint16_t k_maxNumberOfMatrixExpressions = 10;
|
||||
private:
|
||||
static Decimal * defaultExpression();
|
||||
int symbolIndex(const Symbol * symbol) const;
|
||||
Expression * m_expressions[k_maxNumberOfScalarExpressions];
|
||||
Matrix * m_matrixExpressions[k_maxNumberOfMatrixExpressions];
|
||||
ExpressionReference m_expressions[k_maxNumberOfScalarExpressions];
|
||||
MatrixReference m_matrixExpressions[k_maxNumberOfMatrixExpressions];
|
||||
/* Matrix layout memoization */
|
||||
LayoutRef m_matrixLayouts[k_maxNumberOfMatrixExpressions];
|
||||
Approximation<double> m_pi;
|
||||
|
||||
@@ -11,7 +11,6 @@ class GreatCommonDivisor : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,11 +21,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "gcd"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ class HyperbolicArcCosine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,13 +21,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "acosh"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@ class HyperbolicArcSine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,13 +21,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "asinh"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@ class HyperbolicArcTangent : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,13 +21,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "atanh"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@ class HyperbolicCosine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -23,12 +22,12 @@ private:
|
||||
}
|
||||
const char * name() const { return "cosh"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@ class HyperbolicSine : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -23,12 +22,12 @@ private:
|
||||
}
|
||||
const char * name() const { return "sinh"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@ class HyperbolicTangent : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -23,12 +22,12 @@ private:
|
||||
}
|
||||
const char * name() const { return "tanh"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@ class ImaginaryPart : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,13 +21,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "im"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
49
poincare/include/poincare/infinity.h
Normal file
49
poincare/include/poincare/infinity.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef POINCARE_INFINITY_H
|
||||
#define POINCARE_INFINITY_H
|
||||
|
||||
#include <poincare/number.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class InfinityNode : public NumberNode {
|
||||
public:
|
||||
void setNegative(bool negative) { m_negative = negative; }
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(InfinityNode); }
|
||||
const char * description() const override { return "Infinity"; }
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::Infinity; }
|
||||
Sign sign() const override { return m_negative ? Sign::Negative : Sign::Positive; }
|
||||
|
||||
// Approximation
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templatedApproximate<float>();
|
||||
}
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templatedApproximate<double>();
|
||||
}
|
||||
|
||||
// Layout
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
private:
|
||||
template<typename T> EvaluationReference<T> templatedApproximate() const;
|
||||
bool m_negative;
|
||||
};
|
||||
|
||||
class InfinityReference : public NumberReference {
|
||||
public:
|
||||
InfinityReference(bool negative) {
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<InfinityNode>();
|
||||
m_identifier = node->identifier();
|
||||
if (!node->isAllocationFailure()) {
|
||||
static_cast<InfinityNode *>(node)->setNegative(negative);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,54 +3,33 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <poincare/number.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class ExpressionLayout;
|
||||
class LayoutReference;
|
||||
class LayoutNode;
|
||||
class IntegerReference;
|
||||
struct IntegerDivisionReference;
|
||||
|
||||
typedef uint16_t half_native_uint_t;
|
||||
typedef int32_t native_int_t;
|
||||
typedef int64_t double_native_int_t;
|
||||
typedef uint32_t native_uint_t;
|
||||
typedef uint64_t double_native_uint_t;
|
||||
|
||||
/* All algorithm should be improved with:
|
||||
* Modern Computer Arithmetic, Richard P. Brent and Paul Zimmermann */
|
||||
|
||||
struct IntegerDivision;
|
||||
|
||||
class Integer {
|
||||
class NaturalIntegerAbstract {
|
||||
friend class IntegerReference;
|
||||
friend class RationalReference;
|
||||
public:
|
||||
typedef uint16_t half_native_uint_t;
|
||||
typedef int32_t native_int_t;
|
||||
typedef int64_t double_native_int_t;
|
||||
typedef uint32_t native_uint_t;
|
||||
typedef uint64_t double_native_uint_t;
|
||||
|
||||
// FIXME: This constructor should be constexpr
|
||||
Integer(native_int_t i = 0) :
|
||||
m_digit(i>0 ? i : -i),
|
||||
m_numberOfDigits(1),
|
||||
m_negative(i<0)
|
||||
{
|
||||
}
|
||||
Integer(double_native_int_t i);
|
||||
Integer(const char * digits, bool negative = false); // Digits are NOT NULL-terminated
|
||||
static Integer exponent(int fractionalPartLength, const char * exponent, int exponentLength, bool exponentNegative);
|
||||
static Integer numerator(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, bool negative, Integer * exponent);
|
||||
static Integer denominator(Integer * exponent);
|
||||
|
||||
~Integer();
|
||||
Integer(Integer&& other); // C++11 move constructor
|
||||
Integer& operator=(Integer&& other); // C++11 move assignment operator
|
||||
Integer(const Integer& other); // C++11 copy constructor
|
||||
Integer& operator=(const Integer& other); // C++11 copy assignment operator
|
||||
|
||||
// Getter & Setter
|
||||
bool isNegative() const { return m_negative; }
|
||||
void setNegative(bool negative);
|
||||
int extractedInt() const { assert(m_numberOfDigits == 1 && m_digit <= k_maxExtractableInteger); return m_negative ? -m_digit : m_digit; }
|
||||
|
||||
// Comparison
|
||||
static int NaturalOrder(const Integer & i, const Integer & j);
|
||||
bool isEqualTo(const Integer & other) const;
|
||||
bool isLowerThan(const Integer & other) const;
|
||||
// Getters
|
||||
uint32_t digit(int i) const { assert(i < m_numberOfDigits); return digits()[i]; }
|
||||
size_t numberOfDigits() const { return m_numberOfDigits; }
|
||||
|
||||
// Layout
|
||||
int writeTextInBuffer(char * buffer, int bufferSize) const;
|
||||
@@ -59,36 +38,38 @@ public:
|
||||
// Approximation
|
||||
template<typename T> T approximate() const;
|
||||
|
||||
// Arithmetic
|
||||
static Integer Addition(const Integer & i, const Integer & j);
|
||||
static Integer Subtraction(const Integer & i, const Integer & j);
|
||||
static Integer Multiplication(const Integer & i, const Integer & j);
|
||||
static Integer Factorial(const Integer & i);
|
||||
static IntegerDivision Division(const Integer & numerator, const Integer & denominator);
|
||||
static Integer Power(const Integer & i, const Integer & j);
|
||||
static int numberOfDigitsWithoutSign(const Integer & i);
|
||||
//static Integer Division(const Integer & i, const Integer & j);
|
||||
//static IntegerDivision division(const Integer & i, const Integer & j);
|
||||
bool isOne() const { return (m_numberOfDigits == 1 && digit(0) == 1 && !m_negative); };
|
||||
bool isTwo() const { return (m_numberOfDigits == 1 && digit(0) == 2 && !m_negative); };
|
||||
bool isTen() const { return (m_numberOfDigits == 1 && digit(0) == 10 && !m_negative); };
|
||||
bool isMinusOne() const { return (m_numberOfDigits == 1 && digit(0) == 1 && m_negative); };
|
||||
bool isZero() const { return (m_numberOfDigits == 1 && digit(0) == 0); };
|
||||
constexpr static int k_maxExtractableInteger = 0x7FFFFFFF;
|
||||
private:
|
||||
Integer(const native_uint_t * digits, uint16_t numberOfDigits, bool negative);
|
||||
static Integer IntegerWithHalfDigitAtIndex(half_native_uint_t halfDigit, int index);
|
||||
// Properties
|
||||
static int numberOfDigits(const NaturalIntegerAbstract * i);
|
||||
virtual bool isOne() const { return (m_numberOfDigits == 1 && digit(0) == 1); };
|
||||
virtual bool isTwo() const { return (m_numberOfDigits == 1 && digit(0) == 2); };
|
||||
virtual bool isTen() const { return (m_numberOfDigits == 1 && digit(0) == 10); };
|
||||
bool isZero() const { return (m_numberOfDigits == 0); };
|
||||
bool isInfinity() const { return m_numberOfDigits > k_maxNumberOfDigits; }
|
||||
bool isEven() const { return (m_numberOfDigits == 0 || ((digit(0) & 1) == 0)); }
|
||||
|
||||
void releaseDynamicIvars();
|
||||
static int8_t ucmp(const Integer & a, const Integer & b); // -1, 0, or 1
|
||||
static Integer usum(const Integer & a, const Integer & b, bool subtract, bool outputNegative);
|
||||
static Integer addition(const Integer & a, const Integer & b, bool inverseBNegative);
|
||||
static IntegerDivision udiv(const Integer & a, const Integer & b);
|
||||
bool usesImmediateDigit() const { return m_numberOfDigits == 1; }
|
||||
native_uint_t digit(int i) const {
|
||||
assert(i >= 0 && i < m_numberOfDigits);
|
||||
return (usesImmediateDigit() ? m_digit : m_digits[i]);
|
||||
// Arithmetic
|
||||
/* buffer has to be k_maxNumberOfDigits+1 to allow ...*/
|
||||
static int8_t ucmp(const NaturalIntegerAbstract * a, const NaturalIntegerAbstract * b); // -1, 0, or 1
|
||||
static IntegerReference usum(const NaturalIntegerAbstract * a, const NaturalIntegerAbstract * b, bool subtract);
|
||||
static IntegerReference umult(const NaturalIntegerAbstract * a, const NaturalIntegerAbstract * b);
|
||||
static IntegerDivisionReference udiv(const NaturalIntegerAbstract * a, const NaturalIntegerAbstract * b);
|
||||
static IntegerReference upow(const NaturalIntegerAbstract * a, const NaturalIntegerAbstract * b);
|
||||
static IntegerReference ufact(const NaturalIntegerAbstract * a);
|
||||
|
||||
constexpr static int k_maxNumberOfDigits = 11;
|
||||
protected:
|
||||
constexpr static int k_maxNumberOfDigitsBase10 = 105; // (2^32)^k_maxNumberOfDigits-1 ~ 10^105
|
||||
NaturalIntegerAbstract(size_t numberOfDigits = 0) :
|
||||
m_numberOfDigits(numberOfDigits)
|
||||
{
|
||||
}
|
||||
virtual native_uint_t * digits() const = 0;
|
||||
virtual void setDigitAtIndex(native_uint_t digit, int index) = 0;
|
||||
|
||||
size_t m_numberOfDigits; // In base native_uint_max
|
||||
private:
|
||||
static IntegerReference IntegerWithHalfDigitAtIndex(half_native_uint_t halfDigit, int index);
|
||||
|
||||
uint16_t numberOfHalfDigits() const {
|
||||
native_uint_t d = digit(m_numberOfDigits-1);
|
||||
native_uint_t halfBase = 1 << (8*sizeof(half_native_uint_t));
|
||||
@@ -99,23 +80,128 @@ private:
|
||||
if (i >= numberOfHalfDigits()) {
|
||||
return 0;
|
||||
}
|
||||
return (usesImmediateDigit() ? ((half_native_uint_t *)&m_digit)[i] : ((half_native_uint_t *)m_digits)[i]);
|
||||
return ((half_native_uint_t *)digits())[i];
|
||||
}
|
||||
// Small integer optimization. Similar to short string optimization.
|
||||
union {
|
||||
const native_uint_t * m_digits; // Little-endian
|
||||
native_uint_t m_digit;
|
||||
};
|
||||
uint16_t m_numberOfDigits; // In base native_uint_max
|
||||
bool m_negative; // Make sure zero cannot be negative
|
||||
|
||||
static_assert(sizeof(native_int_t) <= sizeof(native_uint_t), "native_uint_t should be able to contain native_int_t data");
|
||||
static_assert(sizeof(double_native_int_t) <= sizeof(double_native_uint_t), "double_native_int_t type has not the right size compared to double_native_uint_t");
|
||||
static_assert(sizeof(native_int_t) == sizeof(native_uint_t), "native_int_t type has not the right size compared to native_uint_t");
|
||||
static_assert(sizeof(double_native_uint_t) == 2*sizeof(native_uint_t), "double_native_uint_t should be twice the size of native_uint_t");
|
||||
static_assert(sizeof(double_native_int_t) == 2*sizeof(native_int_t), "double_native_int_t type has not the right size compared to native_int_t");
|
||||
};
|
||||
|
||||
struct IntegerDivision {
|
||||
Integer quotient;
|
||||
Integer remainder;
|
||||
class NaturalIntegerPointer : public NaturalIntegerAbstract {
|
||||
public:
|
||||
NaturalIntegerPointer(native_uint_t * buffer, size_t size);
|
||||
private:
|
||||
native_uint_t * digits() const override { return m_digits; }
|
||||
void setDigitAtIndex(native_uint_t digit, int index) override { assert(index < m_numberOfDigits); m_digits[index] = digit; }
|
||||
native_uint_t * m_digits;
|
||||
};
|
||||
|
||||
class IntegerNode : public NumberNode, public NaturalIntegerAbstract {
|
||||
public:
|
||||
IntegerNode() :
|
||||
NaturalIntegerAbstract(),
|
||||
m_negative(false) {}
|
||||
void setDigits(native_int_t i);
|
||||
void setDigits(double_native_int_t i);
|
||||
void setDigits(const native_uint_t * digits, size_t size, bool negative);
|
||||
|
||||
// Getters
|
||||
native_uint_t * digits() const override { return (native_uint_t *)m_digits; }
|
||||
|
||||
// ExpressionNode
|
||||
Type type() const override { return Type::Integer; }
|
||||
|
||||
// Simplification
|
||||
ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
|
||||
// Approximation
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return ComplexReference<float>(templatedApproximate<float>()); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return ComplexReference<double>(templatedApproximate<double>()); }
|
||||
template<typename T> T templatedApproximate() const;
|
||||
|
||||
// Layout
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override;
|
||||
const char * description() const override { return "Integer"; }
|
||||
|
||||
// ExpressionNode
|
||||
Sign sign() const override { return m_negative ? Sign::Negative : Sign::Positive; }
|
||||
ExpressionReference setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
|
||||
void setNegative(bool negative);
|
||||
|
||||
// Comparison
|
||||
static int NaturalOrder(const IntegerNode * i, const IntegerNode * j);
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override { return NaturalOrder(this, static_cast<const IntegerNode *>(e)); }
|
||||
|
||||
// Properties
|
||||
bool isOne() const override { return (NaturalIntegerAbstract::isOne() && !m_negative); };
|
||||
bool isTwo() const override { return (NaturalIntegerAbstract::isTwo() && !m_negative); };
|
||||
bool isTen() const override{ return (NaturalIntegerAbstract::isTen() && !m_negative); };
|
||||
bool isMinusOne() const { return (NaturalIntegerAbstract::isOne() && m_negative); };
|
||||
private:
|
||||
void setDigitAtIndex(native_uint_t digit, int index) override { m_digits[index] = digit; }
|
||||
bool m_negative; // Make sure zero cannot be negative
|
||||
native_uint_t m_digits[0];
|
||||
};
|
||||
|
||||
|
||||
class IntegerReference : public NumberReference {
|
||||
friend class NaturalIntegerAbstract;
|
||||
friend class NaturalIntegerPointer;
|
||||
friend class IntegerNode;
|
||||
friend class RationalReference;
|
||||
public:
|
||||
IntegerReference(TreeNode * n) : NumberReference(n) {}
|
||||
IntegerReference(const char * digits, size_t length, bool negative);
|
||||
IntegerReference(const NaturalIntegerAbstract * naturalInteger);
|
||||
IntegerReference(native_int_t i);
|
||||
IntegerReference(double_native_int_t i);
|
||||
static IntegerReference Overflow() { return IntegerReference((native_uint_t *)nullptr, IntegerNode::k_maxNumberOfDigits+1, false); }
|
||||
|
||||
// TreeNode
|
||||
IntegerNode * typedNode() const { assert(node()->type() == ExpressionNode::Type::Integer); return static_cast<IntegerNode *>(node()); }
|
||||
|
||||
constexpr static int k_maxExtractableInteger = 0x7FFFFFFF;
|
||||
int extractedInt() const;
|
||||
|
||||
// Comparison
|
||||
static int NaturalOrder(const IntegerReference i, const IntegerReference j);
|
||||
|
||||
// Properties
|
||||
bool isZero() const;
|
||||
bool isOne() const;
|
||||
bool isInfinity() const;
|
||||
bool isEven() const;
|
||||
bool isNegative() const { return node()->sign() == ExpressionNode::Sign::Negative; }
|
||||
void setNegative(bool negative);
|
||||
|
||||
// Arithmetic
|
||||
static IntegerReference Addition(const IntegerReference i, const IntegerReference j);
|
||||
static IntegerReference Subtraction(const IntegerReference i, const IntegerReference j);
|
||||
static IntegerReference Multiplication(const IntegerReference i, const IntegerReference j);
|
||||
static IntegerDivisionReference Division(const IntegerReference numerator, const IntegerReference denominator);
|
||||
static IntegerReference Power(const IntegerReference i, const IntegerReference j);
|
||||
static IntegerReference Factorial(const IntegerReference i);
|
||||
private:
|
||||
IntegerReference(const native_uint_t * digits, size_t numberOfDigits, bool negative);
|
||||
IntegerReference(size_t size) : NumberReference() {
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<IntegerNode>(size);
|
||||
m_identifier = node->identifier();
|
||||
}
|
||||
static IntegerReference addition(const IntegerReference a, const IntegerReference b, bool inverseBNegative);
|
||||
size_t numberOfDigits() const { return typedNode()->numberOfDigits(); }
|
||||
uint32_t digit(int i) const { return typedNode()->digit(i); }
|
||||
};
|
||||
|
||||
struct IntegerDivisionReference {
|
||||
IntegerReference quotient;
|
||||
IntegerReference remainder;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ class Integral : public StaticHierarchy<3> {
|
||||
using StaticHierarchy<3>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -20,11 +19,11 @@ private:
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "int");
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T>
|
||||
struct DetailedResult
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef POINCARE_LAYOUT_ENGINE_H
|
||||
#define POINCARE_LAYOUT_ENGINE_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/expression_reference.h>
|
||||
#include <poincare/layout_reference.h>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -10,30 +10,14 @@ class LayoutEngine {
|
||||
|
||||
public:
|
||||
/* Expression to Layout */
|
||||
static LayoutRef createInfixLayout(const Expression * expression, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, const char * operatorName);
|
||||
static LayoutRef createPrefixLayout(const Expression * expression, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, const char * operatorName);
|
||||
static LayoutRef createInfixLayout(const ExpressionReference expression, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, const char * operatorName);
|
||||
static LayoutRef createPrefixLayout(const ExpressionReference expression, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, const char * operatorName);
|
||||
|
||||
/* Create special layouts */
|
||||
static LayoutRef createParenthesedLayout(LayoutRef layout, bool cloneLayout);
|
||||
static LayoutRef createStringLayout(const char * buffer, int bufferSize, KDText::FontSize fontSize = KDText::FontSize::Large);
|
||||
static LayoutRef createLogLayout(LayoutRef argument, LayoutRef index);
|
||||
|
||||
/* Expression to Text */
|
||||
static int writeInfixExpressionTextInBuffer(
|
||||
const Expression * expression,
|
||||
char * buffer,
|
||||
int bufferSize,
|
||||
Preferences::PrintFloatMode floatDisplayMode,
|
||||
int numberOfDigits,
|
||||
const char * operatorName);
|
||||
static int writePrefixExpressionTextInBuffer(
|
||||
const Expression * expression,
|
||||
char * buffer,
|
||||
int bufferSize,
|
||||
Preferences::PrintFloatMode floatDisplayMode,
|
||||
int numberOfDigits,
|
||||
const char * operatorName);
|
||||
|
||||
/* SerializableReference to Text */
|
||||
static int writeInfixSerializableRefTextInBuffer(
|
||||
const SerializableRef serializableRef,
|
||||
@@ -58,11 +42,6 @@ public:
|
||||
static int writeOneCharInBuffer(char * buffer, int bufferSize, char charToWrite);
|
||||
|
||||
private:
|
||||
static constexpr char divideChar = '/';
|
||||
// These two functions return the index of the null-terminating char.
|
||||
static int writeInfixExpressionOrExpressionLayoutTextInBuffer(const Expression * expression, void * expressionLayout, char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfDigits, const char * operatorName, int firstChildIndex, int lastChildIndex);
|
||||
static int writePrefixExpressionOrExpressionLayoutTextInBuffer(const Expression * expression, void * expressionLayout, char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfDigits, const char * operatorName, bool writeFirstChild = true);
|
||||
|
||||
static void writeChildTreeInBuffer(SerializableRef childRef, SerializableRef parentRef, char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfDigits, int * numberOfChar);
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ class LeastCommonMultiple : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,11 +21,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "lcm"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ class Logarithm : public BoundedStaticHierarchy<2> {
|
||||
friend class NaperianLogarithm;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
@@ -20,16 +19,16 @@ private:
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "log");
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
Expression * simpleShallowReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression * shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
bool parentIsAPowerOfSameBase() const;
|
||||
Expression * splitInteger(Integer i, bool isDenominator, Context & context, Preferences::AngleUnit angleUnit);
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,53 +1,72 @@
|
||||
#ifndef POINCARE_MATRIX_H
|
||||
#define POINCARE_MATRIX_H
|
||||
|
||||
#include <poincare/dynamic_hierarchy.h>
|
||||
#include <poincare/expression_reference.h>
|
||||
#include <poincare/matrix_data.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Multiplication;
|
||||
|
||||
class Matrix : public DynamicHierarchy {
|
||||
template<typename T> friend class MatrixComplex;
|
||||
class MatrixNode : public ExpressionNode {
|
||||
public:
|
||||
void setDimensions(int numberOfRows, int numberOfColumns) {
|
||||
m_numberOfRows = numberOfRows;
|
||||
m_numberOfColumns = m_numberOfColumns;
|
||||
}
|
||||
int numberOfRows() const { return m_numberOfRows; }
|
||||
int numberOfColumns() const { return m_numberOfColumns; }
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(MatrixNode); }
|
||||
const char * description() const override { return "Matrix"; }
|
||||
int numberOfChildren() const { return m_numberOfRows*m_numberOfColumns; }
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::Matrix; }
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
|
||||
// Approximation
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templatedApproximate<float>();
|
||||
}
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templatedApproximate<double>();
|
||||
}
|
||||
|
||||
// Layout
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
private:
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
class MatrixReference : public ExpressionReference {
|
||||
template<typename T> friend class MatrixComplexNode;
|
||||
friend class GlobalContext;
|
||||
public:
|
||||
Matrix(MatrixData * matrixData); // pilfer the operands of matrixData
|
||||
Matrix(const Expression * const * operands, int numberOfRows, int numberOfColumns, bool cloneOperands = true);
|
||||
Expression * matrixOperand(int i, int j) { return editableOperand(i*numberOfColumns()+j); }
|
||||
MatrixNode * typedNode() const { assert(!isAllocationFailure()); return static_cast<MatrixNode *>(node()); }
|
||||
int numberOfRows() const;
|
||||
int numberOfColumns() const;
|
||||
|
||||
/* Expression */
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
ExpressionReference matrixChild(int i, int j) { assert(!isAllocationFailure()); return childAtIndex(i*numberOfColumns()+j); }
|
||||
|
||||
/* Operation on matrix */
|
||||
int rank(Context & context, Preferences::AngleUnit angleUnit, bool inPlace);
|
||||
// Inverse the array in-place. Array has to be given in the form array[row_index][column_index]
|
||||
template<typename T> static int ArrayInverse(T * array, int numberOfRows, int numberOfColumns);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
//template<typename T> Expression * createTrace() const;
|
||||
//template<typename T> Expression * createDeterminant() const;
|
||||
Matrix * createTranspose() const;
|
||||
static Matrix * createIdentity(int dim);
|
||||
ExpressionReference trace() const;
|
||||
ExpressionReference determinant() const;
|
||||
MatrixReference transpose() const;
|
||||
static MatrixReference createIdentity(int dim);
|
||||
/* createInverse can be called on any matrix reduce or not, approximate or not. */
|
||||
Expression * createInverse(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
ExpressionReference inverse(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
#endif
|
||||
private:
|
||||
/* rowCanonize turns a matrix in its reduced row echelon form. */
|
||||
void rowCanonize(Context & context, Preferences::AngleUnit angleUnit, Multiplication * m = nullptr);
|
||||
// Row canonize the array in place
|
||||
template<typename T> static void ArrayRowCanonize(T * array, int numberOfRows, int numberOfColumns, T * c = nullptr);
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
int m_numberOfRows;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
59
poincare/include/poincare/matrix_complex.h
Normal file
59
poincare/include/poincare/matrix_complex.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef POINCARE_MATRIX_COMPLEX_H
|
||||
#define POINCARE_MATRIX_COMPLEX_H
|
||||
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/complex.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<typename T>
|
||||
class MatrixComplexReference;
|
||||
|
||||
template<typename T>
|
||||
class MatrixComplexNode : public EvaluationNode<T> {
|
||||
public:
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(MatrixComplexNode<T>); }
|
||||
const char * description() const override { return "Evaluation matrix complex"; }
|
||||
int numberOfChildren() const override { return m_numberOfRows*m_numberOfColumns; }
|
||||
|
||||
void setMatrixComplexDimension(int numberOfRows, int numberOfColumns);
|
||||
typename Poincare::EvaluationNode<T>::Type type() const override { return Poincare::EvaluationNode<T>::Type::MatrixComplex; }
|
||||
int numberOfComplexOperands() const { return m_numberOfRows*m_numberOfColumns; }
|
||||
// WARNING: complexOperand may return a nullptr
|
||||
ComplexNode<T> * childAtIndex(int index) const override;
|
||||
int numberOfRows() const { return m_numberOfRows; }
|
||||
int numberOfColumns() const { return m_numberOfColumns; }
|
||||
bool isUndefined() const override;
|
||||
ExpressionReference complexToExpression(Preferences::Preferences::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> trace() const override;
|
||||
std::complex<T> determinant() const override;
|
||||
EvaluationReference<T> inverse() const override;
|
||||
EvaluationReference<T> transpose() const override;
|
||||
private:
|
||||
// TODO: find another solution for inverse and determinant (avoid capping the matrix)
|
||||
static constexpr int k_maxNumberOfCoefficients = 100;
|
||||
int m_numberOfRows;
|
||||
int m_numberOfColumns;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class MatrixComplexReference : public EvaluationReference<T> {
|
||||
public:
|
||||
MatrixComplexReference(TreeNode * t) : EvaluationReference<T>(t) {}
|
||||
MatrixComplexReference(int numberOfRows, int numberOfColumns);
|
||||
static MatrixComplexReference<T> Undefined() {
|
||||
std::complex<T> undef = std::complex<T>(NAN, NAN);
|
||||
return MatrixComplexReference<T>((std::complex<T> *)&undef, 1, 1);
|
||||
}
|
||||
static MatrixComplexReference<T> createIdentity(int dim);
|
||||
int numberOfRows() const;
|
||||
int numberOfColumns() const;
|
||||
private:
|
||||
MatrixComplexReference(std::complex<T> * operands, int numberOfRows, int numberOfColumns);
|
||||
MatrixComplexNode<T> * node() const override{ return static_cast<MatrixComplexNode<T> *>(TreeReference::node()); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -10,7 +10,6 @@ class MatrixDimension : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -21,11 +20,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "dim"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ class MatrixInverse : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Evaluation */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -21,11 +20,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "inverse"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ class MatrixTrace : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,11 +21,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "trace"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ class MatrixTranspose : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -21,11 +20,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "transpose"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ class Multiplication : public DynamicHierarchy {
|
||||
friend class Complex<double>;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
Sign sign() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
int privateGetPolynomialCoefficients(char symbolName, Expression * coefficients[]) const override;
|
||||
@@ -33,13 +32,13 @@ public:
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrices(const MatrixComplex<T> m, const MatrixComplex<T> n);
|
||||
private:
|
||||
/* Property */
|
||||
Expression * setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Layout */
|
||||
bool needParenthesisWithParent(const Expression * e) const override;
|
||||
bool needsParenthesisWithParent(SerializableNode * parentNode) const override;
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
Expression * privateShallowReduce(Context& context, Preferences::AngleUnit angleUnit, bool expand, bool canBeInterrupted);
|
||||
void mergeMultiplicationOperands();
|
||||
void factorizeBase(Expression * e1, Expression * e2, Context & context, Preferences::AngleUnit angleUnit);
|
||||
@@ -62,10 +61,10 @@ private:
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrixAndComplex(const MatrixComplex<T> m, const std::complex<T> c) {
|
||||
return ApproximationEngine::elementWiseOnMatrixComplexAndComplex(m, c, compute<T>);
|
||||
}
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
28
poincare/include/poincare/n_ary_expression_node.h
Normal file
28
poincare/include/poincare/n_ary_expression_node.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef POINCARE_NARY_EXPRESSION_NODE_H
|
||||
#define POINCARE_NARY_EXPRESSION_NODE_H
|
||||
|
||||
#include <poincare/expression_reference.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class NAryExpressionNode : public ExpressionNode { // TODO: VariableArityExpressionNode?
|
||||
public:
|
||||
int numberOfChildren() const override { return m_numberOfChildren; }
|
||||
|
||||
// Comparison
|
||||
typedef int (*ExpressionOrder)(const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted);
|
||||
|
||||
// Commutative properties
|
||||
void sortOperands(ExpressionOrder order, bool canBeInterrupted);
|
||||
ExpressionReference squashUnaryHierarchy();
|
||||
|
||||
protected:
|
||||
int m_numberOfChildren;
|
||||
private:
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
int simplificationOrderGreaterType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -11,7 +11,6 @@ class NaperianLogarithm : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,13 +21,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "ln"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,7 +10,6 @@ class NthRoot : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
@@ -18,11 +17,11 @@ private:
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "root");
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
50
poincare/include/poincare/number.h
Normal file
50
poincare/include/poincare/number.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef POINCARE_NUMBER_H
|
||||
#define POINCARE_NUMBER_H
|
||||
|
||||
#include <poincare/expression_reference.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
/* Number class has 3 subclasses:
|
||||
* - Undefined
|
||||
* - Integer
|
||||
* - Rational
|
||||
* - Float
|
||||
* - Decimal
|
||||
* - Infinite
|
||||
*/
|
||||
|
||||
class IntegerReference;
|
||||
class RationalReference;
|
||||
|
||||
class NumberNode : public ExpressionNode {
|
||||
public:
|
||||
bool isNumber() const override { return true; }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
|
||||
double doubleApproximation() const;
|
||||
};
|
||||
|
||||
class NumberReference : public ExpressionReference {
|
||||
public:
|
||||
using ExpressionReference::ExpressionReference;
|
||||
NumberNode * numberNode() const { assert(!isAllocationFailure()); return static_cast<NumberNode *>(node()); }
|
||||
/* Return either a IntegerReference, a DecimalReference or an InfiniteReference. */
|
||||
static NumberReference Integer(const char * digits, size_t length, bool negative);
|
||||
/* This set of Functions return either a RationalReference or a FloatReference
|
||||
* or InfiniteReference in case of overflow. DecimalReference are not taken into
|
||||
* account as it is not an internal node - it will always be truned into a
|
||||
* Rational/Float beforehand. */
|
||||
static NumberReference Addition(const NumberReference i, const NumberReference j);
|
||||
static NumberReference Multiplication(const NumberReference i, const NumberReference j);
|
||||
static NumberReference Power(const NumberReference i, const NumberReference j);
|
||||
private:
|
||||
typedef IntegerReference (*IntegerBinaryOperation)(const IntegerReference, const IntegerReference);
|
||||
typedef RationalReference (*RationalBinaryOperation)(const RationalReference, const RationalReference);
|
||||
typedef double (*DoubleBinaryOperation)(double, double);
|
||||
static NumberReference BinaryOperation(const NumberReference i, const NumberReference j, IntegerBinaryOperation integerOp, RationalBinaryOperation rationalOp, DoubleBinaryOperation doubleOp);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,34 +1,49 @@
|
||||
#ifndef POINCARE_OPPOSITE_H
|
||||
#define POINCARE_OPPOSITE_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/expression_reference.h>
|
||||
#include <poincare/approximation_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Opposite : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
class OppositeNode : public ExpressionNode {
|
||||
public:
|
||||
Expression * clone() const override;
|
||||
Type type() const override;
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(OppositeNode); }
|
||||
const char * description() const override { return "Opposite"; }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::Opposite; }
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
Sign sign() const override;
|
||||
template<typename T> static std::complex<T> compute(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
private:
|
||||
/* Layout */
|
||||
bool needParenthesisWithParent(const Expression * e) const override;
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
|
||||
// Approximation
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit, compute<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, compute<double>);
|
||||
}
|
||||
|
||||
// Layout
|
||||
bool needsParenthesisWithParent(SerializableNode * parentNode) const override;
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
|
||||
// Simplification
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
|
||||
private:
|
||||
template<typename T> static ComplexReference<T> compute(const std::complex<T> c, Preferences::AngleUnit angleUnit) { return ComplexReference<T>(-c); }
|
||||
};
|
||||
|
||||
class OppositeReference : public ExpressionReference {
|
||||
public:
|
||||
OppositeReference(ExpressionReference operand) {
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<OppositeNode>();
|
||||
m_identifier = node->identifier();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,31 +1,44 @@
|
||||
#ifndef POINCARE_PARENTHESIS_H
|
||||
#define POINCARE_PARENTHESIS_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/expression_reference.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Parenthesis : public StaticHierarchy<1> {
|
||||
class ParenthesisNode : public ExpressionNode {
|
||||
public:
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Expression * clone() const override;
|
||||
Type type() const override;
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(ParenthesisNode); }
|
||||
const char * description() const override { return "Parenthesis"; }
|
||||
int numberOfChildren() const override { return 1; }
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::Parenthesis; }
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
private:
|
||||
/* Layout */
|
||||
|
||||
// Layout
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "");
|
||||
return LayoutEngine::writePrefixSerializableRefTextInBuffer(ExpressionReference(this), buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "");
|
||||
}
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
// Simplification
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
|
||||
// Approximation
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
private:
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
class ParenthesisReference : public ExpressionReference {
|
||||
public:
|
||||
ParenthesisReference(ExpressionReference exp) {
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<ParenthesisNode>();
|
||||
m_identifier = node->identifier();
|
||||
addChildTreeAtIndex(exp, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ class PermuteCoefficient : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
constexpr static int k_maxNValue = 100;
|
||||
/* Layout */
|
||||
@@ -23,11 +22,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "permute"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ class Power : public StaticHierarchy<2> {
|
||||
friend class Symbol;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
Sign sign() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
int privateGetPolynomialCoefficients(char symbolName, Expression * coefficients[]) const override;
|
||||
@@ -29,19 +28,19 @@ private:
|
||||
constexpr static int k_maxNumberOfTermsInExpandedMultinome = 25;
|
||||
constexpr static int k_maxExactPowerMatrix = 100;
|
||||
/* Property */
|
||||
Expression * setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
bool needParenthesisWithParent(const Expression * e) const override;
|
||||
bool needsParenthesisWithParent(SerializableNode * parentNode) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
static const char * name() { return "^"; }
|
||||
/* Simplify */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
Expression * shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
int simplificationOrderGreaterType(const Expression * e, bool canBeInterrupted) const override;
|
||||
int simplificationOrderSameType(const Expression * e, bool canBeInterrupted) const override;
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
Expression * simplifyPowerPower(Power * p, Expression * r, Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression * cloneDenominator(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
Expression * simplifyPowerMultiplication(Multiplication * m, Expression * r, Context & context, Preferences::AngleUnit angleUnit);
|
||||
@@ -60,10 +59,10 @@ private:
|
||||
template<typename T> static MatrixComplex<T> computeOnComplexAndMatrix(const std::complex<T> c, const MatrixComplex<T> n);
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrixAndComplex(const MatrixComplex<T> m, const std::complex<T> d);
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrices(const MatrixComplex<T> m, const MatrixComplex<T> n);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,7 +10,6 @@ class PredictionInterval : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -22,11 +21,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "prediction95"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(Expression::SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<float> approximate(Expression::SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(Expression::DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -9,18 +9,17 @@ class Product : public Sequence {
|
||||
using Sequence::Sequence;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
const char * name() const override;
|
||||
int emptySequenceValue() const override;
|
||||
LayoutRef createSequenceLayout(LayoutRef argumentLayout, LayoutRef subscriptLayout, LayoutRef superscriptLayout) const override;
|
||||
Evaluation<double> * evaluateWithNextTerm(DoublePrecision p, Evaluation<double> * a, Evaluation<double> * b) const override {
|
||||
EvaluationReference<double> evaluateWithNextTerm(DoublePrecision p, Evaluation<double> * a, Evaluation<double> * b) const override {
|
||||
return templatedApproximateWithNextTerm<double>(a, b);
|
||||
}
|
||||
Evaluation<float> * evaluateWithNextTerm(SinglePrecision p, Evaluation<float> * a, Evaluation<float> * b) const override {
|
||||
EvaluationReference<float> evaluateWithNextTerm(SinglePrecision p, Evaluation<float> * a, Evaluation<float> * b) const override {
|
||||
return templatedApproximateWithNextTerm<float>(a, b);
|
||||
}
|
||||
template<typename T> Evaluation<T> * templatedApproximateWithNextTerm(Evaluation<T> * a, Evaluation<T> * b) const;
|
||||
template<typename T> EvaluationReference<T> templatedApproximateWithNextTerm(Evaluation<T> * a, Evaluation<T> * b) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ class Randint : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -21,13 +20,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "randint"; }
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templateApproximate<float>(context, angleUnit);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templateApproximate<double>(context, angleUnit);
|
||||
}
|
||||
template <typename T> Evaluation<T> * templateApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
template <typename T> EvaluationReference<T> templateApproximate()Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,11 +11,10 @@ class Random : public StaticHierarchy<0> {
|
||||
using StaticHierarchy<0>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
Sign sign() const override { return Sign::Positive; }
|
||||
template<typename T> static T random();
|
||||
private:
|
||||
Expression * setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutEngine::createPrefixLayout(this, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
@@ -25,13 +24,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "random"; }
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templateApproximate<float>();
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templateApproximate<double>();
|
||||
}
|
||||
template <typename T> Evaluation<T> * templateApproximate() const {
|
||||
template <typename T> EvaluationReference<T> templateApproximate()) const {
|
||||
return new Complex<T>(random<T>());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,63 +2,90 @@
|
||||
#define POINCARE_RATIONAL_H
|
||||
|
||||
#include <poincare/integer.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Rational : public StaticHierarchy<0> {
|
||||
friend class Power;
|
||||
friend class Multiplication;
|
||||
class RationalNode : public NumberNode {
|
||||
public:
|
||||
/* The constructor build a irreductible fraction whose sign is on numerator */
|
||||
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)) {}
|
||||
void setDigits(native_uint_t * i, size_t numeratorSize, native_uint_t * j, size_t denominatorSize, bool negative);
|
||||
|
||||
NaturalIntegerPointer numerator() const;
|
||||
NaturalIntegerPointer denominator() const;
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override;
|
||||
const char * description() const override { return "Rational"; }
|
||||
|
||||
// Serialization Node
|
||||
bool needsParenthesisWithParent(SerializableNode * e) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
Rational(const Rational & other);
|
||||
Rational & operator=(const Rational & other);
|
||||
// Getter
|
||||
const Integer numerator() const;
|
||||
const Integer denominator() const;
|
||||
// Expression subclassing
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
Type type() const override { return Type::Rational; }
|
||||
Sign sign() const override;
|
||||
Expression * cloneDenominator(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
void setSign(Sign s);
|
||||
|
||||
// Layout
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
// Approximation
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return ComplexReference<float>(templatedApproximate<float>()); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return ComplexReference<double>(templatedApproximate<double>()); }
|
||||
template<typename T> T templatedApproximate() const;
|
||||
|
||||
// Basic test
|
||||
bool isZero() const { return m_numerator.isZero(); }
|
||||
bool isOne() const { return m_numerator.isOne() && m_denominator.isOne(); }
|
||||
bool isMinusOne() const { return m_numerator.isMinusOne() && m_denominator.isOne(); }
|
||||
bool isHalf() const { return m_numerator.isOne() && m_denominator.isTwo(); }
|
||||
bool isMinusHalf() const { return m_numerator.isMinusOne() && m_denominator.isTwo(); }
|
||||
bool isTen() const { return m_numerator.isTen() && m_denominator.isOne(); }
|
||||
bool isZero() const { return numerator().isZero(); }
|
||||
bool isOne() const { return numerator().isOne() && denominator().isOne() && !m_negative; }
|
||||
bool isMinusOne() const { return numerator().isOne() && denominator().isOne() && m_negative; }
|
||||
bool isHalf() const { return numerator().isOne() && denominator().isTwo() && !m_negative; }
|
||||
bool isMinusHalf() const { return numerator().isOne() && denominator().isTwo() && m_negative; }
|
||||
bool isTen() const { return numerator().isTen() && denominator().isOne() && !m_negative; }
|
||||
|
||||
static int NaturalOrder(const RationalNode i, const RationalNode j);
|
||||
private:
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
ExpressionReference shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override {
|
||||
setSign(s);
|
||||
return ExpressionReference(this);
|
||||
}
|
||||
ExpressionReference cloneDenominator(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
bool m_negative;
|
||||
size_t m_numberOfDigitsNumerator;
|
||||
size_t m_numberOfDigitsDenominator;
|
||||
native_uint_t m_digits[0];
|
||||
};
|
||||
|
||||
class RationalReference : public NumberReference {
|
||||
public:
|
||||
/* The constructor build a irreductible fraction */
|
||||
RationalReference(IntegerReference numerator, IntegerReference denominator);
|
||||
RationalReference(const IntegerReference numerator);
|
||||
RationalReference(const NaturalIntegerAbstract * numerator, bool negative);
|
||||
RationalReference(native_int_t i);
|
||||
RationalReference(native_int_t i, native_int_t j);
|
||||
|
||||
// TreeNode
|
||||
RationalNode * typedNode() const { assert(node()->type() == ExpressionNode::Type::Rational); return static_cast<RationalNode *>(node()); }
|
||||
|
||||
// Properties
|
||||
bool isOne() const;
|
||||
bool numeratorOrDenominatorIsInfinity() const;
|
||||
|
||||
// Arithmetic
|
||||
static Rational Addition(const Rational & i, const Rational & j);
|
||||
static Rational Multiplication(const Rational & i, const Rational & j);
|
||||
static Rational Power(const Rational & i, const Integer & j);
|
||||
static int NaturalOrder(const Rational & i, const Rational & j);
|
||||
/* Warning: when using this function, always assert that the result does not
|
||||
* involve infinity numerator or denominator or handle these cases. */
|
||||
static RationalReference Addition(const RationalReference i, const RationalReference j);
|
||||
static RationalReference Multiplication(const RationalReference i, const RationalReference j);
|
||||
// IntegerPower of (p1/q1)^(p2/q2) --> (p1^p2)/(q1^p2)
|
||||
static RationalReference IntegerPower(const RationalReference i, const RationalReference j);
|
||||
static int NaturalOrder(const RationalReference i, const RationalReference j);
|
||||
|
||||
private:
|
||||
bool needParenthesisWithParent(const Expression * e) const override;
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename U> Complex<U> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
Expression * shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
Expression * setSign(Sign s);
|
||||
Expression * setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override {
|
||||
return setSign(s);
|
||||
RationalReference(size_t size) : NumberReference() {
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<RationalNode>(size);
|
||||
m_identifier = node->identifier();
|
||||
}
|
||||
|
||||
/* Sorting */
|
||||
int simplificationOrderSameType(const Expression * e, bool canBeInterrupted) const override;
|
||||
|
||||
Integer m_numerator;
|
||||
Integer m_denominator;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ class RealPart : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,13 +21,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "re"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@ class Round : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
@@ -22,11 +21,11 @@ private:
|
||||
}
|
||||
const char * name() const { return "round"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Complex */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@ private:
|
||||
virtual LayoutRef createSequenceLayout(LayoutRef subscriptLayout, LayoutRef superscriptLayout, LayoutRef argumentLayout) const = 0;
|
||||
virtual const char * name() const = 0;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
virtual int emptySequenceValue() const = 0;
|
||||
virtual Evaluation<float> * evaluateWithNextTerm(SinglePrecision p, Evaluation<float> * a, Evaluation<float> * b) const = 0;
|
||||
virtual Evaluation<double> * evaluateWithNextTerm(DoublePrecision p, Evaluation<double> * a, Evaluation<double> * b) const = 0;
|
||||
virtual EvaluationReference<float> evaluateWithNextTerm(SinglePrecision p, Evaluation<float> * a, Evaluation<float> * b) const = 0;
|
||||
virtual EvaluationReference<double> evaluateWithNextTerm(DoublePrecision p, Evaluation<double> * a, Evaluation<double> * b) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Poincare {
|
||||
class SerializableNode : public TreeNode {
|
||||
public:
|
||||
using TreeNode::TreeNode;
|
||||
virtual bool needsParenthesisWithParent(SerializableNode * parentNode) { return false; } //TODO
|
||||
virtual bool needsParenthesisWithParent(SerializableNode * parentNode) const { return false; } //TODO
|
||||
virtual int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const = 0;
|
||||
|
||||
};
|
||||
|
||||
@@ -17,23 +17,22 @@ public:
|
||||
/* We don't want to clone the expression provided at construction.
|
||||
* So we don't want it to be deleted when we're destroyed (parent destructor). */
|
||||
}
|
||||
Expression * clone() const override { return nullptr; }
|
||||
int polynomialDegree(char symbolName) const override { return -1; }
|
||||
Type type() const override { return Expression::Type::SimplificationRoot; }
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return nullptr;
|
||||
}
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { return 0; }
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
private:
|
||||
Expression * shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override { return this; }
|
||||
ExpressionReference shallowReduce(Context & context, Preferences::AngleUnit angleUnit) override { return this; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ class Sine : public StaticHierarchy<1> {
|
||||
float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian);
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -26,12 +25,12 @@ private:
|
||||
}
|
||||
const char * name() const { return "sin"; }
|
||||
/* Simplication */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,19 +11,18 @@ class SquareRoot : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
virtual bool hasValidNumberOfOperands(int numberOfOperands) const;
|
||||
protected:
|
||||
void build(const Expression * const * operands, int numberOfOperands, bool cloneOperands);
|
||||
int simplificationOrderSameType(const Expression * e, bool canBeInterrupted) const override;
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
const Expression * m_operands[T];
|
||||
};
|
||||
|
||||
|
||||
@@ -13,18 +13,17 @@ class Store : public StaticHierarchy<2> {
|
||||
public:
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
private:
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Evalutation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
const Symbol * symbol() const { return static_cast<const Symbol *>(operand(1)); }
|
||||
const Expression * value() const { return operand(0); }
|
||||
|
||||
@@ -11,12 +11,11 @@ class Subtraction : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
template<typename T> static std::complex<T> compute(const std::complex<T> c, const std::complex<T> d);
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
private:
|
||||
/* Layout */
|
||||
bool needParenthesisWithParent(const Expression * e) const override;
|
||||
bool needsParenthesisWithParent(SerializableNode * parentNode) const override;
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutEngine::createInfixLayout(this, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
@@ -25,7 +24,7 @@ private:
|
||||
}
|
||||
static const char * name() { return "-"; }
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrixAndComplex(const MatrixComplex<T> m, const std::complex<T> c) {
|
||||
return ApproximationEngine::elementWiseOnMatrixComplexAndComplex(m, c, compute<T>);
|
||||
@@ -35,10 +34,10 @@ private:
|
||||
return ApproximationEngine::elementWiseOnComplexMatrices(m, n, compute<T>);
|
||||
}
|
||||
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<float>(this, context, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::mapReduce<double>(this, context, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,18 +9,17 @@ class Sum : public Sequence {
|
||||
using Sequence::Sequence;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
private:
|
||||
const char * name() const override;
|
||||
int emptySequenceValue() const override;
|
||||
LayoutRef createSequenceLayout(LayoutRef argumentLayout, LayoutRef subscriptLayout, LayoutRef superscriptLayout) const override;
|
||||
Evaluation<double> * evaluateWithNextTerm(DoublePrecision p, Evaluation<double> * a, Evaluation<double> * b) const override {
|
||||
EvaluationReference<double> evaluateWithNextTerm(DoublePrecision p, Evaluation<double> * a, Evaluation<double> * b) const override {
|
||||
return templatedApproximateWithNextTerm<double>(a, b);
|
||||
}
|
||||
Evaluation<float> * evaluateWithNextTerm(SinglePrecision p, Evaluation<float> * a, Evaluation<float> * b) const override {
|
||||
EvaluationReference<float> evaluateWithNextTerm(SinglePrecision p, Evaluation<float> * a, Evaluation<float> * b) const override {
|
||||
return templatedApproximateWithNextTerm<float>(a, b);
|
||||
}
|
||||
template<typename T> Evaluation<T> * templatedApproximateWithNextTerm(Evaluation<T> * a, Evaluation<T> * b) const;
|
||||
template<typename T> EvaluationReference<T> templatedApproximateWithNextTerm(Evaluation<T> * a, Evaluation<T> * b) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,52 @@
|
||||
#ifndef POINCARE_SYMBOL_H
|
||||
#define POINCARE_SYMBOL_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/expression_reference.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Symbol : public StaticHierarchy<0> {
|
||||
class SymbolNode : public ExpressionNode {
|
||||
friend class Store;
|
||||
public:
|
||||
void setName(const char name) { m_name = name; }
|
||||
char name() const { return m_name; }
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(SymbolNode); }
|
||||
const char * description() const override { return "Symbol"; }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
|
||||
// Expression Properties
|
||||
Type type() const override { return Type::Symbol; }
|
||||
Sign sign() const override;
|
||||
ExpressionReference replaceSymbolWithExpression(char symbol, ExpressionReference expression) override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
int getPolynomialCoefficients(char symbolName, ExpressionReference coefficients[]) const override;
|
||||
int getVariables(isVariableTest isVariable, char * variables) const override;
|
||||
float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
|
||||
/* Comparison */
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
/* Simplification */
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
|
||||
/* Approximation */
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
|
||||
private:
|
||||
bool hasAnExactRepresentation(Context & context) const;
|
||||
template<typename T> EvaluationReference<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
char m_name;
|
||||
};
|
||||
|
||||
class SymbolReference : public ExpressionReference {
|
||||
public:
|
||||
enum SpecialSymbols : char {
|
||||
/* We can use characters from 1 to 31 as they do not correspond to usual
|
||||
@@ -41,40 +81,22 @@ public:
|
||||
X3,
|
||||
Y3 = 29
|
||||
};
|
||||
SymbolReference(const char name) {
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<SymbolNode>();
|
||||
m_identifier = node->identifier();
|
||||
if (!node->isAllocationFailure()) {
|
||||
static_cast<SymbolNode *>(node)->setName(name);
|
||||
}
|
||||
}
|
||||
// Symbol properties
|
||||
static const char * textForSpecialSymbols(char name);
|
||||
static SpecialSymbols matrixSymbol(char index);
|
||||
Symbol(char name);
|
||||
Symbol(Symbol&& other); // C++11 move constructor
|
||||
Symbol(const Symbol& other); // C++11 copy constructor
|
||||
char name() const;
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
int privateGetPolynomialCoefficients(char symbolName, Expression * coefficients[]) const override;
|
||||
Sign sign() const override;
|
||||
bool isMatrixSymbol() const;
|
||||
bool isScalarSymbol() const;
|
||||
static bool isMatrixSymbol(char c);
|
||||
static bool isScalarSymbol(char c);
|
||||
static bool isVariableSymbol(char c);
|
||||
static bool isSeriesSymbol(char c);
|
||||
static bool isRegressionSymbol(char c);
|
||||
bool isApproximate(Context & context) const;
|
||||
float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
bool hasAnExactRepresentation(Context & context) const;
|
||||
static const char * textForSpecialSymbols(char name);
|
||||
int getVariables(isVariableTest isVariable, char * variables) const override;
|
||||
private:
|
||||
Expression * replaceSymbolWithExpression(char symbol, Expression * expression) override;
|
||||
/* Simplification */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Comparison */
|
||||
int simplificationOrderSameType(const Expression * e, bool canBeInterrupted) const override;
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Evaluation<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
const char m_name;
|
||||
static bool isApproximate(char c, Context & context);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ class Tangent : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -24,13 +23,13 @@ private:
|
||||
}
|
||||
const char * name() const { return "tan"; }
|
||||
/* Simplication */
|
||||
Expression * shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
ExpressionReference shallowReduce(Context& context, Preferences::AngleUnit angleUnit) override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian);
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<float>(this, context, angleUnit,computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationEngine::map<double>(this, context, angleUnit, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -104,6 +104,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void swapChildren(int i, int j);
|
||||
|
||||
protected:
|
||||
TreeReference() : m_identifier(-1) {}
|
||||
void setIdentifierAndRetain(int newId) {
|
||||
|
||||
@@ -1,24 +1,41 @@
|
||||
#ifndef POINCARE_UNDEFINED_H
|
||||
#define POINCARE_UNDEFINED_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/number.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Undefined : public StaticHierarchy<0> {
|
||||
class UndefinedNode : public NumberNode {
|
||||
public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(UndefinedNode); }
|
||||
const char * description() const override { return "Undefined"; }
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::Undefined; }
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
private:
|
||||
/* Layout */
|
||||
|
||||
// Approximation
|
||||
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templatedApproximate<float>();
|
||||
}
|
||||
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templatedApproximate<double>();
|
||||
}
|
||||
|
||||
// Layout
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> * privateApproximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, angleUnit); }
|
||||
Evaluation<double> * privateApproximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, angleUnit); }
|
||||
template<typename T> Complex<T> * templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
private:
|
||||
template<typename T> EvaluationReference<T> templatedApproximate() const;
|
||||
};
|
||||
|
||||
class UndefinedReference : public NumberReference {
|
||||
public:
|
||||
UndefinedReference() {
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<UndefinedNode>();
|
||||
m_identifier = node->identifier();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ LayoutRef AbsoluteValue::createLayout(Preferences::PrintFloatMode floatDisplayMo
|
||||
return AbsoluteValueLayoutRef(operand(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
|
||||
Expression * AbsoluteValue::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
ExpressionReference AbsoluteValue::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
|
||||
@@ -35,7 +35,7 @@ int Addition::polynomialDegree(char symbolName) const {
|
||||
return degree;
|
||||
}
|
||||
|
||||
int Addition::privateGetPolynomialCoefficients(char symbolName, Expression * coefficients[]) const {
|
||||
int Addition::getPolynomialCoefficients(char symbolName, ExpressionReference coefficients[]) const {
|
||||
int deg = polynomialDegree(symbolName);
|
||||
if (deg < 0 || deg > k_maxPolynomialDegree) {
|
||||
return -1;
|
||||
@@ -63,7 +63,7 @@ bool Addition::needParenthesisWithParent(const Expression * e) const {
|
||||
|
||||
/* Simplication */
|
||||
|
||||
Expression * Addition::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
ExpressionReference Addition::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
|
||||
12
poincare/src/allocation_failed_evaluation.cpp
Normal file
12
poincare/src/allocation_failed_evaluation.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include <poincare/allocation_failed_evaluation.h>
|
||||
#include <poincare/expression_reference.h>
|
||||
#include <poincare/undefined.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<typename T>
|
||||
ExpressionReference AllocationFailedEvaluationNode<T>::complexToExpression(Preferences::Preferences::ComplexFormat complexFormat) const {
|
||||
return UndefinedReference();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,101 +25,113 @@ template <typename T> std::complex<T> ApproximationEngine::truncateRealOrImagina
|
||||
return c;
|
||||
}
|
||||
|
||||
template<typename T> Evaluation<T> * ApproximationEngine::map(const Expression * expression, Context& context, Preferences::AngleUnit angleUnit, ComplexCompute<T> compute) {
|
||||
assert(expression->numberOfOperands() == 1);
|
||||
Evaluation<T> * input = expression->operand(0)->privateApproximate(T(), context, angleUnit);
|
||||
Evaluation<T> * result = nullptr;
|
||||
if (input->type() == Evaluation<T>::Type::Complex) {
|
||||
Complex<T> * c = static_cast<Complex<T> *>(input);
|
||||
result = new Complex<T>(compute(*c, angleUnit));
|
||||
template<typename T> EvaluationReference<T> ApproximationEngine::map(const ExpressionNode * expression, Context& context, Preferences::AngleUnit angleUnit, ComplexCompute<T> compute) {
|
||||
assert(expression->numberOfChildren() == 1);
|
||||
EvaluationReference<T> input = expression->childAtIndex(0)->approximate(T(), context, angleUnit);
|
||||
if (input.node()->type() == EvaluationNode<T>::Type::AllocationFailure) {
|
||||
return EvaluationReference<T>(EvaluationNode<T>::FailedAllocationStaticNode());
|
||||
} else if (input.node()->type() == EvaluationNode<T>::Type::Complex) {
|
||||
const ComplexNode<T> * c = static_cast<ComplexNode<T> *>(input.node());
|
||||
return compute(*c, angleUnit);
|
||||
} else {
|
||||
assert(input->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
MatrixComplex<T> * m = static_cast<MatrixComplex<T> *>(input);
|
||||
std::complex<T> * operands = new std::complex<T> [m->numberOfComplexOperands()];
|
||||
for (int i = 0; i < m->numberOfComplexOperands(); i++) {
|
||||
const std::complex<T> c = m->complexOperand(i);
|
||||
operands[i] = compute(c, angleUnit);
|
||||
assert(input.node()->type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
MatrixComplexReference<T> m = MatrixComplexReference<T>(input.node());
|
||||
MatrixComplexReference<T> result(m.numberOfRows(), m.numberOfColumns());
|
||||
for (int i = 0; i < result.numberOfRows()*result.numberOfColumns(); i++) {
|
||||
ComplexNode<T> * child = static_cast<MatrixComplexNode<T> *>(m.node())->childAtIndex(i);
|
||||
if (child) {
|
||||
result.addChildTreeAtIndex(compute(*child, angleUnit), i, i);
|
||||
} else {
|
||||
result.addChildTreeAtIndex(ComplexReference<T>::Undefined(), i, i);
|
||||
}
|
||||
}
|
||||
result = new MatrixComplex<T>(operands, m->numberOfRows(), m->numberOfColumns());
|
||||
delete[] operands;
|
||||
return result;
|
||||
}
|
||||
delete input;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T> Evaluation<T> * ApproximationEngine::mapReduce(const Expression * expression, Context& context, Preferences::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices) {
|
||||
Evaluation<T> * result = expression->operand(0)->privateApproximate(T(), context, angleUnit);
|
||||
for (int i = 1; i < expression->numberOfOperands(); i++) {
|
||||
Evaluation<T> * intermediateResult = nullptr;
|
||||
Evaluation<T> * nextOperandEvaluation = expression->operand(i)->privateApproximate(T(), context, angleUnit);
|
||||
if (result->type() == Evaluation<T>::Type::Complex && nextOperandEvaluation->type() == Evaluation<T>::Type::Complex) {
|
||||
const Complex<T> * c = static_cast<const Complex<T> *>(result);
|
||||
const Complex<T> * d = static_cast<const Complex<T> *>(nextOperandEvaluation);
|
||||
intermediateResult = new Complex<T>(computeOnComplexes(*c, *d));
|
||||
} else if (result->type() == Evaluation<T>::Type::Complex) {
|
||||
const Complex<T> * c = static_cast<const Complex<T> *>(result);
|
||||
assert(nextOperandEvaluation->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
const MatrixComplex<T> * n = static_cast<const MatrixComplex<T> *>(nextOperandEvaluation);
|
||||
intermediateResult = new MatrixComplex<T>(computeOnComplexAndMatrix(*c, *n));
|
||||
} else if (nextOperandEvaluation->type() == Evaluation<T>::Type::Complex) {
|
||||
assert(result->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
const MatrixComplex<T> * m = static_cast<const MatrixComplex<T> *>(result);
|
||||
const Complex<T> * d = static_cast<const Complex<T> *>(nextOperandEvaluation);
|
||||
intermediateResult = new MatrixComplex<T>(computeOnMatrixAndComplex(*m, *d));
|
||||
template<typename T> EvaluationReference<T> ApproximationEngine::mapReduce(const ExpressionNode * expression, Context& context, Preferences::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices) {
|
||||
EvaluationReference<T> result = expression->childAtIndex(0)->approximate(T(), context, angleUnit);
|
||||
for (int i = 1; i < expression->numberOfChildren(); i++) {
|
||||
EvaluationReference<T> intermediateResult(nullptr);
|
||||
EvaluationReference<T> nextOperandEvaluation = expression->childAtIndex(i)->approximate(T(), context, angleUnit);
|
||||
if (result.node()->type() == EvaluationNode<T>::Type::AllocationFailure || nextOperandEvaluation.node()->type() == EvaluationNode<T>::Type::AllocationFailure) {
|
||||
return EvaluationReference<T>(EvaluationNode<T>::FailedAllocationStaticNode());
|
||||
}
|
||||
if (result.node()->type() == EvaluationNode<T>::Type::Complex && nextOperandEvaluation.node()->type() == EvaluationNode<T>::Type::Complex) {
|
||||
const ComplexNode<T> * c = static_cast<const ComplexNode<T> *>(result.node());
|
||||
const ComplexNode<T> * d = static_cast<const ComplexNode<T> *>(nextOperandEvaluation.node());
|
||||
intermediateResult = computeOnComplexes(*c, *d);
|
||||
} else if (result.node()->type() == EvaluationNode<T>::Type::Complex) {
|
||||
assert(nextOperandEvaluation.node()->type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
const ComplexNode<T> * c = static_cast<const ComplexNode<T> *>(result.node());
|
||||
MatrixComplexReference<T> n = MatrixComplexReference<T>(nextOperandEvaluation.node());
|
||||
intermediateResult = computeOnComplexAndMatrix(*c, n);
|
||||
} else if (nextOperandEvaluation.node()->type() == EvaluationNode<T>::Type::Complex) {
|
||||
assert(result.node()->type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
MatrixComplexReference<T> m = MatrixComplexReference<T>(result.node());
|
||||
const ComplexNode<T> * d = static_cast<const ComplexNode<T> *>(nextOperandEvaluation.node());
|
||||
intermediateResult = computeOnMatrixAndComplex(m, *d);
|
||||
} else {
|
||||
assert(result->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
const MatrixComplex<T> * m = static_cast<const MatrixComplex<T> *>(result);
|
||||
assert(nextOperandEvaluation->type() == Evaluation<T>::Type::MatrixComplex);
|
||||
const MatrixComplex<T> * n = static_cast<const MatrixComplex<T> *>(nextOperandEvaluation);
|
||||
intermediateResult = new MatrixComplex<T>(computeOnMatrices(*m, *n));
|
||||
assert(result.node()->type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
assert(nextOperandEvaluation.node()->type() == EvaluationNode<T>::Type::MatrixComplex);
|
||||
MatrixComplexReference<T> m = MatrixComplexReference<T>(result.node());
|
||||
MatrixComplexReference<T> n = MatrixComplexReference<T>(nextOperandEvaluation.node());
|
||||
intermediateResult = computeOnMatrices(m, n);
|
||||
}
|
||||
delete result;
|
||||
delete nextOperandEvaluation;
|
||||
result = intermediateResult;
|
||||
assert(result != nullptr);
|
||||
if (result->isUndefined()) {
|
||||
return new Complex<T>(Complex<T>::Undefined());
|
||||
if (result.isUndefined()) {
|
||||
return ComplexReference<T>::Undefined();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T> MatrixComplex<T> ApproximationEngine::elementWiseOnMatrixComplexAndComplex(const MatrixComplex<T> m, const std::complex<T> c, ComplexAndComplexReduction<T> computeOnComplexes) {
|
||||
std::complex<T> * operands = new std::complex<T> [m.numberOfRows()*m.numberOfColumns()];
|
||||
for (int i = 0; i < m.numberOfComplexOperands(); i++) {
|
||||
const std::complex<T> d = m.complexOperand(i);
|
||||
operands[i] = computeOnComplexes(d, c);
|
||||
template<typename T> MatrixComplexReference<T> ApproximationEngine::elementWiseOnMatrixComplexAndComplex(const MatrixComplexReference<T> m, const std::complex<T> c, ComplexAndComplexReduction<T> computeOnComplexes) {
|
||||
if (m.isAllocationFailure()) {
|
||||
return MatrixComplexReference<T>(EvaluationNode<T>::FailedAllocationStaticNode());
|
||||
}
|
||||
MatrixComplex<T> result = MatrixComplex<T>(operands, m.numberOfRows(), m.numberOfColumns());
|
||||
delete[] operands;
|
||||
return result;
|
||||
MatrixComplexReference<T> matrix(m.numberOfRows(), m.numberOfColumns());
|
||||
for (int i = 0; i < m.numberOfChildren(); i++) {
|
||||
ComplexNode<T> * child = static_cast<MatrixComplexNode<T> *>(m.node())->childAtIndex(i);
|
||||
if (child) {
|
||||
matrix.addChildTreeAtIndex(computeOnComplexes(*child, c), i, i);
|
||||
} else {
|
||||
matrix.addChildTreeAtIndex(ComplexReference<T>::Undefined(), i, i);
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
template<typename T> MatrixComplex<T> ApproximationEngine::elementWiseOnComplexMatrices(const MatrixComplex<T> m, const MatrixComplex<T> n, ComplexAndComplexReduction<T> computeOnComplexes) {
|
||||
template<typename T> MatrixComplexReference<T> ApproximationEngine::elementWiseOnComplexMatrices(const MatrixComplexReference<T> m, const MatrixComplexReference<T> n, ComplexAndComplexReduction<T> computeOnComplexes) {
|
||||
if (m.isAllocationFailure() || n.isAllocationFailure()) {
|
||||
return MatrixComplexReference<T>(EvaluationNode<T>::FailedAllocationStaticNode());
|
||||
}
|
||||
if (m.numberOfRows() != n.numberOfRows() || m.numberOfColumns() != n.numberOfColumns()) {
|
||||
return MatrixComplex<T>::Undefined();
|
||||
return MatrixComplexReference<T>::Undefined();
|
||||
}
|
||||
std::complex<T> * operands = new std::complex<T> [m.numberOfRows()*m.numberOfColumns()];
|
||||
for (int i = 0; i < m.numberOfComplexOperands(); i++) {
|
||||
const Complex<T> c = m.complexOperand(i);
|
||||
const Complex<T> d = n.complexOperand(i);
|
||||
operands[i] = computeOnComplexes(c, d);
|
||||
MatrixComplexReference<T> matrix(m.numberOfRows(), m.numberOfColumns());
|
||||
for (int i = 0; i < m.numberOfChildren(); i++) {
|
||||
ComplexNode<T> * childM = static_cast<MatrixComplexNode<T> *>(m.node())->childAtIndex(i);
|
||||
ComplexNode<T> * childN = static_cast<MatrixComplexNode<T> *>(n.node())->childAtIndex(i);
|
||||
if (childM && childN) {
|
||||
matrix.addChildTreeAtIndex(computeOnComplexes(*childM, *childN), i, i);
|
||||
} else {
|
||||
matrix.addChildTreeAtIndex(ComplexReference<T>::Undefined(), i, i);
|
||||
}
|
||||
}
|
||||
MatrixComplex<T> result = MatrixComplex<T>(operands, m.numberOfRows(), m.numberOfColumns());
|
||||
delete[] operands;
|
||||
return result;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
template std::complex<float> Poincare::ApproximationEngine::truncateRealOrImaginaryPartAccordingToArgument<float>(std::complex<float>);
|
||||
template std::complex<double> Poincare::ApproximationEngine::truncateRealOrImaginaryPartAccordingToArgument<double>(std::complex<double>);
|
||||
template Poincare::Evaluation<float> * Poincare::ApproximationEngine::map(const Poincare::Expression * expression, Poincare::Context& context, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationEngine::ComplexCompute<float> compute);
|
||||
template Poincare::Evaluation<double> * Poincare::ApproximationEngine::map(const Poincare::Expression * expression, Poincare::Context& context, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationEngine::ComplexCompute<double> compute);
|
||||
template Poincare::Evaluation<float> * Poincare::ApproximationEngine::mapReduce(const Poincare::Expression * expression, Poincare::Context& context, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationEngine::ComplexAndComplexReduction<float> computeOnComplexes, Poincare::ApproximationEngine::ComplexAndMatrixReduction<float> computeOnComplexAndMatrix, Poincare::ApproximationEngine::MatrixAndComplexReduction<float> computeOnMatrixAndComplex, Poincare::ApproximationEngine::MatrixAndMatrixReduction<float> computeOnMatrices);
|
||||
template Poincare::Evaluation<double> * Poincare::ApproximationEngine::mapReduce(const Poincare::Expression * expression, Poincare::Context& context, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationEngine::ComplexAndComplexReduction<double> computeOnComplexes, Poincare::ApproximationEngine::ComplexAndMatrixReduction<double> computeOnComplexAndMatrix, Poincare::ApproximationEngine::MatrixAndComplexReduction<double> computeOnMatrixAndComplex, Poincare::ApproximationEngine::MatrixAndMatrixReduction<double> computeOnMatrices);
|
||||
template Poincare::MatrixComplex<float> Poincare::ApproximationEngine::elementWiseOnMatrixComplexAndComplex<float>(const Poincare::MatrixComplex<float>, const std::complex<float>, std::complex<float> (*)(std::complex<float>, std::complex<float>));
|
||||
template Poincare::MatrixComplex<double> Poincare::ApproximationEngine::elementWiseOnMatrixComplexAndComplex<double>(const Poincare::MatrixComplex<double>, std::complex<double> const, std::complex<double> (*)(std::complex<double>, std::complex<double>));
|
||||
template Poincare::MatrixComplex<float> Poincare::ApproximationEngine::elementWiseOnComplexMatrices<float>(const Poincare::MatrixComplex<float>, const Poincare::MatrixComplex<float>, std::complex<float> (*)(std::complex<float>, std::complex<float>));
|
||||
template Poincare::MatrixComplex<double> Poincare::ApproximationEngine::elementWiseOnComplexMatrices<double>(const Poincare::MatrixComplex<double>, const Poincare::MatrixComplex<double>, std::complex<double> (*)(std::complex<double>, std::complex<double>));
|
||||
template Poincare::EvaluationReference<float> Poincare::ApproximationEngine::map(const Poincare::ExpressionNode * expression, Poincare::Context& context, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationEngine::ComplexCompute<float> compute);
|
||||
template Poincare::EvaluationReference<double> Poincare::ApproximationEngine::map(const Poincare::ExpressionNode * expression, Poincare::Context& context, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationEngine::ComplexCompute<double> compute);
|
||||
template Poincare::EvaluationReference<float> Poincare::ApproximationEngine::mapReduce(const Poincare::ExpressionNode * expression, Poincare::Context& context, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationEngine::ComplexAndComplexReduction<float> computeOnComplexes, Poincare::ApproximationEngine::ComplexAndMatrixReduction<float> computeOnComplexAndMatrix, Poincare::ApproximationEngine::MatrixAndComplexReduction<float> computeOnMatrixAndComplex, Poincare::ApproximationEngine::MatrixAndMatrixReduction<float> computeOnMatrices);
|
||||
template Poincare::EvaluationReference<double> Poincare::ApproximationEngine::mapReduce(const Poincare::ExpressionNode * expression, Poincare::Context& context, Poincare::Preferences::AngleUnit angleUnit, Poincare::ApproximationEngine::ComplexAndComplexReduction<double> computeOnComplexes, Poincare::ApproximationEngine::ComplexAndMatrixReduction<double> computeOnComplexAndMatrix, Poincare::ApproximationEngine::MatrixAndComplexReduction<double> computeOnMatrixAndComplex, Poincare::ApproximationEngine::MatrixAndMatrixReduction<double> computeOnMatrices);
|
||||
template Poincare::MatrixComplexReference<float> Poincare::ApproximationEngine::elementWiseOnMatrixComplexAndComplex<float>(const Poincare::MatrixComplexReference<float>, const std::complex<float>, Poincare::ComplexReference<float> (*)(std::complex<float>, std::complex<float>));
|
||||
template Poincare::MatrixComplexReference<double> Poincare::ApproximationEngine::elementWiseOnMatrixComplexAndComplex<double>(const Poincare::MatrixComplexReference<double>, std::complex<double> const, Poincare::ComplexReference<double> (*)(std::complex<double>, std::complex<double>));
|
||||
template Poincare::MatrixComplexReference<float> Poincare::ApproximationEngine::elementWiseOnComplexMatrices<float>(const Poincare::MatrixComplexReference<float>, const Poincare::MatrixComplexReference<float>, Poincare::ComplexReference<float> (*)(std::complex<float>, std::complex<float>));
|
||||
template Poincare::MatrixComplexReference<double> Poincare::ApproximationEngine::elementWiseOnComplexMatrices<double>(const Poincare::MatrixComplexReference<double>, const Poincare::MatrixComplexReference<double>, Poincare::ComplexReference<double> (*)(std::complex<double>, std::complex<double>));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ Expression * ArcCosine::clone() const {
|
||||
return a;
|
||||
}
|
||||
|
||||
Expression * ArcCosine::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
ExpressionReference ArcCosine::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
|
||||
@@ -17,7 +17,7 @@ Expression * ArcSine::clone() const {
|
||||
return a;
|
||||
}
|
||||
|
||||
Expression * ArcSine::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
ExpressionReference ArcSine::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
|
||||
@@ -17,7 +17,7 @@ Expression * ArcTangent::clone() const {
|
||||
return a;
|
||||
}
|
||||
|
||||
Expression * ArcTangent::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
ExpressionReference ArcTangent::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
|
||||
@@ -3,18 +3,24 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
Integer Arithmetic::LCM(const Integer * a, const Integer * b) {
|
||||
if (a->isZero() || b->isZero()) {
|
||||
return Integer(0);
|
||||
IntegerReference Arithmetic::LCM(const IntegerReference a, const IntegerReference b) {
|
||||
if (a.isAllocationFailure() || b.isAllocationFailure()) {
|
||||
return IntegerReference(ExpressionNode::FailedAllocationStaticNode());
|
||||
}
|
||||
Integer signResult = Integer::Division(Integer::Multiplication(*a, *b), GCD(a,b)).quotient;
|
||||
if (a.isZero() || b.isZero()) {
|
||||
return IntegerReference(0);
|
||||
}
|
||||
IntegerReference signResult = IntegerReference::Division(IntegerReference::Multiplication(a, b), GCD(a,b)).quotient;
|
||||
signResult.setNegative(false);
|
||||
return signResult;
|
||||
}
|
||||
|
||||
Integer Arithmetic::GCD(const Integer * a, const Integer * b) {
|
||||
Integer i = *a;
|
||||
Integer j = *b;
|
||||
IntegerReference Arithmetic::GCD(const IntegerReference a, const IntegerReference b) {
|
||||
if (a.isAllocationFailure() || b.isAllocationFailure()) {
|
||||
return IntegerReference(ExpressionNode::FailedAllocationStaticNode());
|
||||
}
|
||||
IntegerReference i = IntegerReference(a.clone().node());
|
||||
IntegerReference j = IntegerReference(b.clone().node());
|
||||
i.setNegative(false);
|
||||
j.setNegative(false);
|
||||
do {
|
||||
@@ -24,10 +30,10 @@ Integer Arithmetic::GCD(const Integer * a, const Integer * b) {
|
||||
if (j.isZero()) {
|
||||
return i;
|
||||
}
|
||||
if (j.isLowerThan(i)) {
|
||||
i = Integer::Division(i, j).remainder;
|
||||
if (IntegerReference::NaturalOrder(i, j) > 0) {
|
||||
i = IntegerReference::Division(i, j).remainder;
|
||||
} else {
|
||||
j = Integer::Division(j, i).remainder;
|
||||
j = IntegerReference::Division(j, i).remainder;
|
||||
}
|
||||
} while(true);
|
||||
}
|
||||
@@ -36,62 +42,74 @@ int primeFactors[Arithmetic::k_numberOfPrimeFactors] = {2, 3, 5, 7, 11, 13, 17,
|
||||
3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919};
|
||||
|
||||
// we can go to 7907*7907 = 62 520 649
|
||||
void Arithmetic::PrimeFactorization(const Integer * n, Integer * outputFactors, Integer * outputCoefficients, int outputLength) {
|
||||
void Arithmetic::PrimeFactorization(const IntegerReference n, IntegerReference outputFactors[], IntegerReference outputCoefficients[], int outputLength) {
|
||||
if (n.isAllocationFailure()) {
|
||||
/* Special case 0: Allocation failure. */
|
||||
outputCoefficients[0] = -1;
|
||||
return;
|
||||
}
|
||||
// To avoid cloning n to get its absolute value m, we change n sign and reset it before returning
|
||||
bool nIsNegative = n.isNegative();
|
||||
IntegerReference m = *(const_cast<IntegerReference *>(&n));
|
||||
m.setNegative(false);
|
||||
|
||||
/* First we look for prime divisors in the table primeFactors (to speed up
|
||||
* the prime factorization for low numbers). When k_numberOfPrimeFactors is
|
||||
* overflow, try every number as divisor. */
|
||||
Integer m = *n;
|
||||
m.setNegative(false);
|
||||
if (m.isEqualTo(Integer(1))) {
|
||||
if (IntegerReference::NaturalOrder(m, IntegerReference(1))) {
|
||||
m.setNegative(nIsNegative);
|
||||
return;
|
||||
}
|
||||
const Integer primorial32("525896479052627740771371797072411912900610967452630");
|
||||
if (primorial32.isLowerThan(m)) {
|
||||
const IntegerReference primorial32("525896479052627740771371797072411912900610967452630", false);
|
||||
if (IntegerReference::NaturalOrder(primorial32, m) < 0) {
|
||||
/* Special case 1: We do not want to break i in prime factor because it
|
||||
* might take too many factors... More than k_maxNumberOfPrimeFactors.
|
||||
* outputCoefficients[0] is set to -1 to indicate a special case. */
|
||||
outputCoefficients[0] = Integer(-1);
|
||||
outputCoefficients[0] = -1;
|
||||
m.setNegative(nIsNegative);
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < outputLength; index++) {
|
||||
outputCoefficients[index] = Integer(0);
|
||||
outputCoefficients[index] = IntegerReference(0);
|
||||
}
|
||||
|
||||
int t = 0; // n prime factor index
|
||||
int k = 0; // prime factor index
|
||||
Integer testedPrimeFactor = Integer(primeFactors[k]); // prime factor
|
||||
IntegerReference testedPrimeFactor(primeFactors[k]); // prime factor
|
||||
outputFactors[t] = testedPrimeFactor;
|
||||
IntegerDivision d = {.quotient = 0, .remainder = 0};
|
||||
IntegerDivisionReference d = {.quotient = 0, .remainder = 0};
|
||||
bool stopCondition;
|
||||
do {
|
||||
stopCondition = Integer::Power(outputFactors[t], Integer(2)).isLowerThan(m);
|
||||
d = Integer::Division(m, testedPrimeFactor);
|
||||
if (d.remainder.isEqualTo(Integer(0))) {
|
||||
outputCoefficients[t] = Integer::Addition(outputCoefficients[t], Integer(1));
|
||||
m = std::move(d.quotient);
|
||||
if (m.isEqualTo(Integer(1))) {
|
||||
stopCondition = IntegerReference::NaturalOrder(IntegerReference::Power(outputFactors[t], IntegerReference(2)), m) < 0;
|
||||
d = IntegerReference::Division(m, testedPrimeFactor);
|
||||
if (d.remainder.isZero()) {
|
||||
outputCoefficients[t] = IntegerReference::Addition(outputCoefficients[t], IntegerReference(1));
|
||||
m = d.quotient;
|
||||
if (m.isOne()) {
|
||||
m.setNegative(nIsNegative);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!outputCoefficients[t].isEqualTo(Integer(0))) {
|
||||
if (!outputCoefficients[t].isZero()) {
|
||||
t++;
|
||||
}
|
||||
k++;
|
||||
testedPrimeFactor = k < k_numberOfPrimeFactors ? Integer(primeFactors[k]) : Integer::Addition(testedPrimeFactor, Integer(1));
|
||||
testedPrimeFactor = k < k_numberOfPrimeFactors ? IntegerReference(primeFactors[k]) : IntegerReference::Addition(testedPrimeFactor, IntegerReference(1));
|
||||
outputFactors[t] = testedPrimeFactor;
|
||||
} while (stopCondition && testedPrimeFactor.isLowerThan(Integer(k_biggestPrimeFactor)));
|
||||
if (Integer::Power(Integer(k_biggestPrimeFactor), Integer(2)).isLowerThan(m)) {
|
||||
} while (stopCondition && IntegerReference::NaturalOrder(testedPrimeFactor,IntegerReference(k_biggestPrimeFactor)) < 0);
|
||||
if (IntegerReference::NaturalOrder(IntegerReference::Power(IntegerReference(k_biggestPrimeFactor), IntegerReference(2)), m) < 0) {
|
||||
/* Special case 2: We do not want to break i in prime factor because it
|
||||
* take too much time: the prime factor that should be tested is above
|
||||
* k_biggestPrimeFactor.
|
||||
* outputCoefficients[0] is set to -1 to indicate a special case. */
|
||||
outputCoefficients[0] = -1;
|
||||
m.setNegative(nIsNegative);
|
||||
return;
|
||||
}
|
||||
outputFactors[t] = std::move(m);
|
||||
outputCoefficients[t] = Integer::Addition(outputCoefficients[t], Integer(1));
|
||||
}
|
||||
outputFactors[t] = m;
|
||||
outputCoefficients[t] = IntegerReference::Addition(outputCoefficients[t], IntegerReference(1));
|
||||
m.setNegative(nIsNegative);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ Expression * BinomialCoefficient::clone() const {
|
||||
return b;
|
||||
}
|
||||
|
||||
Expression * BinomialCoefficient::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
ExpressionReference BinomialCoefficient::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
|
||||
@@ -20,7 +20,7 @@ Expression * Ceiling::clone() const {
|
||||
return c;
|
||||
}
|
||||
|
||||
Expression * Ceiling::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
ExpressionReference Ceiling::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
|
||||
146
poincare/src/complex.cpp
Normal file
146
poincare/src/complex.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <stdlib.h>
|
||||
}
|
||||
#include <poincare/complex.h>
|
||||
//#include <poincare/division.h>
|
||||
//#include <poincare/matrix.h>
|
||||
#include <poincare/expression_reference.h>
|
||||
#include <poincare/undefined.h>
|
||||
#include <poincare/infinity.h>
|
||||
//#include <poincare/decimal.h>
|
||||
//#include <poincare/multiplication.h>
|
||||
#include <poincare/opposite.h>
|
||||
//#include <poincare/addition.h>
|
||||
//#include <poincare/subtraction.h>
|
||||
//#include <poincare/matrix.h>
|
||||
//#include <poincare/power.h>
|
||||
#include <poincare/symbol.h>
|
||||
#include <ion.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<typename T>
|
||||
void ComplexNode<T>::setComplex(std::complex<T> c) {
|
||||
this->real(c.real());
|
||||
this->imag(c.imag());
|
||||
if (this->real() == -0) {
|
||||
this->real(0);
|
||||
}
|
||||
if (this->imag() == -0) {
|
||||
this->imag(0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T ComplexNode<T>::toScalar() const {
|
||||
if (this->imag() == 0.0) {
|
||||
return this->real();
|
||||
}
|
||||
return NAN;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static ExpressionReference CreateDecimal(T f) {
|
||||
if (std::isnan(f)) {
|
||||
return UndefinedReference();
|
||||
}
|
||||
if (std::isinf(f)) {
|
||||
return InfiniteReference(f < 0.0);
|
||||
}
|
||||
return DecimalReference(f);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ExpressionReference ComplexNode<T>::complexToExpression(Preferences::ComplexFormat complexFormat) const {
|
||||
if (std::isnan(this->real()) || std::isnan(this->imag())) {
|
||||
return UndefinedReference();
|
||||
}
|
||||
switch (complexFormat) {
|
||||
case Preferences::ComplexFormat::Cartesian:
|
||||
{
|
||||
ExpressionReference real(nullptr);
|
||||
ExpressionReference imag(nullptr);
|
||||
if (this->real() != 0 || this->imag() == 0) {
|
||||
real = CreateDecimal<T>(this->real());
|
||||
}
|
||||
if (this->imag() != 0) {
|
||||
if (this->imag() == 1.0 || this->imag() == -1) {
|
||||
imag = SymbolReference(Ion::Charset::IComplex);
|
||||
} else if (this->imag() > 0) {
|
||||
imag = MultiplicationReference(CreateDecimal(this->imag()), SymbolReference(Ion::Charset::IComplex));
|
||||
} else {
|
||||
imag = MultiplicationReference(CreateDecimal(-this->imag()), SymbolReference(Ion::Charset::IComplex));
|
||||
}
|
||||
}
|
||||
if (!imag.isDefined()) {
|
||||
return real;
|
||||
} else if (!real.isDefined()) {
|
||||
if (this->imag() > 0) {
|
||||
return imag;
|
||||
} else {
|
||||
return OppositeReference(imag);
|
||||
}
|
||||
return imag;
|
||||
} else if (this->imag() > 0) {
|
||||
return AdditionReference(real, imag);
|
||||
} else {
|
||||
return SubtractionReference(real, imag);
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert(complexFormat == Preferences::ComplexFormat::Polar);
|
||||
ExpressionReference norm(nullptr);
|
||||
ExpressionReference exp(nullptr);
|
||||
T r = std::abs(*this);
|
||||
T th = std::arg(*this);
|
||||
if (r != 1 || th == 0) {
|
||||
norm = CreateDecimal(r);
|
||||
}
|
||||
if (r != 0 && th != 0) {
|
||||
ExpressionReference arg(nullptr);
|
||||
if (th == 1.0) {
|
||||
arg = SymbolReference(Ion::Charset::IComplex);
|
||||
} else if (th == -1.0) {
|
||||
arg = OppositeReference(SymbolReference(Ion::Charset::IComplex));
|
||||
} else if (th > 0) {
|
||||
arg = MultiplicationReference(CreateDecimal(th), SymbolReference(Ion::Charset::IComplex));
|
||||
} else {
|
||||
arg = OppositeRefrence(MultiplicationReference(CreateDecimal(-th), SymbolReference(Ion::Charset::IComplex)));
|
||||
}
|
||||
exp = PowerReference(SymbolReference(Ion::Charset::Exponential), arg);
|
||||
}
|
||||
if (!exp.isDefined()) {
|
||||
return norm;
|
||||
} else if (!norm.isDefined()) {
|
||||
return exp;
|
||||
} else {
|
||||
return MultiplicationReference(norm, exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
EvaluationReference<T> ComplexNode<T>::inverse() const {
|
||||
return ComplexReference<T>(Division::compute(std::complex<T>(1.0), *this));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ComplexReference<T>::ComplexReference(std::complex<T> c) :
|
||||
EvaluationReference<T>()
|
||||
{
|
||||
TreeNode * node = TreePool::sharedPool()->createTreeNode<ComplexNode<T>>();
|
||||
this->m_identifier = node->identifier();
|
||||
if (!(node->isAllocationFailure())) {
|
||||
static_cast<ComplexNode<T> *>(node)->setComplex(c);
|
||||
}
|
||||
}
|
||||
|
||||
template class ComplexReference<float>;
|
||||
template class ComplexReference<double>;
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@ Expression * ComplexArgument::clone() const {
|
||||
return a;
|
||||
}
|
||||
|
||||
Expression * ComplexArgument::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
ExpressionReference ComplexArgument::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
|
||||
@@ -24,7 +24,7 @@ int ConfidenceInterval::polynomialDegree(char symbolName) const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Expression * ConfidenceInterval::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
ExpressionReference ConfidenceInterval::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) {
|
||||
Expression * e = Expression::shallowReduce(context, angleUnit);
|
||||
if (e != this) {
|
||||
return e;
|
||||
@@ -62,7 +62,7 @@ Expression * ConfidenceInterval::shallowReduce(Context& context, Preferences::An
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> * ConfidenceInterval::templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
EvaluationReference<T> ConfidenceInterval::templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
Evaluation<T> * fInput = operand(0)->privateApproximate(T(), context, angleUnit);
|
||||
Evaluation<T> * nInput = operand(1)->privateApproximate(T(), context, angleUnit);
|
||||
T f = static_cast<Complex<T> *>(fInput)->toScalar();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user