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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef _LTI_COMPLEX_H
00041 #define _LTI_COMPLEX_H
00042
00043 #ifdef _LTI_MSC_6
00044 #pragma warning(disable:4275) // warnings for complex<T>
00045
00046
00047 #endif
00048
00049 #include "ltiMath.h"
00050 #include <complex>
00051 #include <iostream>
00052
00053 #ifdef _LTI_GNUC_2
00054 namespace std {
00055 typedef ios ios_base;
00056 }
00057 #endif
00058
00059 namespace lti {
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 template<typename T>
00075 class complex {
00076 public:
00077 typedef T value_type;
00078
00079
00080
00081
00082 complex(const T& = T(), const T & = T());
00083
00084
00085
00086
00087 template<class U>
00088 complex(const complex<U>& other)
00089 : realPart(static_cast<T>(other.realPart)),
00090 imagPart(static_cast<T>(other.imagPart)) {
00091 }
00092
00093
00094
00095
00096 complex(const std::complex<T>& other);
00097
00098
00099
00100
00101 operator std::complex<T>() {
00102 return std::complex<T>(real(),imag());
00103 }
00104
00105
00106
00107
00108 T real() const;
00109
00110
00111
00112
00113 T imag() const;
00114
00115
00116
00117
00118
00119 complex<T>& operator=(const T& other);
00120
00121
00122
00123
00124 complex<T>& operator+=(const T& other);
00125
00126
00127
00128
00129 complex<T>& operator-=(const T& other);
00130
00131
00132
00133
00134 complex<T>& operator*=(const T& other);
00135
00136
00137
00138
00139 complex<T>& operator/=(const T& other);
00140
00141
00142
00143
00144 template<typename U>
00145 complex<T>& operator=(const complex<U>& other) {
00146 realPart = other.realPart;
00147 imagPart = other.imagPart;
00148 return (*this);
00149 };
00150
00151
00152
00153
00154 template<typename U>
00155 complex<T>& operator+=(const complex<U>& other) {
00156 realPart+=static_cast<T>(other.realPart);
00157 imagPart+=static_cast<T>(other.imagPart);
00158 return (*this);
00159 }
00160
00161
00162
00163
00164 template<typename U>
00165 complex<T>& operator-=(const complex<U>& other) {
00166 realPart-=static_cast<T>(other.realPart);
00167 imagPart-=static_cast<T>(other.imagPart);
00168 return (*this);
00169 }
00170
00171
00172
00173
00174 template<typename U>
00175 complex<T>& operator*=(const complex<U>& other) {
00176 const T re = realPart * other.real() - imagPart * other.imag();
00177 imagPart = realPart * other.imag() + imagPart * other.real();
00178 realPart = re;
00179 return *this;
00180 }
00181
00182
00183
00184
00185 template<typename U>
00186 complex<T>& operator/=(const complex<U>& other) {
00187 const T norm = other.real()*other.real() + other.imag()*other.imag();
00188 const T re = (realPart * other.real() + imagPart * other.imag())/norm;
00189 imagPart = (imagPart * other.real() - realPart * other.imag())/norm;
00190 realPart = re;
00191 return *this;
00192 }
00193
00194 private:
00195
00196
00197
00198 T realPart;
00199
00200
00201
00202
00203 T imagPart;
00204 };
00205
00206
00207
00208
00209
00210 template<typename T>
00211 inline T complex<T>::real() const {
00212 return realPart;
00213 }
00214
00215 template<typename T>
00216 inline T complex<T>::imag() const {
00217 return imagPart;
00218 }
00219
00220 template<typename T>
00221 inline complex<T>::complex(const T& re, const T& im)
00222 : realPart(re), imagPart(im) { }
00223
00224 template<typename T>
00225 inline complex<T>::complex(const std::complex<T>& other)
00226 : realPart(other.real()), imagPart(other.imag()) { }
00227
00228 template<typename T>
00229 complex<T>& complex<T>::operator=(const T& other) {
00230 realPart = other;
00231 imagPart = T();
00232 return *this;
00233 }
00234
00235 template<typename T>
00236 inline complex<T>& complex<T>::operator+=(const T& other) {
00237 realPart += other;
00238 return *this;
00239 }
00240
00241 template<typename T>
00242 inline complex<T>& complex<T>::operator-=(const T& other) {
00243 realPart -= other;
00244 return *this;
00245 }
00246
00247 template<typename T>
00248 complex<T>& complex<T>::operator*=(const T& other) {
00249 realPart *= other;
00250 imagPart *= other;
00251 return *this;
00252 }
00253
00254 template<typename T>
00255 complex<T>& complex<T>::operator/=(const T& other) {
00256 realPart /= other;
00257 imagPart /= other;
00258 return *this;
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 template<typename T>
00276 inline complex<T> operator+(const complex<T>& a, const complex<T>& b) {
00277 return complex<T>(a) += b;
00278 }
00279
00280
00281
00282
00283 template<typename T>
00284 inline complex<T> operator+(const complex<T>& a, const T& b) {
00285 return complex<T>(a) += b;
00286 }
00287
00288
00289
00290
00291 template<typename T>
00292 inline complex<T> operator+(const T& a, const complex<T>& b) {
00293 return complex<T>(b) += a;
00294 }
00295
00296
00297
00298
00299 template<typename T>
00300 inline complex<T> operator-(const complex<T>& a, const complex<T>& b) {
00301 return complex<T>(a) -= b;
00302 }
00303
00304
00305
00306
00307 template<typename T>
00308 inline complex<T> operator-(const complex<T>& a, const T& b) {
00309 return complex<T>(a) -= b;
00310 }
00311
00312
00313
00314
00315 template<typename T>
00316 inline complex<T> operator-(const T& a, const complex<T>& b) {
00317 return complex<T>(a) -= b;
00318 }
00319
00320
00321
00322
00323 template<typename T>
00324 inline complex<T> operator*(const complex<T>& a, const complex<T>& b) {
00325 return complex<T>(a) *= b;
00326 }
00327
00328
00329
00330
00331 template<typename T>
00332 inline complex<T> operator*(const complex<T>& a, const T& b) {
00333 return complex<T>(a) *= b;
00334 }
00335
00336
00337
00338
00339 template<typename T>
00340 inline complex<T> operator*(const T& a, const complex<T>& b) {
00341 return complex<T>(b) *= a;
00342 }
00343
00344
00345
00346
00347 template<typename T>
00348 inline complex<T> operator/(const complex<T>& a, const complex<T>& b) {
00349 return complex<T>(a) /= b;
00350 }
00351
00352
00353
00354
00355 template<typename T>
00356 inline complex<T> operator/(const complex<T>& a, const T& b) {
00357 return complex<T>(a) /= b;
00358 }
00359
00360
00361
00362
00363 template<typename T>
00364 inline complex<T> operator/(const T& a, const complex<T>& b) {
00365 return complex<T>(a) /= b;
00366 }
00367
00368
00369
00370
00371 template<typename T>
00372 inline complex<T> operator+(const complex<T>& a) {
00373 return a;
00374 }
00375
00376
00377
00378
00379 template<typename T>
00380 inline complex<T> operator-(const complex<T>& a) {
00381 return complex<T>(-a.real(), -a.imag());
00382 }
00383
00384
00385
00386
00387 template<typename T>
00388 inline bool operator==(const complex<T>& a, const complex<T>& b) {
00389 return (a.real() == b.real()) && (a.imag() == b.imag());
00390 }
00391
00392
00393
00394
00395 template<typename T>
00396 inline bool operator==(const complex<T>& a, const T& b) {
00397 return (a.real() == b) && (a.imag() == T());
00398 }
00399
00400
00401
00402
00403 template<typename T>
00404 inline bool operator==(const T& a, const complex<T>& b) {
00405 return (a == b.real()) && (T() == b.imag());
00406 }
00407
00408
00409
00410
00411 template<typename T>
00412 inline bool operator!=(const complex<T>& a, const complex<T>& b) {
00413 return (a.real() != b.real()) || (a.imag() != b.imag());
00414 }
00415
00416
00417
00418
00419 template<typename T>
00420 inline bool operator!=(const complex<T>& a, const T& b) {
00421 return (a.real() != b) || (a.imag() != T());
00422 }
00423
00424
00425
00426
00427 template<typename T>
00428 inline bool operator!=(const T& a, const complex<T>& b) {
00429 return (a != b.real()) || (T() != b.imag());
00430 }
00431
00432
00433
00434
00435
00436
00437 template<typename T>
00438 inline bool operator<(const complex<T>& a,const complex<T>& b) {
00439 return ((a.real()<b.real()) ||
00440 ((a.real() == b.real()) && (a.imag() < b.imag())));
00441 }
00442
00443
00444
00445
00446
00447
00448 template<typename T>
00449 inline bool operator<(const complex<T>& a,const T& b) {
00450 return ((a.real()<b) ||
00451 ((a.real() == b) && (a.imag() < T())));
00452 }
00453
00454
00455
00456
00457
00458
00459 template<typename T>
00460 inline bool operator<(const T& a,const complex<T>& b) {
00461 return ((a<b.real()) ||
00462 ((a == b.real()) && (T() < b.imag())));
00463 }
00464
00465
00466
00467
00468
00469
00470 template<typename T>
00471 inline bool operator>(const complex<T>& a,const complex<T>& b) {
00472 return ((a.real()>b.real()) ||
00473 ((a.real() == b.real()) && (a.imag() > b.imag())));
00474 }
00475
00476
00477
00478
00479
00480
00481 template<typename T>
00482 inline bool operator>(const complex<T>& a,const T& b) {
00483 return ((a.real()>b) ||
00484 ((a.real() == b) && (a.imag() > T())));
00485 }
00486
00487
00488
00489
00490
00491
00492 template<typename T>
00493 inline bool operator>(const T& a,const complex<T>& b) {
00494 return ((a > b.real()) ||
00495 ( (a == b.real()) && ( b.imag() < T(0) ) ));
00496 }
00497
00498
00499
00500
00501 template<typename T>
00502 inline T real(const complex<T>& cn) {
00503 return cn.real();
00504 }
00505
00506
00507
00508
00509 template<typename T>
00510 inline T imag(const complex<T>& cn) {
00511 return cn.imag();
00512 }
00513
00514
00515
00516
00517 template<typename T>
00518 inline T abs(const complex<T>& cn) {
00519 T a = cn.real();
00520 T b = cn.imag();
00521
00522 const T tmp = max(abs(a), abs(b));
00523 if (tmp == T()) {
00524 return tmp;
00525 }
00526
00527 a /= tmp;
00528 b /= tmp;
00529 return tmp * sqrt(a * a + b * b);
00530 }
00531
00532
00533
00534
00535 template<typename T>
00536 inline T arg(const complex<T>& cn) {
00537 return atan2(cn.imag(), cn.real());
00538 }
00539
00540
00541
00542
00543
00544 template<typename T>
00545 inline T norm(const complex<T>& cn) {
00546 const T a(cn.real),b(cn.imag());
00547 return (a*a+b*b);
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 template<typename T>
00559 inline complex<T> polar(const T& radius, const T& angle) {
00560 return complex<T>(radius * cos(angle), radius * sin(angle));
00561 }
00562
00563
00564
00565
00566 template<typename T>
00567 inline complex<T> conj(const complex<T>& cn) {
00568 return complex<T>(cn.real(), -cn.imag());
00569 }
00570
00571
00572
00573
00574 template<typename T>
00575 inline complex<T> cos(const complex<T>& cn) {
00576 const T a = cn.real();
00577 const T b = cn.imag();
00578 return complex<T>(cos(a) * std::cosh(b), -sin(a) * std::sinh(b));
00579 }
00580
00581
00582
00583
00584 template<typename T>
00585 inline complex<T> cosh(const complex<T>& cn) {
00586 const T a = cn.real();
00587 const T b = cn.imag();
00588 return complex<T>(std::cosh(a) * cos(b), std::sinh(a) * sin(b));
00589 }
00590
00591 template<typename T>
00592 inline complex<T> acos(const complex<T>& cn) {
00593 complex<T> tmp(log(cn+sqrt(cn*cn-T(1))));
00594 return complex<T>(tmp.imag(),-tmp.real());;
00595 }
00596
00597
00598
00599
00600 template<typename T>
00601 inline complex<T> exp(const complex<T>& cn) {
00602 return polar(exp(cn.real()), cn.imag());
00603 }
00604
00605
00606
00607
00608 template<typename T>
00609 inline complex<T> log(const complex<T>& cn) {
00610 return complex<T>(log(abs(cn)), arg(cn));
00611 }
00612
00613
00614
00615
00616 template<typename T>
00617 inline complex<T> log10(const complex<T>& cn) {
00618 return log(cn) / log(T(10.0));
00619 }
00620
00621
00622
00623
00624 template<typename T>
00625 inline complex<T> sin(const complex<T>& cn) {
00626 const T a = cn.real();
00627 const T b = cn.imag();
00628 return complex<T>(sin(a) * std::cosh(b), cos(a) * std::sinh(b));
00629 }
00630
00631
00632
00633
00634 template<typename T>
00635 inline complex<T> sinh(const complex<T>& cn) {
00636 const T a = cn.real();
00637 const T b = cn.imag();
00638 return complex<T>(std::sinh(a) * cos(b), std::cosh(a) * sin(b));
00639 }
00640
00641 template<typename T>
00642 inline complex<T> asin(const complex<T>& cn) {
00643 complex<T> tmp(log(complex<T>(-cn.imag(),cn.real())+sqrt(1-cn*cn)));
00644 return complex<T>(tmp.imag(),-tmp.real());;
00645 }
00646
00647
00648
00649
00650
00651
00652
00653 template<typename T>
00654 complex<T> sqrt(const complex<T>& cn) {
00655 T a = cn.real();
00656 T b = cn.imag();
00657
00658 if (a == T()) {
00659 T other = sqrt(abs(b) / 2);
00660 return complex<T>(other, b < T() ? -other : other);
00661 }
00662 else {
00663 T other = sqrt(2 * (abs(cn) + abs(a)));
00664 T tmp = other / 2;
00665 return (a > T()) ?
00666 complex<T>(tmp, b / other)
00667 : complex<T>(abs(b) / other, b < T() ? -tmp : tmp);
00668 }
00669 }
00670
00671
00672
00673
00674
00675
00676
00677 template<typename T>
00678 inline complex<T> cbrt(const complex<T>& cn) {
00679 const T m = abs(cn);
00680 const T a = arg(cn);
00681 return polar(pow(double(m),1.0/3.0),m/3.0);
00682 }
00683
00684
00685
00686
00687 template<typename T>
00688 inline complex<T> cubeRoot(const complex<T>& cn) {
00689 return cbrt(cn);
00690 }
00691
00692
00693
00694
00695 template<typename T>
00696 inline complex<T> tan(const complex<T>& cn) {
00697 return sin(cn) / cos(cn);
00698 }
00699
00700
00701
00702
00703 template<typename T>
00704 inline complex<T> tanh(const complex<T>& cn) {
00705 return std::sinh(cn) / std::cosh(cn);
00706 }
00707
00708
00709
00710
00711 template<typename T>
00712 inline complex<T> atan(const complex<T>& cn) {
00713 return log((complex<T>(1)+complex<T>(-cn.real(),cn.imag()))/
00714 (complex<T>(1)-complex<T>(-cn.real(),cn.imag())))/
00715 (complex<T>(0,2));
00716 }
00717
00718
00719
00720
00721 template<typename T>
00722 inline complex<T> pow(const complex<T>& a, const T& b) {
00723 return exp(b * log(a));
00724 }
00725
00726
00727
00728
00729 template<typename T>
00730 inline complex<T> pow(const complex<T>& a, const complex<T>& b) {
00731 return exp(b * log(a));
00732 }
00733
00734
00735
00736
00737 template<typename T>
00738 inline complex<T> pow(const T& a, const complex<T>& b) {
00739 return exp(b * log(a));
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 template <typename T>
00749 bool read(ioHandler& handler,complex<T>& p,const bool complete=true) {
00750 bool b(true);
00751
00752 if (complete) {
00753 b = b && handler.readBegin();
00754 }
00755
00756 T re,im;
00757 b = b && handler.read(re);
00758 b = b && handler.readDataSeparator();
00759 b = b && handler.read(im);
00760
00761 p=complex<T>(re,im);
00762
00763 if (complete) {
00764 b = b && handler.readEnd();
00765 }
00766
00767 return b;
00768 };
00769
00770
00771
00772
00773
00774
00775
00776 template<typename T>
00777 bool write(ioHandler& handler,const complex<T>& p,const bool complete=true) {
00778 bool b(true);
00779
00780 if (complete) {
00781 b = b && handler.writeBegin();
00782 }
00783
00784 b = b && handler.write(p.real());
00785 b = b && handler.writeDataSeparator();
00786 b = b && handler.write(p.imag());
00787
00788 if (complete) {
00789 b = b && handler.writeEnd();
00790 }
00791
00792 return b;
00793 };
00794
00795 }
00796
00797 namespace std {
00798
00799 template<typename T>
00800 inline istream& operator>>(istream& in, lti::complex<T>& a) {
00801 T re, im;
00802 char ch;
00803 in >> ch;
00804 if (ch == '(') {
00805 in >> re >> ch;
00806 if (ch == ',') {
00807 in >> im >> ch;
00808 if (ch == ')') {
00809 a = lti::complex<T>(re, im);
00810 } else {
00811 in.setstate(ios_base::failbit);
00812 }
00813 }
00814 else if (ch == ')') {
00815 a = lti::complex<T>(re, T(0));
00816 } else {
00817 in.setstate(ios_base::failbit);
00818 }
00819 }
00820 else {
00821 in.putback(ch);
00822 in >> re;
00823 a = lti::complex<T>(re, T(0));
00824 }
00825 return in;
00826 }
00827
00828 template<typename T>
00829 inline ostream& operator<<(ostream& out, const lti::complex<T>& a) {
00830 out << '(' << a.real() << ',' << a.imag() << ')';
00831 return out;
00832 }
00833
00834 }
00835
00836 #endif