Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members

complex.hxx

00001 
00002 // 
00003 // Copyright (C) 2006 James M. Lawrence.  All rights reserved.
00004 // 
00005 // software: esve-1.0.3
00006 // file: esve/math/complex.hxx
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions
00010 // are met:
00011 // 
00012 // 1. Redistributions of source code must retain the above copyright
00013 //    notice, this list of conditions and the following disclaimer.
00014 // 
00015 // 2. The origin of this software must not be misrepresented; you must
00016 //    not claim that you wrote the original software.  If you use this
00017 //    software in a product, an acknowledgment in the product 
00018 //    documentation would be appreciated but is not required.
00019 // 
00020 // 3. Altered source versions must be plainly marked as such, and must
00021 //    not be misrepresented as being the original software.
00022 // 
00023 // 4. The name of the author may not be used to endorse or promote
00024 //    products derived from this software without specific prior written
00025 //    permission.
00026 // 
00027 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY,
00028 // AND WITH NO CLAIM AS TO ITS SUITABILITY FOR ANY PURPOSE.  IN NO EVENT
00029 // SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM WHATSOEVER MADE IN CONNECTION
00030 // TO THIS SOFTWARE.
00031 // 
00033 //
00034 // complex numbers.
00035 //
00036 // The reason esve has its own complex class is because it came "for
00037 // free" as a cut-and-paste (with regexp substitutions) from
00038 // quaternions.  This provided a further verification of the quat
00039 // class.
00040 //
00041 // Another reason is that esve::math::complex guarantees
00042 // representation for OpenGL, on the hardly-fathomable chance that a
00043 // machine's std::complex uses polar representation or something.
00044 //
00045 // Yet another reason is that it disallows conversions, which I have
00046 // spurned ever since I crippled an inner loop by accidentally using a
00047 // float-constructible class when a regular float would have sufficed.
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 }} // namespace esve::math
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 } // namespace scalar_func
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 // nonmember functions
00203 //
00205 
00207 // realpart
00209 
00210 template< typename F >
00211 inline
00212 F real( const complex<F> & a )
00213 {
00214     return a.real() ;
00215 }
00216 
00218 // imag
00220 
00221 template< typename F >
00222 inline
00223 F imag( const complex<F> & a )
00224 {
00225     return a.imag() ;
00226 }
00227 
00229 // norm
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 // abs
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 // exp
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 // natural log
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 // arg
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 // polar
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 // trig
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 // pow
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 // sqrt
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 // conj
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 // inv
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 // dot
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 // operator==
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 // operator!=
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 // operator+
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 // operator-
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 // operator*
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 // operator/
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 // complex member functions
00686 //
00688 
00690 // constructors
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 // readers
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 // operator+=
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 // operator-=
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 // operator*=
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 // operator/=
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 // data
00852 
00853 template< typename F >
00854 inline
00855 const F*
00856 complex<F>::
00857 data() const
00858 {
00859     return &mw ;
00860 }
00861 
00863 // streams
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 // scalar_func
00919 //
00920 // A new scalar may be introduced by adding the appropriate functions
00921 // to scalar_func (sin, cos, exp, etc.).
00922 //
00923 // The separate namespace also provides the convenience of a 'using'
00924 // directive which pulls in only these functions which do not have a
00925 // class signature.
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 } // namespace scalar_func
00974 
00975 } // namespace complex_namespace
00976 
00977 using complex_namespace::complex ;
00978 
00979 }} // namespace esve::math
00980 
00981 #endif // !defined(USE_STD_COMPLEX)
00982 
00983 #endif

Generated on Tue May 30 11:40:52 2006 for esve by doxygen 1.3.4