Blame view

Giac_maj/epsilon-giac/poincare/src/binary_operation.cpp 4.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
  #include <poincare/binary_operation.h>
  #include <poincare/complex_matrix.h>
  #include <cmath>
  extern "C" {
  #include <assert.h>
  #include <stdlib.h>
  }
  
  namespace Poincare {
  
  BinaryOperation::BinaryOperation()
  {
    m_operands[0] = nullptr;
    m_operands[1] = nullptr;
  }
  
  BinaryOperation::BinaryOperation(Expression ** operands, bool cloneOperands) {
    assert(operands != nullptr);
    assert(operands[0] != nullptr);
    assert(operands[1] != nullptr);
    if (cloneOperands) {
      m_operands[0] = operands[0]->clone();
      m_operands[1] = operands[1]->clone();
    } else {
      m_operands[0] = operands[0];
      m_operands[1] = operands[1];
    }
  }
  
  BinaryOperation::~BinaryOperation() {
    if (m_operands[1] != nullptr) {
      delete m_operands[1];
    }
    if (m_operands[0] != nullptr) {
      delete m_operands[0];
    }
  }
  
  bool BinaryOperation::hasValidNumberOfArguments() const {
    return m_operands[0]->hasValidNumberOfArguments() && m_operands[1]->hasValidNumberOfArguments();
  }
  
  int BinaryOperation::numberOfOperands() const {
    return 2;
  }
  
  const Expression * BinaryOperation::operand(int i) const {
    assert(i >= 0);
    assert(i < 2);
    return m_operands[i];
  }
  
  Expression * BinaryOperation::clone() const {
    return this->cloneWithDifferentOperands((Expression**) m_operands, 2, true);
  }
  
  template<typename T> Evaluation<T> * BinaryOperation::templatedEvaluate(Context& context, AngleUnit angleUnit) const {
    Evaluation<T> * leftOperandEvalutation = m_operands[0]->evaluate<T>(context, angleUnit);
    Evaluation<T> * rightOperandEvalutation = m_operands[1]->evaluate<T>(context, angleUnit);
    Evaluation<T> * result = nullptr;
    if (leftOperandEvalutation->numberOfRows() == 1 && leftOperandEvalutation->numberOfColumns() == 1 && rightOperandEvalutation->numberOfRows() == 1 && rightOperandEvalutation->numberOfColumns() == 1) {
      result = new Complex<T>(privateCompute(*(leftOperandEvalutation->complexOperand(0)), *(rightOperandEvalutation->complexOperand(0))));
    } else if (leftOperandEvalutation->numberOfRows() == 1 && leftOperandEvalutation->numberOfColumns() == 1) {
      result = computeOnComplexAndComplexMatrix(leftOperandEvalutation->complexOperand(0), rightOperandEvalutation);
    } else if (rightOperandEvalutation->numberOfRows() == 1 && rightOperandEvalutation->numberOfColumns() == 1) {
      result = computeOnComplexMatrixAndComplex(leftOperandEvalutation, rightOperandEvalutation->complexOperand(0));
    } else {
      result = computeOnComplexMatrices(leftOperandEvalutation, rightOperandEvalutation);
    }
    delete leftOperandEvalutation;
    delete rightOperandEvalutation;
    if (result == nullptr) {
      result = new Complex<T>(Complex<T>::Float(NAN));
    }
    return result;
  }
  
  template<typename T> Evaluation<T> * BinaryOperation::templatedComputeOnComplexAndComplexMatrix(const Complex<T> * c, Evaluation<T> * n) const {
    return computeOnComplexMatrixAndComplex(n, c);
  }
  
  template<typename T> Evaluation<T> * BinaryOperation::templatedComputeOnComplexMatrixAndComplex(Evaluation<T> * m, const Complex<T> * d) const {
    Complex<T> * operands = new Complex<T>[m->numberOfRows()*m->numberOfColumns()];
    for (int i = 0; i < m->numberOfOperands(); i++) {
      operands[i] = privateCompute(*(m->complexOperand(i)), *d);
    }
    Evaluation<T> * result = new ComplexMatrix<T>(operands, m->numberOfRows(), m->numberOfColumns());
    delete[] operands;
    return result;
  }
  
  template<typename T> Evaluation<T> * BinaryOperation::templatedComputeOnComplexMatrices(Evaluation<T> * m, Evaluation<T> * n) const {
    if (m->numberOfRows() != n->numberOfRows() && m->numberOfColumns() != n->numberOfColumns()) {
      return nullptr;
    }
    Complex<T> * operands = new Complex<T>[m->numberOfRows()*m->numberOfColumns()];
    for (int i = 0; i < m->numberOfOperands(); i++) {
      operands[i] = privateCompute(*(m->complexOperand(i)), *(n->complexOperand(i)));
    }
    Evaluation<T> * result = new ComplexMatrix<T>(operands, m->numberOfRows(), m->numberOfColumns());
    delete[] operands;
    return result;
  }
  
  }
  
  template Poincare::Evaluation<float>* Poincare::BinaryOperation::templatedComputeOnComplexAndComplexMatrix<float>(Poincare::Complex<float> const*, Poincare::Evaluation<float>*) const;
  template Poincare::Evaluation<double>* Poincare::BinaryOperation::templatedComputeOnComplexAndComplexMatrix<double>(Poincare::Complex<double> const*, Poincare::Evaluation<double>*) const;