Numworks Epsilon  1.4.1
Graphing Calculator Operating System
nth_root.cpp
Go to the documentation of this file.
1 #include <poincare/nth_root.h>
2 #include <poincare/complex.h>
3 #include <poincare/division.h>
4 #include <poincare/power.h>
5 #include <poincare/undefined.h>
7 
8 extern "C" {
9 #include <assert.h>
10 }
11 #include <cmath>
12 
13 namespace Poincare {
14 
16  return Type::NthRoot;
17 }
18 
20  NthRoot * a = new NthRoot(m_operands, true); return a;
21 }
22 
23 Expression * NthRoot::shallowReduce(Context& context, AngleUnit angleUnit) {
24  Expression * e = Expression::shallowReduce(context, angleUnit);
25  if (e != this) {
26  return e;
27  }
28 #if MATRIX_EXACT_REDUCING
29  if (operand(0)->type() == Type::Matrix || operand(1)->type() == Type::Matrix) {
30  return replaceWith(new Undefined(), true);
31  }
32 #endif
33  Power * invIndex = new Power(operand(1), new Rational(-1), false);
34  Power * p = new Power(operand(0), invIndex, false);
36  invIndex->shallowReduce(context, angleUnit);
37  replaceWith(p, true);
38  return p->shallowReduce(context, angleUnit);
39 }
40 
41 ExpressionLayout * NthRoot::privateCreateLayout(PrintFloat::Mode floatDisplayMode, ComplexFormat complexFormat) const {
42  assert(floatDisplayMode != PrintFloat::Mode::Default);
43  assert(complexFormat != ComplexFormat::Default);
44  return new NthRootLayout(operand(0)->createLayout(floatDisplayMode, complexFormat), operand(1)->createLayout(floatDisplayMode, complexFormat));
45 }
46 
47 template<typename T>
48 Complex<T> NthRoot::compute(const Complex<T> c, const Complex<T> d) {
49  if (c.a() >= 0 && c.b() == 0 && d.b() == 0) {
50  return Complex<T>::Float(std::pow(c.a(), 1/d.a()));
51  }
52  Complex<T> invIndex = Division::compute(Complex<T>::Float(1), d);
53  return Power::compute(c, invIndex);
54 }
55 
56 template<typename T>
57 Expression * NthRoot::templatedApproximate(Context& context, AngleUnit angleUnit) const {
58  Expression * base = operand(0)->approximate<T>(context, angleUnit);
59  Expression * index = operand(1)->approximate<T>(context, angleUnit);
60  Complex<T> result = Complex<T>::Float(NAN);
61  if (base->type() == Type::Complex && index->type() == Type::Complex) {
62  Complex<T> * basec = static_cast<Complex<T> *>(base);
63  Complex<T> * indexc = static_cast<Complex<T> *>(index);
64  result = compute(*basec, *indexc);
65  }
66  delete base;
67  delete index;
68  return new Complex<T>(result);
69 }
70 
71 }
#define NAN
Definition: math.h:30
friend class NthRoot
Definition: expression.h:61
#define assert(e)
Definition: assert.h:9
Type type() const override
Definition: nth_root.cpp:15
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
Definition: expression.cpp:85
Expression * approximate(Context &context, AngleUnit angleUnit=AngleUnit::Default) const
Definition: expression.cpp:338
#define T(x)
Definition: events.cpp:26
c(generic_all_nodes)
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
#define pow(x, y)
Definition: math.h:190
const Expression * m_operands[T]
ExpressionLayout * createLayout(PrintFloat::Mode floatDisplayMode=PrintFloat::Mode::Default, ComplexFormat complexFormat=ComplexFormat::Default) const
Definition: expression.cpp:244
static Complex< T > Float(T x)
Definition: complex.cpp:23
Expression * clone() const override
Definition: nth_root.cpp:19
static Complex< T > compute(const Complex< T > c, const Complex< T > d)
Definition: power.cpp:84
const Expression * operand(int i) const
Definition: expression.cpp:78
friend class Undefined
Definition: expression.h:17