Simbody  3.5
conjugate.h
Go to the documentation of this file.
1 #ifndef SimTK_SIMMATRIX_CONJUGATE_H_
2 #define SimTK_SIMMATRIX_CONJUGATE_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2005-12 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
60 #include <complex>
61 #include <iostream>
62 #include <limits>
63 
64 using std::complex;
65 
66 
67 // These mixed-precision real/complex operators should not be needed
68 // and may have to be removed on some systems. However neither
69 // gcc 3.4.4 nor VC++ 7 provide them.
70 // Define the symbol below if these conflict with standard library operators.
71 
72 #ifndef SimTK_MIXED_PRECISION_REAL_COMPLEX_ALREADY_DEFINED
73 namespace SimTK {
74 // complex<float> with int, double, long double
75 inline complex<float> operator*(const complex<float>& c,int r) {return c*(float)r;}
76 inline complex<float> operator*(int r,const complex<float>& c) {return (float)r*c;}
77 inline complex<double> operator*(const complex<float>& c,const double& r) {return complex<double>(c)*r;}
78 inline complex<double> operator*(const double& r,const complex<float>& c) {return r*complex<double>(c);}
79 inline complex<long double> operator*(const complex<float>& c,const long double& r) {return complex<long double>(c)*r;}
80 inline complex<long double> operator*(const long double& r,const complex<float>& c) {return r*complex<long double>(c);}
81 
82 inline complex<float> operator/(const complex<float>& c,int r) {return c/(float)r;}
83 inline complex<float> operator/(int r,const complex<float>& c) {return (float)r/c;}
84 inline complex<double> operator/(const complex<float>& c,const double& r) {return complex<double>(c)/r;}
85 inline complex<double> operator/(const double& r,const complex<float>& c) {return r/complex<double>(c);}
86 inline complex<long double> operator/(const complex<float>& c,const long double& r) {return complex<long double>(c)/r;}
87 inline complex<long double> operator/(const long double& r,const complex<float>& c) {return r/complex<long double>(c);}
88 
89 inline complex<float> operator+(const complex<float>& c,int r) {return c+(float)r;}
90 inline complex<float> operator+(int r,const complex<float>& c) {return (float)r+c;}
91 inline complex<double> operator+(const complex<float>& c,const double& r) {return complex<double>(c)+r;}
92 inline complex<double> operator+(const double& r,const complex<float>& c) {return r+complex<double>(c);}
93 inline complex<long double> operator+(const complex<float>& c,const long double& r) {return complex<long double>(c)+r;}
94 inline complex<long double> operator+(const long double& r,const complex<float>& c) {return r+complex<long double>(c);}
95 
96 inline complex<float> operator-(const complex<float>& c,int r) {return c-(float)r;}
97 inline complex<float> operator-(int r,const complex<float>& c) {return (float)r-c;}
98 inline complex<double> operator-(const complex<float>& c,const double& r) {return complex<double>(c)-r;}
99 inline complex<double> operator-(const double& r,const complex<float>& c) {return r-complex<double>(c);}
100 inline complex<long double> operator-(const complex<float>& c,const long double& r) {return complex<long double>(c)-r;}
101 inline complex<long double> operator-(const long double& r,const complex<float>& c) {return r-complex<long double>(c);}
102 
103 // complex<double> with int, float, long double
104 inline complex<double> operator*(const complex<double>& c,int r) {return c*(double)r;}
105 inline complex<double> operator*(int r,const complex<double>& c) {return (double)r*c;}
106 inline complex<double> operator*(const complex<double>& c,const float& r) {return c*(double)r;}
107 inline complex<double> operator*(const float& r,const complex<double>& c) {return (double)r*c;}
108 inline complex<long double> operator*(const complex<double>& c,const long double& r){return complex<long double>(c)*r;}
109 inline complex<long double> operator*(const long double& r,const complex<double>& c){return r*complex<long double>(c);}
110 
111 inline complex<double> operator/(const complex<double>& c,int r) {return c/(double)r;}
112 inline complex<double> operator/(int r,const complex<double>& c) {return (double)r/c;}
113 inline complex<double> operator/(const complex<double>& c,const float& r) {return c/(double)r;}
114 inline complex<double> operator/(const float& r,const complex<double>& c) {return (double)r/c;}
115 inline complex<long double> operator/(const complex<double>& c,const long double& r){return complex<long double>(c)/r;}
116 inline complex<long double> operator/(const long double& r,const complex<double>& c){return r/complex<long double>(c);}
117 
118 inline complex<double> operator+(const complex<double>& c,int r) {return c+(double)r;}
119 inline complex<double> operator+(int r,const complex<double>& c) {return (double)r+c;}
120 inline complex<double> operator+(const complex<double>& c,const float& r) {return c+(double)r;}
121 inline complex<double> operator+(const float& r,const complex<double>& c) {return (double)r+c;}
122 inline complex<long double> operator+(const complex<double>& c,const long double& r){return complex<long double>(c)+r;}
123 inline complex<long double> operator+(const long double& r,const complex<double>& c){return r+complex<long double>(c);}
124 
125 inline complex<double> operator-(const complex<double>& c,int r) {return c-(double)r;}
126 inline complex<double> operator-(int r,const complex<double>& c) {return (double)r-c;}
127 inline complex<double> operator-(const complex<double>& c,const float& r) {return c-(double)r;}
128 inline complex<double> operator-(const float& r,const complex<double>& c) {return (double)r-c;}
129 inline complex<long double> operator-(const complex<double>& c,const long double& r){return complex<long double>(c)-r;}
130 inline complex<long double> operator-(const long double& r,const complex<double>& c){return r-complex<long double>(c);}
131 
132 // complex<long double> with int, float, double
133 inline complex<long double> operator*(const complex<long double>& c,int r) {return c*(long double)r;}
134 inline complex<long double> operator*(int r,const complex<long double>& c) {return (long double)r*c;}
135 inline complex<long double> operator*(const complex<long double>& c,const float& r) {return c*(long double)r;}
136 inline complex<long double> operator*(const float& r,const complex<long double>& c) {return (long double)r*c;}
137 inline complex<long double> operator*(const complex<long double>& c,const double& r){return c*(long double)r;}
138 inline complex<long double> operator*(const double& r,const complex<long double>& c){return (long double)r*c;}
139 
140 inline complex<long double> operator/(const complex<long double>& c,int r) {return c/(long double)r;}
141 inline complex<long double> operator/(int r,const complex<long double>& c) {return (long double)r/c;}
142 inline complex<long double> operator/(const complex<long double>& c,const float& r) {return c/(long double)r;}
143 inline complex<long double> operator/(const float& r,const complex<long double>& c) {return (long double)r/c;}
144 inline complex<long double> operator/(const complex<long double>& c,const double& r){return c/(long double)r;}
145 inline complex<long double> operator/(const double& r,const complex<long double>& c){return (long double)r/c;}
146 
147 inline complex<long double> operator+(const complex<long double>& c,int r) {return c+(long double)r;}
148 inline complex<long double> operator+(int r,const complex<long double>& c) {return (long double)r+c;}
149 inline complex<long double> operator+(const complex<long double>& c,const float& r) {return c+(long double)r;}
150 inline complex<long double> operator+(const float& r,const complex<long double>& c) {return (long double)r+c;}
151 inline complex<long double> operator+(const complex<long double>& c,const double& r){return c+(long double)r;}
152 inline complex<long double> operator+(const double& r,const complex<long double>& c){return (long double)r+c;}
153 
154 inline complex<long double> operator-(const complex<long double>& c,int r) {return c-(long double)r;}
155 inline complex<long double> operator-(int r,const complex<long double>& c) {return (long double)r-c;}
156 inline complex<long double> operator-(const complex<long double>& c,const float& r) {return c-(long double)r;}
157 inline complex<long double> operator-(const float& r,const complex<long double>& c) {return (long double)r-c;}
158 inline complex<long double> operator-(const complex<long double>& c,const double& r){return c-(long double)r;}
159 inline complex<long double> operator-(const double& r,const complex<long double>& c){return (long double)r-c;}
160 } // namespace SimTK
161 #endif
162 
163 namespace SimTK {
164 
165 template <class R> class conjugate; // Only defined for float, double, long double
166 template <> class conjugate<float>;
167 template <> class conjugate<double>;
168 template <> class conjugate<long double>;
169 
170 // This is an adaptor for number types which negates the apparent values. A
171 // negator<N> has exactly the same internal representation as a number
172 // type N, but it is to be interpreted has having the negative of the value
173 // it would have if interpreted as an N. This permits negation to be done
174 // by reinterpretation rather than computation. A full set of arithmetic operators
175 // are provided involving negator<N>'s and N's. Sometimes we can save an op or
176 // two this way. For example negator<N>*negator<N> can be performed as an N*N
177 // since the negations cancel, and we saved two floating point negations.
178 template <class N> class negator; // Only defined for numbers
179 
180 /*
181  * This class is specialized for all 9 combinations of built-in real types
182  * and contains a typedef for the appropriate "widened" real, complex, or
183  * conjugate type for use when R1 & R2 appear in an operation together.
184  */
185 template <class R1, class R2> struct Wider {/* Only defined for built-ins. */};
186 template <> struct Wider<float,float> {
187  typedef float WReal;
188  typedef complex<float> WCplx;
190 };
191 template <> struct Wider<float,double> {
192  typedef double WReal;
193  typedef complex<double> WCplx;
195 };
196 template <> struct Wider<double,float> {
197  typedef double WReal;
198  typedef complex<double> WCplx;
200 };
201 template <> struct Wider<double,double> {
202  typedef double WReal;
203  typedef complex<double> WCplx;
205 };
206 template <> struct Wider<float,long double> {
207  typedef long double WReal;
208  typedef complex<long double> WCplx;
210 };
211 template <> struct Wider<double,long double> {
212  typedef long double WReal;
213  typedef complex<long double> WCplx;
215 };
216 template <> struct Wider<long double,float> {
217  typedef long double WReal;
218  typedef complex<long double> WCplx;
220 };
221 template <> struct Wider<long double,double> {
222  typedef long double WReal;
223  typedef complex<long double> WCplx;
225 };
226 template <> struct Wider<long double,long double> {
227  typedef long double WReal;
228  typedef complex<long double> WCplx;
230 };
231 
232 
249 template <class R> class conjugate {/*Only defined for float, double, long double*/};
250 
252 // Specialization for conjugate<float> //
254 
255 template <> class conjugate<float> {
256 public:
258  #ifndef NDEBUG
259  re = negIm = std::numeric_limits<float>::quiet_NaN();
260  #endif
261  }
262  // default copy constructor, copy assignment, destructor
263 
265  conjugate(const float& real, const float& imag) { re = real; negIm = imag; }
266  conjugate(const float& real, int i) { re = real; negIm = float(i); }
267  conjugate(int r, const float& imag) { re = float(r); negIm = imag; }
268  conjugate(int r, int i) { re = float(r); negIm = float(i); }
269 
271  conjugate(const float& real) { re = real; negIm = 0.f; }
272  conjugate(int r) { re = float(r); negIm = 0.f; }
273 
274  // No implicit conversions from double or long double because precision
275  // will be lost. Some definitions must be deferred until conjugate<double>
276  // and conjugate<long double> are defined below.
277  inline explicit conjugate(const conjugate<double>& cd);
278  inline explicit conjugate(const conjugate<long double>& cl);
279 
280  explicit conjugate(const double& rd)
281  { re = float(rd); negIm = 0.f; }
282  explicit conjugate(const long double& rl)
283  { re = float(rl); negIm = 0.f; }
284 
285  // Conversions from complex are always explicit. Note that the value
286  // represented by the conjugate must be identical to that represented by
287  // the complex, which means we must negate the imaginary part.
288  explicit conjugate(const complex<float>& x)
289  { re = x.real(); negIm = -x.imag(); }
290  explicit conjugate(const complex<double>& x)
291  { re = float(x.real()); negIm = float(-x.imag()); }
292  explicit conjugate(const complex<long double>& x)
293  { re = float(x.real()); negIm = float(-x.imag()); }
294 
297  operator complex<float>() const
298  { return complex<float>(re,-negIm); }
299 
300  // Can't defer here by casting to negator<conjugate> -- this must act
301  // like a built-in. But ... we can use this as a chance to convert
302  // to complex and save one negation.
303  complex<float> operator-() const { return complex<float>(-re,negIm); }
304 
305  // Useless.
306  const conjugate& operator+() const { return *this; }
307 
308  // Computed assignment operators. We don't depend on implicit conversions
309  // from reals to conjugates here because we can save a few flops by handling
310  // the reals explicitly. Note that we only provide operators for implicitly
311  // convertible precisions, though, which in this case means only floats.
312  conjugate& operator=(const float& r)
313  { re = r; negIm = 0.f; return *this; }
314  conjugate& operator+=(const float& r)
315  { re += r; return *this; }
316  conjugate& operator-=(const float& r)
317  { re -= r; return *this; }
318  conjugate& operator*=(const float& r)
319  { re *= r; negIm *= r; return *this; }
320  conjugate& operator/=(const float& r)
321  { re /= r; negIm /= r; return *this; }
322 
324  { re += c.re; negIm += c.negIm; return *this; }
326  { re -= c.re; negIm -= c.negIm; return *this; }
327 
328  conjugate& operator=(const complex<float>& c)
329  { re = c.real(); negIm = -c.imag(); return *this; }
330  conjugate& operator+=(const complex<float>& c)
331  { re += c.real(); negIm -= c.imag(); return *this; }
332  conjugate& operator-=(const complex<float>& c)
333  { re -= c.real(); negIm += c.imag(); return *this; }
334 
335  // It is pleasant to note that we can self-multiply by either a complex or
336  // a conjugate (leaving a conjugate result) in six flops which is the same
337  // cost as an ordinary complex multiply:
338  // cplx=cplx*cplx: (a+bi)(r+si) = (ar-bs)+(as+br)i
339  // conj=conj*conj: (a-bi)(r-si) = (ar-bs)-(as+br)i
340  // conj=conj*cplx: (a-bi)(r+si) = (ar+bs)-(br-as)i
342  const float r=(re*c.re - negIm*c.negIm);
343  negIm=(re*c.negIm + negIm*c.re); re=r; return *this;
344  }
345  conjugate& operator*=(const complex<float>& t) {
346  const float r=(re*t.real() + negIm*t.imag());
347  negIm=(negIm*t.real() - re*t.imag()); re=r; return *this;
348  }
349 
350  // Complex divide is messy and slow anyway so we'll convert to complex and back here,
351  // making use of the fact that for complex c and d, c/d=conj(conj(c)/conj(d)).
353  const complex<float> t = conj()/d.conj();
354  re = t.real(); negIm = t.imag(); // conjugating!
355  return *this;
356  }
357  conjugate& operator/=(const complex<float>& d) {
358  const complex<float> t = conj()/std::conj(d);
359  re = t.real(); negIm = t.imag(); // conjugating!
360  return *this;
361  }
362 
363  const float& real() const { return re; }
364  float& real() { return re; }
365 
366  const negator<float>& imag() const { return reinterpret_cast<const negator<float>&>(negIm); }
367  negator<float>& imag() { return reinterpret_cast<negator<float>&>(negIm); }
368 
369  const complex<float>& conj() const { return reinterpret_cast<const complex<float>&>(*this); }
370  complex<float>& conj() { return reinterpret_cast<complex<float>&>(*this); }
371 
372  // Special conjugate methods of use primarily in operator implementations.
373  const float& negImag() const { return negIm; }
374  float& negImag() { return negIm; }
375  bool isReal() const { return negIm==0.f; }
376 
377 private:
378  float re; // The value represented here is re - negIm*i.
379  float negIm;
380 };
381 
382 
383 
384 
386 // Specialization for conjugate<double> //
388 
389 template <> class conjugate<double> {
390 public:
392  #ifndef NDEBUG
393  re = negIm = std::numeric_limits<double>::quiet_NaN();
394  #endif
395  }
396  // default copy constructor, copy assignment, destructor
397 
399  conjugate(const double& real, const double& imag) { re = real; negIm = imag; }
400  conjugate(const double& real, int i) { re = real; negIm = double(i); }
401  conjugate(int r, const double& imag) { re = double(r); negIm = imag; }
402  conjugate(int r, int i) { re = double(r); negIm = double(i); }
403 
405  conjugate(const double& real) { re = real; negIm = 0.; }
406  conjugate(int r) { re = double(r); negIm = 0.; }
407 
408  // Implicit conversions from float are allowed since
409  // there is no loss in going to double, but long double
410  // requires explicit conversions.
412  { re = double(cf.real()); negIm = double(cf.negImag()); }
413  conjugate(const float& rf)
414  { re = double(rf); negIm = 0.; }
415 
416  // Definition must be deferred until conjugate<long double> is defined below.
417  inline explicit conjugate(const conjugate<long double>& cl);
418  explicit conjugate(const long double& rl)
419  { re = double(rl); negIm = 0.; }
420 
421  // Conversions from complex are always explicit. Note that the value
422  // represented by the conjugate must be identical to that represented by
423  // the complex, which means we must negate the imaginary part.
424  explicit conjugate(const complex<float>& x)
425  { re = double(x.real()); negIm = double(-x.imag()); }
426  explicit conjugate(const complex<double>& x)
427  { re = x.real(); negIm = -x.imag(); }
428  explicit conjugate(const complex<long double>& x)
429  { re = double(x.real()); negIm = double(-x.imag()); }
430 
433  operator complex<double>() const
434  { return complex<double>(re,-negIm); }
435 
436  // Can't defer here by casting to negator<conjugate> -- this must act
437  // like a built-in. But ... we can use this as a chance to convert
438  // to complex and save one negation.
439  complex<double> operator-() const { return complex<double>(-re,negIm); }
440 
441  // Useless.
442  const conjugate& operator+() const { return *this; }
443 
444  // Computed assignment operators. We don't depend on implicit conversions
445  // from reals to conjugates here because we can save a few flops by handling
446  // the reals explicitly. Note that we only provide operators for implicitly
447  // convertible precisions, though, which in this case means floats and doubles.
448  conjugate& operator=(const double& r)
449  { re = r; negIm = 0.; return *this; }
450  conjugate& operator+=(const double& r)
451  { re += r; return *this; }
452  conjugate& operator-=(const double& r)
453  { re -= r; return *this; }
454  conjugate& operator*=(const double& r)
455  { re *= r; negIm *= r; return *this; }
456  conjugate& operator/=(const double& r)
457  { re /= r; negIm /= r; return *this; }
458 
459  conjugate& operator=(const float& r)
460  { re = r; negIm = 0.; return *this; }
461  conjugate& operator+=(const float& r)
462  { re += r; return *this; }
463  conjugate& operator-=(const float& r)
464  { re -= r; return *this; }
465  conjugate& operator*=(const float& r)
466  { re *= r; negIm *= r; return *this; }
467  conjugate& operator/=(const float& r)
468  { re /= r; negIm /= r; return *this; }
469 
470  // Disambiguate int to be a double.
471  conjugate& operator =(int i) {*this =(double)i; return *this;}
472  conjugate& operator+=(int i) {*this+=(double)i; return *this;}
473  conjugate& operator-=(int i) {*this-=(double)i; return *this;}
474  conjugate& operator*=(int i) {*this*=(double)i; return *this;}
475  conjugate& operator/=(int i) {*this/=(double)i; return *this;}
476 
478  { re += c.re; negIm += c.negIm; return *this; }
480  { re -= c.re; negIm -= c.negIm; return *this; }
481 
483  { re += c.real(); negIm += c.negImag(); return *this; }
485  { re -= c.real(); negIm -= c.negImag(); return *this; }
486 
487  conjugate& operator=(const complex<double>& c)
488  { re = c.real(); negIm = -c.imag(); return *this; }
489  conjugate& operator+=(const complex<double>& c)
490  { re += c.real(); negIm -= c.imag(); return *this; }
491  conjugate& operator-=(const complex<double>& c)
492  { re -= c.real(); negIm += c.imag(); return *this; }
493 
494  conjugate& operator=(const complex<float>& c)
495  { re = c.real(); negIm = -c.imag(); return *this; }
496  conjugate& operator+=(const complex<float>& c)
497  { re += c.real(); negIm -= c.imag(); return *this; }
498  conjugate& operator-=(const complex<float>& c)
499  { re -= c.real(); negIm += c.imag(); return *this; }
500 
501  // It is pleasant to note that we can self-multiply by either a complex or
502  // a conjugate (leaving a conjugate result) in six flops which is the same
503  // cost as an ordinary complex multiply:
504  // cplx=cplx*cplx: (a+bi)(r+si) = (ar-bs)+(as+br)i
505  // conj=conj*conj: (a-bi)(r-si) = (ar-bs)-(as+br)i
506  // conj=conj*cplx: (a-bi)(r+si) = (ar+bs)-(br-as)i
508  const double r=(re*c.re - negIm*c.negIm);
509  negIm=(re*c.negIm + negIm*c.re); re=r; return *this;
510  }
511  conjugate& operator*=(const complex<double>& t) {
512  const double r=(re*t.real() + negIm*t.imag());
513  negIm=(negIm*t.real() - re*t.imag()); re=r; return *this;
514  }
515 
517  conjugate& operator*=(const complex<float>& c) { return operator*=(complex<double>(c)); }
518 
519  // Complex divide is messy and slow anyway so we'll convert to complex and back here,
520  // making use of the fact that for complex c and d, c/d=conj(conj(c)/conj(d)).
522  const complex<double> t = conj()/d.conj();
523  re = t.real(); negIm = t.imag(); // conjugating!
524  return *this;
525  }
526  conjugate& operator/=(const complex<double>& d) {
527  const complex<double> t = conj()/std::conj(d);
528  re = t.real(); negIm = t.imag(); // conjugating!
529  return *this;
530  }
531 
533  conjugate& operator/=(const complex<float>& c) { return operator/=(complex<double>(c)); }
534 
535  const double& real() const { return re; }
536  double& real() { return re; }
537 
538  const negator<double>& imag() const { return reinterpret_cast<const negator<double>&>(negIm); }
539  negator<double>& imag() { return reinterpret_cast<negator<double>&>(negIm); }
540 
541  const complex<double>& conj() const { return reinterpret_cast<const complex<double>&>(*this); }
542  complex<double>& conj() { return reinterpret_cast<complex<double>&>(*this); }
543 
544  // Special conjugate methods of use primarily in operator implementations.
545  const double& negImag() const { return negIm; }
546  double& negImag() { return negIm; }
547  bool isReal() const { return negIm==0.; }
548 
549 private:
550  double re; // The value represented here is re - negIm*i.
551  double negIm;
552 };
553 
554 
555 
557 // Specialization for conjugate<long double> //
559 
560 template <> class conjugate<long double> {
561 public:
563  #ifndef NDEBUG
564  re = negIm = std::numeric_limits<long double>::quiet_NaN();
565  #endif
566  }
567  // default copy constructor, copy assignment, destructor
568 
570  conjugate(const long double& real, const long double& imag) { re = real; negIm = imag; }
571  conjugate(const long double& real, int i) { re = real; negIm = (long double)i; }
572  conjugate(int r, const long double& imag) { re = (long double)r; negIm = imag; }
573  conjugate(int r, int i) { re = (long double)r; negIm = (long double)i; }
574 
576  conjugate(const long double& real) { re = real; negIm = 0.L; }
577  conjugate(int r) { re = (long double)r; negIm = 0.L; }
578 
579  // Implicit conversions from float and double are allowed since
580  // there is no loss in going to long double.
582  { re = (long double)cf.real(); negIm = (long double)cf.negImag(); }
584  { re = (long double)cd.real(); negIm = (long double)cd.negImag(); }
585 
586  conjugate(const float& rf)
587  { re = (long double)rf; negIm = 0.L; }
588  conjugate(const double& rd)
589  { re = (long double)rd; negIm = 0.L; }
590 
591 
592  // Conversions from complex are always explicit. Note that the value
593  // represented by the conjugate must be identical to that represented by
594  // the complex, which means we must negate the imaginary part.
595  explicit conjugate(const complex<float>& x)
596  { re = (long double)x.real(); negIm = (long double)(-x.imag()); }
597  explicit conjugate(const complex<double>& x)
598  { re = (long double)x.real(); negIm = (long double)(-x.imag()); }
599  explicit conjugate(const complex<long double>& x)
600  { re = x.real(); negIm = -x.imag(); }
601 
604  operator complex<long double>() const
605  { return complex<long double>(re,-negIm); }
606 
607  // Can't defer here by casting to negator<conjugate> -- this must act
608  // like a built-in. But ... we can use this as a chance to convert
609  // to complex and save one negation.
610  complex<long double> operator-() const
611  { return complex<long double>(-re,negIm); }
612 
613  // Useless.
614  const conjugate& operator+() const { return *this; }
615 
616  // Computed assignment operators. We don't depend on implicit conversions
617  // from reals to conjugates here because we can save a few flops by handling
618  // the reals explicitly. Note that we only provide operators for implicitly
619  // convertible precisions, though, which in this case means any floating
620  // point precision.
621  conjugate& operator=(const long double& r)
622  { re = r; negIm = 0.L; return *this; }
623  conjugate& operator+=(const long double& r)
624  { re += r; return *this; }
625  conjugate& operator-=(const long double& r)
626  { re -= r; return *this; }
627  conjugate& operator*=(const long double& r)
628  { re *= r; negIm *= r; return *this; }
629  conjugate& operator/=(const long double& r)
630  { re /= r; negIm /= r; return *this; }
631 
632  conjugate& operator=(const double& r)
633  { re = r; negIm = 0.L; return *this; }
634  conjugate& operator+=(const double& r)
635  { re += r; return *this; }
636  conjugate& operator-=(const double& r)
637  { re -= r; return *this; }
638  conjugate& operator*=(const double& r)
639  { re *= r; negIm *= r; return *this; }
640  conjugate& operator/=(const double& r)
641  { re /= r; negIm /= r; return *this; }
642 
643  conjugate& operator=(const float& r)
644  { re = r; negIm = 0.L; return *this; }
645  conjugate& operator+=(const float& r)
646  { re += r; return *this; }
647  conjugate& operator-=(const float& r)
648  { re -= r; return *this; }
649  conjugate& operator*=(const float& r)
650  { re *= r; negIm *= r; return *this; }
651  conjugate& operator/=(const float& r)
652  { re /= r; negIm /= r; return *this; }
653 
654  // Disambiguate int to be a long double.
655  conjugate& operator =(int i) {*this =(long double)i; return *this;}
656  conjugate& operator+=(int i) {*this+=(long double)i; return *this;}
657  conjugate& operator-=(int i) {*this-=(long double)i; return *this;}
658  conjugate& operator*=(int i) {*this*=(long double)i; return *this;}
659  conjugate& operator/=(int i) {*this/=(long double)i; return *this;}
660 
662  { re += c.re; negIm += c.negIm; return *this; }
664  { re -= c.re; negIm -= c.negIm; return *this; }
665 
667  { re += c.real(); negIm += c.negImag(); return *this; }
669  { re -= c.real(); negIm -= c.negImag(); return *this; }
670 
672  { re += c.real(); negIm += c.negImag(); return *this; }
674  { re -= c.real(); negIm -= c.negImag(); return *this; }
675 
676  conjugate& operator=(const complex<long double>& c)
677  { re = c.real(); negIm = -c.imag(); return *this; }
678  conjugate& operator+=(const complex<long double>& c)
679  { re += c.real(); negIm -= c.imag(); return *this; }
680  conjugate& operator-=(const complex<long double>& c)
681  { re -= c.real(); negIm += c.imag(); return *this; }
682 
683  conjugate& operator=(const complex<double>& c)
684  { re = c.real(); negIm = -c.imag(); return *this; }
685  conjugate& operator+=(const complex<double>& c)
686  { re += c.real(); negIm -= c.imag(); return *this; }
687  conjugate& operator-=(const complex<double>& c)
688  { re -= c.real(); negIm += c.imag(); return *this; }
689 
690  conjugate& operator=(const complex<float>& c)
691  { re = c.real(); negIm = -c.imag(); return *this; }
692  conjugate& operator+=(const complex<float>& c)
693  { re += c.real(); negIm -= c.imag(); return *this; }
694  conjugate& operator-=(const complex<float>& c)
695  { re -= c.real(); negIm += c.imag(); return *this; }
696 
697  // It is pleasant to note that we can self-multiply by either a complex or
698  // a conjugate (leaving a conjugate result) in six flops which is the same
699  // cost as an ordinary complex multiply:
700  // cplx=cplx*cplx: (a+bi)(r+si) = (ar-bs)+(as+br)i
701  // conj=conj*conj: (a-bi)(r-si) = (ar-bs)-(as+br)i
702  // conj=conj*cplx: (a-bi)(r+si) = (ar+bs)-(br-as)i
704  const long double r=(re*c.re - negIm*c.negIm);
705  negIm=(re*c.negIm + negIm*c.re); re=r; return *this;
706  }
707  conjugate& operator*=(const complex<long double>& t) {
708  const long double r=(re*t.real() + negIm*t.imag());
709  negIm=(negIm*t.real() - re*t.imag()); re=r; return *this;
710  }
711 
713  conjugate& operator*=(const complex<double>& c) { return operator*=(complex<long double>(c)); }
715  conjugate& operator*=(const complex<float>& c) { return operator*=(complex<long double>(c)); }
716 
717  // Complex divide is messy and slow anyway so we'll convert to complex and back here,
718  // making use of the fact that for complex c and d, c/d=conj(conj(c)/conj(d)).
720  const complex<long double> t = conj()/d.conj();
721  re = t.real(); negIm = t.imag(); // conjugating!
722  return *this;
723  }
724  conjugate& operator/=(const complex<long double>& d) {
725  const complex<long double> t = conj()/std::conj(d);
726  re = t.real(); negIm = t.imag(); // conjugating!
727  return *this;
728  }
729 
731  conjugate& operator/=(const complex<double>& c) { return operator/=(complex<long double>(c)); }
733  conjugate& operator/=(const complex<float>& c) { return operator/=(complex<long double>(c)); }
734 
735  const long double& real() const { return re; }
736  long double& real() { return re; }
737 
738  const negator<long double>& imag() const { return reinterpret_cast<const negator<long double>&>(negIm); }
739  negator<long double>& imag() { return reinterpret_cast<negator<long double>&>(negIm); }
740 
741  const complex<long double>& conj() const { return reinterpret_cast<const complex<long double>&>(*this); }
742  complex<long double>& conj() { return reinterpret_cast<complex<long double>&>(*this); }
743 
744  // Special conjugate methods of use primarily in operator implementations.
745  const long double& negImag() const { return negIm; }
746  long double& negImag() { return negIm; }
747  bool isReal() const { return negIm==0.L; }
748 
749 private:
750  long double re; // The value represented here is re - negIm*i.
751  long double negIm;
752 };
753 
754 // These definitions had to be deferred until all the specializations have been declared.
756  re = float(cd.real()); negIm = float(cd.negImag());
757 }
759  re = float(cl.real()); negIm = float(cl.negImag());
760 }
762  re = double(cl.real()); negIm = double(cl.negImag());
763 }
764 
765 // Global functions real(),imag(), conj(), abs(), and norm() are overloaded here
766 // for efficiency (e.g., abs(c)==abs(conj(c))). The others still work through
767 // the implicit conversion from conjugate<T> to complex<T>, which costs
768 // one negation. The non-overloaded functions defined for complex are
769 // arg(), which returns a real, and a set of functions which return complex:
770 // polar,cos,cosh,exp,log,log10,pow,sin,sinh,sqrt,tan,tanh.
771 inline const float& real(const conjugate<float>& c) { return c.real(); }
772 inline const negator<float>& imag(const conjugate<float>& c) { return c.imag(); }
773 inline const complex<float>& conj(const conjugate<float>& c) { return c.conj(); }
774 inline float abs (const conjugate<float>& c) { return std::abs(c.conj()); }
775 inline float norm(const conjugate<float>& c) { return std::norm(c.conj()); }
776 
777 inline const double& real(const conjugate<double>& c) { return c.real(); }
778 inline const negator<double>& imag(const conjugate<double>& c) { return c.imag(); }
779 inline const complex<double>& conj(const conjugate<double>& c) { return c.conj(); }
780 inline double abs (const conjugate<double>& c) { return std::abs(c.conj()); }
781 inline double norm(const conjugate<double>& c) { return std::norm(c.conj()); }
782 
783 inline const long double& real(const conjugate<long double>& c) { return c.real(); }
784 inline const negator<long double>& imag(const conjugate<long double>& c) { return c.imag(); }
785 inline const complex<long double>& conj(const conjugate<long double>& c) { return c.conj(); }
786 inline long double abs (const conjugate<long double>& c) { return std::abs(c.conj()); }
787 inline long double norm(const conjugate<long double>& c) { return std::norm(c.conj()); }
788 
789 
790 
791 
792 
793 
794 // Binary operators with conjugate as one of the operands, and the other any
795 // numerical type (real, complex, conjugate) but NOT a negator type. Each operator
796 // will silently work with operands of mixed precision, widening the result as
797 // necessary. We try to return complex rather than conjugate whenever possible.
798 
799 template <class R, class CHAR, class TRAITS> inline std::basic_istream<CHAR,TRAITS>&
800 operator>>(std::basic_istream<CHAR,TRAITS>& is, conjugate<R>& c) {
801  complex<R> z; is >> z; c=z;
802  return is;
803 }
804 template <class R, class CHAR, class TRAITS> inline std::basic_ostream<CHAR,TRAITS>&
805 operator<<(std::basic_ostream<CHAR,TRAITS>& os, const conjugate<R>& c) {
806  return os << complex<R>(c);
807 }
808 
809 // Operators involving only conjugate and complex can be templatized reliably, as can
810 // operators which do not mix precision. But we have to deal explicitly with mixes
811 // of conjugate<R> and some other real type S, because the 'class S' template
812 // argument can match anything and create ambiguities.
813 
814 // conjugate<R> with float, double, long double. With 'float' we can be sure that R
815 // is the right width for the return value. With 'long double' we are sure that
816 // 'long double' is the return width. 'double' is trickier and we have to use the
817 // Wider<R,...> helper class to give us the right return type.
818 
819 // Commutative ops need be done only once: +, *, ==, and != is defined in terms of ==.
820 
821 // conjugate = conjugate + real
822 template <class R> inline conjugate<R> operator+(const conjugate<R>& a, const float& b)
823  { return conjugate<R>(a) += b; }
824 template <class R> inline conjugate<long double> operator+(const conjugate<R>& a, const long double& b)
825  { return conjugate<long double>(a) += b; }
826 template <class R> inline typename Wider<R,double>::WConj operator+(const conjugate<R>& a, const double& b)
827  { return typename Wider<R,double>::WConj(a) += b; }
828 
829 // conjugate = real + conjugate
830 template <class R> inline conjugate<R> operator+(const float& a, const conjugate<R>& b) {return b+a;}
831 template <class R> inline conjugate<long double> operator+(const long double& a, const conjugate<R>& b) {return b+a;}
832 template <class R> inline typename Wider<R,double>::WConj operator+(const double& a, const conjugate<R>& b) {return b+a;}
833 
834 // conjugate = conjugate * real
835 template <class R> inline conjugate<R> operator*(const conjugate<R>& a, const float& b)
836  { return conjugate<R>(a) *= b; }
837 template <class R> inline conjugate<long double> operator*(const conjugate<R>& a, const long double& b)
838  { return conjugate<long double>(a) *= b; }
839 template <class R> inline typename Wider<R,double>::WConj operator*(const conjugate<R>& a, const double& b)
840  { return typename Wider<R,double>::WConj(a) *= b; }
841 
842 // conjugate = real * conjugate
843 template <class R> inline conjugate<R> operator*(const float& a, const conjugate<R>& b) {return b*a;}
844 template <class R> inline conjugate<long double> operator*(const long double& a, const conjugate<R>& b) {return b*a;}
845 template <class R> inline typename Wider<R,double>::WConj operator*(const double& a, const conjugate<R>& b) {return b*a;}
846 
847 // bool = conjugate==real
848 template <class R> inline bool operator==(const conjugate<R>& a, const float& b)
849  { return a.isReal() && a.real()==b; }
850 template <class R> inline bool operator==(const conjugate<R>& a, const long double& b)
851  { return a.isReal() && a.real()==b; }
852 template <class R> inline bool operator==(const conjugate<R>& a, const double& b)
853  { return a.isReal() && a.real()==b; }
854 
855 // bool = real==conjugate, bool = conjugate!=real, bool = real!=conjugate
856 template <class R> inline bool operator==(const float& a, const conjugate<R>& b) {return b==a;}
857 template <class R> inline bool operator==(const long double& a, const conjugate<R>& b) {return b==a;}
858 template <class R> inline bool operator==(const double& a, const conjugate<R>& b) {return b==a;}
859 template <class R> inline bool operator!=(const conjugate<R>& a, const float& b) {return !(a==b);}
860 template <class R> inline bool operator!=(const conjugate<R>& a, const long double& b) {return !(a==b);}
861 template <class R> inline bool operator!=(const conjugate<R>& a, const double& b) {return !(a==b);}
862 template <class R> inline bool operator!=(const float& a, const conjugate<R>& b) {return !(a==b);}
863 template <class R> inline bool operator!=(const long double& a, const conjugate<R>& b) {return !(a==b);}
864 template <class R> inline bool operator!=(const double& a, const conjugate<R>& b) {return !(a==b);}
865 
866 // Non-commutative ops are a little messier.
867 
868 // conjugate = conjugate - real
869 template <class R> inline conjugate<R> operator-(const conjugate<R>& a, const float& b)
870  { return conjugate<R>(a) -= b; }
871 template <class R> inline conjugate<long double> operator-(const conjugate<R>& a, const long double& b)
872  { return conjugate<long double>(a) -= b; }
873 template <class R> inline typename Wider<R,double>::WConj operator-(const conjugate<R>& a, const double& b)
874  { return typename Wider<R,double>::WConj(a) -= b; }
875 
876 // complex = real - conjugate
877 // This is nice because -conjugate.imag() is free.
878 template <class R> inline complex<R> operator-(const float& a, const conjugate<R>& b)
879  { return complex<R>(a-b.real(), -b.imag()); }
880 template <class R> inline complex<long double> operator-(const long double& a, const conjugate<R>& b)
881  { return complex<long double>(a-b.real(), -b.imag()); }
882 template <class R> inline typename Wider<R,double>::WCplx operator-(const double& a, const conjugate<R>& b)
883  { return typename Wider<R,double>::WCplx(a-b.real(), -b.imag()); }
884 
885 // conjugate = conjugate / real
886 template <class R> inline conjugate<R> operator/(const conjugate<R>& a, const float& b)
887  { return conjugate<R>(a) /= b; }
888 template <class R> inline conjugate<long double> operator/(const conjugate<R>& a, const long double& b)
889  { return conjugate<long double>(a) /= b; }
890 template <class R> inline typename Wider<R,double>::WConj operator/(const conjugate<R>& a, const double& b)
891  { return typename Wider<R,double>::WConj(a) /= b; }
892 
893 // complex = real / conjugate
894 // Division by complex is tricky and slow anyway so we'll just convert to complex
895 // at the cost of one negation.
896 template <class R> inline complex<R> operator/(const float& a, const conjugate<R>& b)
897  { return (R)a/complex<R>(b); }
898 template <class R> inline complex<long double> operator/(const long double& a, const conjugate<R>& b)
899  { return a/complex<long double>(b); }
900 template <class R> inline typename Wider<R,double>::WCplx operator/(const double& a, const conjugate<R>& b)
901  { return (typename Wider<R,double>::WReal)a/(typename Wider<R,double>::WCplx(b)); }
902 
903 
904 // That's it for (conjugate, real) combinations. Now we need to do all the (conjugate, conjugate) and
905 // (conjugate, complex) combinations which are safer to templatize fully. There are many more opportunities
906 // to return complex rather than conjugate here. Keep in mind here that for a conjugate number c=a-bi,
907 // a=c.real() and b=-c.imag() are available for free. conjugate provides negImag() to return b directly.
908 // Below we'll capitalize components that should be accessed with negImag().
909 
910 // conjugate = conjugate + conjugate: (a-Bi)+(r-Si) = (a+r)-(B+S)i
911 template <class R, class S> inline typename Wider<R,S>::WConj
912 operator+(const conjugate<R>& a, const conjugate<S>& r) {
913  return typename Wider<R,S>::WConj(a.real()+r.real(),
914  a.negImag()+r.negImag());
915 }
916 
917 // complex = conjugate + complex = complex + conjugate: (a-Bi)+(r+si) = (a+r)+(s-B)i
918 template <class R, class S> inline typename Wider<R,S>::WCplx
919 operator+(const conjugate<R>& a, const complex<S>& r) {
920  return typename Wider<R,S>::WCplx(a.real()+r.real(),
921  r.imag()-a.negImag());
922 }
923 template <class R, class S> inline typename Wider<R,S>::WCplx
924 operator+(const complex<R>& a, const conjugate<S>& r) { return r+a; }
925 
926 // complex = conjugate - conjugate: (a-Bi)-(r-Si) = (a-r)+(S-B)i
927 template <class R, class S> inline typename Wider<R,S>::WCplx
928 operator-(const conjugate<R>& a, const conjugate<S>& r) {
929  return typename Wider<R,S>::WCplx(a.real()-r.real(),
930  r.negImag()-a.negImag());
931 }
932 
933 // Neg<complex> = conjugate - complex: (a-Bi)-(r+si) = (a-r)+(-B-s)i = -[(r-a)+(B+s)i]
934 template <class R, class S> inline negator<typename Wider<R,S>::WCplx>
935 operator-(const conjugate<R>& a, const complex<S>& r) {
936  return negator<typename Wider<R,S>::WCplx>::recast
937  (typename Wider<R,S>::WCplx(r.real()-a.real(),
938  a.negImag()+r.imag()));
939 }
940 
941 // complex = complex - conjugate: (a+bi)-(r-Si) = (a-r)+(b+S)i
942 template <class R, class S> inline typename Wider<R,S>::WCplx
943 operator-(const complex<R>& a, const conjugate<S>& r) {
944  return typename Wider<R,S>::WCplx(a.real()-r.real(),
945  a.imag()+r.negImag());
946 }
947 
948 // We can multiply by either a complex or a conjugate (leaving a complex
949 // or negated complex result) in six flops which is the same cost as an
950 // ordinary complex multiply.
951 // (cplx=cplx*cplx: (a+bi)(r+si) = (ar-bs)+(as+br)i)
952 
953 // Neg<cplx>=conj*conj: (a-Bi)(r-Si) = -[(BS-ar)+(aS+Br)i]
954 template <class R, class S> inline negator<typename Wider<R,S>::WCplx>
955 operator*(const conjugate<R>& a, const conjugate<S>& r) {
956  return negator<typename Wider<R,S>::WCplx>::recast
957  (typename Wider<R,S>::WCplx(a.negImag()*r.negImag() - a.real()*r.real(),
958  a.real()*r.negImag() + a.negImag()*r.real()));
959 }
960 
961 // cplx=conj*cplx: (a-Bi)(r+si) = (ar+Bs)+(as-Br)i
962 template <class R, class S> inline typename Wider<R,S>::WCplx
963 operator*(const conjugate<R>& a, const complex<S>& r) {
964  return typename Wider<R,S>::WCplx(a.real()*r.real() + a.negImag()*r.imag(),
965  a.real()*r.imag() - a.negImag()*r.real());
966 }
967 
968 template <class R, class S> inline typename Wider<R,S>::WCplx
969 operator*(const complex<R>& a, const conjugate<S>& r)
970  { return r*a; }
971 
972 // If there's a negator on the complex number, move it to the conjugate
973 // one which will change to complex with just one flop; then this
974 // is an ordinary complex mutiply.
975 template <class R, class S> inline typename Wider<R,S>::WCplx
976 operator*(const negator< complex<R> >& a, const conjugate<S>& r)
977  { return (-a)*(-r); } // -a is free here
978 template <class R, class S> inline typename Wider<R,S>::WCplx
979 operator*(const conjugate<R>& a, const negator< complex<S> >& r)
980  { return (-a)*(-r); } // -r is free here
981 
982 // Division is tricky and there is little to gain by trying to exploit
983 // the conjugate class, so we'll just convert to complex. (Remember that
984 // conj() is free for Conjugates.)
985 
986 template <class R, class S> inline typename Wider<R,S>::WCplx
987 operator/(const conjugate<R>& a, const conjugate<S>& r) {
988  return std::conj(a.conj()/r.conj());
989 }
990 
991 template <class R, class S> inline typename Wider<R,S>::WCplx
992 operator/(const conjugate<R>& a, const complex<S>& r) {
993  return std::conj(a.conj()/std::conj(r));
994 }
995 
996 template <class R, class S> inline typename Wider<R,S>::WCplx
997 operator/(const complex<R>& a, const conjugate<S>& r) {
998  return std::conj(std::conj(a)/r.conj());
999 }
1000 
1001 
1002 template <class R, class S> inline bool
1003 operator==(const conjugate<R>& a, const conjugate<S>& r) {
1004  return a.real() == r.real() && a.negImag() == r.negImag();
1005 }
1006 
1007 template <class R, class S> inline bool
1008 operator==(const conjugate<R>& a, const complex<S>& r) {
1009  return a.real() == r.real() && -a.negImag() == r.imag();
1010 }
1011 
1012 template <class R, class S> inline bool
1013 operator==(const complex<R>& a, const conjugate<S>& r) {return r==a;}
1014 
1015 template <class R, class S> inline bool
1016 operator!=(const conjugate<R>& a, const conjugate<S>& r) {return !(a==r);}
1017 
1018 template <class R, class S> inline bool
1019 operator!=(const conjugate<R>& a, const complex<S>& r) {return !(a==r);}
1020 
1021 template <class R, class S> inline bool
1022 operator!=(const complex<R>& a, const conjugate<S>& r) {return !(a==r);}
1023 
1024 
1025 } // namespace SimTK
1026 
1027 #endif //SimTK_SIMMATRIX_CONJUGATE_H_
conjugate & operator/=(const float &r)
Definition: conjugate.h:651
const conjugate & operator+() const
Definition: conjugate.h:306
const complex< float > & conj() const
Definition: conjugate.h:369
conjugate(const long double &real, const long double &imag)
Construction from reals. Note that the numeric result is (real-imag*i).
Definition: conjugate.h:570
Matrix_< E > operator/(const MatrixBase< E > &l, const typename CNT< E >::StdNumber &r)
Definition: BigMatrix.h:613
conjugate & operator*=(const complex< float > &t)
Definition: conjugate.h:345
negator< long double > & imag()
Definition: conjugate.h:739
double & real()
Definition: conjugate.h:536
conjugate< double > WConj
Definition: conjugate.h:199
conjugate & operator=(const double &r)
Definition: conjugate.h:448
conjugate(const complex< long double > &x)
Definition: conjugate.h:292
long double WReal
Definition: conjugate.h:227
conjugate & operator/=(const complex< float > &c)
Definition: conjugate.h:733
conjugate & operator*=(const double &r)
Definition: conjugate.h:454
complex< float > operator-() const
Definition: conjugate.h:303
complex< long double > & conj()
Definition: conjugate.h:742
conjugate(const float &real)
Implicit conversion from float to conjugate<float>.
Definition: conjugate.h:271
conjugate & operator=(const float &r)
Definition: conjugate.h:643
conjugate(const double &real, int i)
Definition: conjugate.h:400
const conjugate & operator+() const
Definition: conjugate.h:442
conjugate & operator+=(const conjugate< float > &c)
Definition: conjugate.h:671
conjugate & operator-=(const conjugate< double > &c)
Definition: conjugate.h:479
conjugate & operator+=(int i)
Definition: conjugate.h:656
complex< float > & conj()
Definition: conjugate.h:370
conjugate< long double > WConj
Definition: conjugate.h:229
negator< float > & imag()
Definition: conjugate.h:367
conjugate< long double > WConj
Definition: conjugate.h:214
long double WReal
Definition: conjugate.h:217
const double & negImag() const
Definition: conjugate.h:545
const float & negImag() const
Definition: conjugate.h:373
conjugate & operator-=(const float &r)
Definition: conjugate.h:463
complex< long double > WCplx
Definition: conjugate.h:223
complex< long double > operator-() const
Definition: conjugate.h:610
negator< double > & imag()
Definition: conjugate.h:539
conjugate(int r)
Definition: conjugate.h:577
conjugate(const complex< float > &x)
Definition: conjugate.h:424
double WReal
Definition: conjugate.h:197
conjugate & operator-=(const double &r)
Definition: conjugate.h:452
conjugate & operator*=(const conjugate< double > &c)
Definition: conjugate.h:712
complex< double > & conj()
Definition: conjugate.h:542
conjugate & operator-=(const float &r)
Definition: conjugate.h:647
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
SimTK::conjugate<R> should be instantiated only for float, double, long double.
Definition: String.h:45
conjugate & operator*=(const float &r)
Definition: conjugate.h:465
conjugate & operator-=(const conjugate< double > &c)
Definition: conjugate.h:668
conjugate & operator*=(const complex< double > &c)
Definition: conjugate.h:713
const long double & real() const
Definition: conjugate.h:735
complex< double > operator-() const
Definition: conjugate.h:439
conjugate & operator+=(const double &r)
Definition: conjugate.h:450
const negator< float > & imag() const
Definition: conjugate.h:366
conjugate & operator-=(const long double &r)
Definition: conjugate.h:625
Definition: conjugate.h:560
conjugate & operator+=(const double &r)
Definition: conjugate.h:634
conjugate & operator+=(const conjugate< float > &c)
Definition: conjugate.h:482
Matrix_< typename CNT< E1 >::template Result< E2 >::Sub > operator-(const MatrixBase< E1 > &l, const MatrixBase< E2 > &r)
Definition: BigMatrix.h:584
bool isReal() const
Definition: conjugate.h:375
const complex< long double > & conj(const conjugate< long double > &c)
Definition: conjugate.h:785
conjugate & operator-=(const complex< double > &c)
Definition: conjugate.h:687
float WReal
Definition: conjugate.h:187
Definition: conjugate.h:255
conjugate & operator*=(int i)
Definition: conjugate.h:474
Definition: conjugate.h:389
conjugate & operator=(const float &r)
Definition: conjugate.h:312
conjugate< double > WConj
Definition: conjugate.h:194
conjugate(const long double &rl)
Definition: conjugate.h:282
std::basic_istream< CHAR, TRAITS > & operator>>(std::basic_istream< CHAR, TRAITS > &is, conjugate< R > &c)
Definition: conjugate.h:800
complex< double > WCplx
Definition: conjugate.h:198
conjugate(int r, int i)
Definition: conjugate.h:402
negator<N>, where N is a number type (real, complex, conjugate), is represented in memory identically...
Definition: String.h:44
conjugate & operator/=(const conjugate< double > &d)
Definition: conjugate.h:521
conjugate & operator-=(const complex< float > &c)
Definition: conjugate.h:332
conjugate & operator+=(const complex< float > &c)
Definition: conjugate.h:692
conjugate(const float &rf)
Definition: conjugate.h:413
conjugate< float > WConj
Definition: conjugate.h:189
complex< float > WCplx
Definition: conjugate.h:188
float & real()
Definition: conjugate.h:364
bool operator==(const PhiMatrix &p1, const PhiMatrix &p2)
Definition: SpatialAlgebra.h:774
conjugate & operator+=(const complex< float > &c)
Definition: conjugate.h:330
double WReal
Definition: conjugate.h:202
conjugate(const complex< double > &x)
Definition: conjugate.h:426
conjugate & operator/=(const conjugate< double > &c)
Definition: conjugate.h:730
conjugate & operator+=(const conjugate< double > &c)
Definition: conjugate.h:666
const double & real() const
Definition: conjugate.h:535
conjugate & operator*=(const long double &r)
Definition: conjugate.h:627
conjugate & operator=(const float &r)
Definition: conjugate.h:459
conjugate & operator/=(const complex< long double > &d)
Definition: conjugate.h:724
conjugate & operator+=(const conjugate< float > &c)
Definition: conjugate.h:323
conjugate & operator-=(const complex< float > &c)
Definition: conjugate.h:694
conjugate & operator*=(const complex< long double > &t)
Definition: conjugate.h:707
conjugate & operator*=(const conjugate< float > &c)
Definition: conjugate.h:516
long double WReal
Definition: conjugate.h:212
conjugate & operator-=(const complex< long double > &c)
Definition: conjugate.h:680
conjugate & operator*=(const conjugate< double > &c)
Definition: conjugate.h:507
conjugate & operator=(const complex< long double > &c)
Definition: conjugate.h:676
conjugate(int r, const double &imag)
Definition: conjugate.h:401
conjugate & operator-=(int i)
Definition: conjugate.h:657
conjugate(const complex< long double > &x)
Definition: conjugate.h:599
conjugate(const conjugate< float > &cf)
Definition: conjugate.h:411
conjugate & operator+=(const long double &r)
Definition: conjugate.h:623
conjugate & operator/=(const complex< double > &d)
Definition: conjugate.h:526
complex< long double > WCplx
Definition: conjugate.h:218
conjugate(int r, const float &imag)
Definition: conjugate.h:267
long double WReal
Definition: conjugate.h:222
double & negImag()
Definition: conjugate.h:546
conjugate(const double &rd)
Definition: conjugate.h:588
conjugate(int r)
Definition: conjugate.h:406
Matrix_< E > operator*(const MatrixBase< E > &l, const typename CNT< E >::StdNumber &r)
Definition: BigMatrix.h:605
conjugate< long double > WConj
Definition: conjugate.h:209
complex< double > WCplx
Definition: conjugate.h:203
Definition: conjugate.h:185
conjugate(int r, const long double &imag)
Definition: conjugate.h:572
conjugate & operator*=(const complex< double > &t)
Definition: conjugate.h:511
conjugate & operator*=(int i)
Definition: conjugate.h:658
conjugate(const complex< float > &x)
Definition: conjugate.h:288
conjugate()
Definition: conjugate.h:257
long double & real()
Definition: conjugate.h:736
complex< double > WCplx
Definition: conjugate.h:193
conjugate & operator+=(int i)
Definition: conjugate.h:472
conjugate & operator+=(const float &r)
Definition: conjugate.h:314
conjugate & operator*=(const conjugate< long double > &c)
Definition: conjugate.h:703
conjugate & operator-=(const complex< float > &c)
Definition: conjugate.h:498
conjugate(int r, int i)
Definition: conjugate.h:268
conjugate(int r)
Definition: conjugate.h:272
const conjugate & operator+() const
Definition: conjugate.h:614
conjugate & operator-=(const conjugate< float > &c)
Definition: conjugate.h:673
conjugate & operator-=(const double &r)
Definition: conjugate.h:636
conjugate(const float &real, const float &imag)
Construction from reals. Note that the numeric result is (real-imag*i).
Definition: conjugate.h:265
float norm(const conjugate< float > &c)
Definition: conjugate.h:775
conjugate & operator-=(const conjugate< float > &c)
Definition: conjugate.h:325
const complex< double > & conj() const
Definition: conjugate.h:541
conjugate & operator/=(const float &r)
Definition: conjugate.h:467
const float & real(const conjugate< float > &c)
Definition: conjugate.h:771
conjugate & operator=(const complex< float > &c)
Definition: conjugate.h:690
conjugate & operator*=(const complex< float > &c)
Definition: conjugate.h:715
long double WReal
Definition: conjugate.h:207
RowVectorBase< typename CNT< ELEM >::TAbs > abs(const RowVectorBase< ELEM > &v)
Definition: VectorMath.h:120
bool isReal() const
Definition: conjugate.h:747
bool operator!=(const conjugate< R > &a, const float &b)
Definition: conjugate.h:859
conjugate & operator/=(const double &r)
Definition: conjugate.h:640
conjugate & operator-=(const conjugate< long double > &c)
Definition: conjugate.h:663
double WReal
Definition: conjugate.h:192
long double & negImag()
Definition: conjugate.h:746
complex< long double > WCplx
Definition: conjugate.h:208
const long double & negImag() const
Definition: conjugate.h:745
conjugate & operator/=(const double &r)
Definition: conjugate.h:456
conjugate & operator=(const long double &r)
Definition: conjugate.h:621
conjugate & operator*=(const complex< float > &c)
Definition: conjugate.h:517
const negator< double > & imag() const
Definition: conjugate.h:538
const float & real() const
Definition: conjugate.h:363
conjugate(const float &rf)
Definition: conjugate.h:586
conjugate()
Definition: conjugate.h:562
conjugate(const double &real, const double &imag)
Construction from reals. Note that the numeric result is (real-imag*i).
Definition: conjugate.h:399
conjugate & operator*=(const float &r)
Definition: conjugate.h:649
conjugate & operator=(const complex< double > &c)
Definition: conjugate.h:487
conjugate(const complex< float > &x)
Definition: conjugate.h:595
conjugate(const conjugate< double > &cd)
Definition: conjugate.h:583
conjugate & operator/=(const complex< float > &c)
Definition: conjugate.h:533
conjugate(const complex< double > &x)
Definition: conjugate.h:597
conjugate(int r, int i)
Definition: conjugate.h:573
conjugate & operator+=(const complex< float > &c)
Definition: conjugate.h:496
conjugate & operator/=(const conjugate< float > &c)
Definition: conjugate.h:732
conjugate & operator/=(const complex< double > &c)
Definition: conjugate.h:731
conjugate & operator/=(const long double &r)
Definition: conjugate.h:629
conjugate & operator*=(const conjugate< float > &c)
Definition: conjugate.h:341
const complex< long double > & conj() const
Definition: conjugate.h:741
long double norm(const conjugate< long double > &c)
Definition: conjugate.h:787
complex< long double > WCplx
Definition: conjugate.h:228
conjugate(const double &rd)
Definition: conjugate.h:280
conjugate & operator/=(int i)
Definition: conjugate.h:475
conjugate & operator*=(const conjugate< float > &c)
Definition: conjugate.h:714
conjugate(const float &real, int i)
Definition: conjugate.h:266
conjugate()
Definition: conjugate.h:391
conjugate & operator=(const complex< float > &c)
Definition: conjugate.h:328
Matrix_< typename CNT< E1 >::template Result< E2 >::Add > operator+(const MatrixBase< E1 > &l, const MatrixBase< E2 > &r)
Definition: BigMatrix.h:568
const negator< long double > & imag() const
Definition: conjugate.h:738
const negator< float > & imag(const conjugate< float > &c)
Definition: conjugate.h:772
conjugate(const double &real)
Implicit conversion from double to conjugate<double>.
Definition: conjugate.h:405
float & negImag()
Definition: conjugate.h:374
conjugate< long double > WConj
Definition: conjugate.h:219
conjugate & operator+=(const complex< long double > &c)
Definition: conjugate.h:678
conjugate & operator=(const complex< double > &c)
Definition: conjugate.h:683
conjugate(const long double &real, int i)
Definition: conjugate.h:571
conjugate(const complex< long double > &x)
Definition: conjugate.h:428
conjugate & operator*=(const double &r)
Definition: conjugate.h:638
conjugate< double > WConj
Definition: conjugate.h:204
conjugate & operator=(const double &r)
Definition: conjugate.h:632
conjugate(const conjugate< float > &cf)
Definition: conjugate.h:581
conjugate & operator-=(int i)
Definition: conjugate.h:473
const complex< float > & conj(const conjugate< float > &c)
Definition: conjugate.h:773
conjugate & operator/=(const conjugate< long double > &d)
Definition: conjugate.h:719
conjugate & operator-=(const complex< double > &c)
Definition: conjugate.h:491
conjugate & operator-=(const conjugate< float > &c)
Definition: conjugate.h:484
conjugate & operator/=(const conjugate< float > &c)
Definition: conjugate.h:532
conjugate< long double > WConj
Definition: conjugate.h:224
conjugate(const long double &rl)
Definition: conjugate.h:418
conjugate & operator/=(const float &r)
Definition: conjugate.h:320
conjugate & operator/=(int i)
Definition: conjugate.h:659
conjugate & operator+=(const float &r)
Definition: conjugate.h:645
conjugate & operator=(const complex< float > &c)
Definition: conjugate.h:494
conjugate & operator+=(const complex< double > &c)
Definition: conjugate.h:685
long double abs(const conjugate< long double > &c)
Definition: conjugate.h:786
conjugate(const long double &real)
Implicit conversion from long double to conjugate<long double>.
Definition: conjugate.h:576
conjugate & operator-=(const float &r)
Definition: conjugate.h:316
bool isReal() const
Definition: conjugate.h:547
conjugate & operator+=(const complex< double > &c)
Definition: conjugate.h:489
conjugate & operator/=(const conjugate< float > &d)
Definition: conjugate.h:352
conjugate(const complex< double > &x)
Definition: conjugate.h:290
conjugate & operator+=(const float &r)
Definition: conjugate.h:461
conjugate & operator/=(const complex< float > &d)
Definition: conjugate.h:357
conjugate & operator+=(const conjugate< double > &c)
Definition: conjugate.h:477
conjugate & operator*=(const float &r)
Definition: conjugate.h:318
complex< long double > WCplx
Definition: conjugate.h:213
conjugate & operator+=(const conjugate< long double > &c)
Definition: conjugate.h:661