[poincare] Add an Array class to factorize Matrix and Grid methods

Change-Id: Ia61caf0bf182c1111119740d43d957f203c0975c
This commit is contained in:
Hugo Saint-Vignes
2020-11-18 10:04:36 +01:00
committed by EmilieNumworks
parent c0413709b7
commit 522456677a
4 changed files with 48 additions and 57 deletions

View File

@@ -0,0 +1,29 @@
#ifndef POINCARE_ARRAY_H
#define POINCARE_ARRAY_H
#include <stdint.h>
#include <assert.h>
namespace Poincare {
class Array {
public:
Array() :
m_numberOfRows(0),
m_numberOfColumns(0) {}
bool isVector() const { return m_numberOfRows == 1 || m_numberOfColumns == 1; }
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

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

@@ -1,22 +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;
bool isVector() const { return m_numberOfRows == 1 || m_numberOfColumns == 1; }
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); }
@@ -53,11 +47,6 @@ public:
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
private:
template<typename T> Evaluation<T> templatedApproximate(ApproximationContext approximationContext) 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;
};
class Matrix final : public Expression {
@@ -98,8 +87,8 @@ 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 row echelon form, reduced or not.
Matrix rowCanonize(ExpressionNode::ReductionContext reductionContext, Expression * determinant, 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,11 +36,6 @@ public:
// EvaluationNode
typename EvaluationNode<T>::Type type() const override { return EvaluationNode<T>::Type::MatrixComplex; }
bool isVector() const { return m_numberOfRows == 1 || m_numberOfColumns == 1; }
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;
@@ -51,10 +46,6 @@ public:
std::complex<T> norm() const override;
std::complex<T> dot(Evaluation<T> * e) const override;
Evaluation<T> cross(Evaluation<T> * e) const override;
private:
// See comment on Matrix
uint16_t m_numberOfRows;
uint16_t m_numberOfColumns;
};
template<typename T>
@@ -79,14 +70,8 @@ public:
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()); }
};