CompositeNumericalTypes.h

Go to the documentation of this file.
00001 #ifndef SimTK_SIMMATRIX_COMPOSITE_NUMERICAL_TYPES_H_
00002 #define SimTK_SIMMATRIX_COMPOSITE_NUMERICAL_TYPES_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTK Simmatrix(tm)                       *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2005-9 Stanford University and the Authors.         *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00115 #include "SimTKcommon/internal/common.h"
00116     
00117 namespace SimTK {
00118 
00119 // These are CNT "depths". 0 means the corresponding CNT is a scalar,
00120 // 1 means it is a composite with scalar elements, 2 means a composite
00121 // with composite elements, and 3 means a composite with depth-2
00122 // composite elements. Beyond that the user will have to diambiguate
00123 // operations by using named routines rather than operators.
00124 enum  {
00125     SCALAR_DEPTH              = 0,
00126     SCALAR_COMPOSITE_DEPTH    = 1,
00127     COMPOSITE_COMPOSITE_DEPTH = 2,
00128     COMPOSITE_3_DEPTH         = 3,
00129     MAX_RESOLVED_DEPTH        = COMPOSITE_3_DEPTH
00130 };
00131 
00145 template <class K> class CNT : private K {
00146 public:
00147     typedef K                        T;
00148     typedef typename K::TNeg         TNeg;
00149     typedef typename K::TWithoutNegator TWithoutNegator;
00150     typedef typename K::TReal        TReal;
00151     typedef typename K::TImag        TImag;
00152     typedef typename K::TComplex     TComplex;
00153     typedef typename K::THerm        THerm;
00154     typedef typename K::TPosTrans    TPosTrans;
00155     typedef typename K::TSqHermT     TSqHermT;
00156     typedef typename K::TSqTHerm     TSqTHerm;
00157     typedef typename K::TElement     TElement;
00158     typedef typename K::TRow         TRow;          // type of a row or column
00159     typedef typename K::TCol         TCol;
00160 
00161     // These are the results of calculations and should be packed regardless
00162     // of the spacing of this CNT.
00163     typedef typename K::TSqrt        TSqrt;         // also turns unit^2 to unit
00164     typedef typename K::TAbs         TAbs;
00165     typedef typename K::TStandard    TStandard;     // packed, StdNumbers
00166     typedef typename K::TInvert      TInvert;       // also turns units into 1/units
00167     typedef typename K::TNormalize   TNormalize;    // TODO: what effect on units?
00168 
00169     typedef typename K::Scalar       Scalar;        // quantity< units, <unitlessScalar> >
00170     typedef typename K::ULessScalar  ULessScalar;   // <number> or negator<number>
00171     typedef typename K::Number       Number;        // <real>, <complex> or <conjugate>
00172     typedef typename K::StdNumber    StdNumber;     // <real>, <complex>
00173     typedef typename K::Precision    Precision;     // float, double, long double
00174 
00175     typedef typename K::ScalarNormSq ScalarNormSq;  // type of conjugate square of underlying scalar or
00176                                                     //   numeric value (squares the units too)
00177 
00178     template <class P> struct Result {
00179         typedef typename K::template Result<P>::Mul Mul;
00180         typedef typename K::template Result<P>::Dvd Dvd;;
00181         typedef typename K::template Result<P>::Add Add;
00182         typedef typename K::template Result<P>::Sub Sub;
00183     };
00184 
00185     // Shape-preserving element substitution
00186     template <class P> struct Substitute {
00187         typedef typename K::template Substitute<P>::Type Type;
00188     };
00189 
00190     enum {
00191         NRows               = K::NRows,
00192         NCols               = K::NCols,
00193         RowSpacing          = K::RowSpacing,
00194         ColSpacing          = K::ColSpacing,
00195         NPackedElements     = K::NPackedElements,
00196         NActualElements     = K::NActualElements,
00197         NActualScalars      = K::NActualScalars,
00198         ImagOffset          = K::ImagOffset,
00199         RealStrideFactor    = K::RealStrideFactor,
00200         ArgDepth            = K::ArgDepth,
00201         IsScalar            = K::IsScalar,          // scalar with units, real, complex, conjugate, negator
00202         IsULessScalar       = K::IsULessScalar,     // real, complex, conjugate, negator
00203         IsNumber            = K::IsNumber,          // real, complex, conjugate
00204         IsStdNumber         = K::IsStdNumber,       // real, complex
00205         IsPrecision         = K::IsPrecision,       // real (float, double, long double)
00206         SignInterpretation  = K::SignInterpretation // 1 normally, -1 if elements are negated
00207     };
00208 
00209     static const Scalar* getData(const T& t) { return t.getData(); }
00210     static       Scalar* updData(T& t)       { return t.updData(); }
00211 
00212     static const TReal& real(const T& t) { return t.real(); }
00213     static       TReal& real(T& t)       { return t.real(); }
00214     static const TImag& imag(const T& t) { return t.imag(); }
00215     static       TImag& imag(T& t)       { return t.imag(); }
00216 
00217     // We expect to be able to negate and transpose (hermitian or
00218     // positional) with just type casting; no need for help from class
00219     // K except to tell us the appropriate types.
00220     static const TNeg& negate(const T& t)
00221       { return reinterpret_cast<const TNeg&>(t); }
00222     static       TNeg& negate(T& t)
00223       { return reinterpret_cast<TNeg&>(t); }
00224 
00225     static const THerm& transpose(const K& t)
00226       { return reinterpret_cast<const THerm&>(t); }
00227     static       THerm& transpose(K& t)
00228       { return reinterpret_cast<THerm&>(t); }
00229 
00230     static const TPosTrans& positionalTranspose(const K& t)
00231       { return reinterpret_cast<const TPosTrans&>(t); }
00232     static       TPosTrans& positionalTranspose(K& t)
00233       { return reinterpret_cast<TPosTrans&>(t); }
00234 
00235     // If the underlying scalars of this CNT are negator<N> for some numeric type N,
00236     // this method removes the negator<>, effectively negating the entire CNT. You
00237     // can still deal with the sign correctly by using the above enum SignInterpretation
00238     // which will be -1 in that case, 1 if there was no negator<> to remove. Note:
00239     // I'm not talking about TWithoutNegator::SignInterpretation -- that one is guaranteed
00240     // to be 1! T::SignInterpretation is the one you want.
00241     static const TWithoutNegator& castAwayNegatorIfAny(const T& t)
00242         {return reinterpret_cast<const TWithoutNegator&>(t);}
00243     static       TWithoutNegator& updCastAwayNegatorIfAny(T& t)
00244         {return reinterpret_cast<TWithoutNegator&>(t);}
00245 
00246     static ScalarNormSq scalarNormSqr(const K& t) {return t.scalarNormSqr();}
00247 
00248     static TSqrt      sqrt(const K& t)          {return t.sqrt();}
00249     static TAbs       abs(const K& t)           {return t.abs();}
00250     static TStandard  standardize(const K& t)   {return t.standardize();}
00251     static TNormalize normalize(const K& t)     {return t.normalize();}
00252     static TInvert    invert(const K& t)        {return t.invert();}
00253 
00254     static K getInfinity() {return K::getInfinity();}
00255     static K getNaN()      {return K::getNaN();}
00256 
00258     static bool isNaN(const K& t) {return t.isNaN();}
00261     static bool isInf(const K& t) {return t.isInf();}
00263     static bool isFinite(const K& t) {return t.isFinite();}
00264 
00272     template <class K2> static bool 
00273     isNumericallyEqual(const K& t1, const K2& t2) 
00274     {   return t1.isNumericallyEqual(t2);}
00275     template <class K2> static bool 
00276     isNumericallyEqual(const K& t1, const K2& t2, double tol)
00277     {   return t1.isNumericallyEqual(t2,tol);}
00278     static double getDefaultTolerance() {return K::getDefaultTolerance();}
00279 
00280 };
00281 
00282 } // namespace SimTK
00283 
00284 #endif // SimTK_SIMMATRIX_COMPOSITE_NUMERICAL_TYPES_H_

Generated by  doxygen 1.6.2