Numworks Epsilon  1.4.1
Graphing Calculator Operating System
matrix_inverse.cpp
Go to the documentation of this file.
2 #include <poincare/matrix.h>
3 #include <poincare/complex.h>
4 #include <poincare/division.h>
5 #include <poincare/undefined.h>
6 #include <poincare/power.h>
7 extern "C" {
8 #include <assert.h>
9 }
10 #include <cmath>
11 
12 namespace Poincare {
13 
15  return Type::MatrixInverse;
16 }
17 
19  MatrixInverse * a = new MatrixInverse(m_operands, true);
20  return a;
21 }
22 
23 Expression * MatrixInverse::shallowReduce(Context& context, AngleUnit angleUnit) {
24  Expression * e = Expression::shallowReduce(context, angleUnit);
25  if (e != this) {
26  return e;
27  }
28  Expression * op = editableOperand(0);
29 #if MATRIX_EXACT_REDUCING
30  if (!op->recursivelyMatches(Expression::IsMatrix)) {
31  detachOperand(op);
32  return replaceWith(new Power(op, new Rational(-1), false), true)->shallowReduce(context, angleUnit);
33  }
34  if (op->type() == Type::Matrix) {
35  Matrix * mat = static_cast<Matrix *>(op);
36  if (mat->numberOfRows() != mat->numberOfColumns()) {
37  return replaceWith(new Undefined(), true);
38  }
39  }
40  return this;
41 #else
42  detachOperand(op);
43  return replaceWith(new Power(op, new Rational(-1), false), true)->shallowReduce(context, angleUnit);
44 #endif
45 }
46 
47 // TODO: handle this exactly in shallowReduce for small dimensions.
48 template<typename T>
49 Expression * MatrixInverse::templatedApproximate(Context& context, AngleUnit angleUnit) const {
50  Expression * input = operand(0)->approximate<T>(context, angleUnit);
51  Expression * result = nullptr;
52  if (input->type() == Type::Complex) {
53  Complex<T> * c = static_cast<Complex<T> *>(input);
54  result = new Complex<T>(Division::compute(Complex<T>::Cartesian(1, 0), *c));
55  } else {
56  assert(input->type() == Type::Matrix);
57  result = static_cast<Matrix *>(input)->createInverse<T>();
58  }
59  if (result == nullptr) {
60  result = new Complex<T>(Complex<T>::Float(NAN));
61  }
62  delete input;
63  return result;
64 }
65 
66 }
67 
#define NAN
Definition: math.h:30
static Complex< T > Cartesian(T a, T b)
Definition: complex.cpp:28
#define assert(e)
Definition: assert.h:9
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
Definition: expression.cpp:85
Expression * approximate(Context &context, AngleUnit angleUnit=AngleUnit::Default) const
Definition: expression.cpp:338
static bool IsMatrix(const Expression *e, Context &context)
Definition: expression.cpp:198
#define T(x)
Definition: events.cpp:26
Expression * clone() const override
c(generic_all_nodes)
Expression * editableOperand(int i)
Definition: expression.h:176
friend class Rational
Definition: expression.h:18
static Complex< T > compute(const Complex< T > c, const Complex< T > d)
Definition: division.cpp:52
friend class Power
Definition: expression.h:21
const Expression * m_operands[T]
Type type() const override
static Complex< T > Float(T x)
Definition: complex.cpp:23
friend class Matrix
Definition: expression.h:73
void detachOperand(const Expression *e)
Definition: expression.cpp:115
friend class MatrixInverse
Definition: expression.h:57
const Expression * operand(int i) const
Definition: expression.cpp:78
friend class Undefined
Definition: expression.h:17