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
00479 conjugate& operator =(int i) {*this =(double)i; return *this;}
00480 conjugate& operator+=(int i) {*this+=(double)i; return *this;}
00481 conjugate& operator-=(int i) {*this-=(double)i; return *this;}
00482 conjugate& operator*=(int i) {*this*=(double)i; return *this;}
00483 conjugate& operator/=(int i) {*this/=(double)i; return *this;}
00484
00485 conjugate& operator+=(const conjugate<double>& c)
00486 { re += c.re; negIm += c.negIm; return *this; }
00487 conjugate& operator-=(const conjugate<double>& c)
00488 { re -= c.re; negIm -= c.negIm; return *this; }
00489
00490 conjugate& operator+=(const conjugate<float>& c)
00491 { re += c.real(); negIm += c.negImag(); return *this; }
00492 conjugate& operator-=(const conjugate<float>& c)
00493 { re -= c.real(); negIm -= c.negImag(); return *this; }
00494
00495 conjugate& operator=(const complex<double>& c)
00496 { re = c.real(); negIm = -c.imag(); return *this; }
00497 conjugate& operator+=(const complex<double>& c)
00498 { re += c.real(); negIm -= c.imag(); return *this; }
00499 conjugate& operator-=(const complex<double>& c)
00500 { re -= c.real(); negIm += c.imag(); return *this; }
00501
00502 conjugate& operator=(const complex<float>& c)
00503 { re = c.real(); negIm = -c.imag(); return *this; }
00504 conjugate& operator+=(const complex<float>& c)
00505 { re += c.real(); negIm -= c.imag(); return *this; }
00506 conjugate& operator-=(const complex<float>& c)
00507 { re -= c.real(); negIm += c.imag(); return *this; }
00508
00509
00510
00511
00512
00513
00514
00515 conjugate& operator*=(const conjugate<double>& c) {
00516 const double r=(re*c.re - negIm*c.negIm);
00517 negIm=(re*c.negIm + negIm*c.re); re=r; return *this;
00518 }
00519 conjugate& operator*=(const complex<double>& t) {
00520 const double r=(re*t.real() + negIm*t.imag());
00521 negIm=(negIm*t.real() - re*t.imag()); re=r; return *this;
00522 }
00523
00524 conjugate& operator*=(const conjugate<float>& c) { return operator*=(conjugate<double>(c)); }
00525 conjugate& operator*=(const complex<float>& c) { return operator*=(complex<double>(c)); }
00526
00527
00528
00529 conjugate& operator/=(const conjugate<double>& d) {
00530 const complex<double> t = conj()/d.conj();
00531 re = t.real(); negIm = t.imag();
00532 return *this;
00533 }
00534 conjugate& operator/=(const complex<double>& d) {
00535 const complex<double> t = conj()/std::conj(d);
00536 re = t.real(); negIm = t.imag();
00537 return *this;
00538 }
00539
00540 conjugate& operator/=(const conjugate<float>& c) { return operator/=(conjugate<double>(c)); }
00541 conjugate& operator/=(const complex<float>& c) { return operator/=(complex<double>(c)); }
00542
00543 const double& real() const { return re; }
00544 double& real() { return re; }
00545
00546 const negator<double>& imag() const { return reinterpret_cast<const negator<double>&>(negIm); }
00547 negator<double>& imag() { return reinterpret_cast<negator<double>&>(negIm); }
00548
00549 const complex<double>& conj() const { return reinterpret_cast<const complex<double>&>(*this); }
00550 complex<double>& conj() { return reinterpret_cast<complex<double>&>(*this); }
00551
00552
00553 const double& negImag() const { return negIm; }
00554 double& negImag() { return negIm; }
00555 bool isReal() const { return negIm==0.; }
00556
00557 private:
00558 double re;
00559 double negIm;
00560 };
00561
00562
00563
00565
00567
00568 template <> class conjugate<long double> {
00569 public:
00570 conjugate() {
00571 #ifndef NDEBUG
00572 re = negIm = std::numeric_limits<long double>::quiet_NaN();
00573 #endif
00574 }
00575
00576
00578 conjugate(const long double& real, const long double& imag) { re = real; negIm = imag; }
00579 conjugate(const long double& real, int i) { re = real; negIm = (long double)i; }
00580 conjugate(int r, const long double& imag) { re = (long double)r; negIm = imag; }
00581 conjugate(int r, int i) { re = (long double)r; negIm = (long double)i; }
00582
00584 conjugate(const long double& real) { re = real; negIm = 0.L; }
00585 conjugate(int r) { re = (long double)r; negIm = 0.L; }
00586
00587
00588
00589 conjugate(const conjugate<float>& cf)
00590 { re = (long double)cf.real(); negIm = (long double)cf.negImag(); }
00591 conjugate(const conjugate<double>& cd)
00592 { re = (long double)cd.real(); negIm = (long double)cd.negImag(); }
00593
00594 conjugate(const float& rf)
00595 { re = (long double)rf; negIm = 0.L; }
00596 conjugate(const double& rd)
00597 { re = (long double)rd; negIm = 0.L; }
00598
00599
00600
00601
00602
00603 explicit conjugate(const complex<float>& x)
00604 { re = (long double)x.real(); negIm = (long double)(-x.imag()); }
00605 explicit conjugate(const complex<double>& x)
00606 { re = (long double)x.real(); negIm = (long double)(-x.imag()); }
00607 explicit conjugate(const complex<long double>& x)
00608 { re = x.real(); negIm = -x.imag(); }
00609
00612 operator complex<long double>() const
00613 { return complex<long double>(re,-negIm); }
00614
00615
00616
00617
00618 complex<long double> operator-() const
00619 { return complex<long double>(-re,negIm); }
00620
00621
00622 const conjugate& operator+() const { return *this; }
00623
00624
00625
00626
00627
00628
00629 conjugate& operator=(const long double& r)
00630 { re = r; negIm = 0.L; return *this; }
00631 conjugate& operator+=(const long double& r)
00632 { re += r; return *this; }
00633 conjugate& operator-=(const long double& r)
00634 { re -= r; return *this; }
00635 conjugate& operator*=(const long double& r)
00636 { re *= r; negIm *= r; return *this; }
00637 conjugate& operator/=(const long double& r)
00638 { re /= r; negIm /= r; return *this; }
00639
00640 conjugate& operator=(const double& r)
00641 { re = r; negIm = 0.L; return *this; }
00642 conjugate& operator+=(const double& r)
00643 { re += r; return *this; }
00644 conjugate& operator-=(const double& r)
00645 { re -= r; return *this; }
00646 conjugate& operator*=(const double& r)
00647 { re *= r; negIm *= r; return *this; }
00648 conjugate& operator/=(const double& r)
00649 { re /= r; negIm /= r; return *this; }
00650
00651 conjugate& operator=(const float& r)
00652 { re = r; negIm = 0.L; return *this; }
00653 conjugate& operator+=(const float& r)
00654 { re += r; return *this; }
00655 conjugate& operator-=(const float& r)
00656 { re -= r; return *this; }
00657 conjugate& operator*=(const float& r)
00658 { re *= r; negIm *= r; return *this; }
00659 conjugate& operator/=(const float& r)
00660 { re /= r; negIm /= r; return *this; }
00661
00662
00663 conjugate& operator =(int i) {*this =(long double)i; return *this;}
00664 conjugate& operator+=(int i) {*this+=(long double)i; return *this;}
00665 conjugate& operator-=(int i) {*this-=(long double)i; return *this;}
00666 conjugate& operator*=(int i) {*this*=(long double)i; return *this;}
00667 conjugate& operator/=(int i) {*this/=(long double)i; return *this;}
00668
00669 conjugate& operator+=(const conjugate<long double>& c)
00670 { re += c.re; negIm += c.negIm; return *this; }
00671 conjugate& operator-=(const conjugate<long double>& c)
00672 { re -= c.re; negIm -= c.negIm; return *this; }
00673
00674 conjugate& operator+=(const conjugate<double>& c)
00675 { re += c.real(); negIm += c.negImag(); return *this; }
00676 conjugate& operator-=(const conjugate<double>& c)
00677 { re -= c.real(); negIm -= c.negImag(); return *this; }
00678
00679 conjugate& operator+=(const conjugate<float>& c)
00680 { re += c.real(); negIm += c.negImag(); return *this; }
00681 conjugate& operator-=(const conjugate<float>& c)
00682 { re -= c.real(); negIm -= c.negImag(); return *this; }
00683
00684 conjugate& operator=(const complex<long double>& c)
00685 { re = c.real(); negIm = -c.imag(); return *this; }
00686 conjugate& operator+=(const complex<long double>& c)
00687 { re += c.real(); negIm -= c.imag(); return *this; }
00688 conjugate& operator-=(const complex<long double>& c)
00689 { re -= c.real(); negIm += c.imag(); return *this; }
00690
00691 conjugate& operator=(const complex<double>& c)
00692 { re = c.real(); negIm = -c.imag(); return *this; }
00693 conjugate& operator+=(const complex<double>& c)
00694 { re += c.real(); negIm -= c.imag(); return *this; }
00695 conjugate& operator-=(const complex<double>& c)
00696 { re -= c.real(); negIm += c.imag(); return *this; }
00697
00698 conjugate& operator=(const complex<float>& c)
00699 { re = c.real(); negIm = -c.imag(); return *this; }
00700 conjugate& operator+=(const complex<float>& c)
00701 { re += c.real(); negIm -= c.imag(); return *this; }
00702 conjugate& operator-=(const complex<float>& c)
00703 { re -= c.real(); negIm += c.imag(); return *this; }
00704
00705
00706
00707
00708
00709
00710
00711 conjugate& operator*=(const conjugate<long double>& c) {
00712 const long double r=(re*c.re - negIm*c.negIm);
00713 negIm=(re*c.negIm + negIm*c.re); re=r; return *this;
00714 }
00715 conjugate& operator*=(const complex<long double>& t) {
00716 const long double r=(re*t.real() + negIm*t.imag());
00717 negIm=(negIm*t.real() - re*t.imag()); re=r; return *this;
00718 }
00719
00720 conjugate& operator*=(const conjugate<double>& c) { return operator*=(conjugate<long double>(c)); }
00721 conjugate& operator*=(const complex<double>& c) { return operator*=(complex<long double>(c)); }
00722 conjugate& operator*=(const conjugate<float>& c) { return operator*=(conjugate<long double>(c)); }
00723 conjugate& operator*=(const complex<float>& c) { return operator*=(complex<long double>(c)); }
00724
00725
00726
00727 conjugate& operator/=(const conjugate<long double>& d) {
00728 const complex<long double> t = conj()/d.conj();
00729 re = t.real(); negIm = t.imag();
00730 return *this;
00731 }
00732 conjugate& operator/=(const complex<long double>& d) {
00733 const complex<long double> t = conj()/std::conj(d);
00734 re = t.real(); negIm = t.imag();
00735 return *this;
00736 }
00737
00738 conjugate& operator/=(const conjugate<double>& c) { return operator/=(conjugate<long double>(c)); }
00739 conjugate& operator/=(const complex<double>& c) { return operator/=(complex<long double>(c)); }
00740 conjugate& operator/=(const conjugate<float>& c) { return operator/=(conjugate<long double>(c)); }
00741 conjugate& operator/=(const complex<float>& c) { return operator/=(complex<long double>(c)); }
00742
00743 const long double& real() const { return re; }
00744 long double& real() { return re; }
00745
00746 const negator<long double>& imag() const { return reinterpret_cast<const negator<long double>&>(negIm); }
00747 negator<long double>& imag() { return reinterpret_cast<negator<long double>&>(negIm); }
00748
00749 const complex<long double>& conj() const { return reinterpret_cast<const complex<long double>&>(*this); }
00750 complex<long double>& conj() { return reinterpret_cast<complex<long double>&>(*this); }
00751
00752
00753 const long double& negImag() const { return negIm; }
00754 long double& negImag() { return negIm; }
00755 bool isReal() const { return negIm==0.L; }
00756
00757 private:
00758 long double re;
00759 long double negIm;
00760 };
00761
00762
00763 conjugate<float>::conjugate(const conjugate<double>& cd) {
00764 re = float(cd.real()); negIm = float(cd.negImag());
00765 }
00766 conjugate<float>::conjugate(const conjugate<long double>& cl) {
00767 re = float(cl.real()); negIm = float(cl.negImag());
00768 }
00769 conjugate<double>::conjugate(const conjugate<long double>& cl) {
00770 re = double(cl.real()); negIm = double(cl.negImag());
00771 }
00772
00773
00774
00775
00776
00777
00778
00779 inline const float& real(const conjugate<float>& c) { return c.real(); }
00780 inline const negator<float>& imag(const conjugate<float>& c) { return c.imag(); }
00781 inline const complex<float>& conj(const conjugate<float>& c) { return c.conj(); }
00782 inline float abs (const conjugate<float>& c) { return std::abs(c.conj()); }
00783 inline float norm(const conjugate<float>& c) { return std::norm(c.conj()); }
00784
00785 inline const double& real(const conjugate<double>& c) { return c.real(); }
00786 inline const negator<double>& imag(const conjugate<double>& c) { return c.imag(); }
00787 inline const complex<double>& conj(const conjugate<double>& c) { return c.conj(); }
00788 inline double abs (const conjugate<double>& c) { return std::abs(c.conj()); }
00789 inline double norm(const conjugate<double>& c) { return std::norm(c.conj()); }
00790
00791 inline const long double& real(const conjugate<long double>& c) { return c.real(); }
00792 inline const negator<long double>& imag(const conjugate<long double>& c) { return c.imag(); }
00793 inline const complex<long double>& conj(const conjugate<long double>& c) { return c.conj(); }
00794 inline long double abs (const conjugate<long double>& c) { return std::abs(c.conj()); }
00795 inline long double norm(const conjugate<long double>& c) { return std::norm(c.conj()); }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 template <class R, class CHAR, class TRAITS> inline std::basic_istream<CHAR,TRAITS>&
00808 operator>>(std::basic_istream<CHAR,TRAITS>& is, conjugate<R>& c) {
00809 complex<R> z; is >> z; c=z;
00810 return is;
00811 }
00812 template <class R, class CHAR, class TRAITS> inline std::basic_ostream<CHAR,TRAITS>&
00813 operator<<(std::basic_ostream<CHAR,TRAITS>& os, const conjugate<R>& c) {
00814 return os << complex<R>(c);
00815 }
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830 template <class R> inline conjugate<R> operator+(const conjugate<R>& a, const float& b)
00831 { return conjugate<R>(a) += b; }
00832 template <class R> inline conjugate<long double> operator+(const conjugate<R>& a, const long double& b)
00833 { return conjugate<long double>(a) += b; }
00834 template <class R> inline typename Wider<R,double>::WConj operator+(const conjugate<R>& a, const double& b)
00835 { return typename Wider<R,double>::WConj(a) += b; }
00836
00837
00838 template <class R> inline conjugate<R> operator+(const float& a, const conjugate<R>& b) {return b+a;}
00839 template <class R> inline conjugate<long double> operator+(const long double& a, const conjugate<R>& b) {return b+a;}
00840 template <class R> inline typename Wider<R,double>::WConj operator+(const double& a, const conjugate<R>& b) {return b+a;}
00841
00842
00843 template <class R> inline conjugate<R> operator*(const conjugate<R>& a, const float& b)
00844 { return conjugate<R>(a) *= b; }
00845 template <class R> inline conjugate<long double> operator*(const conjugate<R>& a, const long double& b)
00846 { return conjugate<long double>(a) *= b; }
00847 template <class R> inline typename Wider<R,double>::WConj operator*(const conjugate<R>& a, const double& b)
00848 { return typename Wider<R,double>::WConj(a) *= b; }
00849
00850
00851 template <class R> inline conjugate<R> operator*(const float& a, const conjugate<R>& b) {return b*a;}
00852 template <class R> inline conjugate<long double> operator*(const long double& a, const conjugate<R>& b) {return b*a;}
00853 template <class R> inline typename Wider<R,double>::WConj operator*(const double& a, const conjugate<R>& b) {return b*a;}
00854
00855
00856 template <class R> inline bool operator==(const conjugate<R>& a, const float& b)
00857 { return a.isReal() && a.real()==b; }
00858 template <class R> inline bool operator==(const conjugate<R>& a, const long double& b)
00859 { return a.isReal() && a.real()==b; }
00860 template <class R> inline bool operator==(const conjugate<R>& a, const double& b)
00861 { return a.isReal() && a.real()==b; }
00862
00863
00864 template <class R> inline bool operator==(const float& a, const conjugate<R>& b) {return b==a;}
00865 template <class R> inline bool operator==(const long double& a, const conjugate<R>& b) {return b==a;}
00866 template <class R> inline bool operator==(const double& a, const conjugate<R>& b) {return b==a;}
00867 template <class R> inline bool operator!=(const conjugate<R>& a, const float& b) {return !(a==b);}
00868 template <class R> inline bool operator!=(const conjugate<R>& a, const long double& b) {return !(a==b);}
00869 template <class R> inline bool operator!=(const conjugate<R>& a, const double& b) {return !(a==b);}
00870 template <class R> inline bool operator!=(const float& a, const conjugate<R>& b) {return !(a==b);}
00871 template <class R> inline bool operator!=(const long double& a, const conjugate<R>& b) {return !(a==b);}
00872 template <class R> inline bool operator!=(const double& a, const conjugate<R>& b) {return !(a==b);}
00873
00874
00875
00876
00877 template <class R> inline conjugate<R> operator-(const conjugate<R>& a, const float& b)
00878 { return conjugate<R>(a) -= b; }
00879 template <class R> inline conjugate<long double> operator-(const conjugate<R>& a, const long double& b)
00880 { return conjugate<long double>(a) -= b; }
00881 template <class R> inline typename Wider<R,double>::WConj operator-(const conjugate<R>& a, const double& b)
00882 { return typename Wider<R,double>::WConj(a) -= b; }
00883
00884
00885
00886 template <class R> inline complex<R> operator-(const float& a, const conjugate<R>& b)
00887 { return complex<R>(a-b.real(), -b.imag()); }
00888 template <class R> inline complex<long double> operator-(const long double& a, const conjugate<R>& b)
00889 { return complex<long double>(a-b.real(), -b.imag()); }
00890 template <class R> inline typename Wider<R,double>::WCplx operator-(const double& a, const conjugate<R>& b)
00891 { return typename Wider<R,double>::WCplx(a-b.real(), -b.imag()); }
00892
00893
00894 template <class R> inline conjugate<R> operator/(const conjugate<R>& a, const float& b)
00895 { return conjugate<R>(a) /= b; }
00896 template <class R> inline conjugate<long double> operator/(const conjugate<R>& a, const long double& b)
00897 { return conjugate<long double>(a) /= b; }
00898 template <class R> inline typename Wider<R,double>::WConj operator/(const conjugate<R>& a, const double& b)
00899 { return typename Wider<R,double>::WConj(a) /= b; }
00900
00901
00902
00903
00904 template <class R> inline complex<R> operator/(const float& a, const conjugate<R>& b)
00905 { return (R)a/complex<R>(b); }
00906 template <class R> inline complex<long double> operator/(const long double& a, const conjugate<R>& b)
00907 { return a/complex<long double>(b); }
00908 template <class R> inline typename Wider<R,double>::WCplx operator/(const double& a, const conjugate<R>& b)
00909 { return (typename Wider<R,double>::WReal)a/(typename Wider<R,double>::WCplx(b)); }
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919 template <class R, class S> inline typename Wider<R,S>::WConj
00920 operator+(const conjugate<R>& a, const conjugate<S>& r) {
00921 return typename Wider<R,S>::WConj(a.real()+r.real(),
00922 a.negImag()+r.negImag());
00923 }
00924
00925
00926 template <class R, class S> inline typename Wider<R,S>::WCplx
00927 operator+(const conjugate<R>& a, const complex<S>& r) {
00928 return typename Wider<R,S>::WCplx(a.real()+r.real(),
00929 r.imag()-a.negImag());
00930 }
00931 template <class R, class S> inline typename Wider<R,S>::WCplx
00932 operator+(const complex<R>& a, const conjugate<S>& r) { return r+a; }
00933
00934
00935 template <class R, class S> inline typename Wider<R,S>::WCplx
00936 operator-(const conjugate<R>& a, const conjugate<S>& r) {
00937 return typename Wider<R,S>::WCplx(a.real()-r.real(),
00938 r.negImag()-a.negImag());
00939 }
00940
00941
00942 template <class R, class S> inline negator<typename Wider<R,S>::WCplx>
00943 operator-(const conjugate<R>& a, const complex<S>& r) {
00944 return negator<typename Wider<R,S>::WCplx>::recast
00945 (typename Wider<R,S>::WCplx(r.real()-a.real(),
00946 a.negImag()+r.imag()));
00947 }
00948
00949
00950 template <class R, class S> inline typename Wider<R,S>::WCplx
00951 operator-(const complex<R>& a, const conjugate<S>& r) {
00952 return typename Wider<R,S>::WCplx(a.real()-r.real(),
00953 a.imag()+r.negImag());
00954 }
00955
00956
00957
00958
00959
00960
00961
00962 template <class R, class S> inline negator<typename Wider<R,S>::WCplx>
00963 operator*(const conjugate<R>& a, const conjugate<S>& r) {
00964 return negator<typename Wider<R,S>::WCplx>::recast
00965 (typename Wider<R,S>::WCplx(a.negImag()*r.negImag() - a.real()*r.real(),
00966 a.real()*r.negImag() + a.negImag()*r.real()));
00967 }
00968
00969
00970 template <class R, class S> inline typename Wider<R,S>::WCplx
00971 operator*(const conjugate<R>& a, const complex<S>& r) {
00972 return typename Wider<R,S>::WCplx(a.real()*r.real() + a.negImag()*r.imag(),
00973 a.real()*r.imag() - a.negImag()*r.real());
00974 }
00975
00976 template <class R, class S> inline typename Wider<R,S>::WCplx
00977 operator*(const complex<R>& a, const conjugate<S>& r)
00978 { return r*a; }
00979
00980
00981
00982
00983 template <class R, class S> inline typename Wider<R,S>::WCplx
00984 operator*(const negator< complex<R> >& a, const conjugate<S>& r)
00985 { return (-a)*(-r); }
00986 template <class R, class S> inline typename Wider<R,S>::WCplx
00987 operator*(const conjugate<R>& a, const negator< complex<S> >& r)
00988 { return (-a)*(-r); }
00989
00990
00991
00992
00993
00994 template <class R, class S> inline typename Wider<R,S>::WCplx
00995 operator/(const conjugate<R>& a, const conjugate<S>& r) {
00996 return std::conj(a.conj()/r.conj());
00997 }
00998
00999 template <class R, class S> inline typename Wider<R,S>::WCplx
01000 operator/(const conjugate<R>& a, const complex<S>& r) {
01001 return std::conj(a.conj()/std::conj(r));
01002 }
01003
01004 template <class R, class S> inline typename Wider<R,S>::WCplx
01005 operator/(const complex<R>& a, const conjugate<S>& r) {
01006 return std::conj(std::conj(a)/r.conj());
01007 }
01008
01009
01010 template <class R, class S> inline bool
01011 operator==(const conjugate<R>& a, const conjugate<S>& r) {
01012 return a.real() == r.real() && a.negImag() == r.negImag();
01013 }
01014
01015 template <class R, class S> inline bool
01016 operator==(const conjugate<R>& a, const complex<S>& r) {
01017 return a.real() == r.real() && -a.negImag() == r.imag();
01018 }
01019
01020 template <class R, class S> inline bool
01021 operator==(const complex<R>& a, const conjugate<S>& r) {return r==a;}
01022
01023 template <class R, class S> inline bool
01024 operator!=(const conjugate<R>& a, const conjugate<S>& r) {return !(a==r);}
01025
01026 template <class R, class S> inline bool
01027 operator!=(const conjugate<R>& a, const complex<S>& r) {return !(a==r);}
01028
01029 template <class R, class S> inline bool
01030 operator!=(const complex<R>& a, const conjugate<S>& r) {return !(a==r);}
01031
01032
01033 }
01034
01035 #endif //SimTK_SIMMATRIX_CONJUGATE_H_