Cpx.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002  $RCSfile: Cpx.h,v $ --- $Date: 2006/07/18 01:45:34 $ --- $Revision: 1.2 $
00003  *****************************************************************************
00004  PREPROCESSOR DIRECTIVES
00005  *****************************************************************************/
00006 
00007  #ifndef CALC_CPX_H
00008  #define CALC_CPX_H
00009 
00010 /*****************************************************************************
00011  INCLUDE FILES
00012  *****************************************************************************/
00013 
00014  #include <cmath>
00015  #include <iostream>
00016 
00017 /*****************************************************************************
00018  NAMESPACE IDENTIFICATIONS
00019  *****************************************************************************/
00020 
00021  namespace calc {
00022 
00023 /*****************************************************************************
00024  Cpx CLASS TEMPLATE
00025  *****************************************************************************/
00031 
00032 
00043  template <typename aType>
00044  class Cpx {
00045 
00046  public:
00047 
00048  // Constructors
00049 
00054     Cpx(void) {re=im=(aType)(0);}
00061     Cpx(float          real) {re=(aType)(real); im=(aType)(0);}
00062     Cpx(char           real) {re=(aType)(real); im=(aType)(0);} 
00063     Cpx(char unsigned  real) {re=(aType)(real); im=(aType)(0);} 
00064     Cpx(short          real) {re=(aType)(real); im=(aType)(0);} 
00065     Cpx(short unsigned real) {re=(aType)(real); im=(aType)(0);} 
00066     Cpx(int            real) {re=(aType)(real); im=(aType)(0);} 
00067     Cpx(int unsigned   real) {re=(aType)(real); im=(aType)(0);} 
00068     Cpx(long           real) {re=(aType)(real); im=(aType)(0);} 
00069     Cpx(long unsigned  real) {re=(aType)(real); im=(aType)(0);} 
00070     Cpx(double         real) {re=(aType)(real); im=(aType)(0);} 
00071     Cpx(double long    real) {re=(aType)(real); im=(aType)(0);} 
00078     Cpx(const float          *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);}
00079     Cpx(const char           *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);} 
00080     Cpx(const char unsigned  *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);} 
00081     Cpx(const short          *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);} 
00082     Cpx(const short unsigned *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);} 
00083     Cpx(const int            *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);} 
00084     Cpx(const int unsigned   *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);} 
00085     Cpx(const long           *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);} 
00086     Cpx(const long unsigned  *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);} 
00087     Cpx(const double         *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);} 
00088     Cpx(const double long    *ptr) {re=(aType)(ptr[0]); im=(aType)(ptr[1]);} 
00096     Cpx(float          real, float          imaginary) {re=(aType)(real); im=(aType)(imaginary);}
00097     Cpx(char           real, char           imaginary) {re=(aType)(real); im=(aType)(imaginary);} 
00098     Cpx(char unsigned  real, char unsigned  imaginary) {re=(aType)(real); im=(aType)(imaginary);} 
00099     Cpx(short          real, short          imaginary) {re=(aType)(real); im=(aType)(imaginary);} 
00100     Cpx(short unsigned real, short unsigned imaginary) {re=(aType)(real); im=(aType)(imaginary);} 
00101     Cpx(int            real, int            imaginary) {re=(aType)(real); im=(aType)(imaginary);} 
00102     Cpx(int unsigned   real, int unsigned   imaginary) {re=(aType)(real); im=(aType)(imaginary);} 
00103     Cpx(long           real, long           imaginary) {re=(aType)(real); im=(aType)(imaginary);} 
00104     Cpx(long unsigned  real, long unsigned  imaginary) {re=(aType)(real); im=(aType)(imaginary);} 
00105     Cpx(double         real, double         imaginary) {re=(aType)(real); im=(aType)(imaginary);} 
00106     Cpx(double long    real, double long    imaginary) {re=(aType)(real); im=(aType)(imaginary);} 
00113     Cpx(const Cpx<aType>& cm) {re=(aType)(cm.re); im=(aType)(cm.im);}
00118    ~Cpx(void) {}
00119 
00120  // Member Functions
00121 
00122     aType            magnitude  (void) const;
00123     Cpx<aType>       operator/  (const Cpx<aType>& cm) const;
00124     const Cpx<aType> operator/= (const Cpx<aType>& cm);
00125 
00126 
00136     aType magnitude2(void) const {return re*re+im*im;}
00152     operator aType *(void) {return &re;}
00161     const Cpx<aType> operator=(const Cpx<aType>& cm)
00162         {re=cm.re; im=cm.im; return *this;}
00169     Cpx<aType> operator~(void) const {return Cpx<aType>(re,-im);}
00182     std::ostream& stream(std::ostream& ostr) const
00183        {const bool bsg=(im<0); ostr<<re<<(bsg?"-i":"+i")<<(bsg?-im:im); return ostr;}
00184 
00185  // Addition Operators
00186 
00193     Cpx<aType> operator+(void) const {return Cpx<aType>(re,im);}
00202     Cpx<aType> operator+(aType scalar) const {return Cpx<aType>(re+scalar,im);}
00211     Cpx<aType> operator+(const Cpx<aType>& cm) const
00212        {return Cpx<aType>(re+cm.re,im+cm.im);}
00222     const Cpx<aType> operator+=(aType scalar) {re+=scalar; return *this;}
00232     const Cpx<aType> operator+=(const Cpx<aType>& cm)
00233        {re+=cm.re; im+=cm.im; return *this;}
00234 
00235  // Subtraction Operators
00236 
00243     Cpx<aType> operator-(void) const {return Cpx<aType>(-re,-im);}
00252     Cpx<aType> operator-(aType scalar) const {return Cpx<aType>(re-scalar,im);}
00261     Cpx<aType> operator-(const Cpx<aType>& cm) const
00262        {return Cpx<aType>(re-cm.re,im-cm.im);}
00272     const Cpx<aType> operator-=(double scalar) {re-=scalar; return *this;}
00282     const Cpx<aType> operator-=(const Cpx<aType>& cm)
00283        {re-=cm.re; im-=cm.im; return *this;}
00284 
00285  // Multiplication Operators
00286 
00295     Cpx<aType> operator*(aType scalar) const
00296        {return Cpx<aType>(re*scalar,im*scalar);}
00305     Cpx<aType> operator*(const Cpx<aType>& cm) const
00306        {return Cpx<aType>(re*cm.re-im*cm.im,im*cm.re+re*cm.im);}
00316     const Cpx<aType> operator*=(aType scalar)
00317        {re*=scalar; im*=scalar; return *this;}
00327     const Cpx<aType> operator*=(const Cpx<aType>& cm)
00328        {aType x=re*cm.re-im*cm.im; im=im*cm.re+re*cm.im; re=x; return *this;}
00329 
00330  // Division Operators
00331 
00340     Cpx<aType> operator/(aType scalar) const
00341        {return Cpx<aType>(re/scalar,im/scalar);}
00351     const Cpx<aType> operator/=(aType scalar)
00352        {re/=scalar; im/=scalar; return *this;}
00353 
00354  // Equality Operators
00355 
00370     bool operator==(const Cpx<aType>& cm) const {return ((re==cm.re)&&(im==cm.im));}
00387     bool operator==(aType scalar) const {return ((im==(aType)(0))&&(re==scalar));}
00388 
00389  // Inequality Operators
00390 
00405     bool operator!=(const Cpx<aType>& cm) const {return ((re!=cm.re)||(im!=cm.im));}
00422     bool operator!=(aType scalar) const {return ((im!=(aType)(0))||(re!=scalar));}
00423 
00424  // Less-Than Operators
00425 
00440     bool operator<(const Cpx<aType>& cm) const {return (magnitude2()<cm.magnitude2());}
00455     bool operator<=(const Cpx<aType>& cm) const {return (magnitude2()<=cm.magnitude2());}
00456 
00457  // Greater-Than Operators
00458 
00473     bool operator>(const Cpx<aType>& cm) const {return (magnitude2()>cm.magnitude2());}
00488     bool operator>=(const Cpx<aType>& cm) const {return (magnitude2()>=cm.magnitude2());}
00489 
00490  // Related Print Functions
00491 
00505     template <class bType>
00506     friend std::ostream& operator<<(std::ostream& ostr, const Cpx<bType>& cm)
00507        {ostr<<cm.re<<","<<cm.im; return ostr;}
00508 
00509  // Related Math Functions
00510 
00520     template <class bType>
00521     friend Cpx<bType> operator+(bType scalar, const Cpx<bType>& cm)
00522        {return Cpx<bType>(cm.re+scalar,cm.im);}
00532     template <class bType>
00533     friend Cpx<bType> operator-(bType scalar, const Cpx<bType>& cm)
00534        {return Cpx<bType>(scalar-cm.re,-cm.im);}
00544     template <class bType>
00545     friend Cpx<bType> operator*(bType scalar, const Cpx<bType>& cm)
00546        {return Cpx<bType>(cm.re*scalar,cm.im*scalar);}
00556     template <class bType>
00557     friend Cpx<bType> operator/(bType scalar, const Cpx<bType>& cm)
00558        {bType u,v,fr; cm.absCpx(u,v);
00559         if(u<v) {
00560            const bType de=cm.im+cm.re*(fr=cm.re/cm.im);
00561            return Cpx<bType>(scalar*fr/de,-scalar/de);
00562         } else {
00563            const bType de=cm.re+cm.im*(fr=cm.im/cm.re);
00564            return Cpx<bType>(scalar/de,-scalar*fr/de);}}
00573     template <class bType>
00574     friend Cpx<bType> ceil(const Cpx<bType>& cm)
00575        {return Cpx<bType>((bType)(std::ceil(cm.re)),(bType)(std::ceil(cm.im)));}
00584     template <class bType>
00585     friend Cpx<bType> floor(const Cpx<bType>& cm)
00586        {return Cpx<bType>((bType)(std::floor(cm.re)),(bType)(std::floor(cm.im)));}
00587 
00588  // Related Equality Functions
00589 
00602     template <class bType>
00603     friend bType fabs(const Cpx<bType>& cm) {return cm.magnitude();}
00621     template <class bType>
00622     friend bool operator==(bType scalar, const Cpx<bType>& cm)
00623        {return ((cm.im==(bType)0)&&(cm.re==scalar));}
00641     template <class bType>
00642     friend bool operator!=(bType scalar, const Cpx<bType>& cm)
00643        {return ((cm.im!=(bType)0)||(cm.re!=scalar));}
00644 
00645  // Related Power Functions
00646 
00660     template <class bType>
00661     friend Cpx<bType> sqrt(const Cpx<bType>& cm)
00662        {bType u,v,ra,fr; cm.absCpx(u,v);
00663         if((u+v)==(bType)(0)) return Cpx<bType>();
00664         if(u<v) {
00665            fr=u/v;
00666            ra=(bType)(std::sqrt(v*(fr+(bType)(std::sqrt((bType)(1)+fr*fr)))/(bType)(2)));
00667         } else {
00668            fr=v/u;
00669            ra=(bType)(std::sqrt(u*((bType)(1)+(bType)(std::sqrt((bType)(1)+fr*fr)))/(bType)(2)));
00670         }
00671         return ((cm.re>=(bType)(0))?Cpx<bType>(ra,cm.im/ra/(bType)(2))
00672                                    :Cpx<bType>(v/ra/(bType)(2),cm.sign(cm.im)*ra));}
00684     template <class bType>
00685     friend Cpx<bType> pow(bType scalar, const Cpx<bType>& cx)
00686        {bType ra,an;
00687         if(scalar<(bType)(0)) {
00688            an=cx.im*(bType)(std::log(-scalar))+(Cpx<bType>::PI)*cx.re;
00689            ra=(bType)(std::pow(-scalar,cx.re)*std::exp((Cpx<bType>::PI)*cx.im));
00690         } else if(scalar>(bType)(0)) {
00691            an=cx.im*(bType)(std::log(scalar));
00692            ra=(bType)(std::pow(scalar,cx.re));
00693         } else return Cpx<bType>();
00694         return Cpx<bType>(ra*std::cos(an),ra*std::sin(an));}
00710     template <class bType>
00711     friend Cpx<bType> pow(const Cpx<bType>& cm, bType scalar)
00712        {const bType an=scalar*(bType)(std::atan2(cm.im,cm.re));
00713         const bType ra=(bType)(std::pow(fabs(cm),scalar));
00714         return Cpx<bType>(ra*std::cos(an),ra*std::sin(an));}
00730     template <class bType>
00731     friend Cpx<bType> pow(const Cpx<bType>& cm, const Cpx<bType>& cx)
00732        {const bType an=cm.modCpx((bType)(std::atan2(cm.im,cm.re)));
00733         const bType ra=fabs(cm);
00734         const bType rx=(bType)(std::pow(ra,cx.re)*std::exp(-an*cx.im));
00735         const bType ax=an*cx.re+cx.im*(bType)(std::log(ra));
00736         return Cpx<bType>(rx*(bType)(std::cos(ax)),rx*(bType)(std::sin(ax)));}
00737 
00738  // Related Exponential & Logarithmic Functions
00739 
00748     template <class bType>
00749     friend Cpx<bType> exp(const Cpx<bType>& cm)
00750        {return (bType)(std::exp(cm.re))*
00751           Cpx<bType>(std::cos(cm.im),std::sin(cm.im));}
00764     template <class bType>
00765     friend Cpx<bType> log(const Cpx<bType>& cm)
00766        {return Cpx<bType>((bType)(0.5*std::log(cm.re*cm.re+cm.im*cm.im)),
00767                           (bType)(cm.modCpx(std::atan2(cm.im,cm.re))));}
00781     template <class bType>
00782     friend Cpx<bType> log10(const Cpx<bType>& cm) {return log(cm)/Cpx<bType>::LN10;}
00783 
00784  // Related Trigononmetric Functions
00785 
00794     template <class bType>
00795     friend Cpx<bType> cos(const Cpx<bType>& cm)
00796        {bType ep,e2; cm.expCpx(ep,e2,cm.im);
00797         return Cpx<bType>(ep*(e2+(bType)(1))*(bType)(std::cos(cm.re)),
00798            cm.sign(cm.im)*ep*(e2-(bType)(1))*(bType)(std::sin(cm.re)));}
00807     template <class bType>
00808     friend Cpx<bType> sin(const Cpx<bType>& cm)
00809        {bType ep,e2; cm.expCpx(ep,e2,cm.im);
00810         return Cpx<bType>(ep*((bType)(1)+e2)*(bType)(std::sin(cm.re)),
00811            cm.sign(cm.im)*ep*((bType)(1)-e2)*(bType)(std::cos(cm.re)));}
00820     template <class bType>
00821     friend Cpx<bType> tan(const Cpx<bType>& cm)
00822        {const bType em=(bType)(std::exp((bType)(2)*((cm.im>(bType)(0))?-cm.im:cm.im)));
00823         const bType e2=em*em;
00824         const bType an=(bType)(2)*cm.re;
00825         const bType de=(bType)(2)*em*(bType)(std::cos(an))+(bType)(1)+e2;
00826         return Cpx<bType>((bType)(2)*em*(bType)(std::sin(an))/de,
00827                                cm.sign(cm.im)*((bType)(1)-e2)/de);}
00828 
00829  // Related Inverse Trigonometric Functions
00830 
00846      template <class bType>
00847      friend Cpx<bType> acos(const Cpx<bType>& cm)
00848         {const  Cpx<bType> cn(-cm.im,cm.re);                           // multiply by i
00849          const  Cpx<bType> cx=log(cn+sqrt(cn*cn+(bType)(1)));
00850          return Cpx<bType>((Cpx<bType>::PI)/(bType)(2)-cx.im,cx.re);}  // multiply by i & add PI/2
00866      template <class bType>
00867      friend Cpx<bType> asin(const Cpx<bType>& cm)
00868         {const  Cpx<bType> cn(-cm.im,cm.re);           // multiply by i
00869          const  Cpx<bType> cx=log(cn+sqrt(cn*cn+(bType)(1)));
00870          return Cpx<bType>(cx.im,-cx.re);}             // multiply by -i
00887      template <class bType>
00888      friend Cpx<bType> atan(const Cpx<bType>& cm)
00889         {const  Cpx<bType> cn(-cm.im,cm.re);           // multiply by i
00890          const  Cpx<bType> cx=(log((bType)(1)+cn)-log((bType)(1)-cn))/(bType)(2);
00891          return Cpx<bType>(cx.im,-cx.re);}             // multiply by -i
00892 
00893  // Related Hyperbolic Functions
00894 
00903     template <class bType>
00904     friend Cpx<bType> cosh(const Cpx<bType>& cm)
00905        {bType ep,e2; cm.expCpx(ep,e2,cm.re);
00906         return Cpx<bType>(ep*((bType)(1)+e2)*(bType)(std::cos(cm.im)),
00907            cm.sign(cm.re)*ep*((bType)(1)-e2)*(bType)(std::sin(cm.im)));}
00916     template <class bType>
00917     friend Cpx<bType> sinh(const Cpx<bType>& cm)
00918        {bType ep,e2; cm.expCpx(ep,e2,cm.re);
00919         return Cpx<bType>(cm.sign(cm.re)*ep*((bType)(1)-e2)*(bType)(std::cos(cm.im)),
00920                                          ep*((bType)(1)+e2)*(bType)(std::sin(cm.im)));}
00929      template <class bType>
00930      friend Cpx<bType> tanh(const Cpx<bType>& cm)
00931         {const bType em=(bType)(std::exp((bType)(2)*(cm.re<(bType)(0)?cm.re:-cm.re)));
00932          const bType e2=em*em;
00933          const bType an=(bType)(2)*cm.im;
00934          const bType de=(bType)(2)*em*(bType)(std::cos(an))+(bType)(1)+e2;
00935          return Cpx<bType>(cm.sign(cm.re)*((bType)(1)-e2)/de,
00936                       (bType)(2)*em*(bType)(std::sin(an))/de);}
00937 
00938  // Related Inverse Hyperbolic Functions
00939 
00952     template <class bType>
00953     friend Cpx<bType> acosh(const Cpx<bType>& cm)
00954        {return (bType)(2)*log(sqrt((cm+(bType)(1))/(bType)(2))
00955                              +sqrt((cm-(bType)(1))/(bType)(2)));}
00971     template <class bType>
00972     friend Cpx<bType> asinh(const Cpx<bType>& cm)
00973        {return log(cm+sqrt(cm*cm+(bType)(1)));}
00990     template <class bType>
00991     friend Cpx<bType> atanh(const Cpx<bType>& cm)
00992        {return (log((bType)(1)+cm)-log((bType)(1)-cm))/(bType)(2);}
00993 
00994  // Data Members
00995 
00996     aType re;  
00997     aType im;  
00999     static const aType PI;
01000     static const aType LN10;
01001 
01002  private:
01003 
01004  // Member functions
01005 
01006     static aType modCpx(aType scalar);
01007     static void  expCpx(aType& ep, aType& e2, aType xin);
01008     void         absCpx(aType& u, aType& v) const;
01009 
01020     static aType sign(aType x) {return (x<(aType)(0)?(aType)(-1):(aType)(1));}
01021  };}
01022 
01023 /*****************************************************************************/
01024 
01026  template <typename aType>
01027  const aType calc::Cpx<aType>::PI=3.141592653589793238462643;
01029  template <typename aType>
01030  const aType calc::Cpx<aType>::LN10=2.302585092994045684017991;
01031 
01032 /*****************************************************************************
01033  PREPROCESSOR DIRECTIVES
01034  *****************************************************************************/
01035 
01036  #endif
01037 
01038 /*****************************************************************************
01039  CLASS TEMPLATE SOURCE
01040  *****************************************************************************/
01041 
01042  #include "Cpx.cpp"
01043 
01044 /*****************************************************************************/

Generated on Wed Jul 19 09:23:35 2006 for CalcLib by  doxygen 1.4.7