00001 #ifndef SimTK_SIMMATRIX_CONJUGATE_H_
00002 #define SimTK_SIMMATRIX_CONJUGATE_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00068 #include <complex>
00069 #include <iostream>
00070 #include <limits>
00071
00072 using std::complex;
00073
00074
00075
00076
00077
00078
00079
00080 #ifndef SimTK_MIXED_PRECISION_REAL_COMPLEX_ALREADY_DEFINED
00081 namespace SimTK {
00082
00083 inline complex<float> operator*(const complex<float>& c,int r) {return c*(float)r;}
00084 inline complex<float> operator*(int r,const complex<float>& c) {return (float)r*c;}
00085 inline complex<double> operator*(const complex<float>& c,const double& r) {return complex<double>(c)*r;}
00086 inline complex<double> operator*(const double& r,const complex<float>& c) {return r*complex<double>(c);}
00087 inline complex<long double> operator*(const complex<float>& c,const long double& r) {return complex<long double>(c)*r;}
00088 inline complex<long double> operator*(const long double& r,const complex<float>& c) {return r*complex<long double>(c);}
00089
00090 inline complex<float> operator/(const complex<float>& c,int r) {return c/(float)r;}
00091 inline complex<float> operator/(int r,const complex<float>& c) {return (float)r/c;}
00092 inline complex<double> operator/(const complex<float>& c,const double& r) {return complex<double>(c)/r;}
00093 inline complex<double> operator/(const double& r,const complex<float>& c) {return r/complex<double>(c);}
00094 inline complex<long double> operator/(const complex<float>& c,const long double& r) {return complex<long double>(c)/r;}
00095 inline complex<long double> operator/(const long double& r,const complex<float>& c) {return r/complex<long double>(c);}
00096
00097 inline complex<float> operator+(const complex<float>& c,int r) {return c+(float)r;}
00098 inline complex<float> operator+(int r,const complex<float>& c) {return (float)r+c;}
00099 inline complex<double> operator+(const complex<float>& c,const double& r) {return complex<double>(c)+r;}
00100 inline complex<double> operator+(const double& r,const complex<float>& c) {return r+complex<double>(c);}
00101 inline complex<long double> operator+(const complex<float>& c,const long double& r) {return complex<long double>(c)+r;}
00102 inline complex<long double> operator+(const long double& r,const complex<float>& c) {return r+complex<long double>(c);}
00103
00104 inline complex<float> operator-(const complex<float>& c,int r) {return c-(float)r;}
00105 inline complex<float> operator-(int r,const complex<float>& c) {return (float)r-c;}
00106 inline complex<double> operator-(const complex<float>& c,const double& r) {return complex<double>(c)-r;}
00107 inline complex<double> operator-(const double& r,const complex<float>& c) {return r-complex<double>(c);}
00108 inline complex<long double> operator-(const complex<float>& c,const long double& r) {return complex<long double>(c)-r;}
00109 inline complex<long double> operator-(const long double& r,const complex<float>& c) {return r-complex<long double>(c);}
00110
00111
00112 inline complex<double> operator*(const complex<double>& c,int r) {return c*(double)r;}
00113 inline complex<double> operator*(int r,const complex<double>& c) {return (double)r*c;}
00114 inline complex<double> operator*(const complex<double>& c,const float& r) {return c*(double)r;}
00115 inline complex<double> operator*(const float& r,const complex<double>& c) {return (double)r*c;}
00116 inline complex<long double> operator*(const complex<double>& c,const long double& r){return complex<long double>(c)*r;}
00117 inline complex<long double> operator*(const long double& r,const complex<double>& c){return r*complex<long double>(c);}
00118
00119 inline complex<double> operator/(const complex<double>& c,int r) {return c/(double)r;}
00120 inline complex<double> operator/(int r,const complex<double>& c) {return (double)r/c;}
00121 inline complex<double> operator/(const complex<double>& c,const float& r) {return c/(double)r;}
00122 inline complex<double> operator/(const float& r,const complex<double>& c) {return (double)r/c;}
00123 inline complex<long double> operator/(const complex<double>& c,const long double& r){return complex<long double>(c)/r;}
00124 inline complex<long double> operator/(const long double& r,const complex<double>& c){return r/complex<long double>(c);}
00125
00126 inline complex<double> operator+(const complex<double>& c,int r) {return c+(double)r;}
00127 inline complex<double> operator+(int r,const complex<double>& c) {return (double)r+c;}
00128 inline complex<double> operator+(const complex<double>& c,const float& r) {return c+(double)r;}
00129 inline complex<double> operator+(const float& r,const complex<double>& c) {return (double)r+c;}
00130 inline complex<long double> operator+(const complex<double>& c,const long double& r){return complex<long double>(c)+r;}
00131 inline complex<long double> operator+(const long double& r,const complex<double>& c){return r+complex<long double>(c);}
00132
00133 inline complex<double> operator-(const complex<double>& c,int r) {return c-(double)r;}
00134 inline complex<double> operator-(int r,const complex<double>& c) {return (double)r-c;}
00135 inline complex<double> operator-(const complex<double>& c,const float& r) {return c-(double)r;}
00136 inline complex<double> operator-(const float& r,const complex<double>& c) {return (double)r-c;}
00137 inline complex<long double> operator-(const complex<double>& c,const long double& r){return complex<long double>(c)-r;}
00138 inline complex<long double> operator-(const long double& r,const complex<double>& c){return r-complex<long double>(c);}
00139
00140
00141 inline complex<long double> operator*(const complex<long double>& c,int r) {return c*(long double)r;}
00142 inline complex<long double> operator*(int r,const complex<long double>& c) {return (long double)r*c;}
00143 inline complex<long double> operator*(const complex<long double>& c,const float& r) {return c*(long double)r;}
00144 inline complex<long double> operator*(const float& r,const complex<long double>& c) {return (long double)r*c;}
00145 inline complex<long double> operator*(const complex<long double>& c,const double& r){return c*(long double)r;}
00146 inline complex<long double> operator*(const double& r,const complex<long double>& c){return (long double)r*c;}
00147
00148 inline complex<long double> operator/(const complex<long double>& c,int r) {return c/(long double)r;}
00149 inline complex<long double> operator/(int r,const complex<long double>& c) {return (long double)r/c;}
00150 inline complex<long double> operator/(const complex<long double>& c,const float& r) {return c/(long double)r;}
00151 inline complex<long double> operator/(const float& r,const complex<long double>& c) {return (long double)r/c;}
00152 inline complex<long double> operator/(const complex<long double>& c,const double& r){return c/(long double)r;}
00153 inline complex<long double> operator/(const double& r,const complex<long double>& c){return (long double)r/c;}
00154
00155 inline complex<long double> operator+(const complex<long double>& c,int r) {return c+(long double)r;}
00156 inline complex<long double> operator+(int r,const complex<long double>& c) {return (long double)r+c;}
00157 inline complex<long double> operator+(const complex<long double>& c,const float& r) {return c+(long double)r;}
00158 inline complex<long double> operator+(const float& r,const complex<long double>& c) {return (long double)r+c;}
00159 inline complex<long double> operator+(const complex<long double>& c,const double& r){return c+(long double)r;}
00160 inline complex<long double> operator+(const double& r,const complex<long double>& c){return (long double)r+c;}
00161
00162 inline complex<long double> operator-(const complex<long double>& c,int r) {return c-(long double)r;}
00163 inline complex<long double> operator-(int r,const complex<long double>& c) {return (long double)r-c;}
00164 inline complex<long double> operator-(const complex<long double>& c,const float& r) {return c-(long double)r;}
00165 inline complex<long double> operator-(const float& r,const complex<long double>& c) {return (long double)r-c;}
00166 inline complex<long double> operator-(const complex<long double>& c,const double& r){return c-(long double)r;}
00167 inline complex<long double> operator-(const double& r,const complex<long double>& c){return (long double)r-c;}
00168 }
00169 #endif
00170
00171 namespace SimTK {
00172
00173 template <class R> class conjugate;
00174 template <> class conjugate<float>;
00175 template <> class conjugate<double>;
00176 template <> class conjugate<long double>;
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 template <class N> class negator;
00187
00188
00189
00190
00191
00192
00193 template <class R1, class R2> struct Wider {};
00194 template <> struct Wider<float,float> {
00195 typedef float WReal;
00196 typedef complex<float> WCplx;
00197 typedef conjugate<float> WConj;
00198 };
00199 template <> struct Wider<float,double> {
00200 typedef double WReal;
00201 typedef complex<double> WCplx;
00202 typedef conjugate<double> WConj;
00203 };
00204 template <> struct Wider<double,float> {
00205 typedef double WReal;
00206 typedef complex<double> WCplx;
00207 typedef conjugate<double> WConj;
00208 };
00209 template <> struct Wider<double,double> {
00210 typedef double WReal;
00211 typedef complex<double> WCplx;
00212 typedef conjugate<double> WConj;
00213 };
00214 template <> struct Wider<float,long double> {
00215 typedef long double WReal;
00216 typedef complex<long double> WCplx;
00217 typedef conjugate<long double> WConj;
00218 };
00219 template <> struct Wider<double,long double> {
00220 typedef long double WReal;
00221 typedef complex<long double> WCplx;
00222 typedef conjugate<long double> WConj;
00223 };
00224 template <> struct Wider<long double,float> {
00225 typedef long double WReal;
00226 typedef complex<long double> WCplx;
00227 typedef conjugate<long double> WConj;
00228 };
00229 template <> struct Wider<long double,double> {
00230 typedef long double WReal;
00231 typedef complex<long double> WCplx;
00232 typedef conjugate<long double> WConj;
00233 };
00234 template <> struct Wider<long double,long double> {
00235 typedef long double WReal;
00236 typedef complex<long double> WCplx;
00237 typedef conjugate<long double> WConj;
00238 };
00239
00240
00257 template <class R> class conjugate {};
00258
00260
00262
00263 template <> class conjugate<float> {
00264 public:
00265 conjugate() {
00266 #ifndef NDEBUG
00267 re = negIm = std::numeric_limits<float>::quiet_NaN();
00268 #endif
00269 }
00270
00271
00273 conjugate(const float& real, const float& imag) { re = real; negIm = imag; }
00274 conjugate(const float& real, int i) { re = real; negIm = float(i); }
00275 conjugate(int r, const float& imag) { re = float(r); negIm = imag; }
00276 conjugate(int r, int i) { re = float(r); negIm = float(i); }
00277
00279 conjugate(const float& real) { re = real; negIm = 0.f; }
00280 conjugate(int r) { re = float(r); negIm = 0.f; }
00281
00282
00283
00284
00285 inline explicit conjugate(const conjugate<double>& cd);
00286 inline explicit conjugate(const conjugate<long double>& cl);
00287
00288 explicit conjugate(const double& rd)
00289 { re = float(rd); negIm = 0.f; }
00290 explicit conjugate(const long double& rl)
00291 { re = float(rl); negIm = 0.f; }
00292
00293
00294
00295
00296 explicit conjugate(const complex<float>& x)
00297 { re = x.real(); negIm = -x.imag(); }
00298 explicit conjugate(const complex<double>& x)
00299 { re = float(x.real()); negIm = float(-x.imag()); }
00300 explicit conjugate(const complex<long double>& x)
00301 { re = float(x.real()); negIm = float(-x.imag()); }
00302
00305 operator complex<float>() const
00306 { return complex<float>(re,-negIm); }
00307
00308
00309
00310
00311 complex<float> operator-() const { return complex<float>(-re,negIm); }
00312
00313
00314 const conjugate& operator+() const { return *this; }
00315
00316
00317
00318
00319
00320 conjugate& operator=(const float& r)
00321 { re = r; negIm = 0.f; return *this; }
00322 conjugate& operator+=(const float& r)
00323 { re += r; return *this; }
00324 conjugate& operator-=(const float& r)
00325 { re -= r; return *this; }
00326 conjugate& operator*=(const float& r)
00327 { re *= r; negIm *= r; return *this; }
00328 conjugate& operator/=(const float& r)
00329 { re /= r; negIm /= r; return *this; }
00330
00331 conjugate& operator+=(const conjugate<float>& c)
00332 { re += c.re; negIm += c.negIm; return *this; }
00333 conjugate& operator-=(const conjugate<float>& c)
00334 { re -= c.re; negIm -= c.negIm; return *this; }
00335
00336 conjugate& operator=(const complex<float>& c)
00337 { re = c.real(); negIm = -c.imag(); return *this; }
00338 conjugate& operator+=(const complex<float>& c)
00339 { re += c.real(); negIm -= c.imag(); return *this; }
00340 conjugate& operator-=(const complex<float>& c)
00341 { re -= c.real(); negIm += c.imag(); return *this; }
00342
00343
00344
00345
00346
00347
00348
00349 conjugate& operator*=(const conjugate<float>& c) {
00350 const float r=(re*c.re - negIm*c.negIm);
00351 negIm=(re*c.negIm + negIm*c.re); re=r; return *this;
00352 }
00353 conjugate& operator*=(const complex<float>& t) {
00354 const float r=(re*t.real() + negIm*t.imag());
00355 negIm=(negIm*t.real() - re*t.imag()); re=r; return *this;
00356 }
00357
00358
00359
00360 conjugate& operator/=(const conjugate<float>& d) {
00361 const complex<float> t = conj()/d.conj();
00362 re = t.real(); negIm = t.imag();
00363 return *this;
00364 }
00365 conjugate& operator/=(const complex<float>& d) {
00366 const complex<float> t = conj()/std::conj(d);
00367 re = t.real(); negIm = t.imag();
00368 return *this;
00369 }
00370
00371 const float& real() const { return re; }
00372 float& real() { return re; }
00373
00374 const negator<float>& imag() const { return reinterpret_cast<const negator<float>&>(negIm); }
00375 negator<float>& imag() { return reinterpret_cast<negator<float>&>(negIm); }
00376
00377 const complex<float>& conj() const { return reinterpret_cast<const complex<float>&>(*this); }
00378 complex<float>& conj() { return reinterpret_cast<complex<float>&>(*this); }
00379
00380
00381 const float& negImag() const { return negIm; }
00382 float& negImag() { return negIm; }
00383 bool isReal() const { return negIm==0.f; }
00384
00385 private:
00386 float re;
00387 float negIm;
00388 };
00389
00390
00391
00392
00394
00396
00397 template <> class conjugate<double> {
00398 public:
00399 conjugate() {
00400 #ifndef NDEBUG
00401 re = negIm = std::numeric_limits<double>::quiet_NaN();
00402 #endif
00403 }
00404
00405
00407 conjugate(const double& real, const double& imag) { re = real; negIm = imag; }
00408 conjugate(const double& real, int i) { re = real; negIm = double(i); }
00409 conjugate(int r, const double& imag) { re = double(r); negIm = imag; }
00410 conjugate(int r, int i) { re = double(r); negIm = double(i); }
00411
00413 conjugate(const double& real) { re = real; negIm = 0.; }
00414 conjugate(int r) { re = double(r); negIm = 0.; }
00415
00416
00417
00418
00419 conjugate(const conjugate<float>& cf)
00420 { re = double(cf.real()); negIm = double(cf.negImag()); }
00421 conjugate(const float& rf)
00422 { re = double(rf); negIm = 0.; }
00423
00424
00425 inline explicit conjugate(const conjugate<long double>& cl);
00426 explicit conjugate(const long double& rl)
00427 { re = double(rl); negIm = 0.; }
00428
00429
00430
00431
00432 explicit conjugate(const complex<float>& x)
00433 { re = double(x.real()); negIm = double(-x.imag()); }
00434 explicit conjugate(const complex<double>& x)
00435 { re = x.real(); negIm = -x.imag(); }
00436 explicit conjugate(const complex<long double>& x)
00437 { re = double(x.real()); negIm = double(-x.imag()); }
00438
00441 operator complex<double>() const
00442 { return complex<double>(re,-negIm); }
00443
00444
00445
00446
00447 complex<double> operator-() const { return complex<double>(-re,negIm); }
00448
00449
00450 const conjugate& operator+() const { return *this; }
00451
00452
00453
00454
00455
00456 conjugate& operator=(const double& r)
00457 { re = r; negIm = 0.; return *this; }
00458 conjugate& operator+=(const double& r)
00459 { re += r; return *this; }
00460 conjugate& operator-=(const double& r)
00461 { re -= r; return *this; }
00462 conjugate& operator*=(const double& r)
00463 { re *= r; negIm *= r; return *this; }
00464 conjugate& operator/=(const double& r)
00465 { re /= r; negIm /= r; return *this; }
00466
00467 conjugate& operator=(const float& r)
00468 { re = r; negIm = 0.; return *this; }
00469 conjugate& operator+=(const float& r)
00470 { re += r; return *this; }
00471 conjugate& operator-=(const float& r)
00472 { re -= r; return *this; }
00473 conjugate& operator*=(const float& r)
00474 { re *= r; negIm *= r; return *this; }
00475 conjugate& operator/=(const float& r)
00476 { re /= r; negIm /= r; return *this; }
00477
00478 conjugate& operator+=(const conjugate<double>& c)
00479 { re += c.re; negIm += c.negIm; return *this; }
00480 conjugate& operator-=(const conjugate<double>& c)
00481 { re -= c.re; negIm -= c.negIm; return *this; }
00482
00483 conjugate& operator+=(const conjugate<float>& c)
00484 { re += c.real(); negIm += c.negImag(); return *this; }
00485 conjugate& operator-=(const conjugate<float>& c)
00486 { re -= c.real(); negIm -= c.negImag(); return *this; }
00487
00488 conjugate& operator=(const complex<double>& c)
00489 { re = c.real(); negIm = -c.imag(); return *this; }
00490 conjugate& operator+=(const complex<double>& c)
00491 { re += c.real(); negIm -= c.imag(); return *this; }
00492 conjugate& operator-=(const complex<double>& c)
00493 { re -= c.real(); negIm += c.imag(); return *this; }
00494
00495 conjugate& operator=(const complex<float>& c)
00496 { re = c.real(); negIm = -c.imag(); return *this; }
00497 conjugate& operator+=(const complex<float>& c)
00498 { re += c.real(); negIm -= c.imag(); return *this; }
00499 conjugate& operator-=(const complex<float>& c)
00500 { re -= c.real(); negIm += c.imag(); return *this; }
00501
00502
00503
00504
00505
00506
00507
00508 conjugate& operator*=(const conjugate<double>& c) {
00509 const double r=(re*c.re - negIm*c.negIm);
00510 negIm=(re*c.negIm + negIm*c.re); re=r; return *this;
00511 }
00512 conjugate& operator*=(const complex<double>& t) {
00513 const double r=(re*t.real() + negIm*t.imag());
00514 negIm=(negIm*t.real() - re*t.imag()); re=r; return *this;
00515 }
00516
00517 conjugate& operator*=(const conjugate<float>& c) { return operator*=(conjugate<double>(c)); }
00518 conjugate& operator*=(const complex<float>& c) { return operator*=(complex<double>(c)); }
00519
00520
00521
00522 conjugate& operator/=(const conjugate<double>& d) {
00523 const complex<double> t = conj()/d.conj();
00524 re = t.real(); negIm = t.imag();
00525 return *this;
00526 }
00527 conjugate& operator/=(const complex<double>& d) {
00528 const complex<double> t = conj()/std::conj(d);
00529 re = t.real(); negIm = t.imag();
00530 return *this;
00531 }
00532
00533 conjugate& operator/=(const conjugate<float>& c) { return operator/=(conjugate<double>(c)); }
00534 conjugate& operator/=(const complex<float>& c) { return operator/=(complex<double>(c)); }
00535
00536 const double& real() const { return re; }
00537 double& real() { return re; }
00538
00539 const negator<double>& imag() const { return reinterpret_cast<const negator<double>&>(negIm); }
00540 negator<double>& imag() { return reinterpret_cast<negator<double>&>(negIm); }
00541
00542 const complex<double>& conj() const { return reinterpret_cast<const complex<double>&>(*this); }
00543 complex<double>& conj() { return reinterpret_cast<complex<double>&>(*this); }
00544
00545
00546 const double& negImag() const { return negIm; }
00547 double& negImag() { return negIm; }
00548 bool isReal() const { return negIm==0.; }
00549
00550 private:
00551 double re;
00552 double negIm;
00553 };
00554
00555
00556
00558
00560
00561 template <> class conjugate<long double> {
00562 public:
00563 conjugate() {
00564 #ifndef NDEBUG
00565 re = negIm = std::numeric_limits<long double>::quiet_NaN();
00566 #endif
00567 }
00568
00569
00571 conjugate(const long double& real, const long double& imag) { re = real; negIm = imag; }
00572 conjugate(const long double& real, int i) { re = real; negIm = (long double)i; }
00573 conjugate(int r, const long double& imag) { re = (long double)r; negIm = imag; }
00574 conjugate(int r, int i) { re = (long double)r; negIm = (long double)i; }
00575
00577 conjugate(const long double& real) { re = real; negIm = 0.L; }
00578 conjugate(int r) { re = (long double)r; negIm = 0.L; }
00579
00580
00581
00582 conjugate(const conjugate<float>& cf)
00583 { re = (long double)cf.real(); negIm = (long double)cf.negImag(); }
00584 conjugate(const conjugate<double>& cd)
00585 { re = (long double)cd.real(); negIm = (long double)cd.negImag(); }
00586
00587 conjugate(const float& rf)
00588 { re = (long double)rf; negIm = 0.L; }
00589 conjugate(const double& rd)
00590 { re = (long double)rd; negIm = 0.L; }
00591
00592
00593
00594
00595
00596 explicit conjugate(const complex<float>& x)
00597 { re = (long double)x.real(); negIm = (long double)(-x.imag()); }
00598 explicit conjugate(const complex<double>& x)
00599 { re = (long double)x.real(); negIm = (long double)(-x.imag()); }
00600 explicit conjugate(const complex<long double>& x)
00601 { re = x.real(); negIm = -x.imag(); }
00602
00605 operator complex<long double>() const
00606 { return complex<long double>(re,-negIm); }
00607
00608
00609
00610
00611 complex<long double> operator-() const
00612 { return complex<long double>(-re,negIm); }
00613
00614
00615 const conjugate& operator+() const { return *this; }
00616
00617
00618
00619
00620
00621
00622 conjugate& operator=(const long double& r)
00623 { re = r; negIm = 0.L; return *this; }
00624 conjugate& operator+=(const long double& r)
00625 { re += r; return *this; }
00626 conjugate& operator-=(const long double& r)
00627 { re -= r; return *this; }
00628 conjugate& operator*=(const long double& r)
00629 { re *= r; negIm *= r; return *this; }
00630 conjugate& operator/=(const long double& r)
00631 { re /= r; negIm /= r; return *this; }
00632
00633 conjugate& operator=(const double& r)
00634 { re = r; negIm = 0.L; return *this; }
00635 conjugate& operator+=(const double& r)
00636 { re += r; return *this; }
00637 conjugate& operator-=(const double& r)
00638 { re -= r; return *this; }
00639 conjugate& operator*=(const double& r)
00640 { re *= r; negIm *= r; return *this; }
00641 conjugate& operator/=(const double& r)
00642 { re /= r; negIm /= r; return *this; }
00643
00644 conjugate& operator=(const float& r)
00645 { re = r; negIm = 0.L; return *this; }
00646 conjugate& operator+=(const float& r)
00647 { re += r; return *this; }
00648 conjugate& operator-=(const float& r)
00649 { re -= r; return *this; }
00650 conjugate& operator*=(const float& r)
00651 { re *= r; negIm *= r; return *this; }
00652 conjugate& operator/=(const float& r)
00653 { re /= r; negIm /= r; return *this; }
00654
00655 conjugate& operator+=(const conjugate<long double>& c)
00656 { re += c.re; negIm += c.negIm; return *this; }
00657 conjugate& operator-=(const conjugate<long double>& c)
00658 { re -= c.re; negIm -= c.negIm; return *this; }
00659
00660 conjugate& operator+=(const conjugate<double>& c)
00661 { re += c.real(); negIm += c.negImag(); return *this; }
00662 conjugate& operator-=(const conjugate<double>& c)
00663 { re -= c.real(); negIm -= c.negImag(); return *this; }
00664
00665 conjugate& operator+=(const conjugate<float>& c)
00666 { re += c.real(); negIm += c.negImag(); return *this; }
00667 conjugate& operator-=(const conjugate<float>& c)
00668 { re -= c.real(); negIm -= c.negImag(); return *this; }
00669
00670 conjugate& operator=(const complex<long double>& c)
00671 { re = c.real(); negIm = -c.imag(); return *this; }
00672 conjugate& operator+=(const complex<long double>& c)
00673 { re += c.real(); negIm -= c.imag(); return *this; }
00674 conjugate& operator-=(const complex<long double>& c)
00675 { re -= c.real(); negIm += c.imag(); return *this; }
00676
00677 conjugate& operator=(const complex<double>& c)
00678 { re = c.real(); negIm = -c.imag(); return *this; }
00679 conjugate& operator+=(const complex<double>& c)
00680 { re += c.real(); negIm -= c.imag(); return *this; }
00681 conjugate& operator-=(const complex<double>& c)
00682 { re -= c.real(); negIm += c.imag(); return *this; }
00683
00684 conjugate& operator=(const complex<float>& c)
00685 { re = c.real(); negIm = -c.imag(); return *this; }
00686 conjugate& operator+=(const complex<float>& c)
00687 { re += c.real(); negIm -= c.imag(); return *this; }
00688 conjugate& operator-=(const complex<float>& c)
00689 { re -= c.real(); negIm += c.imag(); return *this; }
00690
00691
00692
00693
00694
00695
00696
00697 conjugate& operator*=(const conjugate<long double>& c) {
00698 const long double r=(re*c.re - negIm*c.negIm);
00699 negIm=(re*c.negIm + negIm*c.re); re=r; return *this;
00700 }
00701 conjugate& operator*=(const complex<long double>& t) {
00702 const long double r=(re*t.real() + negIm*t.imag());
00703 negIm=(negIm*t.real() - re*t.imag()); re=r; return *this;
00704 }
00705
00706 conjugate& operator*=(const conjugate<double>& c) { return operator*=(conjugate<long double>(c)); }
00707 conjugate& operator*=(const complex<double>& c) { return operator*=(complex<long double>(c)); }
00708 conjugate& operator*=(const conjugate<float>& c) { return operator*=(conjugate<long double>(c)); }
00709 conjugate& operator*=(const complex<float>& c) { return operator*=(complex<long double>(c)); }
00710
00711
00712
00713 conjugate& operator/=(const conjugate<long double>& d) {
00714 const complex<long double> t = conj()/d.conj();
00715 re = t.real(); negIm = t.imag();
00716 return *this;
00717 }
00718 conjugate& operator/=(const complex<long double>& d) {
00719 const complex<long double> t = conj()/std::conj(d);
00720 re = t.real(); negIm = t.imag();
00721 return *this;
00722 }
00723
00724 conjugate& operator/=(const conjugate<double>& c) { return operator/=(conjugate<long double>(c)); }
00725 conjugate& operator/=(const complex<double>& c) { return operator/=(complex<long double>(c)); }
00726 conjugate& operator/=(const conjugate<float>& c) { return operator/=(conjugate<long double>(c)); }
00727 conjugate& operator/=(const complex<float>& c) { return operator/=(complex<long double>(c)); }
00728
00729 const long double& real() const { return re; }
00730 long double& real() { return re; }
00731
00732 const negator<long double>& imag() const { return reinterpret_cast<const negator<long double>&>(negIm); }
00733 negator<long double>& imag() { return reinterpret_cast<negator<long double>&>(negIm); }
00734
00735 const complex<long double>& conj() const { return reinterpret_cast<const complex<long double>&>(*this); }
00736 complex<long double>& conj() { return reinterpret_cast<complex<long double>&>(*this); }
00737
00738
00739 const long double& negImag() const { return negIm; }
00740 long double& negImag() { return negIm; }
00741 bool isReal() const { return negIm==0.L; }
00742
00743 private:
00744 long double re;
00745 long double negIm;
00746 };
00747
00748
00749 conjugate<float>::conjugate(const conjugate<double>& cd) {
00750 re = float(cd.real()); negIm = float(cd.negImag());
00751 }
00752 conjugate<float>::conjugate(const conjugate<long double>& cl) {
00753 re = float(cl.real()); negIm = float(cl.negImag());
00754 }
00755 conjugate<double>::conjugate(const conjugate<long double>& cl) {
00756 re = double(cl.real()); negIm = double(cl.negImag());
00757 }
00758
00759
00760
00761
00762
00763
00764
00765 inline const float& real(const conjugate<float>& c) { return c.real(); }
00766 inline const negator<float>& imag(const conjugate<float>& c) { return c.imag(); }
00767 inline const complex<float>& conj(const conjugate<float>& c) { return c.conj(); }
00768 inline float abs (const conjugate<float>& c) { return std::abs(c.conj()); }
00769 inline float norm(const conjugate<float>& c) { return std::norm(c.conj()); }
00770
00771 inline const double& real(const conjugate<double>& c) { return c.real(); }
00772 inline const negator<double>& imag(const conjugate<double>& c) { return c.imag(); }
00773 inline const complex<double>& conj(const conjugate<double>& c) { return c.conj(); }
00774 inline double abs (const conjugate<double>& c) { return std::abs(c.conj()); }
00775 inline double norm(const conjugate<double>& c) { return std::norm(c.conj()); }
00776
00777 inline const long double& real(const conjugate<long double>& c) { return c.real(); }
00778 inline const negator<long double>& imag(const conjugate<long double>& c) { return c.imag(); }
00779 inline const complex<long double>& conj(const conjugate<long double>& c) { return c.conj(); }
00780 inline long double abs (const conjugate<long double>& c) { return std::abs(c.conj()); }
00781 inline long double norm(const conjugate<long double>& c) { return std::norm(c.conj()); }
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 template <class R, class CHAR, class TRAITS> inline std::basic_istream<CHAR,TRAITS>&
00794 operator>>(std::basic_istream<CHAR,TRAITS>& is, conjugate<R>& c) {
00795 complex<R> z; is >> z; c=z;
00796 return is;
00797 }
00798 template <class R, class CHAR, class TRAITS> inline std::basic_ostream<CHAR,TRAITS>&
00799 operator<<(std::basic_ostream<CHAR,TRAITS>& os, const conjugate<R>& c) {
00800 return os << complex<R>(c);
00801 }
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 template <class R> inline conjugate<R> operator+(const conjugate<R>& a, const float& b)
00817 { return conjugate<R>(a) += b; }
00818 template <class R> inline conjugate<long double> operator+(const conjugate<R>& a, const long double& b)
00819 { return conjugate<long double>(a) += b; }
00820 template <class R> inline typename Wider<R,double>::WConj operator+(const conjugate<R>& a, const double& b)
00821 { return typename Wider<R,double>::WConj(a) += b; }
00822
00823
00824 template <class R> inline conjugate<R> operator+(const float& a, const conjugate<R>& b) {return b+a;}
00825 template <class R> inline conjugate<long double> operator+(const long double& a, const conjugate<R>& b) {return b+a;}
00826 template <class R> inline typename Wider<R,double>::WConj operator+(const double& a, const conjugate<R>& b) {return b+a;}
00827
00828
00829 template <class R> inline conjugate<R> operator*(const conjugate<R>& a, const float& b)
00830 { return conjugate<R>(a) *= b; }
00831 template <class R> inline conjugate<long double> operator*(const conjugate<R>& a, const long double& b)
00832 { return conjugate<long double>(a) *= b; }
00833 template <class R> inline typename Wider<R,double>::WConj operator*(const conjugate<R>& a, const double& b)
00834 { return typename Wider<R,double>::WConj(a) *= b; }
00835
00836
00837 template <class R> inline conjugate<R> operator*(const float& a, const conjugate<R>& b) {return b*a;}
00838 template <class R> inline conjugate<long double> operator*(const long double& a, const conjugate<R>& b) {return b*a;}
00839 template <class R> inline typename Wider<R,double>::WConj operator*(const double& a, const conjugate<R>& b) {return b*a;}
00840
00841
00842 template <class R> inline bool operator==(const conjugate<R>& a, const float& b)
00843 { return a.isReal() && a.real()==b; }
00844 template <class R> inline bool operator==(const conjugate<R>& a, const long double& b)
00845 { return a.isReal() && a.real()==b; }
00846 template <class R> inline bool operator==(const conjugate<R>& a, const double& b)
00847 { return a.isReal() && a.real()==b; }
00848
00849
00850 template <class R> inline bool operator==(const float& a, const conjugate<R>& b) {return b==a;}
00851 template <class R> inline bool operator==(const long double& a, const conjugate<R>& b) {return b==a;}
00852 template <class R> inline bool operator==(const double& a, const conjugate<R>& b) {return b==a;}
00853 template <class R> inline bool operator!=(const conjugate<R>& a, const float& b) {return !(a==b);}
00854 template <class R> inline bool operator!=(const conjugate<R>& a, const long double& b) {return !(a==b);}
00855 template <class R> inline bool operator!=(const conjugate<R>& a, const double& b) {return !(a==b);}
00856 template <class R> inline bool operator!=(const float& a, const conjugate<R>& b) {return !(a==b);}
00857 template <class R> inline bool operator!=(const long double& a, const conjugate<R>& b) {return !(a==b);}
00858 template <class R> inline bool operator!=(const double& a, const conjugate<R>& b) {return !(a==b);}
00859
00860
00861
00862
00863 template <class R> inline conjugate<R> operator-(const conjugate<R>& a, const float& b)
00864 { return conjugate<R>(a) -= b; }
00865 template <class R> inline conjugate<long double> operator-(const conjugate<R>& a, const long double& b)
00866 { return conjugate<long double>(a) -= b; }
00867 template <class R> inline typename Wider<R,double>::WConj operator-(const conjugate<R>& a, const double& b)
00868 { return typename Wider<R,double>::WConj(a) -= b; }
00869
00870
00871
00872 template <class R> inline complex<R> operator-(const float& a, const conjugate<R>& b)
00873 { return complex<R>(a-b.real(), -b.imag()); }
00874 template <class R> inline complex<long double> operator-(const long double& a, const conjugate<R>& b)
00875 { return complex<long double>(a-b.real(), -b.imag()); }
00876 template <class R> inline typename Wider<R,double>::WCplx operator-(const double& a, const conjugate<R>& b)
00877 { return typename Wider<R,double>::WCplx(a-b.real(), -b.imag()); }
00878
00879
00880 template <class R> inline conjugate<R> operator/(const conjugate<R>& a, const float& b)
00881 { return conjugate<R>(a) /= b; }
00882 template <class R> inline conjugate<long double> operator/(const conjugate<R>& a, const long double& b)
00883 { return conjugate<long double>(a) /= b; }
00884 template <class R> inline typename Wider<R,double>::WConj operator/(const conjugate<R>& a, const double& b)
00885 { return typename Wider<R,double>::WConj(a) /= b; }
00886
00887
00888
00889
00890 template <class R> inline complex<R> operator/(const float& a, const conjugate<R>& b)
00891 { return (R)a/complex<R>(b); }
00892 template <class R> inline complex<long double> operator/(const long double& a, const conjugate<R>& b)
00893 { return a/complex<long double>(b); }
00894 template <class R> inline typename Wider<R,double>::WCplx operator/(const double& a, const conjugate<R>& b)
00895 { return (typename Wider<R,double>::WReal)a/(typename Wider<R,double>::WCplx(b)); }
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905 template <class R, class S> inline typename Wider<R,S>::WConj
00906 operator+(const conjugate<R>& a, const conjugate<S>& r) {
00907 return typename Wider<R,S>::WConj(a.real()+r.real(),
00908 a.negImag()+r.negImag());
00909 }
00910
00911
00912 template <class R, class S> inline typename Wider<R,S>::WCplx
00913 operator+(const conjugate<R>& a, const complex<S>& r) {
00914 return typename Wider<R,S>::WCplx(a.real()+r.real(),
00915 r.imag()-a.negImag());
00916 }
00917 template <class R, class S> inline typename Wider<R,S>::WCplx
00918 operator+(const complex<R>& a, const conjugate<S>& r) { return r+a; }
00919
00920
00921 template <class R, class S> inline typename Wider<R,S>::WCplx
00922 operator-(const conjugate<R>& a, const conjugate<S>& r) {
00923 return typename Wider<R,S>::WCplx(a.real()-r.real(),
00924 r.negImag()-a.negImag());
00925 }
00926
00927
00928 template <class R, class S> inline negator<typename Wider<R,S>::WCplx>
00929 operator-(const conjugate<R>& a, const complex<S>& r) {
00930 return negator<typename Wider<R,S>::WCplx>::recast
00931 (typename Wider<R,S>::WCplx(r.real()-a.real(),
00932 a.negImag()+r.imag()));
00933 }
00934
00935
00936 template <class R, class S> inline typename Wider<R,S>::WCplx
00937 operator-(const complex<R>& a, const conjugate<S>& r) {
00938 return typename Wider<R,S>::WCplx(a.real()-r.real(),
00939 a.imag()+r.negImag());
00940 }
00941
00942
00943
00944
00945
00946
00947
00948 template <class R, class S> inline negator<typename Wider<R,S>::WCplx>
00949 operator*(const conjugate<R>& a, const conjugate<S>& r) {
00950 return negator<typename Wider<R,S>::WCplx>::recast
00951 (typename Wider<R,S>::WCplx(a.negImag()*r.negImag() - a.real()*r.real(),
00952 a.real()*r.negImag() + a.negImag()*r.real()));
00953 }
00954
00955
00956 template <class R, class S> inline typename Wider<R,S>::WCplx
00957 operator*(const conjugate<R>& a, const complex<S>& r) {
00958 return typename Wider<R,S>::WCplx(a.real()*r.real() + a.negImag()*r.imag(),
00959 a.real()*r.imag() - a.negImag()*r.real());
00960 }
00961
00962 template <class R, class S> inline typename Wider<R,S>::WCplx
00963 operator*(const complex<R>& a, const conjugate<S>& r)
00964 { return r*a; }
00965
00966
00967
00968
00969
00970 template <class R, class S> inline typename Wider<R,S>::WCplx
00971 operator/(const conjugate<R>& a, const conjugate<S>& r) {
00972 return std::conj(a.conj()/r.conj());
00973 }
00974
00975 template <class R, class S> inline typename Wider<R,S>::WCplx
00976 operator/(const conjugate<R>& a, const complex<S>& r) {
00977 return std::conj(a.conj()/std::conj(r));
00978 }
00979
00980 template <class R, class S> inline typename Wider<R,S>::WCplx
00981 operator/(const complex<R>& a, const conjugate<S>& r) {
00982 return std::conj(std::conj(a)/r.conj());
00983 }
00984
00985
00986 template <class R, class S> inline bool
00987 operator==(const conjugate<R>& a, const conjugate<S>& r) {
00988 return a.real() == r.real() && a.negImag() == r.negImag();
00989 }
00990
00991 template <class R, class S> inline bool
00992 operator==(const conjugate<R>& a, const complex<S>& r) {
00993 return a.real() == r.real() && -a.negImag() == r.imag();
00994 }
00995
00996 template <class R, class S> inline bool
00997 operator==(const complex<R>& a, const conjugate<S>& r) {return r==a;}
00998
00999 template <class R, class S> inline bool
01000 operator!=(const conjugate<R>& a, const conjugate<S>& r) {return !(a==r);}
01001
01002 template <class R, class S> inline bool
01003 operator!=(const conjugate<R>& a, const complex<S>& r) {return !(a==r);}
01004
01005 template <class R, class S> inline bool
01006 operator!=(const complex<R>& a, const conjugate<S>& r) {return !(a==r);}
01007
01008
01009 }
01010
01011 #endif //SimTK_SIMMATRIX_CONJUGATE_H_