Blame view

build4/epsilon-master/poincare/src/approximation_engine.cpp 8.25 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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  #include <poincare/approximation_engine.h>
  #include <poincare/evaluation.h>
  #include <poincare/matrix.h>
  #include <cmath>
  extern "C" {
  #include <assert.h>
  }
  
  namespace Poincare {
  
  template <typename T> T absMod(T a, T b) {
    T result = std::fmod(std::fabs(a), b);
    return result > b/2 ? b-result : result;
  }
  
  template <typename T> std::complex<T> ApproximationEngine::truncateRealOrImaginaryPartAccordingToArgument(std::complex<T> c) {
    T arg = std::arg(c);
    T precision = 10*Expression::epsilon<T>();
    if (absMod<T>(arg, (T)M_PI) <= precision) {
      c.imag(0);
    }
    if (absMod<T>(arg-(T)M_PI/2.0, (T)M_PI) <= precision) {
      c.real(0);
    }
    return c;
  }
  
  template<typename T> Evaluation<T> * ApproximationEngine::map(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexCompute<T> compute) {
    assert(expression->numberOfOperands() == 1);
    Evaluation<T> * input = expression->operand(0)->privateApproximate(T(), context, angleUnit);
    Evaluation<T> * result = nullptr;
    if (input->type() == Evaluation<T>::Type::Complex) {
      Complex<T> * c = static_cast<Complex<T> *>(input);
      result = new Complex<T>(compute(*c, angleUnit));
    } else {
      assert(input->type() == Evaluation<T>::Type::MatrixComplex);
      MatrixComplex<T> * m = static_cast<MatrixComplex<T> *>(input);
      std::complex<T> * operands = new std::complex<T> [m->numberOfComplexOperands()];
      for (int i = 0; i < m->numberOfComplexOperands(); i++) {
        const std::complex<T> c = m->complexOperand(i);
        operands[i] = compute(c, angleUnit);
      }
      result = new MatrixComplex<T>(operands, m->numberOfRows(), m->numberOfColumns());
      delete[] operands;
    }
    delete input;
    return result;
  }
  
  template<typename T> Evaluation<T> * ApproximationEngine::mapReduce(const Expression * expression, Context& context, Expression::AngleUnit angleUnit, ComplexAndComplexReduction<T> computeOnComplexes, ComplexAndMatrixReduction<T> computeOnComplexAndMatrix, MatrixAndComplexReduction<T> computeOnMatrixAndComplex, MatrixAndMatrixReduction<T> computeOnMatrices) {
    Evaluation<T> * result = expression->operand(0)->privateApproximate(T(), context, angleUnit);
    for (int i = 1; i < expression->numberOfOperands(); i++) {
      Evaluation<T> * intermediateResult = nullptr;
      Evaluation<T> * nextOperandEvaluation = expression->operand(i)->privateApproximate(T(), context, angleUnit);
      if (result->type() == Evaluation<T>::Type::Complex && nextOperandEvaluation->type() == Evaluation<T>::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() == Evaluation<T>::Type::Complex) {
        const Complex<T> * c = static_cast<const Complex<T> *>(result);
        assert(nextOperandEvaluation->type() == Evaluation<T>::Type::MatrixComplex);
        const MatrixComplex<T> * n = static_cast<const MatrixComplex<T> *>(nextOperandEvaluation);
        intermediateResult = new MatrixComplex<T>(computeOnComplexAndMatrix(*c, *n));
      } else if (nextOperandEvaluation->type() == Evaluation<T>::Type::Complex) {
        assert(result->type() == Evaluation<T>::Type::MatrixComplex);
        const MatrixComplex<T> * m = static_cast<const MatrixComplex<T> *>(result);
        const Complex<T> * d = static_cast<const Complex<T> *>(nextOperandEvaluation);
        intermediateResult = new MatrixComplex<T>(computeOnMatrixAndComplex(*m, *d));
      } else {
        assert(result->type() == Evaluation<T>::Type::MatrixComplex);
        const MatrixComplex<T> * m = static_cast<const MatrixComplex<T> *>(result);
        assert(nextOperandEvaluation->type() == Evaluation<T>::Type::MatrixComplex);
        const MatrixComplex<T> * n = static_cast<const MatrixComplex<T> *>(nextOperandEvaluation);
        intermediateResult = new MatrixComplex<T>(computeOnMatrices(*m, *n));
      }
      delete result;
      delete nextOperandEvaluation;
      result = intermediateResult;
      assert(result != nullptr);
      if (result->isUndefined()) {
        delete result;
        return new Complex<T>(Complex<T>::Undefined());
      }
    }
    return result;
  }
  
  template<typename T> MatrixComplex<T> ApproximationEngine::elementWiseOnMatrixComplexAndComplex(const MatrixComplex<T> m, const std::complex<T> c, ComplexAndComplexReduction<T> computeOnComplexes) {
    std::complex<T> * operands = new std::complex<T> [m.numberOfRows()*m.numberOfColumns()];
    for (int i = 0; i < m.numberOfComplexOperands(); i++) {
      const std::complex<T> d = m.complexOperand(i);
      operands[i] = computeOnComplexes(d, c);
    }
    MatrixComplex<T> result = MatrixComplex<T>(operands, m.numberOfRows(), m.numberOfColumns());
    delete[] operands;
    return result;
  }
  
  template<typename T> MatrixComplex<T> ApproximationEngine::elementWiseOnComplexMatrices(const MatrixComplex<T> m, const MatrixComplex<T> n, ComplexAndComplexReduction<T> computeOnComplexes) {
    if (m.numberOfRows() != n.numberOfRows() || m.numberOfColumns() != n.numberOfColumns()) {
      return MatrixComplex<T>::Undefined();
    }
    std::complex<T> * operands = new std::complex<T> [m.numberOfRows()*m.numberOfColumns()];
    for (int i = 0; i < m.numberOfComplexOperands(); i++) {
      const Complex<T> c = m.complexOperand(i);
      const Complex<T> d = n.complexOperand(i);
      operands[i] = computeOnComplexes(c, d);
    }
    MatrixComplex<T> result = MatrixComplex<T>(operands, m.numberOfRows(), m.numberOfColumns());
    delete[] operands;
    return result;
  }
  
  template std::complex<float> Poincare::ApproximationEngine::truncateRealOrImaginaryPartAccordingToArgument<float>(std::complex<float>);
  template std::complex<double> Poincare::ApproximationEngine::truncateRealOrImaginaryPartAccordingToArgument<double>(std::complex<double>);
  template Poincare::Evaluation<float> * Poincare::ApproximationEngine::map(const Poincare::Expression * expression, Poincare::Context& context, Poincare::Expression::AngleUnit angleUnit, Poincare::ApproximationEngine::ComplexCompute<float> compute);
  template Poincare::Evaluation<double> * Poincare::ApproximationEngine::map(const Poincare::Expression * expression, Poincare::Context& context, Poincare::Expression::AngleUnit angleUnit, Poincare::ApproximationEngine::ComplexCompute<double> compute);
  template Poincare::Evaluation<float> * 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::Evaluation<double> * 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::MatrixComplex<float> Poincare::ApproximationEngine::elementWiseOnMatrixComplexAndComplex<float>(const Poincare::MatrixComplex<float>, const std::complex<float>, std::complex<float> (*)(std::complex<float>, std::complex<float>));
  template Poincare::MatrixComplex<double> Poincare::ApproximationEngine::elementWiseOnMatrixComplexAndComplex<double>(const Poincare::MatrixComplex<double>, std::complex<double> const, std::complex<double> (*)(std::complex<double>, std::complex<double>));
  template Poincare::MatrixComplex<float> Poincare::ApproximationEngine::elementWiseOnComplexMatrices<float>(const Poincare::MatrixComplex<float>, const Poincare::MatrixComplex<float>, std::complex<float> (*)(std::complex<float>, std::complex<float>));
  template Poincare::MatrixComplex<double> Poincare::ApproximationEngine::elementWiseOnComplexMatrices<double>(const Poincare::MatrixComplex<double>, const Poincare::MatrixComplex<double>, std::complex<double> (*)(std::complex<double>, std::complex<double>));
  
  
  }