Simbody

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 
00114 #include "SimTKcommon/internal/common.h"
00115     
00116 namespace SimTK {
00117 
00118 // These are CNT "depths". 0 means the corresponding CNT is a scalar,
00119 // 1 means it is a composite with scalar elements, 2 means a composite
00120 // with composite elements, and 3 means a composite with depth-2
00121 // composite elements. Beyond that the user will have to diambiguate
00122 // operations by using named routines rather than operators.
00123 enum  {
00124     SCALAR_DEPTH              = 0,
00125     SCALAR_COMPOSITE_DEPTH    = 1,
00126     COMPOSITE_COMPOSITE_DEPTH = 2,
00127     COMPOSITE_3_DEPTH         = 3,
00128     MAX_RESOLVED_DEPTH        = COMPOSITE_3_DEPTH
00129 };
00130 
00144 template <class K> class CNT : private K {
00145 public:
00146     typedef K                        T;
00147     typedef typename K::TNeg         TNeg;
00148     typedef typename K::TWithoutNegator TWithoutNegator;
00149     typedef typename K::TReal        TReal;
00150     typedef typename K::TImag        TImag;
00151     typedef typename K::TComplex     TComplex;
00152     typedef typename K::THerm        THerm;
00153     typedef typename K::TPosTrans    TPosTrans;
00154     typedef typename K::TSqHermT     TSqHermT;
00155     typedef typename K::TSqTHerm     TSqTHerm;
00156     typedef typename K::TElement     TElement;
00157     typedef typename K::TRow         TRow;          // type of a row or column
00158     typedef typename K::TCol         TCol;
00159 
00160     // These are the results of calculations and should be packed regardless
00161     // of the spacing of this CNT.
00162     typedef typename K::TSqrt        TSqrt;         // also turns unit^2 to unit
00163     typedef typename K::TAbs         TAbs;
00164     typedef typename K::TStandard    TStandard;     // packed, StdNumbers
00165     typedef typename K::TInvert      TInvert;       // also turns units into 1/units
00166     typedef typename K::TNormalize   TNormalize;    // TODO: what effect on units?
00167 
00168     typedef typename K::Scalar       Scalar;        // quantity< units, <unitlessScalar> >
00169     typedef typename K::ULessScalar  ULessScalar;   // <number> or negator<number>
00170     typedef typename K::Number       Number;        // <real>, <complex> or <conjugate>
00171     typedef typename K::StdNumber    StdNumber;     // <real>, <complex>
00172     typedef typename K::Precision    Precision;     // float, double, long double
00173 
00174     typedef typename K::ScalarNormSq ScalarNormSq;  // type of conjugate square of underlying scalar or
00175                                                     //   numeric value (squares the units too)
00176 
00177     template <class P> struct Result {
00178         typedef typename K::template Result<P>::Mul Mul;
00179         typedef typename K::template Result<P>::Dvd Dvd;
00180         typedef typename K::template Result<P>::Add Add;
00181         typedef typename K::template Result<P>::Sub Sub;
00182     };
00183 
00184     // Shape-preserving element substitution
00185     template <class P> struct Substitute {
00186         typedef typename K::template Substitute<P>::Type Type;
00187     };
00188 
00189     enum {
00190         NRows               = K::NRows,
00191         NCols               = K::NCols,
00192         RowSpacing          = K::RowSpacing,
00193         ColSpacing          = K::ColSpacing,
00194         NPackedElements     = K::NPackedElements,
00195         NActualElements     = K::NActualElements,
00196         NActualScalars      = K::NActualScalars,
00197         ImagOffset          = K::ImagOffset,
00198         RealStrideFactor    = K::RealStrideFactor,
00199         ArgDepth            = K::ArgDepth,
00200         IsScalar            = K::IsScalar,          // scalar with units, real, complex, conjugate, negator
00201         IsULessScalar       = K::IsULessScalar,     // real, complex, conjugate, negator
00202         IsNumber            = K::IsNumber,          // real, complex, conjugate
00203         IsStdNumber         = K::IsStdNumber,       // real, complex
00204         IsPrecision         = K::IsPrecision,       // real (float, double, long double)
00205         SignInterpretation  = K::SignInterpretation // 1 normally, -1 if elements are negated
00206     };
00207 
00208     static const Scalar* getData(const T& t) { return t.getData(); }
00209     static       Scalar* updData(T& t)       { return t.updData(); }
00210 
00211     static const TReal& real(const T& t) { return t.real(); }
00212     static       TReal& real(T& t)       { return t.real(); }
00213     static const TImag& imag(const T& t) { return t.imag(); }
00214     static       TImag& imag(T& t)       { return t.imag(); }
00215 
00216     // We expect to be able to negate and transpose (hermitian or
00217     // positional) with just type casting; no need for help from class
00218     // K except to tell us the appropriate types.
00219     static const TNeg& negate(const T& t)
00220       { return reinterpret_cast<const TNeg&>(t); }
00221     static       TNeg& negate(T& t)
00222       { return reinterpret_cast<TNeg&>(t); }
00223 
00224     static const THerm& transpose(const K& t)
00225       { return reinterpret_cast<const THerm&>(t); }
00226     static       THerm& transpose(K& t)
00227       { return reinterpret_cast<THerm&>(t); }
00228 
00229     static const TPosTrans& positionalTranspose(const K& t)
00230       { return reinterpret_cast<const TPosTrans&>(t); }
00231     static       TPosTrans& positionalTranspose(K& t)
00232       { return reinterpret_cast<TPosTrans&>(t); }
00233 
00234     // If the underlying scalars of this CNT are negator<N> for some numeric type N,
00235     // this method removes the negator<>, effectively negating the entire CNT. You
00236     // can still deal with the sign correctly by using the above enum SignInterpretation
00237     // which will be -1 in that case, 1 if there was no negator<> to remove. Note:
00238     // I'm not talking about TWithoutNegator::SignInterpretation -- that one is guaranteed
00239     // to be 1! T::SignInterpretation is the one you want.
00240     static const TWithoutNegator& castAwayNegatorIfAny(const T& t)
00241         {return reinterpret_cast<const TWithoutNegator&>(t);}
00242     static       TWithoutNegator& updCastAwayNegatorIfAny(T& t)
00243         {return reinterpret_cast<TWithoutNegator&>(t);}
00244 
00245     static ScalarNormSq scalarNormSqr(const K& t) {return t.scalarNormSqr();}
00246 
00247     static TSqrt      sqrt(const K& t)          {return t.sqrt();}
00248     static TAbs       abs(const K& t)           {return t.abs();}
00249     static TStandard  standardize(const K& t)   {return t.standardize();}
00250     static TNormalize normalize(const K& t)     {return t.normalize();}
00251     static TInvert    invert(const K& t)        {return t.invert();}
00252 
00253     static K getInfinity() {return K::getInfinity();}
00254     static K getNaN()      {return K::getNaN();}
00255 
00257     static bool isNaN(const K& t) {return t.isNaN();}
00260     static bool isInf(const K& t) {return t.isInf();}
00262     static bool isFinite(const K& t) {return t.isFinite();}
00263 
00271     template <class K2> static bool 
00272     isNumericallyEqual(const K& t1, const K2& t2) 
00273     {   return t1.isNumericallyEqual(t2);}
00274     template <class K2> static bool 
00275     isNumericallyEqual(const K& t1, const K2& t2, double tol)
00276     {   return t1.isNumericallyEqual(t2,tol);}
00277     static double getDefaultTolerance() {return K::getDefaultTolerance();}
00278 
00279 };
00280 
00281 } // namespace SimTK
00282 
00283 #endif // SimTK_SIMMATRIX_COMPOSITE_NUMERICAL_TYPES_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines