00001 #ifndef SimTK_SIMMATRIX_NEGATOR_H_
00002 #define SimTK_SIMMATRIX_NEGATOR_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
00065 #include <iostream>
00066
00067 namespace SimTK {
00068
00069
00070
00071 template <class T> class CNT;
00072 template <class N> class NTraits;
00073 template <class N> class negator;
00074
00075
00082 template <class NUMBER>
00083 class SimTK_SimTKCOMMON_EXPORT negator {
00084 typedef NUMBER N;
00085 typedef typename NTraits<N>::TReal NReal;
00086 typedef typename NTraits<N>::TImag NImag;
00087 typedef typename NTraits<N>::TComplex NComplex;
00088 typedef typename NTraits<N>::THerm NHerm;
00089 typedef typename NTraits<N>::TInvert NInvert;
00090 public:
00091 typedef negator<N> T;
00092 typedef NUMBER TNeg;
00093 typedef NUMBER TWithoutNegator;
00094 typedef typename CNT<NReal>::TNeg TReal;
00095 typedef typename CNT<NImag>::TNeg TImag;
00096 typedef typename CNT<NComplex>::TNeg TComplex;
00097 typedef typename CNT<NHerm>::TNeg THerm;
00098 typedef negator<N> TPosTrans;
00099 typedef typename NTraits<N>::TSqHermT TSqHermT;
00100 typedef typename NTraits<N>::TSqTHerm TSqTHerm;
00101 typedef negator<N> TElement;
00102 typedef negator<N> TRow;
00103 typedef negator<N> TCol;
00104
00105 typedef typename NTraits<N>::TSqrt TSqrt;
00106 typedef typename NTraits<N>::TAbs TAbs;
00107 typedef typename NTraits<N>::TStandard TStandard;
00108 typedef typename CNT<NInvert>::TNeg TInvert;
00109 typedef typename NTraits<N>::TStandard TNormalize;
00110
00111
00112 typedef negator<N> Scalar;
00113 typedef negator<N> ULessScalar;
00114 typedef NUMBER Number;
00115 typedef typename NTraits<N>::StdNumber StdNumber;
00116 typedef typename NTraits<N>::Precision Precision;
00117 typedef typename NTraits<N>::ScalarNormSq ScalarNormSq;
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 template <class P> struct Result {
00128 private:
00129
00130 typedef typename CNT<P>::template Result<N>::Mul PMul;
00131 typedef typename NTraits<N>::template Result<P>::Dvd PDvd;
00132 typedef typename CNT<P>::template Result<N>::Sub PAdd;
00133 typedef typename CNT<P>::template Result<N>::Add PSub;
00134 public:
00135
00136 typedef typename CNT<PMul>::TNeg Mul;
00137 typedef typename CNT<PDvd>::TNeg Dvd;
00138 typedef PAdd Add;
00139 typedef typename CNT<PSub>::TNeg Sub;
00140 };
00141
00142
00143 template <class P> struct Substitute {
00144 typedef P Type;
00145 };
00146
00147 enum {
00148 NRows = 1,
00149 NCols = 1,
00150 RowSpacing = 1,
00151 ColSpacing = 1,
00152 NPackedElements = 1,
00153 NActualElements = 1,
00154 NActualScalars = 1,
00155 ImagOffset = NTraits<N>::ImagOffset,
00156 RealStrideFactor = NTraits<N>::RealStrideFactor,
00157 ArgDepth = SCALAR_DEPTH,
00158 IsScalar = 1,
00159 IsULessScalar = 1,
00160 IsNumber = 0,
00161 IsStdNumber = 0,
00162 IsPrecision = 0,
00163 SignInterpretation = -1
00164 };
00165 const negator<N>* getData() const {return this;}
00166 negator<N>* updData() {return this;}
00167
00168 const TReal& real() const {return reinterpret_cast<const TReal&>(NTraits<N>::real(v));}
00169 TReal& real() {return reinterpret_cast< TReal&>(NTraits<N>::real(v));}
00170 const TImag& imag() const {return reinterpret_cast<const TImag&>(NTraits<N>::imag(v));}
00171 TImag& imag() {return reinterpret_cast< TImag&>(NTraits<N>::imag(v));}
00172
00173 ScalarNormSq scalarNormSqr() const {return NTraits<N>::scalarNormSqr(v);}
00174 TSqrt sqrt() const {return NTraits<N>::sqrt(N(v));}
00175 TAbs abs() const {return NTraits<N>::abs(v);}
00176 TStandard standardize() const {return -NTraits<N>::standardize(v);}
00177 TNormalize normalize() const {return -NTraits<N>::normalize(v);}
00178
00179
00180
00181
00182
00183 TInvert invert() const {return recast(NTraits<N>::invert(v));}
00184
00185 static negator<N> getNaN() {return recast(NTraits<N>::getNaN());}
00186 static negator<N> getInfinity() {return recast(NTraits<N>::getInfinity());}
00187
00189 inline bool isFinite() const;
00191 inline bool isNaN() const;
00194 inline bool isInf() const;
00195
00196 static double getDefaultTolerance() {return NTraits<N>::getDefaultTolerance();}
00197
00200 template <class T2> bool isNumericallyEqual(const T2& t2) const
00201 { return CNT<T2>::isNumericallyEqual(t2, -v); }
00202
00206 template <class N2> bool isNumericallyEqual(const negator<N2>& t2) const
00207 { return SimTK::isNumericallyEqual(v, t2.v); }
00208
00210 template <class T2> bool isNumericallyEqual(const T2& t2, double tol) const
00211 { return CNT<T2>::isNumericallyEqual(t2, -v, tol); }
00212
00215 template <class N2> bool isNumericallyEqual(const negator<N2>& t2, double tol) const
00216 { return SimTK::isNumericallyEqual(v, t2.v, tol); }
00217
00218
00219 negator() {
00220 #ifndef NDEBUG
00221 v = NTraits<N>::getNaN();
00222 #endif
00223 }
00224 negator(const negator& n) : v(n.v) { }
00225 negator& operator=(const negator& n) { v=n.v; return *this; }
00226
00227
00228
00229
00230 negator(int t) {v = -N((typename NTraits<N>::Precision)t);}
00231 negator(const float& t) {v = -N((typename NTraits<N>::Precision)t);}
00232 negator(const double& t) {v = -N((typename NTraits<N>::Precision)t);}
00233 negator(const long double& t) {v = -N((typename NTraits<N>::Precision)t);}
00234
00235
00236
00237 template <class P> negator(const std::complex<P>& t) {v = -N(t);}
00238 template <class P> negator(const conjugate<P>& t) {v = -N(t);}
00239
00240
00241
00242
00243
00244 static const negator<N>& recast(const N& val)
00245 { return reinterpret_cast<const negator<N>&>(val); }
00246
00247 const N& operator-() const { return v; }
00248 N& operator-() { return v; }
00249 N operator+() const { return N(-v); }
00250
00251 operator N() const { return N(-v); }
00252
00253 template <class P> negator& operator =(const P& t) { v = -t; return *this; }
00254 template <class P> negator& operator+=(const P& t) { v -= t; return *this; }
00255 template <class P> negator& operator-=(const P& t) { v += t; return *this; }
00256 template <class P> negator& operator*=(const P& t) { v *= t; return *this; }
00257 template <class P> negator& operator/=(const P& t) { v /= t; return *this; }
00258
00259
00260
00261
00262
00263 template <class NN> negator& operator =(const negator<NN>& t)
00264 { v = -t; return *this; }
00265 template <class NN> negator& operator+=(const negator<NN>& t)
00266 { v += -t; return *this; }
00267 template <class NN> negator& operator-=(const negator<NN>& t)
00268 { v -= -t; return *this; }
00269
00270 private:
00271 N v;
00272
00273 template <class N2> friend class negator;
00274 };
00275
00276
00277
00278
00280
00281 inline bool isNaN(const negator<float>& x) {return isNaN(-x);}
00282 inline bool isNaN(const negator<double>& x) {return isNaN(-x);}
00283 inline bool isNaN(const negator<long double>& x) {return isNaN(-x);}
00284 template <class P> inline bool
00285 isNaN(const negator< std::complex<P> >& x) {return isNaN(-x);}
00286 template <class P> inline bool
00287 isNaN(const negator< conjugate<P> >& x) {return isNaN(-x);}
00289
00290
00291
00292
00294
00295 inline bool isFinite(const negator<float>& x) {return isFinite(-x);}
00296 inline bool isFinite(const negator<double>& x) {return isFinite(-x);}
00297 inline bool isFinite(const negator<long double>& x) {return isFinite(-x);}
00298 template <class P> inline bool
00299 isFinite(const negator< std::complex<P> >& x) {return isFinite(-x);}
00300 template <class P> inline bool
00301 isFinite(const negator< conjugate<P> >& x) {return isFinite(-x);}
00303
00304
00305
00306
00308
00309 inline bool isInf(const negator<float>& x) {return isInf(-x);}
00310 inline bool isInf(const negator<double>& x) {return isInf(-x);}
00311 inline bool isInf(const negator<long double>& x) {return isInf(-x);}
00312 template <class P> inline bool
00313 isInf(const negator< std::complex<P> >& x) {return isInf(-x);}
00314 template <class P> inline bool
00315 isInf(const negator< conjugate<P> >& x) {return isInf(-x);}
00317
00318
00319 template <class N> inline bool
00320 negator<N>::isFinite() const {return SimTK::isFinite(*this);}
00321 template <class N> inline bool
00322 negator<N>::isNaN() const {return SimTK::isNaN(*this);}
00323 template <class N> inline bool
00324 negator<N>::isInf() const {return SimTK::isInf(*this);}
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 template <class DEST, class SRC> static inline const DEST&
00338 negRecast(const SRC& s) { return reinterpret_cast<const DEST&>(s); }
00339
00340
00341 template <class A, class B> inline typename negator<A>::template Result<B>::Add
00342 operator+(const negator<A>& l, const B& r)
00343 {return negRecast<typename negator<A>::template Result<B>::Add>(r-(-l));}
00344 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Add
00345 operator+(const A& l, const negator<B>& r)
00346 {return negRecast<typename CNT<A>::template Result<negator<B> >::Add>(l-(-r));}
00347
00348 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Add
00349 operator+(const negator<A>& l, const negator<B>& r)
00350 {return negRecast<typename negator<A>::template Result<negator<B> >::Add>(r-(-l)); }
00351
00352
00353 template <class A, class B> inline typename negator<A>::template Result<B>::Sub
00354 operator-(const negator<A>& l, const B& r)
00355 {return negRecast<typename negator<A>::template Result<B>::Sub>(r+(-l));}
00356 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Sub
00357 operator-(const A& l, const negator<B>& r)
00358 {return negRecast<typename CNT<A>::template Result<negator<B> >::Sub>(l+(-r));}
00359
00360 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Sub
00361 operator-(const negator<A>& l, const negator<B>& r)
00362 {return negRecast<typename negator<A>::template Result<negator<B> >::Sub>(r+(-l));}
00363
00364
00365 template <class A, class B> inline typename negator<A>::template Result<B>::Mul
00366 operator*(const negator<A>& l, const B& r)
00367 {return negRecast<typename negator<A>::template Result<B>::Mul>((-l)*r);}
00368 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Mul
00369 operator*(const A& l, const negator<B>& r)
00370 {return negRecast<typename CNT<A>::template Result<negator<B> >::Mul>(l*(-r));}
00371
00372 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Mul
00373 operator*(const negator<A>& l, const negator<B>& r)
00374 {return negRecast<typename negator<A>::template Result<negator<B> >::Mul>((-l)*r);}
00375
00376
00377 template <class A, class B> inline typename negator<A>::template Result<B>::Dvd
00378 operator/(const negator<A>& l, const B& r)
00379 {return negRecast<typename negator<A>::template Result<B>::Dvd>((-l)/r);}
00380 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Dvd
00381 operator/(const A& l, const negator<B>& r)
00382 {return negRecast<typename CNT<A>::template Result<negator<B> >::Dvd>(l/(-r));}
00383
00384 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Dvd
00385 operator/(const negator<A>& l, const negator<B>& r)
00386 {return negRecast<typename negator<A>::template Result<negator<B> >::Dvd>((-l)/r);}
00387
00388
00389 template <class A, class B> inline bool
00390 operator==(const negator<A>& l, const B& r) { return (A)l == r; }
00391 template <class A, class B> inline bool
00392 operator==(const A& l, const negator<B>& r) { return l == (B)r; }
00393 template <class A, class B> inline bool
00394 operator==(const negator<A>& l, const negator<B>& r) { return (-l) == (-r); }
00395
00396
00397 template <class A, class B> inline bool
00398 operator!=(const negator<A>& l, const B& r) { return !(l==r); }
00399 template <class A, class B> inline bool
00400 operator!=(const A& l, const negator<B>& r) { return !(l==r); }
00401 template <class A, class B> inline bool
00402 operator!=(const negator<A>& l, const negator<B>& r) { return !(l==r); }
00403
00404
00405 template <class NUM, class CHAR, class TRAITS> inline std::basic_istream<CHAR,TRAITS>&
00406 operator>>(std::basic_istream<CHAR,TRAITS>& is, negator<NUM>& nn) {
00407 NUM z; is >> z; nn=z;
00408 return is;
00409 }
00410 template <class NUM, class CHAR, class TRAITS> inline std::basic_ostream<CHAR,TRAITS>&
00411 operator<<(std::basic_ostream<CHAR,TRAITS>& os, const negator<NUM>& nn) {
00412 return os << NUM(nn);
00413 }
00414
00415 }
00416
00417 #endif //SimTK_SIMMATRIX_NEGATOR_H_