core/complex.h

Go to the documentation of this file.
00001 
00017 #ifndef _COMPLEX_H
00018 #define _COMPLEX_H
00019 
00020 typedef enum {I='i',J='j',A='d'} CNOTATION; 
00021 #define CNOTATION_DEFAULT J /* never set this to A */
00022 #define PI 3.1415926535897932384626433832795
00023 #define E 2.71828182845905
00024 
00025 /* only cpp code may actually do complex math */
00026 #ifdef __cplusplus
00027 #include <math.h>
00028 #include "platform.h"
00029 class complex { 
00030 private:
00031     double r; 
00032     double i; 
00033     CNOTATION f; 
00034 public:
00036     inline complex() 
00037     {
00038         r = 0;
00039         i = 0;
00040         f = CNOTATION_DEFAULT;
00041     };
00042     inline complex(double re) 
00043     {
00044         r = re;
00045         i = 0;
00046         f = CNOTATION_DEFAULT;
00047     };
00048     inline complex(double re, double im, CNOTATION nf=CNOTATION_DEFAULT) 
00049     {
00050         r = re;
00051         i = im;
00052         f = nf;
00053     };
00054     
00055     /* assignment operations */
00056     inline complex &operator = (complex x) 
00057     {
00058         r = x.r; 
00059         i = x.i; 
00060         f = x.f; 
00061         return *this;
00062     };
00063     inline complex &operator = (double x) 
00064     {
00065         r = x; 
00066         i = 0; 
00067         f = CNOTATION_DEFAULT;
00068         return *this;
00069     };
00070 
00071     /* access operations */
00072     inline double & Re(void) 
00073     {
00074         return r;
00075     };
00076     inline double & Im(void) 
00077     {
00078         return i;
00079     };
00080     inline CNOTATION & Notation(void) 
00081     {
00082         return f;
00083     };
00084     inline double Mag(void) const 
00085     {
00086         return sqrt(r*r+i*i);
00087     };
00088     inline double Mag(double m)  
00089     {
00090         double old = sqrt(r*r+i*i);
00091         r *= m/old;
00092         i *= m/old;
00093         return m;
00094     };
00095     inline double Arg(void) const 
00096     {
00097         if (r==0)
00098         {
00099             if (i>0)
00100                 return PI/2;
00101             else if (i==0)
00102                 return 0;
00103             else
00104                 return -PI/2;
00105         }
00106         else if (r>0)
00107             return atan(i/r);
00108         else
00109             return PI+atan(i/r);
00110     };
00111     inline double Arg(double a)  
00112     {
00113         SetPolar(Mag(),a,f);
00114         return a;
00115     };
00116     inline complex Log(void) const 
00117     { 
00118         return complex(log(Mag()),Arg(),f);
00119     };
00120     inline void SetReal(double v) 
00121     {
00122         r = v;
00123     };
00124     inline void SetImag(double v) 
00125     {
00126         i = v;
00127     };
00128     inline void SetNotation(CNOTATION nf) 
00129     {
00130         f = nf;
00131     }
00132     inline void SetRect(double rp, double ip, CNOTATION nf=CNOTATION_DEFAULT) 
00133     {
00134         r = rp;
00135         i = ip;
00136         f = nf;
00137     };
00138     inline void SetPolar(double m, double a, CNOTATION nf=A) 
00139     {
00140         r = (m*cos(a)); 
00141         i = (m*sin(a));
00142         f = nf;
00143     };
00144 
00145 #if 0
00146     //inline operator const double (void) const /**< cast real part to double */
00147     //{
00148     //  return r;
00149     //};
00150 #endif
00151 
00152     inline complex operator - (void) 
00153     {
00154         return complex(-r,-i,f);
00155     };
00156     inline complex operator ~ (void) 
00157     { 
00158         return complex(r,-i,f);
00159     };
00160 
00161     /* reflexive math operations */
00162     inline complex &operator += (double x) 
00163     {
00164         r += x; 
00165         return *this;
00166     };
00167     inline complex &operator -= (double x) 
00168     {
00169         r -= x; 
00170         return *this;
00171     };
00172     inline complex &operator *= (double x) 
00173     {
00174         r *= x; 
00175         i *= x; 
00176         return *this;
00177     };
00178     inline complex &operator /= (double x) 
00179     {
00180         r /= x; 
00181         i /= x;
00182         return *this;
00183     };
00184     inline complex &operator ^= (double x) 
00185     { 
00186         double lm = log(Mag()), a = Arg(), b = exp(x*lm), c = x*a; 
00187         r = (b*cos(c)); 
00188         i = (b*sin(c)); 
00189         return *this;
00190     };
00191     inline complex &operator += (complex x) 
00192     {
00193         r += x.r; 
00194         i += x.i; 
00195         return *this;
00196     };
00197     inline complex &operator -= (complex x)  
00198     {
00199         r -= x.r; 
00200         i -= x.i; 
00201         return *this;
00202     };
00203     inline complex &operator *= (complex x)  
00204     {
00205         double pr=r; 
00206         r = pr * x.r - i * x.i; 
00207         i = pr * x.i + i * x.r; 
00208         return *this;
00209     };
00210     inline complex &operator /= (complex y)  
00211     {
00212         double xr=r;
00213         double a = y.r*y.r+y.i*y.i;
00214         r = (xr*y.r+i*y.i)/a; 
00215         i = (i*y.r-xr*y.i)/a;
00216         return *this;
00217     };
00218     inline complex &operator ^= (complex x) 
00219     { 
00220         double lm = log(Mag()), a = Arg(), b = exp(x.r*lm-x.i*a), c = x.r*a+x.i*lm; 
00221         r = (b*cos(c)); 
00222         i = (b*sin(c)); 
00223         return *this;
00224     };
00225 
00226     /* binary math operations */
00227     inline complex operator + (double y) 
00228     {
00229         complex x(*this);
00230         return x+=y;
00231     };
00232     inline complex operator - (double y) 
00233     {
00234         complex x(*this);
00235         return x-=y;
00236     };
00237     inline complex operator * (double y) 
00238     {
00239         complex x(*this);
00240         return x*=y;
00241     };
00242     inline complex operator / (double y) 
00243     {
00244         complex x(*this);
00245         return x/=y;
00246     };
00247     inline complex operator ^ (double y) 
00248     {
00249         complex x(*this);
00250         return x^=y;
00251     };
00252     inline complex operator + (complex y) 
00253     {
00254         complex x(*this);
00255         return x+=y;
00256     };
00257     inline complex operator - (complex y) 
00258     {
00259         complex x(*this);
00260         return x-=y;
00261     };
00262     inline complex operator * (complex y) 
00263     {
00264         complex x(*this);
00265         return x*=y;
00266     };
00267     inline complex operator / (complex y) 
00268     {
00269         complex x(*this);
00270         return x/=y;
00271     };
00272     inline complex operator ^ (complex y) 
00273     {
00274         complex x(*this);
00275         return x^=y;
00276     };
00277 
00279     inline complex SetPowerFactor(double mag, 
00280         double pf, 
00281         CNOTATION n=J) 
00282     {
00283         SetPolar(mag/pf, acos(pf),n);
00284         return *this;
00285     }
00286 
00287 
00288     /* comparison */
00289     inline bool IsZero(double err=0.0) 
00290     {
00291         return Mag()<=err;
00292     }
00293 
00294     /* magnitude comparisons */
00295     inline bool operator == (double m)  { return Mag()==m; };
00296     inline bool operator != (double m)  { return Mag()!=m; };
00297     inline bool operator < (double m)   { return Mag()<m; };
00298     inline bool operator <= (double m)  { return Mag()<=m; };
00299     inline bool operator > (double m)   { return Mag()>m; };
00300     inline bool operator >= (double m)  { return Mag()>=m; };
00301 
00302     /* angle comparisons */
00303     inline complex operator == (complex y)  { return fmod(y.Arg()-Arg(),2*PI)==0.0;};
00304     inline complex operator != (complex y)  { return fmod(y.Arg()-Arg(),2*PI)!=0.0;};
00305     inline complex operator < (complex y)   { return fmod(y.Arg()-Arg(),2*PI)<PI;};
00306     inline complex operator <= (complex y)  { return fmod(y.Arg()-Arg(),2*PI)<=PI;};
00307     inline complex operator > (complex y)   { return fmod(y.Arg()-Arg(),2*PI)>PI;};
00308     inline complex operator >= (complex y)  { return fmod(y.Arg()-Arg(),2*PI)>=PI;};
00309 #ifndef isfinite
00310 #define isfinite(X) (!isinf(X) && !isnan(X))
00311 #endif
00312     inline bool IsFinite(void) { return isfinite(r) && isfinite(i); };
00313 };
00314 #else
00315 typedef struct { 
00316     double r; 
00317     double i; 
00318     CNOTATION f; 
00319 } complex; 
00320 #endif
00321 
00322 #endif
00323 

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy