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
158
159
160
|
/** \file
* \brief Complex Data Type.
*
* See Copyright Notice in im_lib.h
*/
#ifndef __IM_COMPLEX_H
#define __IM_COMPLEX_H
#include "im_math.h"
/** \defgroup cpx Complex Numbers
* \par
* See \ref im_complex.h
* \ingroup util
*/
/** \brief Complex Float Data Type
*
* \par
* Complex class using two floats, one for real part, one for the imaginary part.
* \par
* It is not a complete complex class, we just implement constructors inside the class.
* All the other operators and functions are external to the class.
* \ingroup cpx */
class imcfloat
{
public:
float real; ///< Real part.
float imag; ///< Imaginary part.
/// Default Constructor (0,0).
imcfloat():real(0), imag(0) {}
/// Constructor from (real, imag)
imcfloat(const float& r, const float& i):real(r),imag(i) {}
/// Constructor from (real)
imcfloat(const float& r):real(r),imag(0) {}
};
/** \addtogroup cpx
* Complex numbers operators.
* @{
*/
inline int operator <= (const imcfloat& C1, const imcfloat& C2)
{
return ((C1.real <= C2.real) && (C1.imag <= C2.imag));
}
inline int operator <= (const imcfloat& C, const float& F)
{
return ((F <= C.real) && (0 <= C.imag));
}
inline imcfloat operator + (const imcfloat& C1, const imcfloat& C2)
{
return imcfloat(C1.real + C2.real, C1.imag + C2.imag);
}
inline imcfloat operator += (const imcfloat& C1, const imcfloat& C2)
{
return imcfloat(C1.real + C2.real, C1.imag + C2.imag);
}
inline imcfloat operator - (const imcfloat& C1, const imcfloat& C2)
{
return imcfloat(C1.real - C2.real, C1.imag - C2.imag);
}
inline imcfloat operator * (const imcfloat& C1, const imcfloat& C2)
{
return imcfloat(C1.real * C2.real - C1.imag * C2.imag,
C1.imag * C2.real + C1.real * C2.imag);
}
inline imcfloat operator / (const imcfloat& C1, const imcfloat& C2)
{
float den = C2.real * C2.real - C2.imag * C2.imag;
return imcfloat((C1.real * C2.real + C1.imag * C2.imag) / den,
(C1.imag * C2.real - C1.real * C2.imag) / den);
}
inline imcfloat operator / (const imcfloat& C, const float& R)
{
return imcfloat(C.real / R, C.imag / R);
}
inline imcfloat operator /= (const imcfloat& C, const float& R)
{
return imcfloat(C.real / R, C.imag / R);
}
inline imcfloat operator * (const imcfloat& C, const float& R)
{
return imcfloat(C.real * R, C.imag * R);
}
inline int operator == (const imcfloat& C1, const imcfloat& C2)
{
return ((C1.real == C2.real) && (C1.imag == C2.imag));
}
inline float cpxreal(const imcfloat& C)
{
return C.real;
}
inline float cpximag(const imcfloat& C)
{
return C.imag;
}
inline float cpxmag(const imcfloat& C)
{
return sqrtf(C.real*C.real + C.imag*C.imag);
}
inline float cpxphase(const imcfloat& C)
{
return atan2f(C.real, C.imag);
}
inline imcfloat cpxconj(const imcfloat& C)
{
return imcfloat(C.real, -C.imag);
}
inline imcfloat log(const imcfloat& C)
{
return imcfloat(logf(cpxmag(C)), atan2f(C.real, C.imag));
}
inline imcfloat exp(const imcfloat& C)
{
float mag = expf(C.real);
return imcfloat(mag * cosf(C.imag), mag * sinf(C.imag));
}
inline imcfloat pow(const imcfloat& C1, const imcfloat& C2)
{
return exp(C1 * log(C2));
}
inline imcfloat sqrt(const imcfloat& C)
{
float mag = sqrtf(sqrtf(C.real*C.real + C.imag*C.imag));
float phase = atan2f(C.real, C.imag) / 2;
return imcfloat(mag * cosf(phase), mag * sinf(phase));
}
inline imcfloat cpxpolar(const float& mag, const float& phase)
{
return imcfloat(mag * cosf(phase), mag * sinf(phase));
}
/** @} */
#endif
|