[Update] Epsilon 15.3.1

This commit is contained in:
Joachim LF
2021-01-21 17:27:39 +01:00
700 changed files with 15118 additions and 7297 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,7 +10,7 @@ class EmptyLayoutNode /*final*/ : public LayoutNode {
public:
enum class Color {
Yellow,
Grey
Gray
};
// Layout

View File

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

View File

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

View File

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

View File

@@ -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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View 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

View 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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,6 +25,7 @@ public:
stream << "ParenthesisLayout";
}
#endif
bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const override;
protected:
KDSize computeSize() override {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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