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 explicit negator(int t) {v = -N((typename NTraits<N>::Precision)t);}
00231 explicit negator(const float& t) {v = -N((typename NTraits<N>::Precision)t);}
00232 explicit negator(const double& t) {v = -N((typename NTraits<N>::Precision)t);}
00233 explicit negator(const long double& t) {v = -N((typename NTraits<N>::Precision)t);}
00234
00235
00236
00237 template <class P>
00238 explicit negator(const std::complex<P>& t) {v = -N(t);}
00239 template <class P>
00240 explicit negator(const conjugate<P>& t) {v = -N(t);}
00241
00242
00243
00244
00245
00246 static const negator<N>& recast(const N& val)
00247 { return reinterpret_cast<const negator<N>&>(val); }
00248
00249 const N& operator-() const { return v; }
00250 N& operator-() { return v; }
00251 N operator+() const { return N(-v); }
00252
00253 operator N() const { return N(-v); }
00254
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 template <class P> negator& operator*=(const P& t) { v *= t; return *this; }
00259 template <class P> negator& operator/=(const P& t) { v /= t; return *this; }
00260
00261
00262
00263
00264 template <class NN> negator& operator =(const negator<NN>& t) { v = -t; return *this; }
00265 template <class NN> negator& operator+=(const negator<NN>& t) { v += -t; return *this; }
00266 template <class NN> negator& operator-=(const negator<NN>& t) { v -= -t; return *this; }
00267
00268 private:
00269 N v;
00270
00271 template <class N2> friend class negator;
00272 };
00273
00274
00275
00276
00278
00279 inline bool isNaN(const negator<float>& x) {return isNaN(-x);}
00280 inline bool isNaN(const negator<double>& x) {return isNaN(-x);}
00281 inline bool isNaN(const negator<long double>& x) {return isNaN(-x);}
00282 template <class P> inline bool
00283 isNaN(const negator< std::complex<P> >& x) {return isNaN(-x);}
00284 template <class P> inline bool
00285 isNaN(const negator< conjugate<P> >& x) {return isNaN(-x);}
00287
00288
00289
00290
00292
00293 inline bool isFinite(const negator<float>& x) {return isFinite(-x);}
00294 inline bool isFinite(const negator<double>& x) {return isFinite(-x);}
00295 inline bool isFinite(const negator<long double>& x) {return isFinite(-x);}
00296 template <class P> inline bool
00297 isFinite(const negator< std::complex<P> >& x) {return isFinite(-x);}
00298 template <class P> inline bool
00299 isFinite(const negator< conjugate<P> >& x) {return isFinite(-x);}
00301
00302
00303
00304
00306
00307 inline bool isInf(const negator<float>& x) {return isInf(-x);}
00308 inline bool isInf(const negator<double>& x) {return isInf(-x);}
00309 inline bool isInf(const negator<long double>& x) {return isInf(-x);}
00310 template <class P> inline bool
00311 isInf(const negator< std::complex<P> >& x) {return isInf(-x);}
00312 template <class P> inline bool
00313 isInf(const negator< conjugate<P> >& x) {return isInf(-x);}
00315
00316
00317 template <class N> inline bool
00318 negator<N>::isFinite() const {return SimTK::isFinite(*this);}
00319 template <class N> inline bool
00320 negator<N>::isNaN() const {return SimTK::isNaN(*this);}
00321 template <class N> inline bool
00322 negator<N>::isInf() const {return SimTK::isInf(*this);}
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 template <class DEST, class SRC> static inline const DEST&
00336 negRecast(const SRC& s) { return reinterpret_cast<const DEST&>(s); }
00337
00338
00339 template <class A, class B> inline typename negator<A>::template Result<B>::Add
00340 operator+(const negator<A>& l, const B& r)
00341 {return negRecast<typename negator<A>::template Result<B>::Add>(r-(-l));}
00342 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Add
00343 operator+(const A& l, const negator<B>& r)
00344 {return negRecast<typename CNT<A>::template Result<negator<B> >::Add>(l-(-r));}
00345
00346 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Add
00347 operator+(const negator<A>& l, const negator<B>& r)
00348 {return negRecast<typename negator<A>::template Result<negator<B> >::Add>(r-(-l)); }
00349
00350
00351 template <class A, class B> inline typename negator<A>::template Result<B>::Sub
00352 operator-(const negator<A>& l, const B& r)
00353 {return negRecast<typename negator<A>::template Result<B>::Sub>(r+(-l));}
00354 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Sub
00355 operator-(const A& l, const negator<B>& r)
00356 {return negRecast<typename CNT<A>::template Result<negator<B> >::Sub>(l+(-r));}
00357
00358 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Sub
00359 operator-(const negator<A>& l, const negator<B>& r)
00360 {return negRecast<typename negator<A>::template Result<negator<B> >::Sub>(r+(-l));}
00361
00362
00363 template <class A, class B> inline typename negator<A>::template Result<B>::Mul
00364 operator*(const negator<A>& l, const B& r)
00365 {return negRecast<typename negator<A>::template Result<B>::Mul>((-l)*r);}
00366 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Mul
00367 operator*(const A& l, const negator<B>& r)
00368 {return negRecast<typename CNT<A>::template Result<negator<B> >::Mul>(l*(-r));}
00369
00370 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Mul
00371 operator*(const negator<A>& l, const negator<B>& r)
00372 {return negRecast<typename negator<A>::template Result<negator<B> >::Mul>((-l)*r);}
00373
00374
00375 template <class A, class B> inline typename negator<A>::template Result<B>::Dvd
00376 operator/(const negator<A>& l, const B& r)
00377 {return negRecast<typename negator<A>::template Result<B>::Dvd>((-l)/r);}
00378 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Dvd
00379 operator/(const A& l, const negator<B>& r)
00380 {return negRecast<typename CNT<A>::template Result<negator<B> >::Dvd>(l/(-r));}
00381
00382 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Dvd
00383 operator/(const negator<A>& l, const negator<B>& r)
00384 {return negRecast<typename negator<A>::template Result<negator<B> >::Dvd>((-l)/r);}
00385
00386
00387 template <class A, class B> inline bool
00388 operator==(const negator<A>& l, const B& r) { return (A)l == r; }
00389 template <class A, class B> inline bool
00390 operator==(const A& l, const negator<B>& r) { return l == (B)r; }
00391 template <class A, class B> inline bool
00392 operator==(const negator<A>& l, const negator<B>& r) { return (-l) == (-r); }
00393
00394
00395 template <class A, class B> inline bool
00396 operator!=(const negator<A>& l, const B& r) { return !(l==r); }
00397 template <class A, class B> inline bool
00398 operator!=(const A& l, const negator<B>& r) { return !(l==r); }
00399 template <class A, class B> inline bool
00400 operator!=(const negator<A>& l, const negator<B>& r) { return !(l==r); }
00401
00402
00403 template <class NUM, class CHAR, class TRAITS> inline std::basic_istream<CHAR,TRAITS>&
00404 operator>>(std::basic_istream<CHAR,TRAITS>& is, negator<NUM>& nn) {
00405 NUM z; is >> z; nn=z;
00406 return is;
00407 }
00408 template <class NUM, class CHAR, class TRAITS> inline std::basic_ostream<CHAR,TRAITS>&
00409 operator<<(std::basic_ostream<CHAR,TRAITS>& os, const negator<NUM>& nn) {
00410 return os << NUM(nn);
00411 }
00412
00413 }
00414
00415 #endif //SimTK_SIMMATRIX_NEGATOR_H_