Blame view

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