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