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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #ifndef esve_math_complex_hxx
00051 #define esve_math_complex_hxx
00052
00053 #if defined(USE_STD_COMPLEX)
00054
00055 #include <complex>
00056
00057 namespace esve { namespace math {
00058 namespace complex_namespace { using std::complex ; }
00059 using complex_namespace::complex ;
00060 }}
00061
00062 #elif !defined(USE_STD_COMPLEX)
00063
00064 #include <istream>
00065 #include <ostream>
00066 #include <cmath>
00067
00068 namespace esve { namespace math {
00069
00070 namespace complex_namespace {
00071
00072 template<typename F> class complex ;
00073
00074 template<typename F> F real( const complex<F> & ) ;
00075 template<typename F> F imag( const complex<F> & ) ;
00076 template<typename F> F norm( const complex<F> & ) ;
00077 template<typename F> F abs( const complex<F> & ) ;
00078
00079 template<typename F> F arg( const complex<F> & ) ;
00080 template<typename F> complex<F> polar( F r, F theta ) ;
00081
00082 template<typename F> complex<F> conj( const complex<F> & ) ;
00083 template<typename F> complex<F> inv( const complex<F> & ) ;
00084
00085 template<typename F> F dot( const complex<F> &, const complex<F> & ) ;
00086 template<typename F> F dot( const complex<F> &, F ) ;
00087 template<typename F> F dot( F, const complex<F> & ) ;
00088
00089 template<typename F> complex<F> exp( const complex<F> & ) ;
00090 template<typename F> complex<F> log( const complex<F> & ) ;
00091
00092 template<typename F> complex<F> cos( const complex<F> & ) ;
00093 template<typename F> complex<F> sin( const complex<F> & ) ;
00094 template<typename F> complex<F> tan( const complex<F> & ) ;
00095 template<typename F> complex<F> cosh( const complex<F> & ) ;
00096 template<typename F> complex<F> sinh( const complex<F> & ) ;
00097 template<typename F> complex<F> tanh( const complex<F> & ) ;
00098
00099 template<typename F> complex<F> pow( const complex<F> &, const complex<F> & ) ;
00100 template<typename F> complex<F> pow( const complex<F> &, unsigned int ) ;
00101 template<typename F> complex<F> pow( const complex<F> &, int ) ;
00102 template<typename F> complex<F> pow( const complex<F> &, F ) ;
00103 template<typename F> complex<F> pow( F, const complex<F> & ) ;
00104
00105 template<typename F> complex<F> sqrt( const complex<F> & ) ;
00106
00107 template<typename F> complex<F> operator+( const complex<F> &,
00108 const complex<F> & ) ;
00109 template<typename F> complex<F> operator+( const complex<F> &, F ) ;
00110 template<typename F> complex<F> operator+( F, const complex<F> & ) ;
00111
00112 template<typename F> const complex<F> & operator+( const complex<F> & ) ;
00113
00114 template<typename F> complex<F> operator-( const complex<F> &,
00115 const complex<F> & ) ;
00116 template<typename F> complex<F> operator-( const complex<F> &, F ) ;
00117 template<typename F> complex<F> operator-( F, const complex<F> & ) ;
00118
00119 template<typename F> complex<F> operator-( const complex<F> & ) ;
00120
00121 template<typename F> complex<F> operator*( const complex<F> &,
00122 const complex<F> & ) ;
00123 template<typename F> complex<F> operator*( const complex<F> &, F ) ;
00124 template<typename F> complex<F> operator*( F, const complex<F> & ) ;
00125
00126 template<typename F> complex<F> operator/( const complex<F> &,
00127 const complex<F> & ) ;
00128 template<typename F> complex<F> operator/( F, const complex<F> & ) ;
00129 template<typename F> complex<F> operator/( const complex<F> &, F ) ;
00130
00131 template<typename F> bool operator==( const complex<F> &,
00132 const complex<F> & ) ;
00133 template<typename F> bool operator==( const complex<F> &, F ) ;
00134 template<typename F> bool operator==( F, const complex<F> & ) ;
00135
00136 template<typename F> bool operator!=( const complex<F> &,
00137 const complex<F> & ) ;
00138 template<typename F> bool operator!=( const complex<F> &, F ) ;
00139 template<typename F> bool operator!=( F, const complex<F> & ) ;
00140
00141 template< typename F, typename T_Char, typename T_Traits >
00142 std::basic_ostream<T_Char, T_Traits> &
00143 operator<<( std::basic_ostream<T_Char, T_Traits> & , const complex<F> & ) ;
00144
00145 template< typename F, typename T_Char, typename T_Traits >
00146 std::basic_istream<T_Char, T_Traits> &
00147 operator>>( std::basic_istream<T_Char, T_Traits> & , complex<F> & ) ;
00148
00149 namespace scalar_func {
00150 template< typename F > F real( F a ) ;
00151 template< typename F > F imag( F a ) ;
00152 template< typename F > F norm( F a ) ;
00153 template< typename F > F conj( F a ) ;
00154 template< typename F > F inv( F a ) ;
00155 template< typename F > F dot( F a, F b ) ;
00156 using std::abs ;
00157 using std::exp ;
00158 using std::log ;
00159 using std::cos ;
00160 using std::sin ;
00161 using std::cosh ;
00162 using std::sinh ;
00163 using std::pow ;
00164 using std::sqrt ;
00165 using std::atan2 ;
00166 }
00167
00168 template< typename F >
00169 class complex
00170 {
00171 public:
00172 typedef F value_type ;
00173
00174 complex() ;
00175 complex( F , F ) ;
00176 explicit complex( F ) ;
00177
00178 F real() const ;
00179 F imag() const ;
00180
00181 complex & operator+=( const complex & ) ;
00182 complex & operator+=( F ) ;
00183
00184 complex & operator-=( const complex & ) ;
00185 complex & operator-=( F ) ;
00186
00187 complex & operator*=( const complex & ) ;
00188 complex & operator*=( F ) ;
00189
00190 complex & operator/=( F ) ;
00191 complex & operator/=( const complex & ) ;
00192
00193 const F* data() const ;
00194
00195 private:
00196 F mw ;
00197 F mx ;
00198 } ;
00199
00201
00202
00203
00205
00207
00209
00210 template< typename F >
00211 inline
00212 F real( const complex<F> & a )
00213 {
00214 return a.real() ;
00215 }
00216
00218
00220
00221 template< typename F >
00222 inline
00223 F imag( const complex<F> & a )
00224 {
00225 return a.imag() ;
00226 }
00227
00229
00231
00232 template< typename F >
00233 inline
00234 F norm( const complex<F> & a )
00235 {
00236 return
00237 a.real()*a.real() +
00238 a.imag()*a.imag() ;
00239 }
00240
00242
00244
00245 template< typename F >
00246 inline
00247 F abs( const complex<F> & a )
00248 {
00249 return scalar_func::sqrt(norm(a)) ;
00250 }
00251
00253
00255
00256 template< typename F >
00257 inline
00258 complex<F> exp( const complex<F> & a )
00259 {
00260 const F exp_realpart_a = scalar_func::exp(a.real()) ;
00261
00262 return complex<F>(exp_realpart_a*scalar_func::cos(a.imag()),
00263 exp_realpart_a*scalar_func::sin(a.imag())) ;
00264 }
00265
00267
00269
00270 template< typename F >
00271 inline
00272 complex<F> log( const complex<F> & a )
00273 {
00274 return complex<F>(scalar_func::log(abs(a)),
00275 scalar_func::atan2(a.imag(), a.real())) ;
00276 }
00277
00279
00281
00282 template< typename F >
00283 inline
00284 F arg( const complex<F> & a )
00285 {
00286 return scalar_func::atan2(a.imag(), a.real()) ;
00287 }
00288
00290
00292
00293 template< typename F >
00294 inline
00295 complex<F> polar( F r, F theta )
00296 {
00297 return complex<F>(r*scalar_func::cos(theta),
00298 r*scalar_func::sin(theta)) ;
00299 }
00300
00302
00304
00305 template< typename F >
00306 inline
00307 complex<F> cos( const complex<F> & a )
00308 {
00309 return complex<F>(scalar_func::cos(a.real())
00310 *
00311 scalar_func::cosh(a.imag()),
00312
00313 -scalar_func::sin(a.real())
00314 *
00315 scalar_func::sinh(a.imag())) ;
00316 }
00317
00318 template< typename F >
00319 inline
00320 complex<F> sin( const complex<F> & a )
00321 {
00322 return complex<F>(scalar_func::sin(a.real())
00323 *
00324 scalar_func::cosh(a.imag()),
00325
00326 scalar_func::cos(a.real())
00327 *
00328 scalar_func::sinh(a.imag())) ;
00329 }
00330
00331 template< typename F >
00332 inline
00333 complex<F> tan( const complex<F> & a )
00334 {
00335 return sin(a)/cos(a) ;
00336 }
00337
00338 template< typename F >
00339 inline
00340 complex<F> cosh( const complex<F> & a )
00341 {
00342 return complex<F>(scalar_func::cosh(a.real())
00343 *
00344 scalar_func::cos(a.imag()),
00345
00346 scalar_func::sinh(a.real())
00347 *
00348 scalar_func::sin(a.imag())) ;
00349 }
00350
00351 template< typename F >
00352 inline
00353 complex<F> sinh( const complex<F> & a )
00354 {
00355 return complex<F>(scalar_func::sinh(a.real())
00356 *
00357 scalar_func::cos(a.imag()),
00358
00359 scalar_func::cosh(a.real())
00360 *
00361 scalar_func::sin(a.imag())) ;
00362 }
00363
00364 template< typename F >
00365 inline
00366 complex<F> tanh( const complex<F> & a )
00367 {
00368 return sinh(a)/cosh(a) ;
00369 }
00370
00372
00374
00375 template< typename F >
00376 complex<F> pow( const complex<F> & a, F gamma )
00377 {
00378 if( a.imag() == F() )
00379 {
00380 return complex<F>(scalar_func::pow(a.real(), gamma)) ;
00381 }
00382
00383 const complex<F> log_a = log(a) ;
00384 const F r = scalar_func::exp(gamma*log_a.real()) ;
00385 const F theta = gamma*log_a.imag() ;
00386
00387 return complex<F>(r*scalar_func::cos(theta),
00388 r*scalar_func::sin(theta)) ;
00389 }
00390
00391 template< typename F >
00392 complex<F> pow( const complex<F> & a, unsigned int n )
00393 {
00394 complex<F> b = (n % 2) ? a : complex<F>(F(1)) ;
00395 complex<F> c = a ;
00396
00397 while( n >>= 1 )
00398 {
00399 c = c*c ;
00400 if( n % 2 == 1 )
00401 {
00402 b = c*b ;
00403 }
00404 }
00405
00406 return b ;
00407 }
00408
00409 template< typename F >
00410 inline
00411 complex<F> pow( const complex<F> & a, int n )
00412 {
00413 typedef unsigned int uint ;
00414
00415 return n >= 0 ? pow(a, uint(n)) : inv(pow(a, uint(-n))) ;
00416 }
00417
00418 template< typename F >
00419 inline
00420 complex<F> pow( F gamma, const complex<F> & a )
00421 {
00422 return gamma == F() ? complex<F>(F()) : exp(scalar_func::log(gamma)*a) ;
00423 }
00424
00425 template< typename F >
00426 inline
00427 complex<F> pow( const complex<F> & a, const complex<F> & b )
00428 {
00429 return a == F() ? F() : exp(b*log(a)) ;
00430 }
00431
00433
00435
00436 template< typename F >
00437 inline
00438 complex<F> sqrt( const complex<F> & a )
00439 {
00440 return pow(a, F(0.5)) ;
00441 }
00442
00444
00446
00447 template< typename F >
00448 inline
00449 complex<F> conj( const complex<F> & a )
00450 {
00451 return complex<F>(a.real(),
00452 -a.imag()) ;
00453 }
00454
00456
00458
00459 template< typename F >
00460 inline
00461 complex<F> inv( const complex<F> & a )
00462 {
00463 const F norm_a = norm(a) ;
00464
00465 return complex<F>(a.real()/norm_a,
00466 -a.imag()/norm_a) ;
00467 }
00468
00470
00472
00473 template< typename F >
00474 inline
00475 F dot( const complex<F> & a, const complex<F> & b )
00476 {
00477 return
00478 a.real()*b.real() +
00479 a.imag()*b.imag() ;
00480 }
00481
00482 template< typename F >
00483 inline
00484 F dot( F a, const complex<F> & b )
00485 {
00486 return a*b.real() ;
00487 }
00488
00489 template< typename F >
00490 inline
00491 F dot( const complex<F> & a, F b )
00492 {
00493 return a.real()*b ;
00494 }
00495
00497
00499
00500 template< typename F >
00501 inline
00502 bool operator==( const complex<F> & a, const complex<F> & b )
00503 {
00504 return
00505 a.real() == b.real() &&
00506 a.imag() == b.imag() ;
00507 }
00508
00509 template< typename F >
00510 inline
00511 bool operator==( F a, const complex<F> & b )
00512 {
00513 return
00514 a == b.real() &&
00515 F() == b.imag() ;
00516 }
00517
00518 template< typename F >
00519 inline
00520 bool operator==( const complex<F> & a, F b )
00521 {
00522 return
00523 a.real() == b &&
00524 a.imag() == F() ;
00525 }
00526
00528
00530
00531 template< typename F >
00532 inline
00533 bool operator!=( const complex<F> & a, const complex<F> & b )
00534 {
00535 return !(a == b) ;
00536 }
00537
00538 template< typename F >
00539 inline
00540 bool operator!=( const complex<F> & a, F b )
00541 {
00542 return !(a == b) ;
00543 }
00544
00545 template< typename F >
00546 inline
00547 bool operator!=( F a, const complex<F> & b )
00548 {
00549 return !(a == b) ;
00550 }
00551
00553
00555
00556 template< typename F >
00557 inline
00558 complex<F> operator+( const complex<F> & a, const complex<F> & b )
00559 {
00560 return complex<F>(a.real() + b.real(),
00561 a.imag() + b.imag()) ;
00562 }
00563
00564 template< typename F >
00565 inline
00566 complex<F> operator+( F a, const complex<F> & b )
00567 {
00568 return complex<F>(a + b.real(),
00569 b.imag()) ;
00570 }
00571
00572 template< typename F >
00573 inline
00574 complex<F> operator+( const complex<F> & a, F b )
00575 {
00576 return complex<F>(a.real() + b,
00577 a.imag()) ;
00578 }
00579
00580 template< typename F >
00581 inline
00582 const complex<F> & operator+( const complex<F> & a )
00583 {
00584 return a ;
00585 }
00586
00588
00590
00591 template< typename F >
00592 inline
00593 complex<F> operator-( const complex<F> & a, const complex<F> & b )
00594 {
00595 return complex<F>(a.real() - b.real(),
00596 a.imag() - b.imag()) ;
00597 }
00598
00599 template< typename F >
00600 inline
00601 complex<F> operator-( F a, const complex<F> & b )
00602 {
00603 return complex<F>(a - b.real(),
00604 - b.imag()) ;
00605 }
00606
00607 template< typename F >
00608 inline
00609 complex<F> operator-( const complex<F> & a, F b )
00610 {
00611 return complex<F>(a.real() - b,
00612 a.imag()) ;
00613 }
00614
00615 template< typename F >
00616 inline
00617 complex<F> operator-( const complex<F> & a )
00618 {
00619 return complex<F>(-a.real(),
00620 -a.imag()) ;
00621 }
00622
00624
00626
00627 template< typename F >
00628 inline
00629 complex<F> operator*( const complex<F> & a, const complex<F> & b )
00630 {
00631 return complex<F>(a.real()*b.real() - a.imag()*b.imag(),
00632 a.real()*b.imag() + a.imag()*b.real()) ;
00633 }
00634
00635 template< typename F >
00636 inline
00637 complex<F> operator*( F a, const complex<F> & b )
00638 {
00639 return complex<F>(a*b.real(),
00640 a*b.imag()) ;
00641 }
00642
00643 template< typename F >
00644 inline
00645 complex<F> operator*( const complex<F> & a, F b )
00646 {
00647 return complex<F>(a.real()*b,
00648 a.imag()*b) ;
00649 }
00650
00652
00654
00655 template< typename F >
00656 inline
00657 complex<F> operator/( const complex<F> & a, const complex<F> & b )
00658 {
00659 const F norm_b = norm(b) ;
00660
00661 return complex<F>((a.real()*b.real() + a.imag()*b.imag())/norm_b,
00662 (a.imag()*b.real() - a.real()*b.imag())/norm_b) ;
00663 }
00664
00665 template< typename F >
00666 inline
00667 complex<F> operator/( const complex<F> & a, F b )
00668 {
00669 return complex<F>(a.real()/b,
00670 a.imag()/b) ;
00671 }
00672
00673 template< typename F >
00674 inline
00675 complex<F> operator/( F a, const complex<F> & b )
00676 {
00677 const F t = a/norm(b) ;
00678
00679 return complex<F>( t*b.real(),
00680 -t*b.imag()) ;
00681 }
00682
00684
00685
00686
00688
00690
00692
00693 template< typename F >
00694 inline
00695 complex<F>::
00696 complex()
00697 : mw(F()),
00698 mx(F())
00699 {
00700 }
00701
00702 template< typename F >
00703 inline
00704 complex<F>::
00705 complex( F w, F x )
00706 : mw(w),
00707 mx(x)
00708 {
00709 }
00710
00711 template< typename F >
00712 inline
00713 complex<F>::
00714 complex( F w )
00715 : mw(w),
00716 mx(F())
00717 {
00718 }
00719
00721
00723
00724 template< typename F >
00725 inline
00726 F
00727 complex<F>::
00728 real() const
00729 {
00730 return mw ;
00731 }
00732
00733 template< typename F >
00734 inline
00735 F
00736 complex<F>::
00737 imag() const
00738 {
00739 return mx ;
00740 }
00741
00743
00745
00746 template< typename F >
00747 inline
00748 complex<F> &
00749 complex<F>::
00750 operator+=( const complex & a )
00751 {
00752 mw += a.real() ;
00753 mx += a.imag() ;
00754 return *this ;
00755 }
00756
00757 template< typename F >
00758 inline
00759 complex<F> &
00760 complex<F>::
00761 operator+=( F a )
00762 {
00763 mw += a ;
00764 return *this ;
00765 }
00766
00768
00770
00771 template< typename F >
00772 inline
00773 complex<F> &
00774 complex<F>::
00775 operator-=( const complex & a )
00776 {
00777 mw -= a.real() ;
00778 mx -= a.imag() ;
00779 return *this ;
00780 }
00781
00782 template< typename F >
00783 inline
00784 complex<F> &
00785 complex<F>::
00786 operator-=( F a )
00787 {
00788 mw -= a ;
00789 return *this ;
00790 }
00791
00793
00795
00796 template< typename F >
00797 inline
00798 complex<F> &
00799 complex<F>::
00800 operator*=( const complex & b )
00801 {
00802 const F x = mw*b.imag() + mx*b.real() ;
00803 mw = mw*b.real() - mx*b.imag() ;
00804 mx = x ;
00805 return *this ;
00806 }
00807
00808 template< typename F >
00809 inline
00810 complex<F> &
00811 complex<F>::
00812 operator*=( F a )
00813 {
00814 mw *= a ;
00815 mx *= a ;
00816 return *this ;
00817 }
00818
00820
00822
00823 template< typename F >
00824 inline
00825 complex<F> &
00826 complex<F>::
00827 operator/=( F a )
00828 {
00829 mw /= a ;
00830 mx /= a ;
00831 return *this ;
00832 }
00833
00834 template< typename F >
00835 inline
00836 complex<F> &
00837 complex<F>::
00838 operator/=( const complex & b )
00839 {
00840 const F norm_b = norm(b) ;
00841 const F x = mx*b.real() - mw*b.imag() ;
00842
00843 mw = (mw*b.real() + mx*b.imag())/norm_b ;
00844 mx = x/norm_b ;
00845
00846 return *this ;
00847 }
00848
00850
00852
00853 template< typename F >
00854 inline
00855 const F*
00856 complex<F>::
00857 data() const
00858 {
00859 return &mw ;
00860 }
00861
00863
00865
00866 template< typename F, typename T_Char, typename T_Traits >
00867 std::basic_ostream<T_Char, T_Traits> &
00868 operator<<( std::basic_ostream<T_Char, T_Traits> & out, const complex<F> & a )
00869 {
00870 out << '('
00871 << a.real()
00872 << ','
00873 << a.imag()
00874 << ')' ;
00875
00876 return out ;
00877 }
00878
00879 template< typename F, typename T_Char, typename T_Traits >
00880 std::basic_istream<T_Char, T_Traits> &
00881 operator>>( std::basic_istream<T_Char, T_Traits> & in, complex<F> & a )
00882 {
00883 T_Char ch ;
00884 F w ;
00885 F x ;
00886
00887 ch = 0 ;
00888 in >> ch ;
00889 if( ch != '(' )
00890 {
00891 in.setstate(std::ios_base::failbit) ;
00892 return in ;
00893 }
00894
00895 ch = 0 ;
00896 in >> w >> ch ;
00897 if( ch != ',' )
00898 {
00899 in.setstate(std::ios_base::failbit) ;
00900 return in ;
00901 }
00902
00903 ch = 0 ;
00904 in >> x >> ch ;
00905 if( ch != ')' )
00906 {
00907 in.setstate(std::ios_base::failbit) ;
00908 return in ;
00909 }
00910
00911 a = complex<F>(w, x) ;
00912
00913 return in ;
00914 }
00915
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00928
00929 namespace scalar_func {
00930
00931 template< typename F >
00932 inline
00933 F real( F a )
00934 {
00935 return a ;
00936 }
00937
00938 template< typename F >
00939 inline
00940 F imag( F )
00941 {
00942 return F() ;
00943 }
00944
00945 template< typename F >
00946 inline
00947 F norm( F a )
00948 {
00949 return a*a ;
00950 }
00951
00952 template< typename F >
00953 inline
00954 F conj( F a )
00955 {
00956 return a ;
00957 }
00958
00959 template< typename F >
00960 inline
00961 F inv( F a )
00962 {
00963 return F(1)/a ;
00964 }
00965
00966 template< typename F >
00967 inline
00968 F dot( F a, F b )
00969 {
00970 return a*b ;
00971 }
00972
00973 }
00974
00975 }
00976
00977 using complex_namespace::complex ;
00978
00979 }}
00980
00981 #endif // !defined(USE_STD_COMPLEX)
00982
00983 #endif