Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

CTBcomplex.cxx

Go to the documentation of this file.
00001 
00006 /*----------------------------------------------------------------------------*/
00007 /* C Tool Box: Designed and implemented by:                                   */
00008 /*    Walter F.J. Mueller   Gesellschaft fuer Schwerionenforschung (GSI)      */
00009 /*                          Postfach 110552, D-64220 Darmstadt, Germany       */
00010 /*                  Email:  W.F.J.Mueller@gsi.de                              */
00011 /*                  WWW:    http://www-kp3.gsi.de/www/kp3/people/mueller.html */
00012 /*------------------------------------------+---------------------------------*/
00013 
00014 #include <math.h>
00015 
00016 #include "CTB.hxx"
00017 #include "CTBnum.hxx"
00018 #include "CTBtraits.hxx"
00019 #include "CTBcomplex.hxx"
00020 
00034 //------------------------------------------+-----------------------------------
00036 
00037 template <class T>
00038 CTBcomplex<T> CTBcomplex<T>::Sqrt() const
00039 {
00040   T f_re = 0.;
00041   T f_im = 0.;
00042 
00043   if (IsReal()) {
00044     if (mf_re >= 0.) {
00045       f_re = sqrt(mf_re);
00046     } else {
00047       f_im = sqrt(-mf_re);
00048     }
00049 
00050   } else {
00051     T f_abs = Abs();
00052     if (f_abs > 0.) {
00053       if (mf_re > 0.) {
00054         f_re = sqrt(0.5 * (f_abs + mf_re));
00055         f_im = 0.5 * mf_im / f_re;
00056       } else {
00057         f_im = sqrt(0.5 * (f_abs - mf_re));
00058         if (mf_im < 0.) f_im = -f_im;
00059         f_re = 0.5 * mf_im / f_im;
00060       }
00061     }
00062   }
00063 
00064   return CTBcomplex<T>(f_re, f_im);
00065 }
00066 
00067 //------------------------------------------+-----------------------------------
00069 
00070 template <class T>
00071 static inline void sincos(T& f_sin, T& f_cos, T f_x)
00072 {
00073   f_sin = CTBsin(f_x);
00074   f_cos = CTBcos(f_x);
00075   return;
00076 }
00077 
00078 //------------------------------------------+-----------------------------------
00080 
00081 template <class T>
00082 static inline void sinhcosh(T& f_sinh, T& f_cosh, T f_x)
00083 {
00084   T f_expp = CTBexp(f_x);
00085   T f_expm = 1./f_expp;
00086   f_sinh = 0.5 * (f_expp - f_expm);
00087   f_cosh = 0.5 * (f_expp + f_expm);
00088   return;
00089 }
00090 
00091 //------------------------------------------+-----------------------------------
00093 
00100 template <class T>
00101 static inline void sinhcosh_red(T& f_sinh, T& f_cosh, T f_x)
00102 {
00103   T f_xabs = CTBabs(f_x);
00104   T f_expm = (f_xabs < 25.) ? CTBexp(-2.*f_xabs) : 0.;
00105   f_sinh = CTBsign(1. - f_expm, f_x);
00106   f_cosh = 1. + f_expm;
00107   return;
00108 }
00109 
00110 //------------------------------------------+-----------------------------------
00112 
00113 template <class T>
00114 CTBcomplex<T> CTBcomplex<T>::Exp() const
00115 {
00116   T f_mag = 1.;
00117   T f_re  = 1.;
00118   T f_im  = 0.;
00119 
00120   if (mf_re != 0.) f_mag = CTBexp(mf_re);
00121   if (mf_im != 0.) sincos(f_im, f_re, mf_im);
00122 
00123   return CTBcomplex<T>(f_mag*f_re, f_mag*f_im);
00124 }
00125 
00126 //------------------------------------------+-----------------------------------
00128 
00129 template <class T>
00130 CTBcomplex<T> CTBcomplex<T>::Log() const
00131 {
00132   return CTBcomplex<T>(CTBlog(Abs()),Arg());
00133 }
00134 
00135 //------------------------------------------+-----------------------------------
00137 
00138 template <class T>
00139 CTBcomplex<T> CTBcomplex<T>::Sin() const
00140 {
00141   T f_sin_re  = 0.;
00142   T f_cos_re  = 1.;
00143   T f_sinh_im = 0.;
00144   T f_cosh_im = 1.;
00145   
00146   if (mf_re != 0.) sincos(f_sin_re, f_cos_re, mf_re);
00147   if (mf_im != 0.) sinhcosh(f_sinh_im,f_cosh_im, mf_im);
00148 
00149   return CTBcomplex<T>(f_sin_re*f_cosh_im, f_cos_re*f_sinh_im);
00150 }
00151 
00152 //------------------------------------------+-----------------------------------
00154 
00155 template <class T>
00156 CTBcomplex<T> CTBcomplex<T>::Cos() const
00157 {
00158   T f_sin_re  = 0.;
00159   T f_cos_re  = 1.;
00160   T f_sinh_im = 0.;
00161   T f_cosh_im = 1.;
00162   
00163   if (mf_re != 0.) sincos(f_sin_re, f_cos_re, mf_re);
00164   if (mf_im != 0.) sinhcosh(f_sinh_im, f_cosh_im, mf_im);
00165 
00166   return CTBcomplex<T>(f_cos_re*f_cosh_im, -f_sin_re*f_sinh_im);
00167 }
00168 
00169 //------------------------------------------+-----------------------------------
00171 
00172 template <class T>
00173 CTBcomplex<T> CTBcomplex<T>::Tan() const
00174 {
00175   T f_sin_re  = 0.;
00176   T f_cos_re  = 1.;
00177   T f_sinh_im = 0.;
00178   T f_cosh_im = 1.;
00179   
00180   if (mf_re != 0.) sincos(f_sin_re, f_cos_re, mf_re);
00181   if (mf_im != 0.) sinhcosh_red(f_sinh_im, f_cosh_im, mf_im);
00182 
00183   CTBcomplex<T> z_sin(f_sin_re*f_cosh_im,  f_cos_re*f_sinh_im);
00184   CTBcomplex<T> z_cos(f_cos_re*f_cosh_im, -f_sin_re*f_sinh_im);
00185 
00186   return z_sin/z_cos;
00187 }
00188 
00189 //------------------------------------------+-----------------------------------
00191 
00192 template <class T>
00193 CTBcomplex<T> CTBcomplex<T>::Asin() const
00194 {
00195   return CTBtimesI(CTBlog(-CTBtimesI(*this) + CTBsqrt((T)1.-CTBpow2(*this))));
00196 }
00197 
00198 //------------------------------------------+-----------------------------------
00200 
00201 template <class T>
00202 CTBcomplex<T> CTBcomplex<T>::Acos() const
00203 {
00204   return - CTBtimesI(CTBlog(*this + CTBtimesI(CTBsqrt((T)1.-CTBpow2(*this)))));
00205 }
00206 
00207 //------------------------------------------+-----------------------------------
00209 
00210 template <class T>
00211 CTBcomplex<T> CTBcomplex<T>::Atan() const
00212 {
00213   CTBcomplex<T> i(0.,1.);
00214   
00215   return (T)0.5 * CTBtimesI( CTBlog((i + *this) / (i - *this) ));
00216 }
00217 
00218 //------------------------------------------+-----------------------------------
00220 
00221 template <class T>
00222 CTBcomplex<T> CTBcomplex<T>::Sinh() const
00223 {
00224   T f_sinh_re = 0.;
00225   T f_cosh_re = 1.;
00226   T f_sin_im  = 0.;
00227   T f_cos_im  = 1.;
00228   
00229   if (mf_re != 0.) sinhcosh(f_sinh_re,f_cosh_re, mf_re);
00230   if (mf_im != 0.) sincos(f_sin_im, f_cos_im, mf_im);
00231 
00232   return CTBcomplex<T>(f_sinh_re*f_cos_im, f_cosh_re*f_sin_im);
00233 }
00234 
00235 //------------------------------------------+-----------------------------------
00237 
00238 template <class T>
00239 CTBcomplex<T> CTBcomplex<T>::Cosh() const
00240 {
00241   T f_sinh_re = 0.;
00242   T f_cosh_re = 1.;
00243   T f_sin_im  = 0.;
00244   T f_cos_im  = 1.;
00245   
00246   if (mf_re != 0.) sinhcosh(f_sinh_re, f_cosh_re, mf_re);
00247   if (mf_im != 0.) sincos(f_sin_im, f_cos_im, mf_im);
00248 
00249   return CTBcomplex<T>(f_cosh_re*f_cos_im, f_sinh_re*f_sin_im);
00250 }
00251 
00252 //------------------------------------------+-----------------------------------
00254 
00255 template <class T>
00256 CTBcomplex<T> CTBcomplex<T>::Tanh() const
00257 {
00258   T f_sinh_re = 0.;
00259   T f_cosh_re = 1.;
00260   T f_sin_im  = 0.;
00261   T f_cos_im  = 1.;
00262   
00263   if (mf_re != 0.) sinhcosh_red(f_sinh_re, f_cosh_re, mf_re);
00264   if (mf_im != 0.) sincos(f_sin_im, f_cos_im, mf_im);
00265 
00266   CTBcomplex<T> z_sinh(f_sinh_re*f_cos_im, f_cosh_re*f_sin_im);
00267   CTBcomplex<T> z_cosh(f_cosh_re*f_cos_im, f_sinh_re*f_sin_im);
00268 
00269   return z_sinh/z_cosh;
00270 }
00271 
00272 //------------------------------------------+-----------------------------------
00274 
00275 template <class T>
00276 CTBcomplex<T> CTBcomplex<T>::Asinh() const
00277 {
00278   return CTBlog(*this + CTBsqrt(CTBpow2(*this) + (T)1.));
00279 }
00280 
00281 //------------------------------------------+-----------------------------------
00283 
00284 template <class T>
00285 CTBcomplex<T> CTBcomplex<T>::Acosh() const
00286 {
00287   return CTBlog(*this + CTBsqrt(CTBpow2(*this) - (T)1.));
00288 }
00289 
00290 //------------------------------------------+-----------------------------------
00292 
00293 template <class T>
00294 CTBcomplex<T> CTBcomplex<T>::Atanh() const
00295 {
00296   return (T)0.5 * CTBlog( ((T)1. + *this) / ((T)1. - *this));
00297 }
00298 
00299 //------------------------------------------+-----------------------------------
00301 
00302 template <class T>
00303 CTBcomplex<T> CTBcomplex<T>::Pow(int i_y) const
00304 {
00305   CTBcomplex<T> z_f(1.);
00306   int           i_nmul = CTBabs(i_y);
00307 
00308   for (int i = 0; i < i_nmul; i++) z_f *= *this;
00309   if (i_y < 0) z_f = (T)1./z_f;
00310 
00311   return z_f;
00312 }
00313 
00314 //------------------------------------------+-----------------------------------
00316 
00317 template <class T>
00318 CTBcomplex<T> CTBcomplex<T>::Pow(const CTBcomplex<T>& z_y) const
00319 {
00320   return CTBexp(z_y * CTBlog(*this));
00321 }
00322 
00323 //------------------------------------------+-----------------------------------
00336 template <class T>
00337   CTBcomplex<T> CTBcomplex<T>::Divide(const CTBcomplex<T>& z_den) const
00338 {
00339   T f_re;
00340   T f_im;
00341   
00342   if (fabs(z_den.mf_re) >= fabs(z_den.mf_im)) {
00343     T f_t1 = z_den.mf_im / z_den.mf_re;
00344     T f_t2 = 1./ (z_den.mf_re + f_t1 * z_den.mf_im);
00345     f_re   = (mf_re + f_t1 * mf_im) * f_t2;
00346     f_im   = (mf_im - f_t1 * mf_re) * f_t2;
00347 
00348   } else {
00349     T f_t1 = z_den.mf_re / z_den.mf_im;
00350     T f_t2 = 1. / (f_t1 * z_den.mf_re + z_den.mf_im);
00351     f_re   = (f_t1 * mf_re + mf_im) * f_t2;
00352     f_im   = (f_t1 * mf_im - mf_re) * f_t2;
00353   }
00354 
00355   return CTBcomplex<T>(f_re, f_im);
00356 }
00357 
00358 //------------------------------------------+-----------------------------------
00363 template <class T>
00364   CTBcomplex<T> CTBcomplex<T>::Invert(T f_nom) const
00365 {  
00366   T f_re;
00367   T f_im;
00368   
00369   if (fabs(mf_re) >= fabs(mf_im)) {
00370     T f_t1 = mf_im / mf_re;
00371     T f_t2 = 1./ (mf_re + f_t1 * mf_im);
00372     f_re   =   f_nom * f_t2;
00373     f_im   = - f_nom * f_t1 * f_t2;
00374 
00375   } else {
00376     T f_t1 = mf_re / mf_im;
00377     T f_t2 = 1./ (f_t1 * mf_re + mf_im);
00378     f_re   =   f_nom * f_t1 * f_t2;
00379     f_im   = - f_nom * f_t2;
00380   }
00381 
00382   return CTBcomplex<T>(f_re, f_im);
00383 }
00384 
00385 //------------------------------------------+-----------------------------------
00387 
00388 template <class T>
00389 void CTBcomplex<T>::ToStream(ostream& os) const
00390 {
00391   int i_width = os.width();
00392 
00393   os << setw(0) << "(" << setw(i_width) << mf_re 
00394      << "," << setw(i_width) << mf_im << ")";
00395   return;
00396 }
00397 
00398 //------------------------------------------+-----------------------------------
00400 
00404 template <class T>
00405 void CTBcomplex<T>::FromStream(istream& is)
00406 {
00407   T    f_re;
00408   T    f_im;
00409   char c_char;
00410   
00411   if (!is) return;                          // quit if stream not good
00412 
00413   is >> c_char;                             // get '('
00414   if (c_char != '(') { 
00415     is.setstate(ios::failbit);
00416     return;
00417   }
00418 
00419   is >> f_re;                               // read real part
00420   if (!is) return;
00421 
00422   is >> c_char;                             // get ',' or ')'
00423 
00424   if (c_char == ',') {
00425     is >> f_im;                             // read imaginary part
00426     if (!is) return;
00427     is >> c_char;                           // get trailing ')'
00428   }
00429 
00430   if (c_char != ')') { 
00431     is.setstate(ios::failbit);
00432     return;
00433   }
00434 
00435   mf_re = f_re;
00436   mf_im = f_im;
00437 
00438   return;
00439 }
00440 

Generated at Fri Oct 24 18:11:27 2003 for CTBbase by doxygen1.2.9-20010812 written by Dimitri van Heesch, © 1997-2001