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 public:
00090 typedef negator<N> T;
00091 typedef NUMBER TNeg;
00092 typedef NUMBER TWithoutNegator;
00093 typedef typename CNT<NReal>::TNeg TReal;
00094 typedef typename CNT<NImag>::TNeg TImag;
00095 typedef typename CNT<NComplex>::TNeg TComplex;
00096 typedef typename CNT<NHerm>::TNeg THerm;
00097 typedef negator<N> TPosTrans;
00098 typedef typename NTraits<N>::TSqHermT TSqHermT;
00099 typedef typename NTraits<N>::TSqTHerm TSqTHerm;
00100 typedef negator<N> TElement;
00101 typedef negator<N> TRow;
00102 typedef negator<N> TCol;
00103
00104 typedef typename NTraits<N>::TAbs TAbs;
00105 typedef typename NTraits<N>::TStandard TStandard;
00106 typedef typename NTraits<N>::TInvert TInvert;
00107 typedef typename NTraits<N>::TStandard TNormalize;
00108
00109
00110 typedef negator<N> Scalar;
00111 typedef NUMBER Number;
00112 typedef typename NTraits<N>::StdNumber StdNumber;
00113 typedef typename NTraits<N>::Precision Precision;
00114 typedef typename NTraits<N>::ScalarSq ScalarSq;
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 template <class P> struct Result {
00125 private:
00126
00127 typedef typename CNT<P>::template Result<N>::Mul PMul;
00128 typedef typename NTraits<N>::template Result<P>::Dvd PDvd;
00129 typedef typename CNT<P>::template Result<N>::Sub PAdd;
00130 typedef typename CNT<P>::template Result<N>::Add PSub;
00131 public:
00132
00133 typedef typename CNT<PMul>::TNeg Mul;
00134 typedef typename CNT<PDvd>::TNeg Dvd;
00135 typedef PAdd Add;
00136 typedef typename CNT<PSub>::TNeg Sub;
00137 };
00138
00139
00140 template <class P> struct Substitute {
00141 typedef P Type;
00142 };
00143
00144 enum {
00145 NRows = 1,
00146 NCols = 1,
00147 RowSpacing = 1,
00148 ColSpacing = 1,
00149 NPackedElements = 1,
00150 NActualElements = 1,
00151 NActualScalars = 1,
00152 ImagOffset = NTraits<N>::ImagOffset,
00153 RealStrideFactor = NTraits<N>::RealStrideFactor,
00154 ArgDepth = SCALAR_DEPTH,
00155 IsScalar = 1,
00156 IsNumber = 0,
00157 IsStdNumber = 0,
00158 IsPrecision = 0,
00159 SignInterpretation = -1
00160 };
00161 static negator<N> getNaN() {return recast(NTraits<N>::getNaN());}
00162 static negator<N> getInfinity() {return recast(NTraits<N>::getInfinity());}
00163
00164 const negator<N>* getData() const {return this;}
00165 negator<N>* updData() {return this;}
00166
00167 const TReal& real() const {return reinterpret_cast<const TReal&>(NTraits<N>::real(v));}
00168 TReal& real() {return reinterpret_cast< TReal&>(NTraits<N>::real(v));}
00169 const TImag& imag() const {return reinterpret_cast<const TImag&>(NTraits<N>::imag(v));}
00170 TImag& imag() {return reinterpret_cast< TImag&>(NTraits<N>::imag(v));}
00171
00172 ScalarSq scalarNormSqr() const {return NTraits<N>::scalarNormSqr(v);}
00173 TAbs abs() const {return NTraits<N>::abs(v);}
00174 TStandard standardize() const {return -NTraits<N>::standardize(v);}
00175 TNormalize normalize() const {return -NTraits<N>::normalize(v);}
00176 TInvert invert() const {return -NTraits<N>::invert(v);}
00177
00178 negator() {
00179 #ifndef NDEBUG
00180 v = NTraits<N>::getNaN();
00181 #endif
00182 }
00183 negator(const negator& n) : v(n.v) { }
00184 negator& operator=(const negator& n) { v=n.v; return *this; }
00185
00186
00187
00188
00189 explicit negator(int t) {v = -N((typename NTraits<N>::Precision)t);}
00190 explicit negator(const float& t) {v = -N(t);}
00191 explicit negator(const double& t) {v = -N(t);}
00192 explicit negator(const long double& t) {v = -N(t);}
00193 explicit negator(const std::complex<float>& t) {v = -N(t);}
00194 explicit negator(const std::complex<double>& t) {v = -N(t);}
00195 explicit negator(const std::complex<long double>& t) {v = -N(t);}
00196 explicit negator(const conjugate<float>& t) {v = -N(t);}
00197 explicit negator(const conjugate<double>& t) {v = -N(t);}
00198 explicit negator(const conjugate<long double>& t) {v = -N(t);}
00199
00200
00201
00202
00203
00204 static const negator<N>& recast(const N& val)
00205 { return reinterpret_cast<const negator<N>&>(val); }
00206
00207 const N& operator-() const { return v; }
00208 N& operator-() { return v; }
00209 N operator+() const { return N(-v); }
00210
00211 operator N() const { return N(-v); }
00212
00213 template <class P> negator& operator =(const P& t) { v = -t; return *this; }
00214 template <class P> negator& operator+=(const P& t) { v -= t; return *this; }
00215 template <class P> negator& operator-=(const P& t) { v += t; return *this; }
00216 template <class P> negator& operator*=(const P& t) { v *= t; return *this; }
00217 template <class P> negator& operator/=(const P& t) { v /= t; return *this; }
00218
00219
00220
00221
00222 template <class NN> negator& operator =(const negator<NN>& t) { v = -t; return *this; }
00223 template <class NN> negator& operator+=(const negator<NN>& t) { v += -t; return *this; }
00224 template <class NN> negator& operator-=(const negator<NN>& t) { v -= -t; return *this; }
00225
00226 private:
00227 N v;
00228 };
00229
00230
00231
00232
00233
00234
00235
00236
00237 template <class DEST, class SRC> static inline const DEST&
00238 negRecast(const SRC& s) { return reinterpret_cast<const DEST&>(s); }
00239
00240
00241 template <class A, class B> inline typename negator<A>::template Result<B>::Add
00242 operator+(const negator<A>& l, const B& r)
00243 {return negRecast<typename negator<A>::template Result<B>::Add>(r-(-l));}
00244 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Add
00245 operator+(const A& l, const negator<B>& r)
00246 {return negRecast<typename CNT<A>::template Result<negator<B> >::Add>(l-(-r));}
00247 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Add
00248 operator+(const negator<A>& l, const negator<B>& r)
00249 {return negRecast<typename negator<A>::template Result<negator<B> >::Add>((-l)+(-r)); }
00250
00251
00252 template <class A, class B> inline typename negator<A>::template Result<B>::Sub
00253 operator-(const negator<A>& l, const B& r)
00254 {return negRecast<typename negator<A>::template Result<B>::Sub>((-l)+r);}
00255 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Sub
00256 operator-(const A& l, const negator<B>& r)
00257 {return negRecast<typename CNT<A>::template Result<negator<B> >::Sub>(l+(-r));}
00258 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Sub
00259 operator-(const negator<A>& l, const negator<B>& r)
00260 {return negRecast<typename negator<A>::template Result<negator<B> >::Sub>((-r)-(-l));}
00261
00262
00263 template <class A, class B> inline typename negator<A>::template Result<B>::Mul
00264 operator*(const negator<A>& l, const B& r)
00265 {return negRecast<typename negator<A>::template Result<B>::Mul>((-l)*r);}
00266 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Mul
00267 operator*(const A& l, const negator<B>& r)
00268 {return negRecast<typename CNT<A>::template Result<negator<B> >::Mul>(l*(-r));}
00269 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Mul
00270 operator*(const negator<A>& l, const negator<B>& r)
00271 {return negRecast<typename negator<A>::template Result<negator<B> >::Mul>((-l)*(-r));}
00272
00273
00274 template <class A, class B> inline typename negator<A>::template Result<B>::Dvd
00275 operator/(const negator<A>& l, const B& r)
00276 {return negRecast<typename negator<A>::template Result<B>::Dvd>((-l)/r);}
00277 template <class A, class B> inline typename CNT<A>::template Result<negator<B> >::Dvd
00278 operator/(const A& l, const negator<B>& r)
00279 {return negRecast<typename CNT<A>::template Result<negator<B> >::Dvd>(l/(-r));}
00280 template <class A, class B> inline typename negator<A>::template Result<negator<B> >::Dvd
00281 operator/(const negator<A>& l, const negator<B>& r)
00282 {return negRecast<typename negator<A>::template Result<negator<B> >::Dvd>((-l)/(-r));}
00283
00284
00285 template <class A, class B> inline bool
00286 operator==(const negator<A>& l, const B& r) { return (A)l == r; }
00287 template <class A, class B> inline bool
00288 operator==(const A& l, const negator<B>& r) { return l == (B)r; }
00289 template <class A, class B> inline bool
00290 operator==(const negator<A>& l, const negator<B>& r) { return (-l) == (-r); }
00291
00292
00293 template <class A, class B> inline bool
00294 operator!=(const negator<A>& l, const B& r) { return !(l==r); }
00295 template <class A, class B> inline bool
00296 operator!=(const A& l, const negator<B>& r) { return !(l==r); }
00297 template <class A, class B> inline bool
00298 operator!=(const negator<A>& l, const negator<B>& r) { return !(l==r); }
00299
00300
00301 template <class NUM, class CHAR, class TRAITS> inline std::basic_istream<CHAR,TRAITS>&
00302 operator>>(std::basic_istream<CHAR,TRAITS>& is, negator<NUM>& nn) {
00303 NUM z; is >> z; nn=z;
00304 return is;
00305 }
00306 template <class NUM, class CHAR, class TRAITS> inline std::basic_ostream<CHAR,TRAITS>&
00307 operator<<(std::basic_ostream<CHAR,TRAITS>& os, const negator<NUM>& nn) {
00308 return os << NUM(nn);
00309 }
00310
00311 }
00312
00313 #endif //SimTK_SIMMATRIX_NEGATOR_H_