My Project
 All Classes Files Functions Variables Enumerations Enumerator Friends Macros Pages
Complex.h
Go to the documentation of this file.
1 #ifndef GCP_UTIL_COMPLEX_H
2 #define GCP_UTIL_COMPLEX_H
3 
11 #include <cmath>
12 #include <iostream>
13 #include <sstream>
14 #include <complex>
15 
16 // Conversion from radians to degrees
17 
18 #define radiansToDegrees_ 180.0/M_PI
19 
20 namespace gcp {
21  namespace util {
22 
23  // Non-member template friends require forward declaration
24 
25  template<class Type>
26  class Complex;
27 
28  template<class Type>
29  std::ostream& operator<<(std::ostream& os,
30  Complex<Type>& val);
31  template<class Type>
32  std::ostringstream& operator<<(std::ostringstream& os,
33  Complex<Type>& val);
34 
35  // A class for handling complex numbers, since std::complex<> is
36  // pretty useless
37 
38  template<class Type>
39  class Complex {
40 
41  public:
42 
43  // An internal data struct we will use for raw pointers. I.e.,
44  // a raw byte array can be cast to type (Complex<Type>::Data)*
45  // without confusion, whereas the same cannot be done with
46  // Complex<Type>*
47 
48  struct Data {
49  Type real_;
50  Type imag_;
51  };
52 
56  Complex(Type real, Type imag) {
57  data_.real_ = real;
58  data_.imag_ = imag;
59  }
60 
61  Complex(std::complex<Type> cVal) {
62  data_.real_ = cVal.real();
63  data_.imag_ = cVal.imag();
64  }
65 
66  // Constructor with a Data struct
67 
68  Complex(Data& data)
69  {
70  data_.real_ = data.real_;
71  data_.imag_ = data.imag_;
72  }
73 
74  // Copy constructor
75 
76  Complex(const Complex<Type>& complx)
77  {
78  data_.real_ = complx.data_.real_;
79  data_.imag_ = complx.data_.imag_;
80  }
81 
82  Complex() {
83  initialize();
84  };
85 
89  virtual ~Complex() {};
90 
91  void setReal(Type real) {
92  data_.real_ = real;
93  }
94 
95  void setImag(Type imag) {
96  data_.imag_ = imag;
97  }
98 
99  // Return the real part of the complex number
100 
101  inline Type real() {
102  return data_.real_;
103  }
104 
105  // Return the imaginary part of the complex number
106 
107  inline Type imag() {
108  return data_.imag_;
109  }
110 
111  // Return the amplitude of the complex number
112 
113  inline double amp() {
114  return amplitude();
115  }
116 
117  inline double amplitude() {
118  Type real = data_.real_;
119  Type imag = data_.imag_;
120  return sqrt((double)(real*real + imag*imag));
121  }
122 
123  inline double squaredAmplitude() const {
124  Type real = data_.real_;
125  Type imag = data_.imag_;
126  return (real*real + imag*imag);
127  }
128 
129  // Return the conjugate of a complex number
130 
131  Complex<Type> conjugate() const {
132  Complex<Type> conj(data_.real_, -data_.imag_);
133  return conj;
134  }
135 
136  // Return the phase of the complex number
137 
138  inline double phaseInRadians() {
139  if((double)data_.real_ == 0.0 && (double)data_.imag_ == 0.0)
140  return 0.0;
141  else {
142  Type real = data_.real_;
143  Type imag = data_.imag_;
144  return atan2((double)imag, (double)real);
145  }
146  }
147 
148  inline double phaseInDegrees() {
149  return phaseInRadians() * radiansToDegrees_;
150  }
151 
152  inline void initialize() {
153  data_.real_ = (Type)0;
154  data_.imag_ = (Type)0;
155  }
156 
157  // Assignment operator.
158 
159  void operator=(Data& data) {
160  data_.real_ = data.real_;
161  data_.imag_ = data.imag_;
162  }
163 
164  void operator=(const Complex<Type>& cmplx) {
165  data_.real_ = cmplx.data_.real_;
166  data_.imag_ = cmplx.data_.imag_;
167  }
168 
169  void operator+=(const Complex<Type>& cmplx) {
170  data_.real_ += cmplx.data_.real_;
171  data_.imag_ += cmplx.data_.imag_;
172  }
173 
174  void operator-=(const Complex<Type>& cmplx) {
175  data_.real_ -= cmplx.data_.real_;
176  data_.imag_ -= cmplx.data_.imag_;
177  }
178 
179  Complex<Type> operator+(const Complex<Type>& cmplx) {
180  Complex<Type> sum(data_.real_ + cmplx.data_.real_,
181  data_.imag_ + cmplx.data_.imag_);
182  return sum;
183  }
184 
185  Complex<Type> operator-(const Complex<Type>& cmplx) {
186  Complex<Type> diff(data_.real_ - cmplx.data_.real_,
187  data_.imag_ - cmplx.data_.imag_);
188  return diff;
189  }
190 
191  Complex<Type> operator*(const Complex<Type>& cmplx) {
192  Type re, im;
193 
194  re = data_.real_ * cmplx.data_.real_ - data_.imag_ * cmplx.data_.imag_;
195  im = data_.imag_ * cmplx.data_.real_ + data_.real_ * cmplx.data_.imag_;
196 
197  Complex<Type> product(re, im);
198  return product;
199  }
200 
201  Complex<Type> operator/(const Complex<Type>& cmplx) {
202  return (*this) * (cmplx.conjugate()/cmplx.squaredAmplitude());
203  }
204 
205  Complex<Type> operator/(unsigned int divisor){
206  Complex<Type> div(data_.real_ / divisor,
207  data_.imag_ / divisor);
208  return div;
209  }
210 
211  Complex<Type> operator/(double divisor){
212  Complex<Type> div(data_.real_ / divisor,
213  data_.imag_ / divisor);
214  return div;
215  }
216 
217  // Comparison operator.
218 
219  bool operator==(Complex<Type>& comp) {
220  return (real() == comp.real()) && (imag() == comp.imag());
221  }
222 
223  bool operator>(Complex<Type>& comp) {
224  return amp() > comp.amp();
225  }
226 
227  bool operator>=(Complex<Type>& comp) {
228  return amp() >= comp.amp();
229  }
230 
231  bool operator<(Complex<Type>& comp) {
232  return amp() < comp.amp();
233  }
234 
235  bool operator<=(Complex<Type>& comp) {
236  return amp() <= comp.amp();
237  }
238 
239  // Return our internal data
240 
241  Data* data() {
242  return &data_;
243  }
244 
245  // Friend operators for printing a complex number
246 
247  friend std::ostream& gcp::util::operator << <>
248  (std::ostream& os, Complex<Type>& val);
249 
250  friend std::ostringstream& gcp::util::operator << <>
251  (std::ostringstream& os, Complex<Type>& val);
252 
253  private:
254 
255  // The internal data of this complex number
256 
257  Data data_;
258 
259  }; // End class Complex
260 
261 
262  // Class methods
263 
264  // Some friend helper functions
265 
266  // Print out a matrix to a stream
267 
268  template<class Type>
269  std::ostream& operator<<(std::ostream& os,
270  Complex<Type>& val)
271  {
272  Type real = val.real();
273  Type imag = val.imag();
274 
275  os << real << (imag < 0 ? " - " : " + ") << "i " << fabs(imag);
276  return os;
277  }
278 
279  // Print out a complex to an ostringstream
280 
281  template<class Type>
282  std::ostringstream& operator<<(std::ostringstream& os,
283  Complex<Type>& val)
284  {
285  Type real = val.real();
286  Type imag = val.imag();
287 
288  os << real() << (imag < 0 ? "-" : "+") << "i" << abs(imag);
289  return os;
290  }
291 
292  } // End namespace util
293 } // End namespace gcp
294 
295 
296 
297 
298 #endif // End #ifndef GCP_UTIL_COMPLEX_H
virtual ~Complex()
Definition: Complex.h:89
Definition: Complex.h:48
Complex(Type real, Type imag)
Definition: Complex.h:56
Definition: Complex.h:26