binary_operation.cpp
4.25 KB
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;