00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __SEAL_COMPLEX_H__
00030 #define __SEAL_COMPLEX_H__
00031
00032 #include <cmath>
00033
00034 namespace seal
00035 {
00036
00037 template <typename T>
00038 class Complex;
00039
00040 template <typename T>
00041 Complex<T> operator~(const Complex<T> &op);
00042
00046 template <typename T>
00047 class Complex
00048 {
00049
00050 template <typename T1>
00051 friend class Complex;
00052
00053 public:
00056 Complex(void) {}
00057
00060 Complex(const Complex<T> &c) : _re(c._re), _im(c._im) {}
00061
00067 template <typename Tr, typename Ti>
00068 Complex(const Tr re, const Ti im = 0)
00069 {
00070 _re = static_cast<T>(re);
00071 _im = static_cast<T>(im);
00072 }
00073
00076 ~Complex() {}
00077
00080 inline T& real() { return _re; }
00081
00084 inline T& imag() { return _im; }
00085
00088 inline const T& real() const { return _re; }
00089
00092 inline const T& imag() const { return _im; }
00093
00096 template <typename T2>
00097 const Complex<T>& operator=(const Complex<T2> &rhs)
00098 {
00099 _re = static_cast<T>(rhs.real());
00100 _im = static_cast<T>(rhs.imag());
00101 }
00102
00105 template <typename Tr>
00106 const Complex<T>& operator=(const Tr re)
00107 {
00108 _re = static_cast<T>(re);
00109 _im = 0;
00110 return *this;
00111 }
00112
00115 template <typename T2>
00116 Complex<T> operator+(const Complex<T2> &op2)
00117 {
00118 Complex<T> res;
00119 res._re = _re + static_cast<T>(op2._re);
00120 res._im = _im + static_cast<T>(op2._im);
00121
00122 return res;
00123 }
00124
00127 template <typename T2>
00128 Complex<T> operator+(const T2 &op2)
00129 {
00130 Complex<T> res;
00131 res._re = _re + static_cast<T>(op2);
00132 res._im = _im;
00133
00134 return res;
00135 }
00136
00139 template <typename T2>
00140 Complex<T> operator-(const Complex<T2> &op2)
00141 {
00142 Complex<T> res;
00143 res._re = _re - static_cast<T>(op2._re);
00144 res._im = _im - static_cast<T>(op2._im);
00145
00146 return res;
00147 }
00148
00151 template <typename T2>
00152 Complex<T> operator-(const T2 &op2)
00153 {
00154 Complex<T> res;
00155 res._re = _re - static_cast<T>(op2);
00156 res._im = _im;
00157
00158 return res;
00159 }
00160
00163 template <typename T2>
00164 Complex<T> operator*(const Complex<T2> &op2)
00165 {
00166 Complex<T> res;
00167 res._re = static_cast<T>(_re*op2._re - _im*op2._im);
00168 res._im = static_cast<T>(_re*op2._im + _im*op2._re);
00169
00170 return res;
00171 }
00172
00175 template <typename T2>
00176 Complex<T> operator*(const T2 &op2)
00177 {
00178 Complex<T> res;
00179 res._re = static_cast<T>(_re * op2);
00180 res._im = static_cast<T>(_im * op2);
00181
00182 return res;
00183 }
00184
00187 template <typename T2>
00188 Complex<T> operator/(const Complex<T2> &op2)
00189 {
00190 Complex<T> res = (*this)*op2.conj()/abs()/abs();
00191
00192 return res;
00193 }
00194
00197 template <typename T2>
00198 Complex<T> operator/(const T2 &op2)
00199 {
00200 Complex<T> res;
00201 res._re = static_cast<T>(_re/op2);
00202 res._im = static_cast<T>(_im/op2);
00203
00204 return res;
00205 }
00206
00209 double abs(void) const
00210 {
00211 return sqrt(_re*_re + _im*_im);
00212 }
00213
00216 Complex<T> conj(void) const
00217 {
00218 Complex<T> res;
00219 res._re = _re;
00220 res._im = -_im;
00221
00222 return res;
00223 }
00224
00225 private:
00226 T _re, _im;
00227 };
00228
00229 template <typename T>
00230 std::ostream& operator<<(const std::ostream &osobj, const Complex<T> &c)
00231 {
00232 if (c.imag() > 0)
00233 return (std::cout << c.real() << "+" << c.imag() << "i");
00234 else if (c.imag() == 0)
00235 return (std::cout << c.real());
00236 else
00237 return (std::cout << c.real() << c.imag() << "i");
00238 }
00239
00240 template <typename T>
00241 Complex<T> operator+(const int v, const Complex<T> c)
00242 {
00243 Complex<T> res;
00244 res.real() = static_cast<T>(v) + c.real();
00245 res.imag() = c.imag();
00246
00247 return res;
00248 }
00249
00250 template <typename T>
00251 Complex<T> operator-(const int v, const Complex<T> c)
00252 {
00253 Complex<T> res;
00254 res.real() = static_cast<T>(v) - c.real();
00255 res.imag() = 0-c.imag();
00256
00257 return res;
00258 }
00259
00260 template <typename T>
00261 Complex<T> operator*(const int v, const Complex<T> c)
00262 {
00263 Complex<T> res;
00264 res.real() = static_cast<T>(v) * c.real();
00265 res.imag() = static_cast<T>(v) * c.imag();
00266
00267 return res;
00268 }
00269
00270 template <typename T>
00271 Complex<T> operator/(const int v, const Complex<T> c)
00272 {
00273 Complex<T> res;
00274
00275 res = c.conj() * v / c.abs() / c.abs();
00276 return res;
00277 }
00278
00279 template <typename T>
00280 Complex<T> operator+(const unsigned int v, const Complex<T> c)
00281 {
00282 Complex<T> res;
00283 res.real() = static_cast<T>(v) + c.real();
00284 res.imag() = c.imag();
00285
00286 return res;
00287 }
00288
00289 template <typename T>
00290 Complex<T> operator-(const unsigned int v, const Complex<T> c)
00291 {
00292 Complex<T> res;
00293 res.real() = static_cast<T>(v) - c.real();
00294 res.imag() = 0-c.imag();
00295
00296 return res;
00297 }
00298
00299 template <typename T>
00300 Complex<T> operator*(const unsigned int v, const Complex<T> c)
00301 {
00302 Complex<T> res;
00303 res.real() = static_cast<T>(v) * c.real();
00304 res.imag() = static_cast<T>(v) * c.imag();
00305
00306 return res;
00307 }
00308
00309 template <typename T>
00310 Complex<T> operator/(const unsigned int v, const Complex<T> c)
00311 {
00312 Complex<T> res;
00313
00314 res = c.conj() * v / c.abs() / c.abs();
00315 return res;
00316 }
00317
00318 template <typename T>
00319 Complex<T> operator+(const short int v, const Complex<T> c)
00320 {
00321 Complex<T> res;
00322 res.real() = static_cast<T>(v) + c.real();
00323 res.imag() = c.imag();
00324
00325 return res;
00326 }
00327
00328 template <typename T>
00329 Complex<T> operator-(const short int v, const Complex<T> c)
00330 {
00331 Complex<T> res;
00332 res.real() = static_cast<T>(v) - c.real();
00333 res.imag() = 0-c.imag();
00334
00335 return res;
00336 }
00337
00338 template <typename T>
00339 Complex<T> operator*(const short int v, const Complex<T> c)
00340 {
00341 Complex<T> res;
00342 res.real() = static_cast<T>(v) * c.real();
00343 res.imag() = static_cast<T>(v) * c.imag();
00344
00345 return res;
00346 }
00347
00348 template <typename T>
00349 Complex<T> operator/(const short int v, const Complex<T> c)
00350 {
00351 Complex<T> res;
00352
00353 res = c.conj() * v / c.abs() / c.abs();
00354 return res;
00355 }
00356
00357 template <typename T>
00358 Complex<T> operator+(const long int v, const Complex<T> c)
00359 {
00360 Complex<T> res;
00361 res.real() = static_cast<T>(v) + c.real();
00362 res.imag() = c.imag();
00363
00364 return res;
00365 }
00366
00367 template <typename T>
00368 Complex<T> operator-(const long int v, const Complex<T> c)
00369 {
00370 Complex<T> res;
00371 res.real() = static_cast<T>(v) - c.real();
00372 res.imag() = 0-c.imag();
00373
00374 return res;
00375 }
00376
00377 template <typename T>
00378 Complex<T> operator*(const long int v, const Complex<T> c)
00379 {
00380 Complex<T> res;
00381 res.real() = static_cast<T>(v) * c.real();
00382 res.imag() = static_cast<T>(v) * c.imag();
00383
00384 return res;
00385 }
00386
00387 template <typename T>
00388 Complex<T> operator/(const long int v, const Complex<T> c)
00389 {
00390 Complex<T> res;
00391
00392 res = c.conj() * v / c.abs() / c.abs();
00393 return res;
00394 }
00395
00396 template <typename T>
00397 Complex<T> operator+(const float v, const Complex<T> c)
00398 {
00399 Complex<T> res;
00400 res.real() = static_cast<T>(v) + c.real();
00401 res.imag() = c.imag();
00402
00403 return res;
00404 }
00405
00406 template <typename T>
00407 Complex<T> operator-(const float v, const Complex<T> c)
00408 {
00409 Complex<T> res;
00410 res.real() = static_cast<T>(v) - c.real();
00411 res.imag() = 0-c.imag();
00412
00413 return res;
00414 }
00415
00416 template <typename T>
00417 Complex<T> operator*(const float v, const Complex<T> c)
00418 {
00419 Complex<T> res;
00420 res.real() = static_cast<T>(v) * c.real();
00421 res.imag() = static_cast<T>(v) * c.imag();
00422
00423 return res;
00424 }
00425
00426 template <typename T>
00427 Complex<T> operator/(const float v, const Complex<T> c)
00428 {
00429 Complex<T> res;
00430
00431 res = c.conj() * v / c.abs() / c.abs();
00432 return res;
00433 }
00434
00435 template <typename T>
00436 Complex<T> operator+(const double v, const Complex<T> c)
00437 {
00438 Complex<T> res;
00439 res.real() = static_cast<T>(v) + c.real();
00440 res.imag() = c.imag();
00441
00442 return res;
00443 }
00444
00445 template <typename T>
00446 Complex<T> operator-(const double v, const Complex<T> c)
00447 {
00448 Complex<T> res;
00449 res.real() = static_cast<T>(v) - c.real();
00450 res.imag() = 0-c.imag();
00451
00452 return res;
00453 }
00454
00455 template <typename T>
00456 Complex<T> operator*(const double v, const Complex<T> c)
00457 {
00458 Complex<T> res;
00459 res.real() = static_cast<T>(v) * c.real();
00460 res.imag() = static_cast<T>(v) * c.imag();
00461
00462 return res;
00463 }
00464
00465 template <typename T>
00466 Complex<T> operator/(const double v, const Complex<T> c)
00467 {
00468 Complex<T> res;
00469
00470 res = c.conj() * v / c.abs() / c.abs();
00471 return res;
00472 }
00473
00474 }
00475
00476 #endif // __SEAL_COMPLEX_H__
00477