#include #include #include #include #include extern "C" { #include } #include namespace Poincare { Expression::Type MatrixInverse::type() const { return Type::MatrixInverse; } Expression * MatrixInverse::clone() const { MatrixInverse * a = new MatrixInverse(m_operands, true); return a; } Expression * MatrixInverse::shallowReduce(Context& context, AngleUnit angleUnit) { Expression * e = Expression::shallowReduce(context, angleUnit); if (e != this) { return e; } Expression * op = editableOperand(0); #if MATRIX_EXACT_REDUCING if (!op->recursivelyMatches(Expression::IsMatrix)) { detachOperand(op); return replaceWith(new Power(op, new Rational(-1), false), true)->shallowReduce(context, angleUnit); } if (op->type() == Type::Matrix) { Matrix * mat = static_cast(op); if (mat->numberOfRows() != mat->numberOfColumns()) { return replaceWith(new Undefined(), true); } } return this; #else detachOperand(op); return replaceWith(new Power(op, new Rational(-1), false), true)->shallowReduce(context, angleUnit); #endif } // TODO: handle this exactly in shallowReduce for small dimensions. template Evaluation * MatrixInverse::templatedApproximate(Context& context, AngleUnit angleUnit) const { Evaluation * input = operand(0)->privateApproximate(T(), context, angleUnit); Evaluation * inverse = input->createInverse(); if (inverse == nullptr) { inverse = new Complex(Complex::Undefined()); } delete input; return inverse; } }