extern "C" { #include <assert.h> #include <string.h> #include <float.h> } #include <poincare/division.h> #include <poincare/power.h> #include <poincare/rational.h> #include <poincare/tangent.h> #include <poincare/multiplication.h> #include <poincare/opposite.h> #include "layout/fraction_layout.h" #include <cmath> namespace Poincare { Expression::Type Division::type() const { return Type::Division; } Expression * Division::clone() const { return new Division(m_operands, true); } int Division::polynomialDegree(char symbolName) const { if (operand(1)->polynomialDegree(symbolName) != 0) { return -1; } return operand(0)->polynomialDegree(symbolName); } bool Division::needParenthesisWithParent(const Expression * e) const { Type types[] = {Type::Division, Type::Power, Type::Factorial}; return e->isOfType(types, 3); } Expression * Division::shallowReduce(Context& context, AngleUnit angleUnit) { Expression * e = Expression::shallowReduce(context, angleUnit); if (e != this) { return e; } Power * p = new Power(operand(1), new Rational(-1), false); Multiplication * m = new Multiplication(operand(0), p, false); detachOperands(); p->shallowReduce(context, angleUnit); replaceWith(m, true); return m->shallowReduce(context, angleUnit); } template<typename T> std::complex<T> Division::compute(const std::complex<T> c, const std::complex<T> d) { return c/d; } ExpressionLayout * Division::createLayout(PrintFloat::Mode floatDisplayMode, int numberOfSignificantDigits) const { const Expression * numerator = operand(0)->type() == Type::Parenthesis ? operand(0)->operand(0) : operand(0); const Expression * denominator = operand(1)->type() == Type::Parenthesis ? operand(1)->operand(0) : operand(1); return new FractionLayout(numerator->createLayout(floatDisplayMode, numberOfSignificantDigits), denominator->createLayout(floatDisplayMode, numberOfSignificantDigits), false); } template<typename T> MatrixComplex<T> Division::computeOnComplexAndMatrix(const std::complex<T> c, const MatrixComplex<T> n) { MatrixComplex<T> * inverse = n.createInverse(); if (inverse == nullptr) { return MatrixComplex<T>::Undefined(); } MatrixComplex<T> result = Multiplication::computeOnComplexAndMatrix<T>(c, *inverse); delete inverse; return result; } template<typename T> MatrixComplex<T> Division::computeOnMatrices(const MatrixComplex<T> m, const MatrixComplex<T> n) { if (m.numberOfColumns() != n.numberOfColumns()) { return MatrixComplex<T>::Undefined(); } MatrixComplex<T> * inverse = n.createInverse(); if (inverse == nullptr) { return MatrixComplex<T>::Undefined(); } MatrixComplex<T> result = Multiplication::computeOnMatrices<T>(m, *inverse); delete inverse; return result; } }