-
Notifications
You must be signed in to change notification settings - Fork 549
Expand file tree
/
Copy pathcomplex.cpp
More file actions
157 lines (129 loc) · 4.65 KB
/
complex.cpp
File metadata and controls
157 lines (129 loc) · 4.65 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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*******************************************************
* Copyright (c) 2014, ArrayFire
* All rights reserved.
*
* This file is distributed under 3-clause BSD license.
* The complete license agreement can be obtained at:
* http://arrayfire.com/licenses/BSD-3-Clause
********************************************************/
#include <af/complex.h>
#include <cmath>
#include <complex>
#include <istream>
namespace af {
using std::complex;
float real(af_cfloat val) { return val.real; }
double real(af_cdouble val) { return val.real; }
float imag(af_cfloat val) { return val.imag; }
double imag(af_cdouble val) { return val.imag; }
cfloat operator+(const cfloat &lhs, const cfloat &rhs) {
cfloat out(lhs.real + rhs.real, lhs.imag + rhs.imag);
return out;
}
cdouble operator+(const cdouble &lhs, const cdouble &rhs) {
cdouble out(lhs.real + rhs.real, lhs.imag + rhs.imag);
return out;
}
cfloat operator*(const cfloat &lhs, const cfloat &rhs) {
complex<float> clhs(lhs.real, lhs.imag);
complex<float> crhs(rhs.real, rhs.imag);
complex<float> out = clhs * crhs;
return {out.real(), out.imag()};
}
cdouble operator*(const cdouble &lhs, const cdouble &rhs) {
complex<double> clhs(lhs.real, lhs.imag);
complex<double> crhs(rhs.real, rhs.imag);
complex<double> out = clhs * crhs;
return {out.real(), out.imag()};
}
cfloat operator-(const cfloat &lhs, const cfloat &rhs) {
cfloat out(lhs.real - rhs.real, lhs.imag - rhs.imag);
return out;
}
cdouble operator-(const cdouble &lhs, const cdouble &rhs) {
cdouble out(lhs.real - rhs.real, lhs.imag - rhs.imag);
return out;
}
cfloat operator/(const cfloat &lhs, const cfloat &rhs) {
complex<float> clhs(lhs.real, lhs.imag);
complex<float> crhs(rhs.real, rhs.imag);
complex<float> out = clhs / crhs;
return {out.real(), out.imag()};
}
cdouble operator/(const cdouble &lhs, const cdouble &rhs) {
complex<double> clhs(lhs.real, lhs.imag);
complex<double> crhs(rhs.real, rhs.imag);
complex<double> out = clhs / crhs;
return {out.real(), out.imag()};
}
#define IMPL_OP(OP) \
cfloat operator OP(const cfloat &lhs, const double &rhs) { \
return lhs OP cfloat(rhs); \
} \
cdouble operator OP(const cdouble &lhs, const double &rhs) { \
return lhs OP cdouble(rhs); \
} \
cfloat operator OP(const double &lhs, const cfloat &rhs) { \
return cfloat(lhs) OP rhs; \
} \
cdouble operator OP(const double &lhs, const cdouble &rhs) { \
return cdouble(lhs) OP rhs; \
} \
cdouble operator OP(const cfloat &lhs, const cdouble &rhs) { \
return cdouble(real(lhs), imag(lhs)) OP rhs; \
} \
cdouble operator OP(const cdouble &lhs, const cfloat &rhs) { \
return lhs OP cdouble(real(rhs), imag(rhs)); \
}
IMPL_OP(+)
IMPL_OP(-)
IMPL_OP(*)
IMPL_OP(/)
#undef IMPL_OP
bool operator!=(const cfloat &lhs, const cfloat &rhs) { return !(lhs == rhs); }
bool operator!=(const cdouble &lhs, const cdouble &rhs) {
return !(lhs == rhs);
}
bool operator==(const cfloat &lhs, const cfloat &rhs) {
return lhs.real == rhs.real && lhs.imag == rhs.imag;
}
bool operator==(const cdouble &lhs, const cdouble &rhs) {
return lhs.real == rhs.real && lhs.imag == rhs.imag;
}
float abs(const cfloat &val) {
std::complex<float> out(val.real, val.imag);
return abs(out);
}
double abs(const cdouble &val) {
std::complex<double> out(val.real, val.imag);
return abs(out);
}
cfloat conj(const cfloat &val) { return {val.real, -val.imag}; }
cdouble conj(const cdouble &val) { return {val.real, -val.imag}; }
std::ostream &operator<<(std::ostream &os, const cfloat &in) {
os << "(" << in.real << ", " << in.imag << ")";
return os;
}
std::ostream &operator<<(std::ostream &os, const cdouble &in) {
os << "(" << in.real << " " << in.imag << ")";
return os;
}
std::istream &operator>>(std::istream &is, cfloat &in) {
char trash;
is >> trash;
is >> in.real;
is >> trash;
is >> in.imag;
is >> trash;
return is;
}
std::istream &operator>>(std::istream &is, cdouble &in) {
char trash;
is >> trash;
is >> in.real;
is >> trash;
is >> in.imag;
is >> trash;
return is;
}
} // namespace af