diff --git a/poincare/Makefile b/poincare/Makefile index bac81600c23..64c6232b0c4 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -12,6 +12,7 @@ poincare_src += $(addprefix poincare/src/,\ grid_layout.cpp \ horizontal_layout.cpp \ integral_layout.cpp \ + kmat.cpp \ layout_cursor.cpp \ layout.cpp \ layout_node.cpp \ diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index 2d3b33a33c9..ee25c232429 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -74,6 +74,7 @@ class ExpressionNode : public TreeNode { Integral, InvBinom, InvNorm, + KMat, LeastCommonMultiple, Logarithm, MatrixTrace, diff --git a/poincare/include/poincare/kmat.h b/poincare/include/poincare/kmat.h new file mode 100644 index 00000000000..6b0a6cf7260 --- /dev/null +++ b/poincare/include/poincare/kmat.h @@ -0,0 +1,53 @@ +#ifndef POINCARE_KMAT_H +#define POINCARE_KMAT_H + +#include +#include + +namespace Poincare { + +class KMatNode final : public ExpressionNode { +public: + + // TreeNode + size_t size() const override { return sizeof(KMatNode); } + int numberOfChildren() const override; +#if POINCARE_TREE_LOG + void logNodeName(std::ostream & stream) const override { + stream << "KMat"; + } +#endif + + // Properties + Type type() const override { return Type::KMat; } + + // 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 approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(); } + Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(); } + template Evaluation templatedApproximate() const; +}; + +class KMat final : public Expression { +public: + KMat(const KMatNode * n) : Expression(n) {} + static KMat Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder({child0, child1, child2}); } + + + static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("kmat", 3, &UntypedBuilderThreeChildren); + + Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); + +}; + +} + +#endif diff --git a/poincare/include/poincare_nodes.h b/poincare/include/poincare_nodes.h index 33076f227d2..7ff358fa616 100644 --- a/poincare/include/poincare_nodes.h +++ b/poincare/include/poincare_nodes.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/src/kmat.cpp b/poincare/src/kmat.cpp new file mode 100644 index 00000000000..3a578ccbc28 --- /dev/null +++ b/poincare/src/kmat.cpp @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include "parsing/token.h" +#include +#include +#include +#include +#include +#include +#include + +namespace Poincare { + +constexpr Expression::FunctionHelper KMat::s_functionHelper; + +int KMatNode::numberOfChildren() const { return KMat::s_functionHelper.numberOfChildren(); } + +Layout KMatNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { + return LayoutHelper::Prefix(KMat(this), floatDisplayMode, numberOfSignificantDigits, KMat::s_functionHelper.name()); +} + +int KMatNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, KMat::s_functionHelper.name()); +} + +template Evaluation KMatNode::templatedApproximate() const { + return Complex::RealUndefined(); +} + +Expression KMatNode::shallowReduce(ExpressionNode::ReductionContext reductionContext) { + return KMat(this).shallowReduce(reductionContext); +} + +Expression KMat::shallowReduce(ExpressionNode::ReductionContext reductionContext) { + Expression c0 = childAtIndex(0); + Expression c1 = childAtIndex(1); + if (c0.type() == ExpressionNode::Type::Rational) { + Rational r0 = static_cast(c0); + if (!r0.isInteger() || r0.signedIntegerNumerator().isNegative()) { + return replaceWithUndefinedInPlace(); + } + } + if (c1.type() == ExpressionNode::Type::Rational) { + Rational r1 = static_cast(c1); + if (!r1.isInteger() || r1.signedIntegerNumerator().isNegative()) { + return replaceWithUndefinedInPlace(); + } + } + if (c0.type() != ExpressionNode::Type::Rational || c1.type() != ExpressionNode::Type::Rational) { + return *this; + } + + Rational r0 = static_cast(c0); + Rational r1 = static_cast(c1); + + Integer w = r0.signedIntegerNumerator(); + Integer h = r1.signedIntegerNumerator(); + uint32_t size = *Integer::Multiplication(w,h).digits(); + Matrix matrix = Matrix::Builder(); + matrix.addChildAtIndexInPlace(childAtIndex(2).clone(), 0, 0); + for (uint32_t i = 1; i < size; i++) { + matrix.addChildAtIndexInPlace(childAtIndex(2).clone(), matrix.numberOfChildren(), matrix.numberOfChildren()); + } + matrix.setDimensions(*w.digits(), *h.digits()); + replaceWithInPlace(matrix); + return std::move(matrix); +} + +} diff --git a/poincare/src/parsing/parser.h b/poincare/src/parsing/parser.h index 37ff4f523d3..3c2ed9f9034 100644 --- a/poincare/src/parsing/parser.h +++ b/poincare/src/parsing/parser.h @@ -123,6 +123,7 @@ class Parser { &InvBinom::s_functionHelper, &MatrixInverse::s_functionHelper, &InvNorm::s_functionHelper, + &KMat::s_functionHelper, &LeastCommonMultiple::s_functionHelper, &NaperianLogarithm::s_functionHelper, &CommonLogarithm::s_functionHelper, diff --git a/poincare/src/tree_handle.cpp b/poincare/src/tree_handle.cpp index 477565d25fc..8aafb180ee8 100644 --- a/poincare/src/tree_handle.cpp +++ b/poincare/src/tree_handle.cpp @@ -324,6 +324,7 @@ template Integral TreeHandle::FixedArityBuilder(const Tu template IntegralLayout TreeHandle::FixedArityBuilder(const Tuple &); template InvBinom TreeHandle::FixedArityBuilder(const Tuple &); template InvNorm TreeHandle::FixedArityBuilder(const Tuple &); +template KMat TreeHandle::FixedArityBuilder(const Tuple &); template LeastCommonMultiple TreeHandle::FixedArityBuilder(const Tuple &); template LeftParenthesisLayout TreeHandle::FixedArityBuilder(const Tuple &); template LeftSquareBracketLayout TreeHandle::FixedArityBuilder(const Tuple &);