mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[Update] Epsilon 15.3.1
This commit is contained in:
@@ -101,8 +101,12 @@ poincare_src += $(addprefix poincare/src/,\
|
||||
matrix_inverse.cpp \
|
||||
matrix_trace.cpp \
|
||||
matrix_transpose.cpp \
|
||||
matrix_echelon_form.cpp \
|
||||
matrix_row_echelon_form.cpp \
|
||||
matrix_reduced_row_echelon_form.cpp \
|
||||
multiplication.cpp \
|
||||
n_ary_expression.cpp \
|
||||
n_ary_infix_expression.cpp \
|
||||
naperian_logarithm.cpp \
|
||||
norm_cdf.cpp \
|
||||
norm_cdf2.cpp \
|
||||
@@ -133,6 +137,7 @@ poincare_src += $(addprefix poincare/src/,\
|
||||
solver.cpp \
|
||||
square_root.cpp \
|
||||
store.cpp \
|
||||
sum_and_product.cpp \
|
||||
subtraction.cpp \
|
||||
sum.cpp \
|
||||
symbol.cpp \
|
||||
@@ -148,6 +153,10 @@ poincare_src += $(addprefix poincare/src/,\
|
||||
unit_convert.cpp \
|
||||
unreal.cpp \
|
||||
variable_context.cpp \
|
||||
vector_cross.cpp \
|
||||
vector_dot.cpp \
|
||||
vector_norm.cpp \
|
||||
zoom.cpp \
|
||||
)
|
||||
|
||||
poincare_src += $(addprefix poincare/src/parsing/,\
|
||||
@@ -162,6 +171,7 @@ tests_src += $(addprefix poincare/test/,\
|
||||
arithmetic.cpp\
|
||||
context.cpp\
|
||||
erf_inv.cpp \
|
||||
derivative.cpp\
|
||||
expression.cpp\
|
||||
expression_order.cpp\
|
||||
expression_properties.cpp\
|
||||
@@ -170,7 +180,6 @@ tests_src += $(addprefix poincare/test/,\
|
||||
function_solver.cpp\
|
||||
helper.cpp\
|
||||
helpers.cpp\
|
||||
ieee754.cpp\
|
||||
integer.cpp\
|
||||
layout.cpp\
|
||||
layout_cursor.cpp\
|
||||
@@ -182,6 +191,7 @@ tests_src += $(addprefix poincare/test/,\
|
||||
rational.cpp\
|
||||
regularized_incomplete_beta_function.cpp \
|
||||
simplification.cpp\
|
||||
zoom.cpp\
|
||||
)
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
|
||||
@@ -21,17 +21,18 @@ public:
|
||||
// Properties
|
||||
Type type() const override { return Type::AbsoluteValue; }
|
||||
Sign sign(Context * context) const override { return Sign::Positive; }
|
||||
NullStatus nullStatus(Context * context) const override { return childAtIndex(0)->nullStatus(context); }
|
||||
Expression setSign(Sign s, ReductionContext reductionContext) override;
|
||||
|
||||
// Approximation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) {
|
||||
return Complex<T>::Builder(std::abs(c));
|
||||
}
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit, computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
|
||||
// Layout
|
||||
@@ -41,6 +42,8 @@ public:
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
private:
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
};
|
||||
|
||||
class AbsoluteValue final : public Expression {
|
||||
@@ -52,6 +55,7 @@ public:
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("abs", 1, &UntypedBuilderOneChild<AbsoluteValue>);
|
||||
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ public:
|
||||
|
||||
private:
|
||||
KDCoordinate widthMargin() const override { return 2; }
|
||||
virtual KDCoordinate verticalExternMargin() const override { return 1; }
|
||||
KDCoordinate verticalMargin() const override { return 0; }
|
||||
KDCoordinate verticalExternMargin() const override { return 1; }
|
||||
bool renderTopBar() const override { return false; }
|
||||
bool renderBottomBar() const override { return false; }
|
||||
};
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
#define POINCARE_ADDITION_H
|
||||
|
||||
#include <poincare/approximation_helper.h>
|
||||
#include <poincare/n_ary_expression.h>
|
||||
#include <poincare/n_ary_infix_expression.h>
|
||||
#include <poincare/rational.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class AdditionNode final : public NAryExpressionNode {
|
||||
class AdditionNode final : public NAryInfixExpressionNode {
|
||||
friend class Addition;
|
||||
public:
|
||||
using NAryExpressionNode::NAryExpressionNode;
|
||||
using NAryInfixExpressionNode::NAryInfixExpressionNode;
|
||||
|
||||
// Tree
|
||||
size_t size() const override { return sizeof(AdditionNode); }
|
||||
@@ -55,17 +55,20 @@ private:
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
|
||||
// Derivation
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
|
||||
/* Evaluation */
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrixAndComplex(const MatrixComplex<T> m, const std::complex<T> c, Preferences::ComplexFormat complexFormat) {
|
||||
return MatrixComplex<T>::Undefined();
|
||||
}
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::MapReduce<float>(this, context, complexFormat, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::MapReduce<float>(this, approximationContext, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::MapReduce<double>(this, context, complexFormat, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::MapReduce<double>(this, approximationContext, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -80,7 +83,8 @@ public:
|
||||
static Addition Builder(Expression e1, Expression e2) { return Addition::Builder({e1, e2}); }
|
||||
// Expression
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
void sortChildrenInPlace(NAryExpressionNode::ExpressionOrder order, Context * context, bool canBeInterrupted) {
|
||||
NAryExpression::sortChildrenInPlace(order, context, true, canBeInterrupted);
|
||||
|
||||
@@ -9,17 +9,18 @@
|
||||
namespace Poincare {
|
||||
|
||||
namespace ApproximationHelper {
|
||||
template <typename T> int PositiveIntegerApproximationIfPossible(const ExpressionNode * expression, bool * isUndefined, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
template <typename T> T Epsilon();
|
||||
template <typename T> int PositiveIntegerApproximationIfPossible(const ExpressionNode * expression, bool * isUndefined, ExpressionNode::ApproximationContext approximationContext);
|
||||
template <typename T> std::complex<T> NeglectRealOrImaginaryPartIfNeglectable(std::complex<T> result, std::complex<T> input1, std::complex<T> input2 = 1.0, bool enableNullResult = true);
|
||||
|
||||
template <typename T> using ComplexCompute = Complex<T>(*)(const std::complex<T>, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
template<typename T> Evaluation<T> Map(const ExpressionNode * expression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ComplexCompute<T> compute);
|
||||
template<typename T> Evaluation<T> Map(const ExpressionNode * expression, ExpressionNode::ApproximationContext approximationContext, ComplexCompute<T> compute);
|
||||
|
||||
template <typename T> using ComplexAndComplexReduction = Complex<T>(*)(const std::complex<T>, const std::complex<T>, Preferences::ComplexFormat complexFormat);
|
||||
template <typename T> using ComplexAndMatrixReduction = MatrixComplex<T>(*)(const std::complex<T> c, const MatrixComplex<T> m, Preferences::ComplexFormat complexFormat);
|
||||
template <typename T> using MatrixAndComplexReduction = MatrixComplex<T>(*)(const MatrixComplex<T> m, const std::complex<T> c, Preferences::ComplexFormat complexFormat);
|
||||
template <typename T> using MatrixAndMatrixReduction = MatrixComplex<T>(*)(const MatrixComplex<T> m, const MatrixComplex<T> n, Preferences::ComplexFormat complexFormat);
|
||||
template<typename T> Evaluation<T> MapReduce(const ExpressionNode * expression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices);
|
||||
template<typename T> Evaluation<T> MapReduce(const ExpressionNode * expression, ExpressionNode::ApproximationContext approximationContext, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices);
|
||||
|
||||
template<typename T> MatrixComplex<T> ElementWiseOnMatrixComplexAndComplex(const MatrixComplex<T> n, std::complex<T> c, Preferences::ComplexFormat complexFormat, ComplexAndComplexReduction<T> computeOnComplexes);
|
||||
template<typename T> MatrixComplex<T> ElementWiseOnComplexMatrices(const MatrixComplex<T> m, const MatrixComplex<T> n, Preferences::ComplexFormat complexFormat, ComplexAndComplexReduction<T> computeOnComplexes);
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Sign sign(Context * context) const override { return childAtIndex(0)->sign(context) == Sign::Unknown ? Sign::Unknown : Sign::Positive; }
|
||||
Type type() const override { return Type::ArcCosine; }
|
||||
|
||||
private:
|
||||
@@ -34,11 +35,11 @@ private:
|
||||
|
||||
//Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Sign sign(Context * context) const override { return childAtIndex(0)->sign(context); }
|
||||
NullStatus nullStatus(Context * context) const override { return childAtIndex(0)->nullStatus(context); }
|
||||
Type type() const override { return Type::ArcSine; }
|
||||
private:
|
||||
// Layout
|
||||
@@ -32,11 +34,11 @@ private:
|
||||
|
||||
//Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Sign sign(Context * context) const override { return childAtIndex(0)->sign(context); }
|
||||
NullStatus nullStatus(Context * context) const override { return childAtIndex(0)->nullStatus(context); }
|
||||
Type type() const override { return Type::ArcTangent; }
|
||||
|
||||
private:
|
||||
@@ -33,11 +35,11 @@ private:
|
||||
|
||||
//Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,13 +2,20 @@
|
||||
#define POINCARE_ARITHMETIC_H
|
||||
|
||||
#include <poincare/integer.h>
|
||||
#include <poincare/approximation_helper.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Arithmetic final {
|
||||
public:
|
||||
static Integer LCM(const Integer & i, const Integer & j);
|
||||
static Integer GCD(const Integer & i, const Integer & j);
|
||||
static Integer LCM(const Integer & i, const Integer & j);
|
||||
static Expression GCD(const Expression & expression);
|
||||
static Expression LCM(const Expression & expression);
|
||||
static int GCD(int i, int j);
|
||||
static int LCM(int i, int j);
|
||||
template<typename T> static Evaluation<T> GCD(const ExpressionNode & expressionNode, ExpressionNode::ApproximationContext approximationContext);
|
||||
template<typename T> static Evaluation<T> LCM(const ExpressionNode & expressionNode, ExpressionNode::ApproximationContext approximationContext);
|
||||
/* When outputCoefficients[0] is set to -1, that indicates a special case:
|
||||
* i could not be factorized.
|
||||
* Before calling PrimeFactorization, we initiate two tables of Integers
|
||||
|
||||
34
poincare/include/poincare/array.h
Normal file
34
poincare/include/poincare/array.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef POINCARE_ARRAY_H
|
||||
#define POINCARE_ARRAY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Array {
|
||||
public:
|
||||
enum class VectorType {
|
||||
None,
|
||||
Vertical,
|
||||
Horizontal
|
||||
};
|
||||
Array() :
|
||||
m_numberOfRows(0),
|
||||
m_numberOfColumns(0) {}
|
||||
VectorType vectorType() const { return m_numberOfColumns == 1 ? VectorType::Vertical : (m_numberOfRows == 1 ? VectorType::Horizontal : VectorType::None); }
|
||||
int numberOfRows() const { return m_numberOfRows; }
|
||||
int numberOfColumns() const { return m_numberOfColumns; }
|
||||
void setNumberOfRows(int rows) { assert(rows >= 0); m_numberOfRows = rows; }
|
||||
void setNumberOfColumns(int columns) { assert(columns >= 0); m_numberOfColumns = columns; }
|
||||
protected:
|
||||
/* We could store 2 uint8_t but multiplying m_numberOfRows and
|
||||
* m_numberOfColumns could then lead to overflow. As we are unlikely to use
|
||||
* greater matrix than 100*100, uint16_t is fine. */
|
||||
uint16_t m_numberOfRows;
|
||||
uint16_t m_numberOfColumns;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
size_t size() const override;
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "Based Integer";
|
||||
stream << "BasedInteger";
|
||||
}
|
||||
virtual void logAttributes(std::ostream & stream) const override;
|
||||
#endif
|
||||
@@ -28,16 +28,18 @@ public:
|
||||
// Expression subclassing
|
||||
Type type() const override { return Type::BasedInteger; }
|
||||
Sign sign(Context * context) const override { return Sign::Positive; }
|
||||
NullStatus nullStatus(Context * context) const override { return integer().isZero() ? NullStatus::Null : NullStatus::NonNull; }
|
||||
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
// Approximation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex<float>::Builder(templatedApproximate<float>()); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex<double>::Builder(templatedApproximate<double>()); }
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return Complex<float>::Builder(templatedApproximate<float>()); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return Complex<double>::Builder(templatedApproximate<double>()); }
|
||||
template<typename T> T templatedApproximate() const;
|
||||
|
||||
private:
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return m_base == Integer::Base::Decimal ? LayoutShape::Integer : LayoutShape::BinaryHexadecimal; }
|
||||
Integer::Base m_base;
|
||||
|
||||
@@ -29,9 +29,9 @@ private:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class BinomCDF final : public BinomialDistributionFunction {
|
||||
|
||||
@@ -29,9 +29,9 @@ private:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class BinomPDF final : public BinomialDistributionFunction {
|
||||
|
||||
@@ -30,9 +30,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; };
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Complex<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Complex<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class BinomialCoefficient final : public Expression {
|
||||
|
||||
@@ -44,12 +44,18 @@ private:
|
||||
constexpr static KDCoordinate k_bracketWidth = 5;
|
||||
constexpr static KDCoordinate k_lineThickness = 1;
|
||||
constexpr static KDCoordinate k_verticalMargin = 1;
|
||||
KDCoordinate externWidthMargin() const { return k_externWidthMargin; }
|
||||
constexpr static bool k_renderTopBar = true;
|
||||
constexpr static bool k_renderBottomBar = true;
|
||||
constexpr static bool k_renderDoubleBar = false;
|
||||
virtual KDCoordinate externWidthMargin() const { return k_externWidthMargin; }
|
||||
virtual KDCoordinate widthMargin() const { return k_widthMargin; }
|
||||
virtual KDCoordinate verticalExternMargin() const { return k_verticalExternMargin; }
|
||||
virtual bool renderTopBar() const { return true; }
|
||||
virtual bool renderBottomBar() const { return true; }
|
||||
virtual KDCoordinate verticalMargin() const { return k_verticalMargin; }
|
||||
virtual bool renderTopBar() const { return k_renderTopBar; }
|
||||
virtual bool renderBottomBar() const { return k_renderBottomBar; }
|
||||
virtual bool renderDoubleBar() const { return k_renderDoubleBar; }
|
||||
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor, Layout * selectionStart = nullptr, Layout * selectionEnd = nullptr, KDColor selectionColor = KDColorRed) override;
|
||||
static void renderWithParameters(KDSize childSize, KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor, KDCoordinate verticalMargin, KDCoordinate externWidthMargin, KDCoordinate verticalExternMargin, KDCoordinate widthMargin, bool renderTopBar, bool renderBottomBar, bool renderDoubleBar);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Sign sign(Context * context) const override { return childAtIndex(0)->sign(context); }
|
||||
Type type() const override { return Type::Ceiling; }
|
||||
private:
|
||||
// Layout
|
||||
@@ -30,11 +31,11 @@ private:
|
||||
|
||||
// Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit, computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@ public:
|
||||
Expression complexToExpression(Preferences::Preferences::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> trace() const override { return *this; }
|
||||
std::complex<T> determinant() const override { return *this; }
|
||||
Evaluation<T> cross(Evaluation<T> * e) const override { return Complex<T>::Undefined(); }
|
||||
std::complex<T> dot(Evaluation<T> * e) const override { return std::complex<T>(NAN, NAN); }
|
||||
std::complex<T> norm() const override { return std::complex<T>(NAN, NAN); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -31,11 +31,11 @@ private:
|
||||
|
||||
// Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -19,16 +19,18 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Sign sign(Context * context) const override { return childAtIndex(1)->nullStatus(context) == NullStatus::Null ? childAtIndex(0)->sign(context) : Sign::Unknown; }
|
||||
NullStatus nullStatus(Context * context) const override;
|
||||
Type type() const override { return Type::ComplexCartesian; }
|
||||
private:
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { assert(false); return Layout(); }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override {
|
||||
/* leftLayoutShape is called after beautifying expression. ComplexCartesian
|
||||
* is transformed in another expression at beautifying. */
|
||||
@@ -36,7 +38,7 @@ private:
|
||||
return LayoutShape::BoundaryPunctuation;
|
||||
};
|
||||
|
||||
template<typename T> Complex<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> Complex<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class ComplexCartesian final : public Expression {
|
||||
@@ -51,8 +53,8 @@ public:
|
||||
Expression imag() { return childAtIndex(1); }
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce();
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
|
||||
// Common operations (done in-place)
|
||||
Expression squareNorm(ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
@@ -32,9 +32,9 @@ private:
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class SimplePredictionIntervalNode final : public ConfidenceIntervalNode {
|
||||
|
||||
@@ -19,6 +19,8 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Sign sign(Context * context) const override { return childAtIndex(0)->sign(context); }
|
||||
NullStatus nullStatus(Context * context) const override { return childAtIndex(0)->nullStatus(context); }
|
||||
Type type() const override { return Type::Conjugate; }
|
||||
private:
|
||||
// Layout
|
||||
@@ -31,11 +33,11 @@ private:
|
||||
|
||||
// Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -28,13 +28,14 @@ public:
|
||||
// Expression Properties
|
||||
Type type() const override { return Type::Constant; }
|
||||
Sign sign(Context * context) const override;
|
||||
NullStatus nullStatus(Context * context) const override { return NullStatus::NonNull; }
|
||||
|
||||
/* Layout */
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
/* Approximation */
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(); }
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(); }
|
||||
|
||||
/* Symbol properties */
|
||||
bool isPi() const { return isConstantCodePoint(UCodePointGreekSmallLetterPi); }
|
||||
@@ -49,6 +50,9 @@ public:
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::OneLetter; };
|
||||
|
||||
/* Derivation */
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
|
||||
private:
|
||||
char m_name[0]; // MUST be the last member variable
|
||||
|
||||
@@ -69,6 +73,7 @@ public:
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
|
||||
private:
|
||||
ConstantNode * node() const { return static_cast<ConstantNode *>(Expression::node()); }
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -14,10 +15,11 @@ public:
|
||||
enum class SymbolAbstractType : uint8_t {
|
||||
None,
|
||||
Function,
|
||||
Sequence,
|
||||
Symbol
|
||||
};
|
||||
virtual SymbolAbstractType expressionTypeForIdentifier(const char * identifier, int length) = 0;
|
||||
virtual const Expression expressionForSymbolAbstract(const SymbolAbstract & symbol, bool clone) = 0;
|
||||
virtual const Expression expressionForSymbolAbstract(const SymbolAbstract & symbol, bool clone, float unknownSymbolValue = NAN) = 0;
|
||||
virtual void setExpressionForSymbolAbstract(const Expression & expression, const SymbolAbstract & symbol) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@ public:
|
||||
// Context
|
||||
SymbolAbstractType expressionTypeForIdentifier(const char * identifier, int length) override { return m_parentContext->expressionTypeForIdentifier(identifier, length); }
|
||||
void setExpressionForSymbolAbstract(const Expression & expression, const SymbolAbstract & symbol) override { m_parentContext->setExpressionForSymbolAbstract(expression, symbol); }
|
||||
const Expression expressionForSymbolAbstract(const SymbolAbstract & symbol, bool clone) override { return m_parentContext->expressionForSymbolAbstract(symbol, clone); }
|
||||
const Expression expressionForSymbolAbstract(const SymbolAbstract & symbol, bool clone, float unknownSymbolValue = NAN) override { return m_parentContext->expressionForSymbolAbstract(symbol, clone, unknownSymbolValue); }
|
||||
|
||||
private:
|
||||
Context * m_parentContext;
|
||||
};
|
||||
|
||||
@@ -21,7 +21,6 @@ public:
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::Cosine; }
|
||||
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
|
||||
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Radian);
|
||||
|
||||
@@ -34,12 +33,16 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
|
||||
// Derivation
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
Expression unaryFunctionDifferential(ReductionContext reductionContext) override;
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -51,6 +54,9 @@ public:
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("cos", 1, &UntypedBuilderOneChild<Cosine>);
|
||||
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
Expression unaryFunctionDifferential(ExpressionNode::ReductionContext reductionContext);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -42,13 +42,14 @@ public:
|
||||
// Properties
|
||||
Type type() const override { return Type::Decimal; }
|
||||
Sign sign(Context * context) const override { return m_negative ? Sign::Negative : Sign::Positive; }
|
||||
NullStatus nullStatus(Context * context) const override { return unsignedMantissa().isZero() ? NullStatus::Null : NullStatus::NonNull; }
|
||||
Expression setSign(Sign s, ReductionContext reductionContext) override;
|
||||
|
||||
// Approximation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return Complex<float>::Builder(templatedApproximate<float>());
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return Complex<double>::Builder(templatedApproximate<double>());
|
||||
}
|
||||
|
||||
@@ -60,7 +61,7 @@ public:
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { assert(!m_negative); return LayoutShape::Decimal; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::Decimal; }
|
||||
|
||||
|
||||
@@ -34,12 +34,12 @@ private:
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> T approximateWithArgument(T x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> T growthRateAroundAbscissa(T x, T h, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> T riddersApproximation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, T x, T h, T * error) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
template<typename T> T approximateWithArgument(T x, ApproximationContext approximationContext) const;
|
||||
template<typename T> T growthRateAroundAbscissa(T x, T h, ApproximationContext approximationContext) const;
|
||||
template<typename T> T riddersApproximation(ApproximationContext approximationContext, T x, T h, T * error) const;
|
||||
// TODO: Change coefficients?
|
||||
constexpr static double k_maxErrorRateOnApproximation = 0.001;
|
||||
constexpr static double k_minInitialRate = 0.01;
|
||||
@@ -52,8 +52,9 @@ public:
|
||||
static Derivative Builder(Expression child0, Symbol child1, Expression child2) { return TreeHandle::FixedArityBuilder<Derivative, DerivativeNode>({child0, child1, child2}); }
|
||||
static Expression UntypedBuilder(Expression children);
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("diff", 3, &UntypedBuilder);
|
||||
static void DerivateUnaryFunction(Expression function, Expression symbol, Expression symbolValue, ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
Expression shallowReduce(Context * context);
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext context);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
/* Approximation */
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -23,20 +23,25 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Sign sign(Context * context) const override;
|
||||
NullStatus nullStatus(Context * context) const override {
|
||||
// NonNull Status can't be returned because denominator could be infinite.
|
||||
return childAtIndex(0)->nullStatus(context) == NullStatus::Null ? NullStatus::Null : NullStatus::Unknown;
|
||||
}
|
||||
Type type() const override { return Type::Division; }
|
||||
int polynomialDegree(Context * context, const char * symbolName) const override;
|
||||
Expression removeUnit(Expression * unit) override { assert(false); return ExpressionNode::removeUnit(unit); }
|
||||
|
||||
// Approximation
|
||||
virtual Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
virtual Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::MapReduce<float>(
|
||||
this, context, complexFormat, angleUnit, compute<float>,
|
||||
this, approximationContext, compute<float>,
|
||||
computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>,
|
||||
computeOnMatrices<float>);
|
||||
}
|
||||
virtual Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
virtual Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::MapReduce<double>(
|
||||
this, context, complexFormat, angleUnit, compute<double>,
|
||||
this, approximationContext, compute<double>,
|
||||
computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>,
|
||||
computeOnMatrices<double>);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
#endif
|
||||
|
||||
// ExpressionNode
|
||||
Sign sign(Context * context) const override;
|
||||
Type type() const override { return Type::DivisionQuotient; }
|
||||
|
||||
// Simplification
|
||||
@@ -32,9 +33,9 @@ private:
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class DivisionQuotient final : public Expression {
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
#endif
|
||||
|
||||
// ExpressionNode
|
||||
Sign sign(Context * context) const override { return Sign::Positive; }
|
||||
Type type() const override { return Type::DivisionRemainder; }
|
||||
|
||||
|
||||
@@ -34,9 +35,9 @@ private:
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class DivisionRemainder final : public Expression {
|
||||
|
||||
@@ -12,7 +12,7 @@ public:
|
||||
// Context
|
||||
SymbolAbstractType expressionTypeForIdentifier(const char * identifier, int length) override { return SymbolAbstractType::None; }
|
||||
void setExpressionForSymbolAbstract(const Expression & expression, const SymbolAbstract & symbol) override { assert(false); }
|
||||
const Expression expressionForSymbolAbstract(const SymbolAbstract & symbol, bool clone) override { return Expression(); }
|
||||
const Expression expressionForSymbolAbstract(const SymbolAbstract & symbol, bool clone, float unknownSymbolValue = NAN) override { return Expression(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ private:
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class EmptyExpression final : public Expression {
|
||||
|
||||
@@ -10,7 +10,7 @@ class EmptyLayoutNode /*final*/ : public LayoutNode {
|
||||
public:
|
||||
enum class Color {
|
||||
Yellow,
|
||||
Grey
|
||||
Gray
|
||||
};
|
||||
|
||||
// Layout
|
||||
|
||||
@@ -28,9 +28,9 @@ private:
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Evalutation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class Equal final : public Expression {
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
static Equal Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder<Equal, EqualNode>({child0, child1}); }
|
||||
|
||||
// For the equation A = B, create the reduced expression A-B
|
||||
Expression standardEquation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Expression standardEquation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::ReductionTarget reductionTarget) const;
|
||||
// Expression
|
||||
Expression shallowReduce();
|
||||
};
|
||||
|
||||
@@ -32,6 +32,9 @@ public:
|
||||
virtual Expression complexToExpression(Preferences::ComplexFormat complexFormat) const = 0;
|
||||
virtual std::complex<T> trace() const = 0;
|
||||
virtual std::complex<T> determinant() const = 0;
|
||||
virtual Evaluation<T> cross(Evaluation<T> * e) const = 0;
|
||||
virtual std::complex<T> dot(Evaluation<T> * e) const = 0;
|
||||
virtual std::complex<T> norm() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -64,6 +67,9 @@ public:
|
||||
Expression complexToExpression(Preferences::ComplexFormat complexFormat) const;
|
||||
std::complex<T> trace() const { return node()->trace(); }
|
||||
std::complex<T> determinant() const { return node()->determinant(); }
|
||||
Evaluation<T> cross(Evaluation<T> * e) const { return node()->cross(e); }
|
||||
std::complex<T> dot(Evaluation<T> * e) const { return node()->dot(e); }
|
||||
std::complex<T> norm() const { return node()->norm(); }
|
||||
protected:
|
||||
Evaluation(EvaluationNode<T> * n) : TreeHandle(n) {}
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <poincare/complex.h>
|
||||
#include <poincare/solver.h>
|
||||
#include <ion/storage.h>
|
||||
#include <utility>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -63,6 +64,9 @@ class Expression : public TreeHandle {
|
||||
friend class MatrixInverse;
|
||||
friend class MatrixTrace;
|
||||
friend class MatrixTranspose;
|
||||
friend class MatrixEchelonForm;
|
||||
friend class MatrixRowEchelonForm;
|
||||
friend class MatrixReducedRowEchelonForm;
|
||||
friend class Multiplication;
|
||||
friend class MultiplicationNode;
|
||||
friend class NaperianLogarithm;
|
||||
@@ -84,6 +88,7 @@ class Expression : public TreeHandle {
|
||||
friend class RealPart;
|
||||
friend class Round;
|
||||
friend class Sequence;
|
||||
friend class SequenceNode;
|
||||
friend class SignFunction;
|
||||
friend class Sine;
|
||||
friend class SquareRoot;
|
||||
@@ -92,6 +97,8 @@ class Expression : public TreeHandle {
|
||||
friend class Subtraction;
|
||||
friend class SubtractionNode;
|
||||
friend class Sum;
|
||||
friend class SumAndProduct;
|
||||
friend class SumAndProductNode;
|
||||
friend class Symbol;
|
||||
friend class SymbolAbstractNode;
|
||||
friend class Tangent;
|
||||
@@ -99,6 +106,9 @@ class Expression : public TreeHandle {
|
||||
friend class TrigonometryCheatTable;
|
||||
friend class Unit;
|
||||
friend class UnitConvert;
|
||||
friend class VectorCross;
|
||||
friend class VectorDot;
|
||||
friend class VectorNorm;
|
||||
|
||||
friend class AdditionNode;
|
||||
friend class DerivativeNode;
|
||||
@@ -113,6 +123,7 @@ class Expression : public TreeHandle {
|
||||
friend class MatrixNode;
|
||||
friend class NaperianLogarithmNode;
|
||||
friend class NAryExpressionNode;
|
||||
friend class NAryInfixExpressionNode;
|
||||
friend class StoreNode;
|
||||
friend class SymbolNode;
|
||||
friend class UnitNode;
|
||||
@@ -140,9 +151,10 @@ public:
|
||||
ExpressionNode::Type type() const { return node()->type(); }
|
||||
bool isOfType(ExpressionNode::Type * types, int length) const { return node()->isOfType(types, length); }
|
||||
ExpressionNode::Sign sign(Context * context) const { return node()->sign(context); }
|
||||
ExpressionNode::NullStatus nullStatus(Context * context) const { return node()->nullStatus(context); }
|
||||
bool isStrictly(ExpressionNode::Sign s, Context * context) const { return s == node()->sign(context) && node()->nullStatus(context) == ExpressionNode::NullStatus::NonNull; }
|
||||
bool isUndefined() const { return node()->type() == ExpressionNode::Type::Undefined || node()->type() == ExpressionNode::Type::Unreal; }
|
||||
bool isNumber() const { return node()->isNumber(); }
|
||||
bool isRationalZero() const;
|
||||
bool isRationalOne() const;
|
||||
bool isRandom() const { return node()->isRandom(); }
|
||||
bool isParameteredExpression() const { return node()->isParameteredExpression(); }
|
||||
@@ -162,15 +174,6 @@ public:
|
||||
static bool IsRandom(const Expression e, Context * context);
|
||||
static bool IsMatrix(const Expression e, Context * context);
|
||||
static bool IsInfinity(const Expression e, Context * context);
|
||||
/* 'characteristicXRange' tries to assess the range on x where the expression
|
||||
* (considered as a function on x) has an interesting evolution. For example,
|
||||
* 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 node()->characteristicXRange(context, angleUnit); }
|
||||
/* polynomialDegree returns:
|
||||
* - (-1) if the expression is not a polynome
|
||||
* - the degree of the polynome otherwise */
|
||||
@@ -188,14 +191,14 @@ public:
|
||||
* 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, int maxVariableLength, Expression coefficients[], Expression constant[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
bool getLinearCoefficients(char * variables, int maxVariableLength, Expression coefficients[], Expression constant[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
/* getPolynomialCoefficients fills the table coefficients with the expressions
|
||||
* of the first 3 polynomial coefficients and returns the polynomial degree.
|
||||
* It is supposed to be called on a reduced expression.
|
||||
* coefficients has up to 3 entries. */
|
||||
static constexpr int k_maxPolynomialDegree = 2;
|
||||
static constexpr int k_maxNumberOfPolynomialCoefficients = k_maxPolynomialDegree+1;
|
||||
int getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
int getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation) const;
|
||||
Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { return node()->replaceSymbolWithExpression(symbol, expression); }
|
||||
|
||||
/* Units */
|
||||
@@ -218,7 +221,7 @@ public:
|
||||
/* isIdenticalToWithoutParentheses behaves as isIdenticalTo, but without
|
||||
* taking into account parentheses: e^(0) is identical to e^0. */
|
||||
bool isIdenticalToWithoutParentheses(const Expression e) const;
|
||||
static bool ParsedExpressionsAreEqual(const char * e0, const char * e1, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
static bool ParsedExpressionsAreEqual(const char * e0, const char * e1, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat);
|
||||
|
||||
/* Layout Helper */
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
|
||||
@@ -239,12 +242,13 @@ public:
|
||||
* account the complex format required in the expression they return.
|
||||
* (For instance, in Polar mode, they return an expression of the form
|
||||
* r*e^(i*th) reduced and approximated.) */
|
||||
static Expression ParseAndSimplify(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default);
|
||||
static Expression ParseAndSimplify(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default);
|
||||
Expression simplify(ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
static void ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default);
|
||||
void simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default);
|
||||
static void ParseAndSimplifyAndApproximate(const char * text, Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default);
|
||||
void simplifyAndApproximate(Expression * simplifiedExpression, Expression * approximateExpression, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::UnitConversion unitConversion = ExpressionNode::UnitConversion::Default);
|
||||
Expression reduce(ExpressionNode::ReductionContext context);
|
||||
Expression reduceAndRemoveUnit(ExpressionNode::ReductionContext context, Expression * Unit);
|
||||
|
||||
Expression mapOnMatrixFirstChild(ExpressionNode::ReductionContext reductionContext);
|
||||
/* 'ExpressionWithoutSymbols' returns an uninitialized expression if it is
|
||||
@@ -257,9 +261,9 @@ public:
|
||||
/* Approximation Helper */
|
||||
// These methods reset the sApproximationEncounteredComplex flag. They should not be use to implement node approximation
|
||||
template<typename U> static U Epsilon();
|
||||
template<typename U> Expression approximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename U> U approximateToScalar(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename U> static U ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
|
||||
template<typename U> Expression approximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool withinReduce = false) const;
|
||||
template<typename U> U approximateToScalar(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool withinReduce = false) const;
|
||||
template<typename U> static U ApproximateToScalar(const char * text, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ExpressionNode::SymbolicComputation symbolicComputation = ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
|
||||
template<typename U> U approximateWithValueForSymbol(const char * symbol, U x, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
/* Expression roots/extrema solver */
|
||||
Coordinate2D<double> nextMinimum(const char * symbol, double start, double step, double max, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
@@ -314,6 +318,18 @@ protected:
|
||||
assert(children.type() == ExpressionNode::Type::Matrix);
|
||||
return U::Builder(children.childAtIndex(0), children.childAtIndex(1), children.childAtIndex(2), children.childAtIndex(3));
|
||||
}
|
||||
template<typename U>
|
||||
static Expression UntypedBuilderMultipleChildren(Expression children) {
|
||||
// Only with Expression classes implementing addChildAtIndexInPlace
|
||||
assert(children.type() == ExpressionNode::Type::Matrix);
|
||||
int childrenNumber = children.numberOfChildren();
|
||||
assert(childrenNumber > 0);
|
||||
U expression = U::Builder({children.childAtIndex(0)});
|
||||
for (int i = 1; i < childrenNumber; ++i) {
|
||||
expression.addChildAtIndexInPlace(children.childAtIndex(i), i, i);
|
||||
}
|
||||
return std::move(expression);
|
||||
}
|
||||
|
||||
template<class T> T convert() const {
|
||||
/* This function allows to convert Expression to derived Expressions.
|
||||
@@ -375,11 +391,18 @@ protected:
|
||||
Expression makePositiveAnyNegativeNumeralFactor(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression denominator(ExpressionNode::ReductionContext reductionContext) const { return node()->denominator(reductionContext); }
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext) { return node()->shallowReduce(reductionContext); }
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext) { return node()->shallowBeautify(reductionContext); }
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext) { return node()->shallowBeautify(reductionContext); }
|
||||
Expression deepBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
// WARNING: this must be called on reduced expressions
|
||||
Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
/* Derivation */
|
||||
/* This method is used for the reduction of Derivative expressions.
|
||||
* It returns whether the instance is differentiable, and differentiates it if
|
||||
* able. */
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue) { return node()->derivate(reductionContext, symbol, symbolValue); }
|
||||
Expression unaryFunctionDifferential(ExpressionNode::ReductionContext reductionContext) { return node()->unaryFunctionDifferential(reductionContext); }
|
||||
|
||||
private:
|
||||
static constexpr int k_maxSymbolReplacementsCount = 10;
|
||||
static bool sSymbolReplacementsCountLock;
|
||||
@@ -407,9 +430,15 @@ private:
|
||||
Expression defaultHandleUnitsInChildren(); // Children must be reduced
|
||||
Expression shallowReduceUsingApproximation(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression defaultShallowBeautify() { return *this; }
|
||||
void deepBeautifyChildren(ExpressionNode::ReductionContext reductionContext) {
|
||||
node()->deepBeautifyChildren(reductionContext);
|
||||
}
|
||||
void defaultDeepBeautifyChildren(ExpressionNode::ReductionContext reductionContext);
|
||||
bool defaultDidDerivate() { return false; }
|
||||
Expression defaultUnaryFunctionDifferential() { return *this; }
|
||||
|
||||
/* Approximation */
|
||||
template<typename U> Evaluation<U> approximateToEvaluation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename U> Evaluation<U> approximateToEvaluation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool withinReduce = false) const;
|
||||
|
||||
/* Properties */
|
||||
int defaultGetPolynomialCoefficients(Context * context, const char * symbol, Expression expression[]) const;
|
||||
|
||||
@@ -20,18 +20,23 @@ class ExpressionNode : public TreeNode {
|
||||
friend class AdditionNode;
|
||||
friend class DivisionNode;
|
||||
friend class NAryExpressionNode;
|
||||
friend class NAryInfixExpressionNode;
|
||||
friend class PowerNode;
|
||||
friend class SymbolNode;
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
// The types order is important here.
|
||||
enum class Type : uint8_t {
|
||||
Uninitialized = 0,
|
||||
Undefined = 1,
|
||||
Unreal,
|
||||
Rational,
|
||||
BasedInteger,
|
||||
Decimal,
|
||||
Double,
|
||||
Float,
|
||||
Infinity,
|
||||
/* When merging number nodes together, we do a linear scan which stops at
|
||||
* the first non-number child. */
|
||||
Multiplication,
|
||||
Power,
|
||||
Addition,
|
||||
@@ -90,23 +95,33 @@ public:
|
||||
Randint,
|
||||
RealPart,
|
||||
Round,
|
||||
Sequence,
|
||||
SignFunction,
|
||||
SquareRoot,
|
||||
Subtraction,
|
||||
Sum,
|
||||
|
||||
VectorDot,
|
||||
VectorNorm,
|
||||
/* When sorting the children of an expression, we assert that the following
|
||||
* nodes are at the end of the list : */
|
||||
// - Units
|
||||
Unit,
|
||||
// - Complexes
|
||||
ComplexCartesian,
|
||||
|
||||
// - Any kind of matrices :
|
||||
ConfidenceInterval,
|
||||
MatrixDimension,
|
||||
MatrixIdentity,
|
||||
MatrixInverse,
|
||||
MatrixTranspose,
|
||||
MatrixRowEchelonForm,
|
||||
MatrixReducedRowEchelonForm,
|
||||
PredictionInterval,
|
||||
VectorCross,
|
||||
Matrix,
|
||||
|
||||
EmptyExpression
|
||||
};
|
||||
};
|
||||
|
||||
/* Poor man's RTTI */
|
||||
virtual Type type() const = 0;
|
||||
@@ -141,33 +156,82 @@ public:
|
||||
Unknown = 0,
|
||||
Positive = 1
|
||||
};
|
||||
enum class NullStatus {
|
||||
Unknown = -1,
|
||||
NonNull = 0,
|
||||
Null = 1,
|
||||
};
|
||||
|
||||
class ReductionContext {
|
||||
class ComputationContext {
|
||||
public:
|
||||
ReductionContext(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target, SymbolicComputation symbolicComputation = SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, UnitConversion unitConversion = UnitConversion::Default) :
|
||||
ComputationContext(
|
||||
Context * context,
|
||||
Preferences::ComplexFormat complexFormat,
|
||||
Preferences::AngleUnit angleUnit) :
|
||||
m_context(context),
|
||||
m_complexFormat(complexFormat),
|
||||
m_angleUnit(angleUnit),
|
||||
m_target(target),
|
||||
m_symbolicComputation(symbolicComputation),
|
||||
m_unitConversion(unitConversion)
|
||||
m_angleUnit(angleUnit)
|
||||
{}
|
||||
Context * context() { return m_context; }
|
||||
void setContext(Context * context) { m_context = context; }
|
||||
Preferences::ComplexFormat complexFormat() const { return m_complexFormat; }
|
||||
Preferences::AngleUnit angleUnit() const { return m_angleUnit; }
|
||||
ReductionTarget target() const { return m_target; }
|
||||
SymbolicComputation symbolicComputation() const { return m_symbolicComputation; }
|
||||
UnitConversion unitConversion() const { return m_unitConversion; }
|
||||
private:
|
||||
Context * m_context;
|
||||
Preferences::ComplexFormat m_complexFormat;
|
||||
Preferences::AngleUnit m_angleUnit;
|
||||
};
|
||||
|
||||
class ReductionContext : public ComputationContext {
|
||||
public:
|
||||
ReductionContext(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, ReductionTarget target, SymbolicComputation symbolicComputation = SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, UnitConversion unitConversion = UnitConversion::Default) :
|
||||
ComputationContext(context, complexFormat, angleUnit),
|
||||
m_unitFormat(unitFormat),
|
||||
m_target(target),
|
||||
m_symbolicComputation(symbolicComputation),
|
||||
m_unitConversion(unitConversion)
|
||||
{}
|
||||
static ReductionContext NonInvasiveReductionContext(ReductionContext reductionContext) {
|
||||
return ReductionContext(
|
||||
reductionContext.context(),
|
||||
reductionContext.complexFormat(),
|
||||
reductionContext.angleUnit(),
|
||||
reductionContext.unitFormat(),
|
||||
reductionContext.target(),
|
||||
SymbolicComputation::DoNotReplaceAnySymbol,
|
||||
UnitConversion::None
|
||||
);
|
||||
}
|
||||
Preferences::UnitFormat unitFormat() const { return m_unitFormat; }
|
||||
ReductionTarget target() const { return m_target; }
|
||||
SymbolicComputation symbolicComputation() const { return m_symbolicComputation; }
|
||||
UnitConversion unitConversion() const { return m_unitConversion; }
|
||||
private:
|
||||
Preferences::UnitFormat m_unitFormat;
|
||||
ReductionTarget m_target;
|
||||
SymbolicComputation m_symbolicComputation;
|
||||
UnitConversion m_unitConversion;
|
||||
};
|
||||
|
||||
class ApproximationContext : public ComputationContext {
|
||||
public:
|
||||
ApproximationContext(
|
||||
Context * context,
|
||||
Preferences::ComplexFormat complexFormat,
|
||||
Preferences::AngleUnit angleUnit,
|
||||
bool withinReduce = false) :
|
||||
ComputationContext(context, complexFormat, angleUnit),
|
||||
m_withinReduce(withinReduce)
|
||||
{}
|
||||
ApproximationContext(ReductionContext reductionContext, bool withinReduce) :
|
||||
ApproximationContext(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit(), withinReduce) {}
|
||||
bool withinReduce() const { return m_withinReduce; }
|
||||
private:
|
||||
bool m_withinReduce;
|
||||
};
|
||||
|
||||
virtual Sign sign(Context * context) const { return Sign::Unknown; }
|
||||
virtual NullStatus nullStatus(Context * context) const { return NullStatus::Unknown; }
|
||||
virtual bool isNumber() const { return false; }
|
||||
virtual bool isRandom() const { return false; }
|
||||
virtual bool isParameteredExpression() const { return false; }
|
||||
@@ -183,7 +247,6 @@ public:
|
||||
/*!*/ virtual Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount);
|
||||
typedef bool (*isVariableTest)(const char * c, Poincare::Context * context);
|
||||
virtual int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const;
|
||||
virtual float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const;
|
||||
bool isOfType(Type * types, int length) const;
|
||||
|
||||
virtual Expression removeUnit(Expression * unit); // Only reduced nodes should answer
|
||||
@@ -216,13 +279,22 @@ public:
|
||||
typedef float SinglePrecision;
|
||||
typedef double DoublePrecision;
|
||||
constexpr static int k_maxNumberOfSteps = 10000;
|
||||
virtual Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const = 0;
|
||||
virtual Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const = 0;
|
||||
virtual Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const = 0;
|
||||
virtual Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const = 0;
|
||||
|
||||
/* Simplification */
|
||||
/*!*/ virtual void deepReduceChildren(ReductionContext reductionContext);
|
||||
/*!*/ virtual void deepBeautifyChildren(ReductionContext reductionContext);
|
||||
/*!*/ virtual Expression shallowReduce(ReductionContext reductionContext);
|
||||
/*!*/ virtual Expression shallowBeautify(ReductionContext reductionContext);
|
||||
/* TODO: shallowBeautify takes a pointer to the reduction context, unlike
|
||||
* other methods. The pointer is needed to allow UnitConvert to modify the
|
||||
* context and prevent unit modifications (in Expression::deepBeautify, after
|
||||
* calling UnitConvert::shallowBeautify).
|
||||
* We should uniformize this behaviour and use pointers in other methods using
|
||||
* the reduction context. */
|
||||
/*!*/ virtual Expression shallowBeautify(ReductionContext * reductionContext);
|
||||
/*!*/ virtual bool derivate(ReductionContext, Expression symbol, Expression symbolValue);
|
||||
virtual Expression unaryFunctionDifferential(ReductionContext reductionContext);
|
||||
/* Return a clone of the denominator part of the expression */
|
||||
/*!*/ virtual Expression denominator(ExpressionNode::ReductionContext reductionContext) const;
|
||||
/* LayoutShape is used to check if the multiplication sign can be omitted between two expressions. It depends on the "layout syle" of the on the right of the left expression */
|
||||
|
||||
@@ -18,6 +18,8 @@ public:
|
||||
stream << "Factor";
|
||||
}
|
||||
#endif
|
||||
Sign sign(Context * context) const override { return childAtIndex(0)->sign(context); }
|
||||
NullStatus nullStatus(Context * context) const override { return childAtIndex(0)->nullStatus(context); }
|
||||
Type type() const override { return Type::Factor; }
|
||||
private:
|
||||
/* Layout */
|
||||
@@ -25,15 +27,15 @@ private:
|
||||
/* Serialization */
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Simplification */
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
|
||||
/* Evaluation */
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class Factor final : public Expression {
|
||||
@@ -43,11 +45,11 @@ public:
|
||||
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("factor", 1, &UntypedBuilderOneChild<Factor>);
|
||||
|
||||
Multiplication createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Multiplication createMultiplicationOfIntegerPrimeDecomposition(Integer i) const;
|
||||
|
||||
// Expression
|
||||
Expression shallowReduce(Context * context);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
NullStatus nullStatus(Context * context) const override { return NullStatus::NonNull; }
|
||||
Type type() const override { return Type::Factorial; }
|
||||
Sign sign(Context * context) const override { return Sign::Positive; }
|
||||
Expression setSign(Sign s, ReductionContext reductionContext) override;
|
||||
@@ -36,11 +37,11 @@ private:
|
||||
|
||||
// Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -36,8 +36,9 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::Float; }
|
||||
Type type() const override { return (sizeof(T) == sizeof(float)) ? Type::Float : Type::Double; }
|
||||
Sign sign(Context * context) const override { return m_value < 0 ? Sign::Negative : Sign::Positive; }
|
||||
NullStatus nullStatus(Context * context) const override { return m_value == 0.0 ? NullStatus::Null : NullStatus::NonNull; }
|
||||
Expression setSign(Sign s, ReductionContext reductionContext) override;
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
|
||||
@@ -46,13 +47,13 @@ public:
|
||||
/* Layout */
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Evaluation */
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
private:
|
||||
// Simplification
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::Decimal; }
|
||||
|
||||
template<typename U> Evaluation<U> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
||||
template<typename U> Evaluation<U> templatedApproximate(ApproximationContext approximationContext) const {
|
||||
return Complex<U>::Builder((U)m_value);
|
||||
}
|
||||
T m_value;
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Sign sign(Context * context) const override { return childAtIndex(0)->sign(context); }
|
||||
Type type() const override { return Type::Floor; }
|
||||
|
||||
private:
|
||||
@@ -31,11 +32,11 @@ private:
|
||||
|
||||
// Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit, computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -19,10 +19,9 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Sign sign(Context * context) const override { return Sign::Positive; }
|
||||
Type type() const override { return Type::FracPart; }
|
||||
|
||||
|
||||
|
||||
private:
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
@@ -34,11 +33,11 @@ private:
|
||||
|
||||
// Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit, computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ public:
|
||||
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const override;
|
||||
bool shouldCollapseSiblingsOnLeft() const override { return true; }
|
||||
bool shouldCollapseSiblingsOnRight() const override { return true; }
|
||||
int leftCollapsingAbsorbingChildIndex() const override { return 0; }
|
||||
|
||||
@@ -27,7 +27,6 @@ public:
|
||||
int polynomialDegree(Context * context, const char * symbolName) const override;
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const override;
|
||||
int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const override;
|
||||
float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const override;
|
||||
|
||||
private:
|
||||
char m_name[0]; // MUST be the last member variable
|
||||
@@ -43,9 +42,9 @@ private:
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override;
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override;
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override;
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override;
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class Function : public SymbolAbstract {
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
#ifndef POINCARE_GREAT_COMMON_DIVISOR_H
|
||||
#define POINCARE_GREAT_COMMON_DIVISOR_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/n_ary_expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class GreatCommonDivisorNode final : public ExpressionNode {
|
||||
class GreatCommonDivisorNode final : public NAryExpressionNode {
|
||||
public:
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(GreatCommonDivisorNode); }
|
||||
int numberOfChildren() const override;
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "GreatCommonDivisor";
|
||||
@@ -18,6 +17,7 @@ public:
|
||||
#endif
|
||||
|
||||
// ExpressionNode
|
||||
Sign sign(Context * context) const override { return Sign::Positive; }
|
||||
Type type() const override { return Type::GreatCommonDivisor; }
|
||||
|
||||
private:
|
||||
@@ -26,22 +26,25 @@ private:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class GreatCommonDivisor final : public Expression {
|
||||
class GreatCommonDivisor final : public NAryExpression {
|
||||
public:
|
||||
GreatCommonDivisor(const GreatCommonDivisorNode * n) : Expression(n) {}
|
||||
static GreatCommonDivisor Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder<GreatCommonDivisor, GreatCommonDivisorNode>({child0, child1}); }
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("gcd", 2, &UntypedBuilderTwoChildren<GreatCommonDivisor>);
|
||||
GreatCommonDivisor(const GreatCommonDivisorNode * n) : NAryExpression(n) {}
|
||||
static GreatCommonDivisor Builder(const Tuple & children = {}) { return TreeHandle::NAryBuilder<GreatCommonDivisor, GreatCommonDivisorNode>(convert(children)); }
|
||||
// Using a -2 as numberOfChildren to allow 2 or more children when parsing
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("gcd", -2, &UntypedBuilderMultipleChildren<GreatCommonDivisor>);
|
||||
|
||||
// Expression
|
||||
Expression shallowReduce(Context * context);
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(Context * context);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +1,30 @@
|
||||
#ifndef POINCARE_GRID_LAYOUT_NODE_H
|
||||
#define POINCARE_GRID_LAYOUT_NODE_H
|
||||
|
||||
#include <poincare/array.h>
|
||||
#include <poincare/empty_layout.h>
|
||||
#include <poincare/layout.h>
|
||||
#include <poincare/layout_cursor.h>
|
||||
#include <poincare/empty_layout.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class GridLayout;
|
||||
class MatrixLayoutNode;
|
||||
|
||||
class GridLayoutNode : public LayoutNode {
|
||||
class GridLayoutNode : public Array, public LayoutNode {
|
||||
friend class MatrixLayoutNode;
|
||||
friend class BinomialCoefficientLayoutNode;
|
||||
friend class BinomialCoefficientLayout;
|
||||
friend class GridLayout;
|
||||
public:
|
||||
GridLayoutNode() :
|
||||
LayoutNode(),
|
||||
m_numberOfRows(0),
|
||||
m_numberOfColumns(0)
|
||||
Array(),
|
||||
LayoutNode()
|
||||
{}
|
||||
|
||||
// Layout
|
||||
Type type() const override { return Type::GridLayout; }
|
||||
|
||||
int numberOfRows() const { return m_numberOfRows; }
|
||||
int numberOfColumns() const { return m_numberOfColumns; }
|
||||
virtual void setNumberOfRows(int numberOfRows) { m_numberOfRows = numberOfRows; }
|
||||
virtual void setNumberOfColumns(int numberOfColumns) { m_numberOfColumns = numberOfColumns; }
|
||||
KDSize gridSize() const { return KDSize(width(), height()); }
|
||||
|
||||
// LayoutNode
|
||||
@@ -70,8 +66,6 @@ protected:
|
||||
int rowAtChildIndex(int index) const;
|
||||
int columnAtChildIndex(int index) const;
|
||||
int indexAtRowColumn(int rowIndex, int columnIndex) const;
|
||||
int m_numberOfRows;
|
||||
int m_numberOfColumns;
|
||||
|
||||
// LayoutNode
|
||||
KDSize computeSize() override;
|
||||
@@ -100,14 +94,8 @@ public:
|
||||
int numberOfColumns() const { return node()->numberOfColumns(); }
|
||||
private:
|
||||
virtual GridLayoutNode * node() const { return static_cast<GridLayoutNode *>(Layout::node()); }
|
||||
void setNumberOfRows(int rows) {
|
||||
assert(rows >= 0);
|
||||
node()->setNumberOfRows(rows);
|
||||
}
|
||||
void setNumberOfColumns(int columns) {
|
||||
assert(columns >= 0);
|
||||
node()->setNumberOfColumns(columns);
|
||||
}
|
||||
void setNumberOfRows(int rows) { node()->setNumberOfRows(rows); }
|
||||
void setNumberOfColumns(int columns) { node()->setNumberOfColumns(columns); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -8,9 +8,13 @@ namespace Poincare {
|
||||
|
||||
namespace Helpers {
|
||||
|
||||
typedef void (*Swap) (int i, int j, void * context, int numberOfElements);
|
||||
typedef bool (*Compare) (int i, int j, void * context, int numberOfElements);
|
||||
|
||||
size_t AlignedSize(size_t realSize, size_t alignment);
|
||||
size_t Gcd(size_t a, size_t b);
|
||||
bool Rotate(uint32_t * dst, uint32_t * src, size_t len);
|
||||
void Sort(Swap swap, Compare compare, void * context, int numberOfElements);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,17 +21,17 @@ public:
|
||||
Type type() const override { return Type::HyperbolicArcCosine; }
|
||||
private:
|
||||
// Simplification
|
||||
bool isNotableValue(Expression e) const override { return e.isRationalOne(); }
|
||||
bool isNotableValue(Expression e, Context * context) const override { return e.isRationalOne(); }
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
//Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
//Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@ private:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
//Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -25,13 +25,16 @@ private:
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Derivation
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
Expression unaryFunctionDifferential(ReductionContext reductionContext) override;
|
||||
//Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -40,6 +43,9 @@ public:
|
||||
HyperbolicCosine(const HyperbolicCosineNode * n) : HyperbolicTrigonometricFunction(n) {}
|
||||
static HyperbolicCosine Builder(Expression child) { return TreeHandle::FixedArityBuilder<HyperbolicCosine, HyperbolicCosineNode>({child}); }
|
||||
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
Expression unaryFunctionDifferential(ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("cosh", 1, &UntypedBuilderOneChild<HyperbolicCosine>);
|
||||
};
|
||||
|
||||
|
||||
@@ -23,13 +23,16 @@ private:
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Derivation
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
Expression unaryFunctionDifferential(ReductionContext reductionContext) override;
|
||||
//Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -38,6 +41,9 @@ public:
|
||||
HyperbolicSine(const HyperbolicSineNode * n) : HyperbolicTrigonometricFunction(n) {}
|
||||
static HyperbolicSine Builder(Expression child) { return TreeHandle::FixedArityBuilder<HyperbolicSine, HyperbolicSineNode>({child}); }
|
||||
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
Expression unaryFunctionDifferential(ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sinh", 1, &UntypedBuilderOneChild<HyperbolicSine>);
|
||||
};
|
||||
|
||||
|
||||
@@ -23,13 +23,16 @@ private:
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Derivation
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
Expression unaryFunctionDifferential(ReductionContext reductionContext) override;
|
||||
//Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -38,6 +41,9 @@ public:
|
||||
HyperbolicTangent(const HyperbolicTangentNode * n) : HyperbolicTrigonometricFunction(n) {}
|
||||
static HyperbolicTangent Builder(Expression child) { return TreeHandle::FixedArityBuilder<HyperbolicTangent, HyperbolicTangentNode>({child}); }
|
||||
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
Expression unaryFunctionDifferential(ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("tanh", 1, &UntypedBuilderOneChild<HyperbolicTangent>);
|
||||
};
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
virtual bool isNotableValue(Expression e) const { return e.isRationalZero(); }
|
||||
virtual bool isNotableValue(Expression e, Context * context) const { return e.nullStatus(context) == ExpressionNode::NullStatus::Null; }
|
||||
virtual Expression imageOfNotableValue() const { return Rational::Builder(0); }
|
||||
};
|
||||
|
||||
|
||||
@@ -73,40 +73,12 @@ public:
|
||||
}
|
||||
return exponentBase10;
|
||||
}
|
||||
static T next(T f) {
|
||||
return nextOrPrevious(f, true);
|
||||
}
|
||||
|
||||
static T previous(T f) {
|
||||
return nextOrPrevious(f, false);
|
||||
}
|
||||
|
||||
private:
|
||||
union uint_float {
|
||||
uint64_t ui;
|
||||
T f;
|
||||
};
|
||||
static T nextOrPrevious(T f, bool isNext) {
|
||||
if (std::isinf(f) || std::isnan(f)) {
|
||||
return f;
|
||||
}
|
||||
uint_float u;
|
||||
u.ui = 0;
|
||||
u.f = f;
|
||||
uint64_t oneBitOnSignBit = (uint64_t)1 << (k_exponentNbBits + k_mantissaNbBits);
|
||||
if ((isNext && (u.ui & oneBitOnSignBit) > 0) // next: Negative float
|
||||
|| (!isNext && (u.ui & oneBitOnSignBit) == 0)) { // previous: Positive float
|
||||
if ((isNext && u.ui == oneBitOnSignBit) // next: -0.0
|
||||
|| (!isNext && u.ui == 0.0)) { // previous: 0.0
|
||||
u.ui = isNext ? 0 : oneBitOnSignBit;
|
||||
} else {
|
||||
u.ui -= 1;
|
||||
}
|
||||
} else { // next: Positive float, previous: Negative float
|
||||
u.ui += 1;
|
||||
}
|
||||
return u.f;
|
||||
}
|
||||
|
||||
constexpr static size_t k_signNbBits = 1;
|
||||
constexpr static size_t k_exponentNbBits = sizeof(T) == sizeof(float) ? 8 : 11;
|
||||
|
||||
@@ -19,9 +19,9 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
NullStatus nullStatus(Context * context) const override { return childAtIndex(0)->sign(context) != Sign::Unknown ? NullStatus::Null : NullStatus::Unknown; }
|
||||
Type type() const override { return Type::ImaginaryPart; }
|
||||
|
||||
|
||||
private:
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
@@ -34,11 +34,11 @@ private:
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) {
|
||||
return Complex<T>::Builder(std::imag(c));
|
||||
}
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -23,19 +23,25 @@ public:
|
||||
// Properties
|
||||
Type type() const override { return Type::Infinity; }
|
||||
Sign sign(Context * context) const override { return m_negative ? Sign::Negative : Sign::Positive; }
|
||||
NullStatus nullStatus(Context * context) const override { return NullStatus::NonNull; }
|
||||
Expression setSign(Sign s, ReductionContext reductionContext) override;
|
||||
|
||||
// Approximation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return templatedApproximate<float>();
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return templatedApproximate<double>();
|
||||
}
|
||||
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
|
||||
/* Derivation
|
||||
* Unlike Numbers that derivate to 0, Infinity derivates to Undefined. */
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
|
||||
private:
|
||||
// Simplification
|
||||
LayoutShape leftLayoutShape() const override { assert(!m_negative); return LayoutShape::MoreLetters; }
|
||||
@@ -55,6 +61,7 @@ public:
|
||||
static int NameSize() {
|
||||
return 4;
|
||||
}
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
private:
|
||||
InfinityNode * node() const { return static_cast<InfinityNode *>(Number::node()); }
|
||||
};
|
||||
|
||||
@@ -31,9 +31,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::MoreLetters; }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
template<typename T>
|
||||
struct DetailedResult
|
||||
{
|
||||
@@ -44,10 +44,10 @@ private:
|
||||
#ifdef LAGRANGE_METHOD
|
||||
template<typename T> T lagrangeGaussQuadrature(T a, T b, Context Context * context, Preferences::AngleUnit angleUnit context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
#else
|
||||
template<typename T> DetailedResult<T> kronrodGaussQuadrature(T a, T b, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> T adaptiveQuadrature(T a, T b, T eps, int numberOfIterations, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> DetailedResult<T> kronrodGaussQuadrature(T a, T b, ApproximationContext approximationContext) const;
|
||||
template<typename T> T adaptiveQuadrature(T a, T b, T eps, int numberOfIterations, ApproximationContext approximationContext) const;
|
||||
#endif
|
||||
template<typename T> T functionValueAtAbscissa(T x, Context * xcontext, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> T functionValueAtAbscissa(T x, ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class Integral final : public ParameteredExpression {
|
||||
|
||||
@@ -9,7 +9,9 @@ namespace Poincare {
|
||||
|
||||
class IntegralLayoutNode final : public LayoutNode {
|
||||
public:
|
||||
constexpr static KDCoordinate k_symbolHeight = 4;
|
||||
|
||||
// Sizes of the upper and lower curls of the integral symbol
|
||||
constexpr static KDCoordinate k_symbolHeight = 9;
|
||||
constexpr static KDCoordinate k_symbolWidth = 4;
|
||||
|
||||
using LayoutNode::LayoutNode;
|
||||
@@ -40,16 +42,18 @@ protected:
|
||||
// LayoutNode
|
||||
KDSize computeSize() override;
|
||||
KDCoordinate computeBaseline() override;
|
||||
KDCoordinate centralArgumentHeight();
|
||||
KDPoint positionOfChild(LayoutNode * child) override;
|
||||
|
||||
private:
|
||||
constexpr static int k_integrandLayoutIndex = 0;
|
||||
constexpr static int k_differentialLayoutIndex = 1;
|
||||
constexpr static const KDFont * k_font = KDFont::LargeFont;
|
||||
constexpr static KDCoordinate k_boundHeightMargin = 8;
|
||||
constexpr static KDCoordinate k_boundWidthMargin = 5;
|
||||
constexpr static KDCoordinate k_differentialWidthMargin = 3;
|
||||
constexpr static KDCoordinate k_integrandWidthMargin = 2;
|
||||
constexpr static KDCoordinate k_integrandHeigthMargin = 2;
|
||||
constexpr static KDCoordinate k_boundVerticalMargin = 4;
|
||||
constexpr static KDCoordinate k_boundHorizontalMargin = 3;
|
||||
constexpr static KDCoordinate k_differentialHorizontalMargin = 3;
|
||||
constexpr static KDCoordinate k_integrandHorizontalMargin = 2;
|
||||
constexpr static KDCoordinate k_integrandVerticalMargin = 3;
|
||||
constexpr static KDCoordinate k_lineThickness = 1;
|
||||
// int(f(x), x, a, b)
|
||||
LayoutNode * integrandLayout() { return childAtIndex(k_integrandLayoutIndex); } // f(x)
|
||||
@@ -57,6 +61,23 @@ private:
|
||||
LayoutNode * lowerBoundLayout() { return childAtIndex(2); } // a
|
||||
LayoutNode * upperBoundLayout() { return childAtIndex(3); } // b
|
||||
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor, Layout * selectionStart = nullptr, Layout * selectionEnd = nullptr, KDColor selectionColor = KDColorRed) override;
|
||||
|
||||
enum class BoundPosition : uint8_t{
|
||||
UpperBound,
|
||||
LowerBound
|
||||
};
|
||||
|
||||
enum class NestedPosition : uint8_t{
|
||||
Previous,
|
||||
Next
|
||||
};
|
||||
|
||||
LayoutNode * boundLayout(BoundPosition position) { return position == BoundPosition::UpperBound ? upperBoundLayout() : lowerBoundLayout(); }
|
||||
IntegralLayoutNode * nextNestedIntegral();
|
||||
IntegralLayoutNode * previousNestedIntegral();
|
||||
IntegralLayoutNode * nestedIntegral(NestedPosition position) { return position == NestedPosition::Next ? nextNestedIntegral() : previousNestedIntegral(); }
|
||||
KDCoordinate boundMaxHeight(BoundPosition position);
|
||||
IntegralLayoutNode * mostNestedIntegral (NestedPosition position);
|
||||
};
|
||||
|
||||
class IntegralLayout final : public Layout {
|
||||
|
||||
@@ -30,9 +30,9 @@ private:
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class InvBinom final : public BinomialDistributionFunction {
|
||||
|
||||
@@ -30,9 +30,9 @@ private:
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class InvNorm final : public NormalDistributionFunction {
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
assert(isUninitialized() || !TreeHandle::node()->isGhost());
|
||||
return static_cast<LayoutNode *>(TreeHandle::node());
|
||||
}
|
||||
static Layout LayoutFromAddress(const void * address, size_t size);
|
||||
|
||||
// Properties
|
||||
LayoutNode::Type type() const { return node()->type(); }
|
||||
@@ -59,9 +60,9 @@ public:
|
||||
|
||||
// Layout modification
|
||||
void deleteBeforeCursor(LayoutCursor * cursor) { return node()->deleteBeforeCursor(cursor); }
|
||||
bool removeGreySquaresFromAllMatrixAncestors() { return node()->removeGreySquaresFromAllMatrixAncestors(); }
|
||||
bool removeGreySquaresFromAllMatrixChildren() { return node()->removeGreySquaresFromAllMatrixChildren(); }
|
||||
bool addGreySquaresToAllMatrixAncestors() { return node()->addGreySquaresToAllMatrixAncestors(); }
|
||||
bool removeGraySquaresFromAllMatrixAncestors() { return node()->removeGraySquaresFromAllMatrixAncestors(); }
|
||||
bool removeGraySquaresFromAllMatrixChildren() { return node()->removeGraySquaresFromAllMatrixChildren(); }
|
||||
bool addGraySquaresToAllMatrixAncestors() { return node()->addGraySquaresToAllMatrixAncestors(); }
|
||||
Layout layoutToPointWhenInserting(Expression * correspondingExpression) {
|
||||
// Pointer to correspondingExpr because expression.h includes layout.h
|
||||
assert(correspondingExpression != nullptr);
|
||||
|
||||
@@ -95,15 +95,11 @@ public:
|
||||
void moveUnder(bool * shouldRecomputeLayout, bool forSelection = false) {
|
||||
layoutNode()->moveCursorDown(this, shouldRecomputeLayout, false, forSelection);
|
||||
}
|
||||
LayoutCursor cursorAtDirection(Direction direction, bool * shouldRecomputeLayout, bool forSelection = false);
|
||||
LayoutCursor cursorAtDirection(Direction direction, bool * shouldRecomputeLayout, bool forSelection = false, int step = 1);
|
||||
|
||||
/* Select */
|
||||
void select(Direction direction, bool * shouldRecomputeLayout, Layout * selection);
|
||||
LayoutCursor selectAtDirection(Direction direction, bool * shouldRecomputeLayout, Layout * selection) {
|
||||
LayoutCursor result = clone();
|
||||
result.select(direction, shouldRecomputeLayout, selection);
|
||||
return result;
|
||||
}
|
||||
LayoutCursor selectAtDirection(Direction direction, bool * shouldRecomputeLayout, Layout * selection);
|
||||
|
||||
/* Layout modification */
|
||||
void addEmptyExponentialLayout();
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
RightParenthesisLayout,
|
||||
RightSquareBracketLayout,
|
||||
SumLayout,
|
||||
VectorNormLayout,
|
||||
VerticalOffsetLayout
|
||||
};
|
||||
|
||||
@@ -104,9 +105,9 @@ public:
|
||||
|
||||
// Other
|
||||
virtual LayoutNode * layoutToPointWhenInserting(Expression * correspondingExpression);
|
||||
bool removeGreySquaresFromAllMatrixAncestors();
|
||||
bool removeGreySquaresFromAllMatrixChildren();
|
||||
bool addGreySquaresToAllMatrixAncestors();
|
||||
bool removeGraySquaresFromAllMatrixAncestors();
|
||||
bool removeGraySquaresFromAllMatrixChildren();
|
||||
bool addGraySquaresToAllMatrixAncestors();
|
||||
/* A layout has text if it is not empty and it is not an horizontal layout
|
||||
* with no child or with one child with no text. */
|
||||
virtual bool hasText() const { return true; }
|
||||
@@ -174,7 +175,7 @@ private:
|
||||
int * resultScore,
|
||||
bool forSelection);
|
||||
virtual void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor, Layout * selectionStart = nullptr, Layout * selectionEnd = nullptr, KDColor selectionColor = KDColorRed) = 0;
|
||||
void changeGreySquaresOfAllMatrixRelatives(bool add, bool ancestors, bool * changedSquares);
|
||||
void changeGraySquaresOfAllMatrixRelatives(bool add, bool ancestors, bool * changedSquares);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,47 +1,50 @@
|
||||
#ifndef POINCARE_LEAST_COMMON_MULTIPLE_H
|
||||
#define POINCARE_LEAST_COMMON_MULTIPLE_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/n_ary_expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class LeastCommonMultipleNode final : public ExpressionNode {
|
||||
class LeastCommonMultipleNode final : public NAryExpressionNode {
|
||||
public:
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(LeastCommonMultipleNode); }
|
||||
int numberOfChildren() const override;
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "LeastCommonMultiple";
|
||||
}
|
||||
#endif
|
||||
|
||||
// ExpressionNode
|
||||
Sign sign(Context * context) const override { return Sign::Positive; }
|
||||
Type type() const override { return Type::LeastCommonMultiple; }
|
||||
|
||||
|
||||
private:
|
||||
/* Layout */
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
/* Simplification */
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
/* Evaluation */
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class LeastCommonMultiple final : public Expression {
|
||||
class LeastCommonMultiple final : public NAryExpression {
|
||||
public:
|
||||
LeastCommonMultiple(const LeastCommonMultipleNode * n) : Expression(n) {}
|
||||
static LeastCommonMultiple Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder<LeastCommonMultiple, LeastCommonMultipleNode>({child0, child1}); }
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("lcm", 2, &UntypedBuilderTwoChildren<LeastCommonMultiple>);
|
||||
LeastCommonMultiple(const LeastCommonMultipleNode * n) : NAryExpression(n) {}
|
||||
static LeastCommonMultiple Builder(const Tuple & children = {}) { return TreeHandle::NAryBuilder<LeastCommonMultiple, LeastCommonMultipleNode>(convert(children)); }
|
||||
// Using a -2 as numberOfChildren to allow 2 or more children when parsing
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("lcm", -2, &UntypedBuilderMultipleChildren<LeastCommonMultiple>);
|
||||
|
||||
// Expression
|
||||
Expression shallowReduce(Context * context);
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(Context * context);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -16,9 +16,6 @@ public:
|
||||
|
||||
static void RenderWithChildHeight(KDCoordinate childHeight, KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor);
|
||||
|
||||
// Layout Node
|
||||
bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const override;
|
||||
|
||||
// Serializable Node
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return SerializationHelper::CodePoint(buffer, bufferSize, '(');
|
||||
|
||||
@@ -29,9 +29,12 @@ public:
|
||||
// Simplification
|
||||
void deepReduceChildren(ExpressionNode::ReductionContext reductionContext) override;
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Derivation
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
Expression unaryFunctionDifferential(ReductionContext reductionContext) override;
|
||||
// Evaluation
|
||||
template<typename U> static Complex<U> computeOnComplex(const std::complex<U> c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) {
|
||||
/* log has a branch cut on ]-inf, 0]: it is then multivalued on this cut. We
|
||||
@@ -39,9 +42,9 @@ public:
|
||||
* (warning: log takes the other side of the cut values on ]-inf-0i, 0-0i]). */
|
||||
return Complex<U>::Builder(std::log10(c));
|
||||
}
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename U> Evaluation<U> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename U> Evaluation<U> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class Logarithm final : public Expression {
|
||||
@@ -53,10 +56,12 @@ public:
|
||||
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify();
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
Expression unaryFunctionDifferential(ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
private:
|
||||
void deepReduceChildren(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression simpleShallowReduce(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);
|
||||
Expression simpleShallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Integer simplifyLogarithmIntegerBaseInteger(Integer i, Integer & base, Addition & a, bool isDenominator);
|
||||
Expression splitLogarithmInteger(Integer i, bool isDenominator, ExpressionNode::ReductionContext reductionContext);
|
||||
bool parentIsAPowerOfSameBase() const;
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
#ifndef POINCARE_MATRIX_H
|
||||
#define POINCARE_MATRIX_H
|
||||
|
||||
#include <poincare/array.h>
|
||||
#include <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixNode /*final*/ : public ExpressionNode {
|
||||
class MatrixNode /*final*/ : public Array, public ExpressionNode {
|
||||
public:
|
||||
MatrixNode() :
|
||||
m_numberOfRows(0),
|
||||
m_numberOfColumns(0) {}
|
||||
MatrixNode() : Array() {}
|
||||
|
||||
bool hasMatrixChild(Context * context) const;
|
||||
int numberOfRows() const { return m_numberOfRows; }
|
||||
int numberOfColumns() const { return m_numberOfColumns; }
|
||||
virtual void setNumberOfRows(int rows) { assert(rows >= 0); m_numberOfRows = rows; }
|
||||
virtual void setNumberOfColumns(int columns) { assert(columns >= 0); m_numberOfColumns = columns; }
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(MatrixNode); }
|
||||
@@ -40,23 +35,18 @@ public:
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
|
||||
// Approximation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return templatedApproximate<float>(context, complexFormat, angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return templatedApproximate<float>(approximationContext);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return templatedApproximate<double>(context, complexFormat, angleUnit);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return templatedApproximate<double>(approximationContext);
|
||||
}
|
||||
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
private:
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
/* We could store 2 uint8_t but multiplying m_numberOfRows and
|
||||
* m_numberOfColumns could then lead to overflow. As we are unlikely to use
|
||||
* greater matrix than 100*100, uint16_t is fine. */
|
||||
uint16_t m_numberOfRows;
|
||||
uint16_t m_numberOfColumns;
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class Matrix final : public Expression {
|
||||
@@ -67,6 +57,7 @@ public:
|
||||
static Matrix Builder() { return TreeHandle::NAryBuilder<Matrix, MatrixNode>(); }
|
||||
|
||||
void setDimensions(int rows, int columns);
|
||||
Array::VectorType vectorType() const { return node()->vectorType(); }
|
||||
int numberOfRows() const { return node()->numberOfRows(); }
|
||||
int numberOfColumns() const { return node()->numberOfColumns(); }
|
||||
using TreeHandle::addChildAtIndexInPlace;
|
||||
@@ -74,15 +65,20 @@ public:
|
||||
Expression matrixChild(int i, int j) { return childAtIndex(i*numberOfColumns()+j); }
|
||||
|
||||
/* Operation on matrix */
|
||||
int rank(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool inPlace = false);
|
||||
int rank(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, Preferences::UnitFormat unitFormat, bool inPlace = false);
|
||||
Expression createTrace();
|
||||
// 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);
|
||||
static Matrix CreateIdentity(int dim);
|
||||
Matrix createTranspose() const;
|
||||
Expression createRef(ExpressionNode::ReductionContext reductionContext, bool * couldComputeRef, bool reduced) const;
|
||||
/* createInverse can be called on any matrix, reduced or not, approximated or
|
||||
* not. */
|
||||
Expression createInverse(ExpressionNode::ReductionContext reductionContext, bool * couldComputeInverse) const;
|
||||
Expression determinant(ExpressionNode::ReductionContext reductionContext, bool * couldComputeDeterminant, bool inPlace);
|
||||
Expression norm(ExpressionNode::ReductionContext reductionContext) const;
|
||||
Expression dot(Matrix * b, ExpressionNode::ReductionContext reductionContext) const;
|
||||
Matrix cross(Matrix * b, ExpressionNode::ReductionContext reductionContext) const;
|
||||
// TODO: find another solution for inverse and determinant (avoid capping the matrix)
|
||||
static constexpr int k_maxNumberOfCoefficients = 100;
|
||||
|
||||
@@ -91,13 +87,13 @@ public:
|
||||
|
||||
private:
|
||||
MatrixNode * node() const { return static_cast<MatrixNode *>(Expression::node()); }
|
||||
void setNumberOfRows(int rows) { assert(rows >= 0); node()->setNumberOfRows(rows); }
|
||||
void setNumberOfColumns(int columns) { assert(columns >= 0); node()->setNumberOfColumns(columns); }
|
||||
void setNumberOfRows(int rows) { node()->setNumberOfRows(rows); }
|
||||
void setNumberOfColumns(int columns) { node()->setNumberOfColumns(columns); }
|
||||
Expression computeInverseOrDeterminant(bool computeDeterminant, ExpressionNode::ReductionContext reductionContext, bool * couldCompute) const;
|
||||
// rowCanonize turns a matrix in its reduced row echelon form.
|
||||
Matrix rowCanonize(ExpressionNode::ReductionContext reductionContext, Expression * determinant);
|
||||
// rowCanonize turns a matrix in its row echelon form, reduced or not.
|
||||
Matrix rowCanonize(ExpressionNode::ReductionContext reductionContext, Expression * determinant, bool reduced = true);
|
||||
// Row canonize the array in place
|
||||
template<typename T> static void ArrayRowCanonize(T * array, int numberOfRows, int numberOfColumns, T * c = nullptr);
|
||||
template<typename T> static void ArrayRowCanonize(T * array, int numberOfRows, int numberOfColumns, T * c = nullptr, bool reduced = true);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef POINCARE_MATRIX_COMPLEX_H
|
||||
#define POINCARE_MATRIX_COMPLEX_H
|
||||
|
||||
#include <poincare/evaluation.h>
|
||||
#include <poincare/array.h>
|
||||
#include <poincare/complex.h>
|
||||
#include <poincare/evaluation.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -10,12 +11,11 @@ template<typename T>
|
||||
class MatrixComplex;
|
||||
|
||||
template<typename T>
|
||||
class MatrixComplexNode final : public EvaluationNode<T> {
|
||||
class MatrixComplexNode final : public Array, public EvaluationNode<T> {
|
||||
public:
|
||||
MatrixComplexNode() :
|
||||
EvaluationNode<T>(),
|
||||
m_numberOfRows(0),
|
||||
m_numberOfColumns(0)
|
||||
Array(),
|
||||
EvaluationNode<T>()
|
||||
{}
|
||||
|
||||
std::complex<T> complexAtIndex(int index) const;
|
||||
@@ -36,20 +36,16 @@ public:
|
||||
|
||||
// EvaluationNode
|
||||
typename EvaluationNode<T>::Type type() const override { return EvaluationNode<T>::Type::MatrixComplex; }
|
||||
int numberOfRows() const { return m_numberOfRows; }
|
||||
int numberOfColumns() const { return m_numberOfColumns; }
|
||||
virtual void setNumberOfRows(int rows) { assert(rows >= 0); m_numberOfRows = rows; }
|
||||
virtual void setNumberOfColumns(int columns) { assert(columns >= 0); m_numberOfColumns = columns; }
|
||||
bool isUndefined() const override;
|
||||
Expression complexToExpression(Preferences::Preferences::ComplexFormat complexFormat) const override;
|
||||
std::complex<T> trace() const override;
|
||||
std::complex<T> determinant() const override;
|
||||
MatrixComplex<T> inverse() const;
|
||||
MatrixComplex<T> transpose() const;
|
||||
private:
|
||||
// See comment on Matrix
|
||||
uint16_t m_numberOfRows;
|
||||
uint16_t m_numberOfColumns;
|
||||
MatrixComplex<T> ref(bool reduced) const;
|
||||
std::complex<T> norm() const override;
|
||||
std::complex<T> dot(Evaluation<T> * e) const override;
|
||||
Evaluation<T> cross(Evaluation<T> * e) const override;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -63,23 +59,19 @@ public:
|
||||
static MatrixComplex<T> CreateIdentity(int dim);
|
||||
MatrixComplex<T> inverse() const { return node()->inverse(); }
|
||||
MatrixComplex<T> transpose() const { return node()->transpose(); }
|
||||
MatrixComplex<T> ref(bool reduced) const { return node()->ref(reduced); }
|
||||
std::complex<T> complexAtIndex(int index) const {
|
||||
return node()->complexAtIndex(index);
|
||||
}
|
||||
Array::VectorType vectorType() const { return node()->vectorType(); }
|
||||
int numberOfRows() const { return node()->numberOfRows(); }
|
||||
int numberOfColumns() const { return node()->numberOfColumns(); }
|
||||
void setDimensions(int rows, int columns);
|
||||
void addChildAtIndexInPlace(Evaluation<T> t, int index, int currentNumberOfChildren);
|
||||
private:
|
||||
MatrixComplexNode<T> * node() { return static_cast<MatrixComplexNode<T> *>(Evaluation<T>::node()); }
|
||||
void setNumberOfRows(int rows) {
|
||||
assert(rows >= 0);
|
||||
node()->setNumberOfRows(rows);
|
||||
}
|
||||
void setNumberOfColumns(int columns) {
|
||||
assert(columns >= 0);
|
||||
node()->setNumberOfColumns(columns);
|
||||
}
|
||||
void setNumberOfRows(int rows) { node()->setNumberOfRows(rows); }
|
||||
void setNumberOfColumns(int columns) { node()->setNumberOfColumns(columns); }
|
||||
MatrixComplexNode<T> * node() const { return static_cast<MatrixComplexNode<T> *>(Evaluation<T>::node()); }
|
||||
};
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class MatrixDimension final : public Expression {
|
||||
|
||||
41
poincare/include/poincare/matrix_echelon_form.h
Normal file
41
poincare/include/poincare/matrix_echelon_form.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef POINCARE_MATRIX_ECHELON_FORM_H
|
||||
#define POINCARE_MATRIX_ECHELON_FORM_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixEchelonFormNode : public ExpressionNode {
|
||||
public:
|
||||
|
||||
// TreeNode
|
||||
int numberOfChildren() const override;
|
||||
virtual bool isFormReduced() const = 0;
|
||||
static constexpr int sNumberOfChildren = 1;
|
||||
private:
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
|
||||
// Properties
|
||||
virtual const char * functionHelperName() const = 0;
|
||||
};
|
||||
|
||||
class MatrixEchelonForm : public Expression {
|
||||
public:
|
||||
MatrixEchelonForm(const MatrixEchelonFormNode * n) : Expression(n) {}
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
bool isFormReduced() const { return static_cast<MatrixEchelonFormNode *>(node())->isFormReduced(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -27,9 +27,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class MatrixIdentity final : public Expression {
|
||||
|
||||
@@ -28,9 +28,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class MatrixInverse final : public Expression {
|
||||
|
||||
@@ -19,8 +19,8 @@ public:
|
||||
Type type() const override { return Type::MatrixLayout; }
|
||||
|
||||
// MatrixLayoutNode
|
||||
void addGreySquares();
|
||||
void removeGreySquares();
|
||||
void addGraySquares();
|
||||
void removeGraySquares();
|
||||
|
||||
// LayoutNode
|
||||
void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) override;
|
||||
@@ -50,7 +50,7 @@ private:
|
||||
void newRowOrColumnAtIndex(int index);
|
||||
bool isRowEmpty(int index) const;
|
||||
bool isColumnEmpty(int index) const;
|
||||
bool hasGreySquares() const;
|
||||
bool hasGraySquares() const;
|
||||
|
||||
// LayoutNode
|
||||
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor, Layout * selectionStart = nullptr, Layout * selectionEnd = nullptr, KDColor selectionColor = KDColorRed) override;
|
||||
@@ -64,9 +64,9 @@ public:
|
||||
static MatrixLayout Builder() { return TreeHandle::NAryBuilder<MatrixLayout, MatrixLayoutNode>(); }
|
||||
static MatrixLayout Builder(Layout l1, Layout l2, Layout l3, Layout l4);
|
||||
|
||||
bool hasGreySquares() const { return node()->hasGreySquares(); }
|
||||
void addGreySquares() { node()->addGreySquares(); }
|
||||
void removeGreySquares() { node()->removeGreySquares(); }
|
||||
bool hasGraySquares() const { return node()->hasGraySquares(); }
|
||||
void addGraySquares() { node()->addGraySquares(); }
|
||||
void removeGraySquares() { node()->removeGraySquares(); }
|
||||
private:
|
||||
MatrixLayoutNode * node() const { return static_cast<MatrixLayoutNode *>(Layout::node()); }
|
||||
};
|
||||
|
||||
37
poincare/include/poincare/matrix_reduced_row_echelon_form.h
Normal file
37
poincare/include/poincare/matrix_reduced_row_echelon_form.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef POINCARE_MATRIX_REDUCED_ROW_ECHELON_FORM_H
|
||||
#define POINCARE_MATRIX_REDUCED_ROW_ECHELON_FORM_H
|
||||
|
||||
#include <poincare/matrix_echelon_form.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixReducedRowEchelonFormNode final : public MatrixEchelonFormNode {
|
||||
public:
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(MatrixReducedRowEchelonFormNode); }
|
||||
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "MatrixReducedRowEchelonForm";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::MatrixReducedRowEchelonForm; }
|
||||
private:
|
||||
const char * functionHelperName() const override;
|
||||
bool isFormReduced() const override { return true; }
|
||||
};
|
||||
|
||||
|
||||
class MatrixReducedRowEchelonForm final : public MatrixEchelonForm {
|
||||
public:
|
||||
MatrixReducedRowEchelonForm(const MatrixReducedRowEchelonFormNode * n) : MatrixEchelonForm(n) {}
|
||||
static MatrixReducedRowEchelonForm Builder(Expression child) { return TreeHandle::FixedArityBuilder<MatrixReducedRowEchelonForm, MatrixReducedRowEchelonFormNode>({child}); }
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("rref", MatrixEchelonFormNode::sNumberOfChildren, &UntypedBuilderOneChild<MatrixReducedRowEchelonForm>);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
37
poincare/include/poincare/matrix_row_echelon_form.h
Normal file
37
poincare/include/poincare/matrix_row_echelon_form.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef POINCARE_MATRIX_ROW_ECHELON_FORM_H
|
||||
#define POINCARE_MATRIX_ROW_ECHELON_FORM_H
|
||||
|
||||
#include <poincare/matrix_echelon_form.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixRowEchelonFormNode final : public MatrixEchelonFormNode {
|
||||
public:
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(MatrixRowEchelonFormNode); }
|
||||
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "MatrixRowEchelonForm";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::MatrixRowEchelonForm; }
|
||||
private:
|
||||
const char * functionHelperName() const override;
|
||||
bool isFormReduced() const override { return false; }
|
||||
};
|
||||
|
||||
|
||||
class MatrixRowEchelonForm final : public MatrixEchelonForm {
|
||||
public:
|
||||
MatrixRowEchelonForm(const MatrixRowEchelonFormNode * n) : MatrixEchelonForm(n) {}
|
||||
static MatrixRowEchelonForm Builder(Expression child) { return TreeHandle::FixedArityBuilder<MatrixRowEchelonForm, MatrixRowEchelonFormNode>({child}); }
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ref", MatrixEchelonFormNode::sNumberOfChildren, &UntypedBuilderOneChild<MatrixRowEchelonForm>);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -28,9 +28,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class MatrixTrace final : public Expression {
|
||||
|
||||
@@ -28,9 +28,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class MatrixTranspose final : public Expression {
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
#define POINCARE_MULTIPLICATION_H
|
||||
|
||||
#include <poincare/approximation_helper.h>
|
||||
#include <poincare/n_ary_expression.h>
|
||||
#include <poincare/n_ary_infix_expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MultiplicationNode final : public NAryExpressionNode {
|
||||
class MultiplicationNode final : public NAryInfixExpressionNode {
|
||||
friend class Addition;
|
||||
public:
|
||||
using NAryExpressionNode::NAryExpressionNode;
|
||||
using NAryInfixExpressionNode::NAryInfixExpressionNode;
|
||||
|
||||
// Tree
|
||||
size_t size() const override { return sizeof(MultiplicationNode); }
|
||||
@@ -47,18 +47,20 @@ private:
|
||||
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
Expression denominator(ExpressionNode::ReductionContext reductionContext) const override;
|
||||
// Derivation
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
|
||||
// Approximation
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrixAndComplex(const MatrixComplex<T> m, const std::complex<T> c, Preferences::ComplexFormat complexFormat) {
|
||||
return ApproximationHelper::ElementWiseOnMatrixComplexAndComplex(m, c, complexFormat, compute<T>);
|
||||
}
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::MapReduce<float>(this, context, complexFormat, angleUnit, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::MapReduce<float>(this, approximationContext, compute<float>, computeOnComplexAndMatrix<float>, computeOnMatrixAndComplex<float>, computeOnMatrices<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::MapReduce<double>(this, context, complexFormat, angleUnit, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::MapReduce<double>(this, approximationContext, compute<double>, computeOnComplexAndMatrix<double>, computeOnMatrixAndComplex<double>, computeOnMatrices<double>);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -83,11 +85,13 @@ public:
|
||||
// Simplification
|
||||
Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
Expression denominator(ExpressionNode::ReductionContext reductionContext) const;
|
||||
void sortChildrenInPlace(NAryExpressionNode::ExpressionOrder order, Context * context, bool canBeInterrupted) {
|
||||
NAryExpression::sortChildrenInPlace(order, context, false, canBeInterrupted);
|
||||
}
|
||||
// Derivation
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
private:
|
||||
// Unit
|
||||
Expression removeUnit(Expression * unit);
|
||||
@@ -103,6 +107,7 @@ private:
|
||||
static bool HaveSameNonNumeralFactors(const Expression & e1, const Expression & e2);
|
||||
static bool TermsHaveIdenticalBase(const Expression & e1, const Expression & e2);
|
||||
static bool TermsHaveIdenticalExponent(const Expression & e1, const Expression & e2);
|
||||
static bool TermsCanSafelyCombineExponents(const Expression & e1, const Expression & e2, ExpressionNode::ReductionContext reductionContext);
|
||||
static bool TermHasNumeralBase(const Expression & e);
|
||||
static bool TermHasNumeralExponent(const Expression & e);
|
||||
static const Expression CreateExponent(Expression e);
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#include <poincare/expression.h>
|
||||
|
||||
// NAryExpressions are additions and multiplications
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class NAryExpressionNode : public ExpressionNode { // TODO: VariableArityExpressionNode?
|
||||
@@ -20,9 +18,6 @@ public:
|
||||
}
|
||||
void eraseNumberOfChildren() override { m_numberOfChildren = 0; }
|
||||
|
||||
// Properties
|
||||
bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override;
|
||||
|
||||
// Comparison
|
||||
typedef int (*ExpressionOrder)(const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted);
|
||||
|
||||
@@ -37,9 +32,6 @@ protected:
|
||||
/* With a pool of size < 120k and TreeNode of size 20, a node can't have more
|
||||
* than 6144 children which fit in uint16_t. */
|
||||
uint16_t m_numberOfChildren;
|
||||
private:
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
};
|
||||
|
||||
class NAryExpression : public Expression {
|
||||
@@ -63,6 +55,7 @@ protected:
|
||||
node()->sortChildrenInPlace(order, context, canSwapMatrices, canBeInterrupted);
|
||||
}
|
||||
NAryExpressionNode * node() const { return static_cast<NAryExpressionNode *>(Expression::node()); }
|
||||
Expression checkChildrenAreRationalIntegersAndUpdate(ExpressionNode::ReductionContext reductionContext);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
23
poincare/include/poincare/n_ary_infix_expression.h
Normal file
23
poincare/include/poincare/n_ary_infix_expression.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef POINCARE_N_ARY_INFIX_EXPRESSION_H
|
||||
#define POINCARE_N_ARY_INFIX_EXPRESSION_H
|
||||
|
||||
#include <poincare/n_ary_expression.h>
|
||||
|
||||
// NAryInfixExpressionNode are additions and multiplications
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class NAryInfixExpressionNode : public NAryExpressionNode {
|
||||
public:
|
||||
using NAryExpressionNode::NAryExpressionNode;
|
||||
// Properties
|
||||
bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override;
|
||||
protected:
|
||||
// Order
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -35,11 +35,11 @@ private:
|
||||
* (warning: ln takes the other side of the cut values on ]-inf-0i, 0-0i]). */
|
||||
return Complex<T>::Builder(std::log(c));
|
||||
}
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit,computeOnComplex<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, computeOnComplex<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, computeOnComplex<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, computeOnComplex<double>);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ private:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class NormCDF final : public NormalDistributionFunction {
|
||||
|
||||
@@ -31,9 +31,9 @@ private:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class NormCDF2 final : public NormalDistributionFunction {
|
||||
|
||||
@@ -29,9 +29,9 @@ private:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class NormPDF final : public NormalDistributionFunction {
|
||||
|
||||
@@ -16,11 +16,6 @@ public:
|
||||
* The result of the verification is *result. */
|
||||
static bool ExpressionMuAndVarAreOK(bool * result, const Expression & mu, const Expression & sigma, Context * context);
|
||||
private:
|
||||
/* For the standard normal distribution, P(X < y) > 0.99999995 for y >= 5.33 so the
|
||||
* value displayed is 1. But this is dependent on the fact that we display
|
||||
* only 7 decimal values! */
|
||||
static_assert(Preferences::LargeNumberOfSignificantDigits == 7, "k_boundStandardNormalDistribution is ill-defined compared to LargeNumberOfSignificantDigits");
|
||||
constexpr static double k_boundStandardNormalDistribution = 5.33;
|
||||
template<typename T> static T StandardNormalCumulativeDistributiveFunctionAtAbscissa(T abscissa);
|
||||
template<typename T> static T StandardNormalCumulativeDistributiveInverseForProbability(T probability);
|
||||
};
|
||||
|
||||
@@ -29,9 +29,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::NthRoot; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::Root; };
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -26,13 +26,15 @@ public:
|
||||
|
||||
double doubleApproximation() const;
|
||||
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
|
||||
};
|
||||
|
||||
class Number : public Expression {
|
||||
public:
|
||||
Number(const NumberNode * node) : Expression(node) {}
|
||||
/* Return either a Rational, a Decimal or an Infinity. */
|
||||
static Number ParseNumber(const char * integralPart, size_t integralLength, const char * decimalPart, size_t decimalLenght, bool exponentIsNegative, const char * exponentPart, size_t exponentLength);
|
||||
static Number ParseNumber(const char * integralPart, size_t integralLength, const char * decimalPart, size_t decimalLength, bool exponentIsNegative, const char * exponentPart, size_t exponentLength);
|
||||
/* Return either a Decimal or an Infinity or an Undefined. */
|
||||
template <typename T> static Number DecimalNumber(T f);
|
||||
/* Return either a Float or an Infinity or an Undefined */
|
||||
@@ -51,8 +53,10 @@ public:
|
||||
ExpressionNode::Sign sign() const { return Expression::sign(nullptr); }
|
||||
Number setSign(ExpressionNode::Sign s) {
|
||||
assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative);
|
||||
return Expression::setSign(s, ExpressionNode::ReductionContext(nullptr, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Degree, ExpressionNode::ReductionTarget::User)).convert<Number>();
|
||||
return Expression::setSign(s, ExpressionNode::ReductionContext(nullptr, Preferences::ComplexFormat::Real, Preferences::AngleUnit::Degree, Preferences::UnitFormat::Metric, ExpressionNode::ReductionTarget::User)).convert<Number>();
|
||||
}
|
||||
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
protected:
|
||||
Number() : Expression() {}
|
||||
NumberNode * node() const { return static_cast<NumberNode *>(Expression::node()); }
|
||||
|
||||
@@ -23,17 +23,18 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
NullStatus nullStatus(Context * context) const override { return childAtIndex(0)->nullStatus(context); }
|
||||
Type type() const override { return Type::Opposite; }
|
||||
int polynomialDegree(Context * context, const char * symbolName) const override;
|
||||
Sign sign(Context * context) const override;
|
||||
bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override;
|
||||
|
||||
// Approximation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, complexFormat, angleUnit, compute<float>);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<float>(this, approximationContext, compute<float>);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<double>(this, context, complexFormat, angleUnit, compute<double>);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return ApproximationHelper::Map<double>(this, approximationContext, compute<double>);
|
||||
}
|
||||
|
||||
// Layout
|
||||
|
||||
@@ -19,6 +19,8 @@ public:
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Sign sign(Context * context) const override { return childAtIndex(0)->sign(context); }
|
||||
NullStatus nullStatus(Context * context) const override { return childAtIndex(0)->nullStatus(context); }
|
||||
Type type() const override { return Type::Parenthesis; }
|
||||
int polynomialDegree(Context * context, const char * symbolName) const override;
|
||||
Expression removeUnit(Expression * unit) override { assert(false); return ExpressionNode::removeUnit(unit); }
|
||||
@@ -31,10 +33,10 @@ public:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; };
|
||||
|
||||
// Approximation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
private:
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class Parenthesis final : public Expression {
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
stream << "ParenthesisLayout";
|
||||
}
|
||||
#endif
|
||||
bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const override;
|
||||
|
||||
protected:
|
||||
KDSize computeSize() override {
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
|
||||
// Properties
|
||||
Type type() const override{ return Type::PermuteCoefficient; }
|
||||
|
||||
Sign sign(Context * context) const override { return Sign::Positive; }
|
||||
|
||||
private:
|
||||
// Layout
|
||||
@@ -33,9 +33,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class PermuteCoefficient final : public Expression {
|
||||
|
||||
@@ -27,6 +27,10 @@ public:
|
||||
// Properties
|
||||
Type type() const override { return Type::Power; }
|
||||
Sign sign(Context * context) const override;
|
||||
NullStatus nullStatus(Context * context) const override {
|
||||
// NonNull Status can't be returned because base could be infinite.
|
||||
return childAtIndex(0)->nullStatus(context) == NullStatus::Null ? NullStatus::Null : NullStatus::Unknown;
|
||||
}
|
||||
Expression setSign(Sign s, ReductionContext reductionContext) override;
|
||||
bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override;
|
||||
Expression removeUnit(Expression * unit) override;
|
||||
@@ -49,23 +53,24 @@ private:
|
||||
|
||||
// Simplify
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return childAtIndex(0)->leftLayoutShape(); }
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::RightOfPower; }
|
||||
int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
Expression denominator(ReductionContext reductionContext) const override;
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
// Evaluation
|
||||
template<typename T> static MatrixComplex<T> computeOnComplexAndMatrix(const std::complex<T> c, const MatrixComplex<T> n, Preferences::ComplexFormat complexFormat);
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrixAndComplex(const MatrixComplex<T> m, const std::complex<T> d, Preferences::ComplexFormat complexFormat);
|
||||
template<typename T> static MatrixComplex<T> computeOnMatrices(const MatrixComplex<T> m, const MatrixComplex<T> n, Preferences::ComplexFormat complexFormat);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return templatedApproximate<float>(context, complexFormat, angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return templatedApproximate<float>(approximationContext);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return templatedApproximate<double>(context, complexFormat, angleUnit);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return templatedApproximate<double>(approximationContext);
|
||||
}
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class Power final : public Expression {
|
||||
@@ -78,7 +83,8 @@ public:
|
||||
Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext);
|
||||
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const;
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify(ExpressionNode::ReductionContext * reductionContext);
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
|
||||
private:
|
||||
constexpr static int k_maxExactPowerMatrix = 100;
|
||||
|
||||
@@ -31,9 +31,9 @@ private:
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<float>(context, complexFormat, angleUnit); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate<double>(context, complexFormat, angleUnit); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
|
||||
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) const;
|
||||
};
|
||||
|
||||
class PredictionInterval final : public Expression {
|
||||
|
||||
@@ -52,6 +52,10 @@ public:
|
||||
Large = 0,
|
||||
Small = 1
|
||||
};
|
||||
enum class UnitFormat : uint8_t {
|
||||
Metric = 0,
|
||||
Imperial = 1
|
||||
};
|
||||
Preferences();
|
||||
static Preferences * sharedPreferences();
|
||||
AngleUnit angleUnit() const { return m_angleUnit; }
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef POINCARE_PRODUCT_H
|
||||
#define POINCARE_PRODUCT_H
|
||||
|
||||
#include <poincare/sequence.h>
|
||||
#include <poincare/sum_and_product.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class ProductNode final : public SequenceNode {
|
||||
class ProductNode final : public SumAndProductNode {
|
||||
public:
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(ProductNode); }
|
||||
@@ -18,8 +18,8 @@ public:
|
||||
Type type() const override { return Type::Product; }
|
||||
|
||||
private:
|
||||
float emptySequenceValue() const override { return 1.0f; }
|
||||
Layout createSequenceLayout(Layout argumentLayout, Layout symbolLayout, Layout subscriptLayout, Layout superscriptLayout) const override;
|
||||
float emptySumAndProductValue() const override { return 1.0f; }
|
||||
Layout createSumAndProductLayout(Layout argumentLayout, Layout symbolLayout, Layout subscriptLayout, Layout superscriptLayout) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
Evaluation<double> evaluateWithNextTerm(DoublePrecision p, Evaluation<double> a, Evaluation<double> b, Preferences::ComplexFormat complexFormat) const override {
|
||||
return templatedApproximateWithNextTerm<double>(a, b, complexFormat);
|
||||
@@ -30,10 +30,10 @@ private:
|
||||
template<typename T> Evaluation<T> templatedApproximateWithNextTerm(Evaluation<T> a, Evaluation<T> b, Preferences::ComplexFormat complexFormat) const;
|
||||
};
|
||||
|
||||
class Product final : public Sequence {
|
||||
class Product final : public SumAndProduct {
|
||||
friend class ProductNode;
|
||||
public:
|
||||
Product(const ProductNode * n) : Sequence(n) {}
|
||||
Product(const ProductNode * n) : SumAndProduct(n) {}
|
||||
static Product Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder<Product, ProductNode>({child0, child1, child2, child3}); }
|
||||
static Expression UntypedBuilder(Expression children);
|
||||
|
||||
@@ -42,4 +42,4 @@ public:
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -28,13 +28,13 @@ private:
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return templateApproximate<float>(context, complexFormat, angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return templateApproximate<float>(approximationContext);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
return templateApproximate<double>(context, complexFormat, angleUnit);
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return templateApproximate<double>(approximationContext);
|
||||
}
|
||||
template <typename T> Evaluation<T> templateApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool * inputIsUndefined = nullptr) const;
|
||||
template <typename T> Evaluation<T> templateApproximate(ApproximationContext approximationContext, bool * inputIsUndefined = nullptr) const;
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
|
||||
@@ -32,10 +32,10 @@ private:
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override {
|
||||
return templateApproximate<float>();
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override {
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override {
|
||||
return templateApproximate<double>();
|
||||
}
|
||||
template <typename T> Evaluation<T> templateApproximate() const;
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
bool isNegative() const { return m_negative; }
|
||||
void setNegative(bool negative) { m_negative = negative; }
|
||||
bool isInteger() const { return denominator().isOne(); }
|
||||
NullStatus nullStatus(Context * context) const override { return isZero() ? NullStatus::Null : NullStatus::NonNull; }
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override;
|
||||
@@ -38,8 +39,8 @@ public:
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
|
||||
// Approximation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex<float>::Builder(templatedApproximate<float>()); }
|
||||
Evaluation<double> approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex<double>::Builder(templatedApproximate<double>()); }
|
||||
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return Complex<float>::Builder(templatedApproximate<float>()); }
|
||||
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return Complex<double>::Builder(templatedApproximate<double>()); }
|
||||
template<typename T> T templatedApproximate() const;
|
||||
|
||||
// Basic test
|
||||
@@ -57,7 +58,7 @@ public:
|
||||
private:
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override;
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
Expression shallowBeautify(ReductionContext * reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { assert(!m_negative); return isInteger() ? LayoutShape::Integer : LayoutShape::Fraction; };
|
||||
Expression setSign(Sign s, ReductionContext reductionContext) override;
|
||||
Expression denominator(ReductionContext reductionContext) const override;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user