00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef CMPLX_D
00022 #define CMPLX_D
00023 #include <cstdlib>
00024 #include <spuc.h>
00025 #include <cmath>
00026 namespace SPUC {
00029 template <class T> class complex
00030 {
00031 public:
00032 T re;
00033 T im;
00034
00035 complex()
00036 {
00037 re = 0;
00038 im = 0;
00039 }
00040 void* operator new (size_t) {
00041 T* re = new T;
00042 T* im = new T;
00043 }
00044 complex(T r, T i) :re(r), im(i) {}
00045 complex(T r) : re(r), im(0) {}
00046
00047
00048 inline T real() { return(re);};
00049 inline T imag() { return(im);};
00050
00051 friend T real( complex<T> y ) { return(y.re);}
00052 friend T imag( complex<T> y ) { return(y.im);}
00053
00054 inline T operator=(T r)
00055 {
00056 re = r;
00057 im = 0;
00058 return r;
00059 }
00060
00061 inline complex operator =(const complex<T>& y) {
00062 re = (T)y.re; im = (T)y.im; return *this;
00063 }
00064 inline complex operator *=(const complex<T>& y) {
00065 T r = re*y.re - im*y.im;
00066 im = re*y.im + im*y.re;
00067 re = r;
00068 return *this;
00069 }
00070 inline complex operator +=(const complex<T>& y) {
00071 re += y.re;
00072 im += y.im;
00073 return *this;
00074 }
00075 inline complex operator -=(const complex<T>& y) {
00076 re -= y.re;
00077 im -= y.im;
00078 return *this;
00079 }
00080
00081 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00082 operator const complex<long> () const { return(complex<long>((long)re,(long)im)); }
00083 #endif
00084 };
00085
00086 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00087
00088 template <class T1, class T2> inline complex<T1> operator *(complex<T1> r, complex<T2> l)
00089 {
00090 complex<T1> x;
00091 x.re = ((r.re*l.re) - (r.im*l.im));
00092 x.im = (r.re*l.im + r.im*l.re);
00093 return x;
00094 };
00096 template <class T1, class T2> inline complex<T1> operator +(complex<T1> r, complex<T2> l)
00097 {
00098 complex<T1> x;
00099 x.re = r.re + l.re;
00100 x.im = r.im + l.im;
00101 return x;
00102 };
00104 template <class T> inline complex<T> operator +(complex<T> r, T l)
00105 {
00106 complex<T> x;
00107 x.re = r.re + l;
00108 x.im = r.im;
00109 return x;
00110 };
00112 template <class T> inline complex<T> operator +(T r, complex<T> l)
00113 {
00114 complex<T> x;
00115 x.re = r + l.re;
00116 x.im = l.im;
00117 return x;
00118 };
00119
00121 template <class T1, class T2> inline complex<T1> operator -(complex<T1> r, complex<T2> l)
00122 {
00123 complex<T1> x;
00124 x.re = r.re - l.re;
00125 x.im = r.im - l.im;
00126 return x;
00127 };
00129 template <class T> inline complex<T> operator -(complex<T> r, T l)
00130 {
00131 complex<T> x;
00132 x.re = r.re - l;
00133 x.im = r.im;
00134 return x;
00135 };
00137 template <class T> inline complex<T> operator -(T r, complex<T> l)
00138 {
00139 complex<T> x;
00140 x.re = r - l.re;
00141 x.im = -l.im;
00142 return x;
00143 };
00145 template <class T> inline complex<T> operator &(complex<T> r, T l)
00146 {
00147 complex<T> x;
00148 x.re = r.re & l;
00149 x.im = r.im & l;
00150 return x;
00151 };
00153 template <class T> inline complex<T> operator &(T r, complex<T> l)
00154 {
00155 complex<T> x;
00156 x.re = r & l.re;
00157 x.im = r & l.im;
00158 return x;
00159 };
00160 template <class T> inline complex<T> operator %(complex<T> r, T l)
00161 {
00162 complex<T> x;
00163 x.re = r.re % l;
00164 x.im = r.im % l;
00165 return x;
00166 };
00168 template <class T> inline complex<T> operator ^(complex<T> r, T l)
00169 {
00170 complex<T> x;
00171 x.re = r.re ^ l;
00172 x.im = r.im ^ l;
00173 return x;
00174 };
00176 template <class T> inline complex<T> operator ^(T r, complex<T> l)
00177 {
00178 complex<T> x;
00179 x.re = r ^ l.re;
00180 x.im = r ^ l.im;
00181 return x;
00182 };
00183 template <class T> inline complex<T> operator |(complex<T> r, T l)
00184 {
00185 complex<T> x;
00186 x.re = r.re | l;
00187 x.im = r.im | l;
00188 return x;
00189 };
00191 template <class T> inline complex<T> operator |(T r, complex<T> l)
00192 {
00193 complex<T> x;
00194 x.re = r | l.re;
00195 x.im = r | l.im;
00196 return x;
00197 };
00198
00200 template <class T> inline complex<T> operator <<(complex<T> r, const long shift)
00201 {
00202 complex<long> res = complex<long>(r.re << shift, r.im << shift);
00203 return(res);
00204 }
00206 template <class T> inline complex<T> operator >>(complex<T> r, const long shift)
00207 {
00208 complex<long> res = complex<long>(r.re >> shift, r.im >> shift);
00209 return(res);
00210 }
00212 template <class T> inline complex<T> operator -(complex<T> r)
00213 {
00214 complex<T> x;
00215 x.re = -r.re;
00216 x.im = -r.im;
00217 return x;
00218 };
00219
00220
00221
00222
00224 inline complex<long> operator *( double r, complex<long> l)
00225 {
00226 return(complex<long>((long)floor((double)(r*l.re+0.5)),
00227 (long)floor((double)(r*l.im+0.5))));
00228
00229 };
00231 inline complex<double> operator *( long r, complex<double> l)
00232 {
00233 complex<double> x;
00234 x.re = (r*l.re);
00235 x.im = (r*l.im);
00236 return x;
00237 };
00239 inline complex<double> operator *( double r, complex<double> l)
00240 {
00241 complex<double> x;
00242 x.re = (r*l.re);
00243 x.im = (r*l.im);
00244 return x;
00245 };
00246
00248 template <class T> inline complex<T> operator *(complex<T> r, T l)
00249 {
00250 complex<T> x;
00251 x.re = r.re*l;
00252 x.im = r.im*l;
00253 return x;
00254 };
00255
00257 template <class T> complex<T> operator /(complex<T> l, T r)
00258 {
00259 complex<T> x(0,0);
00260 if (r != 0)
00261 {
00262 x.re = l.re/r;
00263 x.im = l.im/r;
00264 }
00266 return x;
00267 };
00268
00270 template <class T1, class T2> complex<T1> operator /(complex<T1> r, complex<T2> l)
00271 {
00272 complex<T1> x;
00273 T2 den;
00274 den = magsq(l);
00275 x = (r * conj(l))/den;
00276 return x;
00277 };
00278
00280 template <class T1, class T2> inline bool operator ==(complex<T1> r, complex<T2> l)
00281 {
00282 return ((r.re == l.re) && (r.im == l.im));
00283 };
00284
00286 template <class T1, class T2> inline bool operator !=(complex<T1> r, complex<T2> l)
00287 {
00288 return ((r.re != l.re) || (r.im != l.im));
00289 };
00290
00292 inline complex<double> expj(double x)
00293 {
00294 complex<double> y;
00295 y.re = cos(x);
00296 y.im = sin(x);
00297 return y;
00298 }
00300 inline complex<double> polar(double amp,double arg)
00301 {
00302 complex<double> y;
00303 y.re = amp*cos(arg);
00304 y.im = amp*sin(arg);
00305 return y;
00306 }
00307
00309 template <class T> inline complex<T> complexj(void)
00310 {
00311 return(complex<T>(0,1));
00312 }
00313
00314 template <class T> inline T re(complex<T> x)
00315 {
00316 T y;
00317 y = x.re;
00318 return y;
00319 };
00320
00321 template <class T> inline T im(complex<T> x)
00322 {
00323 T y;
00324 y = x.im;
00325 return y;
00326 };
00327
00329 template <class T> inline complex<T> conj(complex<T> x)
00330 {
00331 complex<T> y;
00332 y.re = x.re;
00333 y.im = -x.im;
00334 return y;
00335 }
00337 template <class T> inline T magsq(complex<T> x)
00338 {
00339 T y;
00340 y = (x.re*x.re + x.im*x.im);
00341 return y;
00342 };
00344 template <class T> inline complex<double> norm(complex<T> x)
00345 {
00346 T y;
00347 y = ::sqrt(x.re*x.re + x.im*x.im);
00348 return (complex<double>(x.re/y,x.im/y));
00349 };
00350
00351
00352 template <class T> inline T approx_mag(complex<T> x)
00353 {
00354 return(MAX(abs(x.re),abs(x.im)) + MIN(abs(x.re),abs(x.im))/4);
00355 };
00356
00357 template <class T> inline complex<T> maxvalue(complex<T> x1)
00358 {
00359 return(complex<T>(MAX(x1.re,x1.im)));
00360 };
00361
00362 template <class T> inline complex<T> minimum(complex<T> x1, complex<T> x2)
00363 {
00364 return(complex<T>(MIN(x1.re,x2.re),MIN(x1.im,x2.im)));
00365 }
00366 template <class T> inline complex<T> maximum(complex<T> x1, complex<T> x2)
00367 {
00368 return(complex<T>(MAX(x1.re,x2.re),MAX(x1.im,x2.im)));
00369 };
00371 template <class T> inline double arg(const complex<T> x)
00372 {
00373 double TMPANG;
00374 if (real(x) == 0) {
00375 if (imag(x) < 0) return(3.0*PI/2.0);
00376 else return(PI/2.0);
00377 } else {
00378 TMPANG=atan((double)imag(x)/(double)real(x));
00379 if (real(x) < 0) TMPANG -= PI;
00380 if (TMPANG < 0) TMPANG += TWOPI;
00381 }
00382 return(TMPANG);
00383 }
00385 template <class T> inline complex<double> rational(complex<T> l) {
00386 return(complex<double>((double)l.re,(double)l.im));
00387 }
00388
00390 inline complex<long> round(complex<long> in, long bits)
00391 {
00392 double scale = 1.0/(double)(1 << bits);
00393 return(complex<long>((long)floor((double)(scale*in.re)+0.5),
00394 (long)floor((double)(scale*in.im)+0.5)));
00395 }
00397 inline complex<long> saturate(complex<long> in, long bits)
00398 {
00399 complex<long> out;
00400 long low_mask = ((1<<(bits-1)) - 1);
00401 if (labs(in.re) > low_mask) out.re = (in.re>0) ? low_mask : ~low_mask;
00402 else out.re = in.re;
00403 if (labs(in.im) > low_mask) out.im = (in.im>0) ? low_mask : ~low_mask;
00404 else out.im = in.im;
00405 return(out);
00406 }
00407 template <class T> complex<T> signbit(complex<T> in)
00408 {
00409 return(complex<T>(SGN(in.re),SGN(in.im)));
00410 }
00411
00412
00413
00414
00415 template <class T> inline complex<double> reciprocal(complex<T> x)
00416 {
00417 T y;
00418 y = (x.re*x.re + x.im*x.im);
00419 return (complex<double>(x.re/y,-x.im/y));
00420 };
00422 template <class T> inline complex<T> sqr(complex<T> x)
00423 {
00424 return (x*x);
00425 };
00427 template <class T> inline complex<double> csqrt(complex<T> x)
00428 {
00429 double mag = sqrt(sqrt(magsq(x)));
00430 double ang = 0.5*arg(x);
00431 return(polar(mag,ang));
00432 };
00434 inline complex<double> exp(complex<double> x)
00435 {
00436 return (::exp(x.real()) * expj(x.imag()));
00437 }
00439 inline double hypot(complex<double> z) {
00440 double _hypot(double x, double y);
00441 return _hypot(z.imag(), z.real()); }
00442 #endif
00443 }
00444 #endif