Numworks Epsilon  1.4.1
Graphing Calculator Operating System
approximation_engine.cpp
Go to the documentation of this file.
2 #include <poincare/matrix.h>
3 #include <cmath>
4 extern "C" {
5 #include <assert.h>
6 }
7 
8 namespace Poincare {
9 
10 template<typename T> Expression * ApproximationEngine::map(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexCompute<T> compute) {
11  assert(expression->numberOfOperands() == 1);
12  Expression * input = expression->operand(0)->approximate<T>(context, angleUnit);
13  Expression * result = nullptr;
14  if (input->type() == Expression::Type::Complex) {
15  Complex<T> * c = static_cast<Complex<T> *>(input);
16  result = new Complex<T>(compute(*c, angleUnit));
17  } else {
18  assert(input->type() == Expression::Type::Matrix);
19  Expression ** operands = new Expression * [input->numberOfOperands()];
20  for (int i = 0; i < input->numberOfOperands(); i++) {
21  assert(input->operand(i)->type() == Expression::Type::Complex);
22  const Complex<T> * c = static_cast<const Complex<T> *>(input->operand(i));
23  operands[i] = new Complex<T>(compute(*c, angleUnit));
24  }
25  result = new Matrix(operands, static_cast<Matrix *>(input)->numberOfRows(), static_cast<Matrix *>(input)->numberOfColumns(), false);
26  delete[] operands;
27  }
28  delete input;
29  return result;
30 }
31 
32 template<typename T> Expression * ApproximationEngine::mapReduce(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices) {
33  Expression * result = expression->operand(0)->approximate<T>(context, angleUnit);
34  for (int i = 1; i < expression->numberOfOperands(); i++) {
35  Expression * intermediateResult = nullptr;
36  Expression * nextOperandEvaluation = expression->operand(i)->approximate<T>(context, angleUnit);
37  if (result->type() == Expression::Type::Complex && nextOperandEvaluation->type() == Expression::Type::Complex) {
38  const Complex<T> * c = static_cast<const Complex<T> *>(result);
39  const Complex<T> * d = static_cast<const Complex<T> *>(nextOperandEvaluation);
40  intermediateResult = new Complex<T>(computeOnComplexes(*c, *d));
41  } else if (result->type() == Expression::Type::Complex) {
42  const Complex<T> * c = static_cast<const Complex<T> *>(result);
43  assert(nextOperandEvaluation->type() == Expression::Type::Matrix);
44  const Matrix * n = static_cast<const Matrix *>(nextOperandEvaluation);
45  intermediateResult = computeOnComplexAndMatrix(c, n);
46  } else if (nextOperandEvaluation->type() == Expression::Type::Complex) {
47  assert(result->type() == Expression::Type::Matrix);
48  const Matrix * m = static_cast<const Matrix *>(result);
49  const Complex<T> * d = static_cast<const Complex<T> *>(nextOperandEvaluation);
50  intermediateResult = computeOnMatrixAndComplex(m, d);
51  } else {
52  assert(result->type() == Expression::Type::Matrix);
53  const Matrix * m = static_cast<const Matrix *>(result);
54  assert(nextOperandEvaluation->type() == Expression::Type::Matrix);
55  const Matrix * n = static_cast<const Matrix *>(nextOperandEvaluation);
56  intermediateResult = computeOnMatrices(m, n);
57  }
58  delete result;
59  delete nextOperandEvaluation;
60  result = intermediateResult;
61  if (result == nullptr) {
62  return new Complex<T>(Complex<T>::Float(NAN));
63  }
64  }
65  return result;
66 }
67 
69  Expression ** operands = new Expression * [m->numberOfRows()*m->numberOfColumns()];
70  for (int i = 0; i < m->numberOfOperands(); i++) {
71  const Complex<T> * d = static_cast<const Complex<T> *>(m->operand(i));
72  operands[i] = new Complex<T>(computeOnComplexes(*d, *c));
73  }
74  Matrix * result = new Matrix(operands, m->numberOfRows(), m->numberOfColumns(), false);
75  delete[] operands;
76  return result;
77 }
78 
79 template<typename T> Matrix * ApproximationEngine::elementWiseOnComplexMatrices(const Matrix * m, const Matrix * n, ComplexAndComplexReduction<T> computeOnComplexes) {
80  if (m->numberOfRows() != n->numberOfRows() || m->numberOfColumns() != n->numberOfColumns()) {
81  return nullptr;
82  }
83  Expression ** operands = new Expression * [m->numberOfRows()*m->numberOfColumns()];
84  for (int i = 0; i < m->numberOfOperands(); i++) {
85  const Complex<T> * c = static_cast<const Complex<T> *>(m->operand(i));
86  const Complex<T> * d = static_cast<const Complex<T> *>(n->operand(i));
87  operands[i] = new Complex<T>(computeOnComplexes(*c, *d));
88  }
89  Matrix * result = new Matrix(operands, m->numberOfRows(), m->numberOfColumns(), false);
90  delete[] operands;
91  return result;
92 }
93 
98 template Poincare::Matrix * Poincare::ApproximationEngine::elementWiseOnComplexAndComplexMatrix<float>(Poincare::Complex<float> const*, const Poincare::Matrix *, Poincare::Complex<float> (*)(Poincare::Complex<float>, Poincare::Complex<float>));
99 template Poincare::Matrix* Poincare::ApproximationEngine::elementWiseOnComplexAndComplexMatrix<double>(Poincare::Complex<double> const*, const Poincare::Matrix*, Poincare::Complex<double> (*)(Poincare::Complex<double>, Poincare::Complex<double>));
100 template Poincare::Matrix* Poincare::ApproximationEngine::elementWiseOnComplexMatrices<float>(const Poincare::Matrix*, const Poincare::Matrix*, Poincare::Complex<float> (*)(Poincare::Complex<float>, Poincare::Complex<float>));
101 template Poincare::Matrix* Poincare::ApproximationEngine::elementWiseOnComplexMatrices<double>(const Poincare::Matrix*, const Poincare::Matrix*, Poincare::Complex<double> (*)(Poincare::Complex<double>, Poincare::Complex<double>));
102 
103 
104 }
int numberOfColumns() const
Definition: matrix.cpp:40
#define NAN
Definition: math.h:30
#define assert(e)
Definition: assert.h:9
Expression * approximate(Context &context, AngleUnit angleUnit=AngleUnit::Default) const
Definition: expression.cpp:338
#define T(x)
Definition: events.cpp:26
Matrix *(*)(const Complex< T > *c, const Matrix *m) ComplexAndMatrixReduction
static Expression * mapReduce(const Expression *expression, Context &context, Expression::AngleUnit angleUnit, ComplexAndComplexReduction< T > computeOnComplexes, ComplexAndMatrixReduction< T > computeOnComplexAndMatrix, MatrixAndComplexReduction< T > computeOnMatrixAndComplex, MatrixAndMatrixReduction< T > computeOnMatrices)
static Matrix * elementWiseOnComplexAndComplexMatrix(const Complex< T > *c, const Matrix *n, ComplexAndComplexReduction< T > computeOnComplexes)
c(generic_all_nodes)
virtual int numberOfOperands() const =0
Matrix *(*)(const Matrix *m, const Complex< T > *c) MatrixAndComplexReduction
constexpr uint8_t numberOfColumns
Definition: keyboard.h:39
int numberOfRows() const
Definition: matrix.cpp:36
static Complex< T > Float(T x)
Definition: complex.cpp:23
Complex< T >(*)(const Complex< T >, Expression::AngleUnit angleUnit) ComplexCompute
Matrix *(*)(const Matrix *m, const Matrix *n) MatrixAndMatrixReduction
constexpr uint8_t numberOfRows
Definition: keyboard.h:35
int numberOfOperands() const override
const Expression * operand(int i) const
Definition: expression.cpp:78
virtual Type type() const =0
static Matrix * elementWiseOnComplexMatrices(const Matrix *m, const Matrix *n, ComplexAndComplexReduction< T > computeOnComplexes)
static Expression * map(const Expression *expression, Context &context, Expression::AngleUnit angleUnit, ComplexCompute< T > compute)