mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Factorize Echelon Form classes
Change-Id: I7ec7290a4d94b9bd1224ad4c53be8b4662bd32d5
This commit is contained in:
committed by
Émilie Feral
parent
f00c135b69
commit
3bfc0c83d8
@@ -56,13 +56,13 @@ void MatrixListController::setExpression(Poincare::Expression e) {
|
||||
}
|
||||
// 3. Matrix row echelon form
|
||||
messageIndex = 2;
|
||||
Expression rowEchelonForm = MatrixRef::Builder(m_expression.clone());
|
||||
Expression rowEchelonForm = MatrixRowEchelonForm::Builder(m_expression.clone());
|
||||
m_indexMessageMap[index] = messageIndex++;
|
||||
m_layouts[index++] = getLayoutFromExpression(rowEchelonForm, context, preferences);
|
||||
/* 4. Matrix reduced row echelon form
|
||||
* it can be computed from row echelon form to save computation time.*/
|
||||
m_indexMessageMap[index] = messageIndex++;
|
||||
m_layouts[index++] = getLayoutFromExpression(MatrixRref::Builder(rowEchelonForm), context, preferences);
|
||||
m_layouts[index++] = getLayoutFromExpression(MatrixReducedRowEchelonForm::Builder(rowEchelonForm), context, preferences);
|
||||
// 5. Matrix trace if square matrix
|
||||
if (mIsSquared) {
|
||||
m_indexMessageMap[index] = messageIndex++;
|
||||
|
||||
@@ -101,8 +101,9 @@ poincare_src += $(addprefix poincare/src/,\
|
||||
matrix_inverse.cpp \
|
||||
matrix_trace.cpp \
|
||||
matrix_transpose.cpp \
|
||||
matrix_ref.cpp \
|
||||
matrix_rref.cpp \
|
||||
matrix_echelon_form.cpp \
|
||||
matrix_row_echelon_form.cpp \
|
||||
matrix_reduced_row_echelon_form.cpp \
|
||||
multiplication.cpp \
|
||||
n_ary_expression.cpp \
|
||||
naperian_logarithm.cpp \
|
||||
|
||||
@@ -63,8 +63,9 @@ class Expression : public TreeHandle {
|
||||
friend class MatrixInverse;
|
||||
friend class MatrixTrace;
|
||||
friend class MatrixTranspose;
|
||||
friend class MatrixRef;
|
||||
friend class MatrixRref;
|
||||
friend class MatrixEchelonForm;
|
||||
friend class MatrixRowEchelonForm;
|
||||
friend class MatrixReducedRowEchelonForm;
|
||||
friend class Multiplication;
|
||||
friend class MultiplicationNode;
|
||||
friend class NaperianLogarithm;
|
||||
|
||||
@@ -103,8 +103,8 @@ public:
|
||||
MatrixIdentity,
|
||||
MatrixInverse,
|
||||
MatrixTranspose,
|
||||
MatrixRef,
|
||||
MatrixRref,
|
||||
MatrixRowEchelonForm,
|
||||
MatrixReducedRowEchelonForm,
|
||||
PredictionInterval,
|
||||
Matrix,
|
||||
EmptyExpression
|
||||
|
||||
@@ -1,24 +1,17 @@
|
||||
#ifndef POINCARE_MATRIX_REF_H
|
||||
#define POINCARE_MATRIX_REF_H
|
||||
#ifndef POINCARE_MATRIX_ECHELON_FORM_H
|
||||
#define POINCARE_MATRIX_ECHELON_FORM_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixRefNode final : public ExpressionNode {
|
||||
class MatrixEchelonFormNode : public ExpressionNode {
|
||||
public:
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(MatrixRefNode); }
|
||||
int numberOfChildren() const override;
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "MatrixRef";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::MatrixRef; }
|
||||
virtual bool isFormReduced() const = 0;
|
||||
static constexpr int sNumberOfChildren = 1;
|
||||
private:
|
||||
// Layout
|
||||
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
@@ -31,16 +24,16 @@ private:
|
||||
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;
|
||||
|
||||
// Properties
|
||||
virtual const char * functionHelperName() const = 0;
|
||||
};
|
||||
|
||||
class MatrixRef final : public Expression {
|
||||
class MatrixEchelonForm : public Expression {
|
||||
public:
|
||||
MatrixRef(const MatrixRefNode * n) : Expression(n) {}
|
||||
static MatrixRef Builder(Expression child) { return TreeHandle::FixedArityBuilder<MatrixRef, MatrixRefNode>({child}); }
|
||||
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ref", 1, &UntypedBuilderOneChild<MatrixRef>);
|
||||
|
||||
MatrixEchelonForm(const MatrixEchelonFormNode * n) : Expression(n) {}
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
bool isFormReduced() const { return static_cast<MatrixEchelonFormNode *>(node())->isFormReduced(); }
|
||||
};
|
||||
|
||||
}
|
||||
37
poincare/include/poincare/matrix_reduced_row_echelon_form.h
Normal file
37
poincare/include/poincare/matrix_reduced_row_echelon_form.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef POINCARE_MATRIX_REDUCED_ROW_ECHELON_FORM_H
|
||||
#define POINCARE_MATRIX_REDUCED_ROW_ECHELON_FORM_H
|
||||
|
||||
#include <poincare/matrix_echelon_form.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixReducedRowEchelonFormNode final : public MatrixEchelonFormNode {
|
||||
public:
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(MatrixReducedRowEchelonFormNode); }
|
||||
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "MatrixReducedRowEchelonForm";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::MatrixReducedRowEchelonForm; }
|
||||
private:
|
||||
const char * functionHelperName() const override;
|
||||
bool isFormReduced() const override { return true; }
|
||||
};
|
||||
|
||||
|
||||
class MatrixReducedRowEchelonForm final : public MatrixEchelonForm {
|
||||
public:
|
||||
MatrixReducedRowEchelonForm(const MatrixReducedRowEchelonFormNode * n) : MatrixEchelonForm(n) {}
|
||||
static MatrixReducedRowEchelonForm Builder(Expression child) { return TreeHandle::FixedArityBuilder<MatrixReducedRowEchelonForm, MatrixReducedRowEchelonFormNode>({child}); }
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("rref", MatrixEchelonFormNode::sNumberOfChildren, &UntypedBuilderOneChild<MatrixReducedRowEchelonForm>);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
37
poincare/include/poincare/matrix_row_echelon_form.h
Normal file
37
poincare/include/poincare/matrix_row_echelon_form.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef POINCARE_MATRIX_ROW_ECHELON_FORM_H
|
||||
#define POINCARE_MATRIX_ROW_ECHELON_FORM_H
|
||||
|
||||
#include <poincare/matrix_echelon_form.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixRowEchelonFormNode final : public MatrixEchelonFormNode {
|
||||
public:
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(MatrixRowEchelonFormNode); }
|
||||
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "MatrixRowEchelonForm";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::MatrixRowEchelonForm; }
|
||||
private:
|
||||
const char * functionHelperName() const override;
|
||||
bool isFormReduced() const override { return false; }
|
||||
};
|
||||
|
||||
|
||||
class MatrixRowEchelonForm final : public MatrixEchelonForm {
|
||||
public:
|
||||
MatrixRowEchelonForm(const MatrixRowEchelonFormNode * n) : MatrixEchelonForm(n) {}
|
||||
static MatrixRowEchelonForm Builder(Expression child) { return TreeHandle::FixedArityBuilder<MatrixRowEchelonForm, MatrixRowEchelonFormNode>({child}); }
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ref", MatrixEchelonFormNode::sNumberOfChildren, &UntypedBuilderOneChild<MatrixRowEchelonForm>);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,48 +0,0 @@
|
||||
#ifndef POINCARE_MATRIX_RREF_H
|
||||
#define POINCARE_MATRIX_RREF_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class MatrixRrefNode final : public ExpressionNode {
|
||||
public:
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(MatrixRrefNode); }
|
||||
int numberOfChildren() const override;
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "MatrixRref";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::MatrixRref; }
|
||||
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, 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;
|
||||
};
|
||||
|
||||
class MatrixRref final : public Expression {
|
||||
public:
|
||||
MatrixRref(const MatrixRrefNode * n) : Expression(n) {}
|
||||
static MatrixRref Builder(Expression child) { return TreeHandle::FixedArityBuilder<MatrixRref, MatrixRrefNode>({child}); }
|
||||
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("rref", 1, &UntypedBuilderOneChild<MatrixRref>);
|
||||
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -54,8 +54,8 @@
|
||||
#include <poincare/matrix_inverse.h>
|
||||
#include <poincare/matrix_trace.h>
|
||||
#include <poincare/matrix_transpose.h>
|
||||
#include <poincare/matrix_ref.h>
|
||||
#include <poincare/matrix_rref.h>
|
||||
#include <poincare/matrix_row_echelon_form.h>
|
||||
#include <poincare/matrix_reduced_row_echelon_form.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/naperian_logarithm.h>
|
||||
#include <poincare/norm_cdf.h>
|
||||
|
||||
@@ -186,8 +186,8 @@ bool Expression::IsMatrix(const Expression e, Context * context) {
|
||||
|| e.type() == ExpressionNode::Type::MatrixInverse
|
||||
|| e.type() == ExpressionNode::Type::MatrixIdentity
|
||||
|| e.type() == ExpressionNode::Type::MatrixTranspose
|
||||
|| e.type() == ExpressionNode::Type::MatrixRef
|
||||
|| e.type() == ExpressionNode::Type::MatrixRref;
|
||||
|| e.type() == ExpressionNode::Type::MatrixRowEchelonForm
|
||||
|| e.type() == ExpressionNode::Type::MatrixReducedRowEchelonForm;
|
||||
}
|
||||
|
||||
bool Expression::IsInfinity(const Expression e, Context * context) {
|
||||
|
||||
59
poincare/src/matrix_echelon_form.cpp
Normal file
59
poincare/src/matrix_echelon_form.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include <poincare/matrix_echelon_form.h>
|
||||
#include <poincare/matrix_complex.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/serialization_helper.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
int MatrixEchelonFormNode::numberOfChildren() const { return sNumberOfChildren; }
|
||||
|
||||
Expression MatrixEchelonFormNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return MatrixEchelonForm(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
Layout MatrixEchelonFormNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return LayoutHelper::Prefix(MatrixEchelonForm(this), floatDisplayMode, numberOfSignificantDigits, functionHelperName());
|
||||
}
|
||||
|
||||
int MatrixEchelonFormNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, functionHelperName());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> MatrixEchelonFormNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
||||
Evaluation<T> input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit);
|
||||
Evaluation<T> ref;
|
||||
if (input.type() == EvaluationNode<T>::Type::MatrixComplex) {
|
||||
ref = static_cast<MatrixComplex<T>&>(input).ref(isFormReduced());
|
||||
} else {
|
||||
ref = Complex<T>::Undefined();
|
||||
}
|
||||
assert(!ref.isUninitialized());
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
Expression MatrixEchelonForm::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
e = e.defaultHandleUnitsInChildren();
|
||||
if (e.isUndefined()) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
bool couldComputeRef = false;
|
||||
Expression result = static_cast<Matrix&>(c).createRef(reductionContext, &couldComputeRef, isFormReduced());
|
||||
if (couldComputeRef) {
|
||||
replaceWithInPlace(result);
|
||||
return result;
|
||||
}
|
||||
// The matrix could not be transformed properly
|
||||
return *this;
|
||||
}
|
||||
return replaceWithUndefinedInPlace();
|
||||
}
|
||||
|
||||
}
|
||||
9
poincare/src/matrix_reduced_row_echelon_form.cpp
Normal file
9
poincare/src/matrix_reduced_row_echelon_form.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <poincare/matrix_reduced_row_echelon_form.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
constexpr Expression::FunctionHelper MatrixReducedRowEchelonForm::s_functionHelper;
|
||||
|
||||
const char * MatrixReducedRowEchelonFormNode::functionHelperName() const { return MatrixReducedRowEchelonForm::s_functionHelper.name(); }
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
#include <poincare/matrix_ref.h>
|
||||
#include <poincare/matrix_complex.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/serialization_helper.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
constexpr Expression::FunctionHelper MatrixRef::s_functionHelper;
|
||||
|
||||
int MatrixRefNode::numberOfChildren() const { return MatrixRef::s_functionHelper.numberOfChildren(); }
|
||||
|
||||
Expression MatrixRefNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return MatrixRef(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
Layout MatrixRefNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return LayoutHelper::Prefix(MatrixRef(this), floatDisplayMode, numberOfSignificantDigits, MatrixRef::s_functionHelper.name());
|
||||
}
|
||||
|
||||
int MatrixRefNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, MatrixRef::s_functionHelper.name());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> MatrixRefNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
||||
Evaluation<T> input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit);
|
||||
Evaluation<T> ref;
|
||||
if (input.type() == EvaluationNode<T>::Type::MatrixComplex) {
|
||||
ref = static_cast<MatrixComplex<T>&>(input).ref(false);
|
||||
} else {
|
||||
ref = Complex<T>::Undefined();
|
||||
}
|
||||
assert(!ref.isUninitialized());
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
Expression MatrixRef::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
e = e.defaultHandleUnitsInChildren();
|
||||
if (e.isUndefined()) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
bool couldComputeRef = false;
|
||||
Expression result = static_cast<Matrix&>(c).createRef(reductionContext, &couldComputeRef, false);
|
||||
if (couldComputeRef) {
|
||||
replaceWithInPlace(result);
|
||||
return result;
|
||||
}
|
||||
// The matrix could not be transformed properly
|
||||
return *this;
|
||||
}
|
||||
return replaceWithUndefinedInPlace();
|
||||
}
|
||||
|
||||
}
|
||||
9
poincare/src/matrix_row_echelon_form.cpp
Normal file
9
poincare/src/matrix_row_echelon_form.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <poincare/matrix_row_echelon_form.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
constexpr Expression::FunctionHelper MatrixRowEchelonForm::s_functionHelper;
|
||||
|
||||
const char * MatrixRowEchelonFormNode::functionHelperName() const { return MatrixRowEchelonForm::s_functionHelper.name(); }
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
#include <poincare/matrix_rref.h>
|
||||
#include <poincare/matrix_complex.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/serialization_helper.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
constexpr Expression::FunctionHelper MatrixRref::s_functionHelper;
|
||||
|
||||
int MatrixRrefNode::numberOfChildren() const { return MatrixRref::s_functionHelper.numberOfChildren(); }
|
||||
|
||||
Expression MatrixRrefNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return MatrixRref(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
Layout MatrixRrefNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return LayoutHelper::Prefix(MatrixRref(this), floatDisplayMode, numberOfSignificantDigits, MatrixRref::s_functionHelper.name());
|
||||
}
|
||||
|
||||
int MatrixRrefNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, MatrixRref::s_functionHelper.name());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> MatrixRrefNode::templatedApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
|
||||
Evaluation<T> input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit);
|
||||
Evaluation<T> rref;
|
||||
if (input.type() == EvaluationNode<T>::Type::MatrixComplex) {
|
||||
rref = static_cast<MatrixComplex<T>&>(input).ref(true);
|
||||
} else {
|
||||
rref = Complex<T>::Undefined();
|
||||
}
|
||||
assert(!rref.isUninitialized());
|
||||
return rref;
|
||||
}
|
||||
|
||||
|
||||
Expression MatrixRref::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
{
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
e = e.defaultHandleUnitsInChildren();
|
||||
if (e.isUndefined()) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
Expression c = childAtIndex(0);
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
bool couldComputeRref = false;
|
||||
Expression result = static_cast<Matrix&>(c).createRef(reductionContext, &couldComputeRref, true);
|
||||
if (couldComputeRref) {
|
||||
replaceWithInPlace(result);
|
||||
return result;
|
||||
}
|
||||
// The matrix could not be transformed properly
|
||||
return *this;
|
||||
}
|
||||
return replaceWithUndefinedInPlace();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -138,11 +138,11 @@ private:
|
||||
&Randint::s_functionHelper,
|
||||
&Random::s_functionHelper,
|
||||
&RealPart::s_functionHelper,
|
||||
&MatrixRef::s_functionHelper,
|
||||
&MatrixRowEchelonForm::s_functionHelper,
|
||||
&DivisionRemainder::s_functionHelper,
|
||||
&NthRoot::s_functionHelper,
|
||||
&Round::s_functionHelper,
|
||||
&MatrixRref::s_functionHelper,
|
||||
&MatrixReducedRowEchelonForm::s_functionHelper,
|
||||
&SignFunction::s_functionHelper,
|
||||
&Sine::s_functionHelper,
|
||||
&HyperbolicSine::s_functionHelper,
|
||||
|
||||
@@ -336,8 +336,8 @@ template MatrixIdentity TreeHandle::FixedArityBuilder<MatrixIdentity, MatrixIden
|
||||
template MatrixInverse TreeHandle::FixedArityBuilder<MatrixInverse, MatrixInverseNode>(const Tuple &);
|
||||
template MatrixTrace TreeHandle::FixedArityBuilder<MatrixTrace, MatrixTraceNode>(const Tuple &);
|
||||
template MatrixTranspose TreeHandle::FixedArityBuilder<MatrixTranspose, MatrixTransposeNode>(const Tuple &);
|
||||
template MatrixRef TreeHandle::FixedArityBuilder<MatrixRef, MatrixRefNode>(const Tuple &);
|
||||
template MatrixRref TreeHandle::FixedArityBuilder<MatrixRref, MatrixRrefNode>(const Tuple &);
|
||||
template MatrixRowEchelonForm TreeHandle::FixedArityBuilder<MatrixRowEchelonForm, MatrixRowEchelonFormNode>(const Tuple &);
|
||||
template MatrixReducedRowEchelonForm TreeHandle::FixedArityBuilder<MatrixReducedRowEchelonForm, MatrixReducedRowEchelonFormNode>(const Tuple &);
|
||||
template Multiplication TreeHandle::NAryBuilder<Multiplication, MultiplicationNode>(const Tuple &);
|
||||
template NaperianLogarithm TreeHandle::FixedArityBuilder<NaperianLogarithm, NaperianLogarithmNode>(const Tuple &);
|
||||
template NormCDF TreeHandle::FixedArityBuilder<NormCDF, NormCDFNode>(const Tuple &);
|
||||
|
||||
@@ -410,8 +410,8 @@ QUIZ_CASE(poincare_parsing_identifiers) {
|
||||
assert_parsed_expression_is("tanh(1)", HyperbolicTangent::Builder(BasedInteger::Builder(1)));
|
||||
assert_parsed_expression_is("trace(1)", MatrixTrace::Builder(BasedInteger::Builder(1)));
|
||||
assert_parsed_expression_is("transpose(1)", MatrixTranspose::Builder(BasedInteger::Builder(1)));
|
||||
assert_parsed_expression_is("ref(1)", MatrixRef::Builder(BasedInteger::Builder(1)));
|
||||
assert_parsed_expression_is("rref(1)", MatrixRref::Builder(BasedInteger::Builder(1)));
|
||||
assert_parsed_expression_is("ref(1)", MatrixRowEchelonForm::Builder(BasedInteger::Builder(1)));
|
||||
assert_parsed_expression_is("rref(1)", MatrixReducedRowEchelonForm::Builder(BasedInteger::Builder(1)));
|
||||
assert_parsed_expression_is("√(1)", SquareRoot::Builder(BasedInteger::Builder(1)));
|
||||
assert_text_not_parsable("cos(1,2)");
|
||||
assert_text_not_parsable("log(1,2,3)");
|
||||
|
||||
Reference in New Issue
Block a user