Simbody  3.4 (development)
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  *                       Simbody(tm): SimTKcommon                             *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK 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/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2005-12 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00106 #include "SimTKcommon/internal/common.h"
00107     
00108 namespace SimTK {
00109 
00110 // These are CNT "depths". 0 means the corresponding CNT is a scalar,
00111 // 1 means it is a composite with scalar elements, 2 means a composite
00112 // with composite elements, and 3 means a composite with depth-2
00113 // composite elements. Beyond that the user will have to diambiguate
00114 // operations by using named routines rather than operators.
00115 enum  {
00116     SCALAR_DEPTH              = 0,
00117     SCALAR_COMPOSITE_DEPTH    = 1,
00118     COMPOSITE_COMPOSITE_DEPTH = 2,
00119     COMPOSITE_3_DEPTH         = 3,
00120     MAX_RESOLVED_DEPTH        = COMPOSITE_3_DEPTH
00121 };
00122 
00136 template <class K> class CNT : private K {
00137 public:
00138     typedef K                        T;
00139     typedef typename K::TNeg         TNeg;
00140     typedef typename K::TWithoutNegator TWithoutNegator;
00141     typedef typename K::TReal        TReal;
00142     typedef typename K::TImag        TImag;
00143     typedef typename K::TComplex     TComplex;
00144     typedef typename K::THerm        THerm;
00145     typedef typename K::TPosTrans    TPosTrans;
00146     typedef typename K::TSqHermT     TSqHermT;
00147     typedef typename K::TSqTHerm     TSqTHerm;
00148     typedef typename K::TElement     TElement;
00149     typedef typename K::TRow         TRow;          // type of a row or column
00150     typedef typename K::TCol         TCol;
00151 
00152     // These are the results of calculations and should be packed regardless
00153     // of the spacing of this CNT.
00154     typedef typename K::TSqrt        TSqrt;         // also turns unit^2 to unit
00155     typedef typename K::TAbs         TAbs;
00156     typedef typename K::TStandard    TStandard;     // packed, StdNumbers
00157     typedef typename K::TInvert      TInvert;       // also turns units into 1/units
00158     typedef typename K::TNormalize   TNormalize;    // TODO: what effect on units?
00159 
00160     typedef typename K::Scalar       Scalar;        // quantity< units, <unitlessScalar> >
00161     typedef typename K::ULessScalar  ULessScalar;   // <number> or negator<number>
00162     typedef typename K::Number       Number;        // <real>, <complex> or <conjugate>
00163     typedef typename K::StdNumber    StdNumber;     // <real>, <complex>
00164     typedef typename K::Precision    Precision;     // float, double, long double
00165 
00166     typedef typename K::ScalarNormSq ScalarNormSq;  // type of conjugate square of underlying scalar or
00167                                                     //   numeric value (squares the units too)
00168 
00169     template <class P> struct Result {
00170         typedef typename K::template Result<P>::Mul Mul;
00171         typedef typename K::template Result<P>::Dvd Dvd;
00172         typedef typename K::template Result<P>::Add Add;
00173         typedef typename K::template Result<P>::Sub Sub;
00174     };
00175 
00176     // Shape-preserving element substitution
00177     template <class P> struct Substitute {
00178         typedef typename K::template Substitute<P>::Type Type;
00179     };
00180 
00181     enum {
00182         NRows               = K::NRows,
00183         NCols               = K::NCols,
00184         RowSpacing          = K::RowSpacing,
00185         ColSpacing          = K::ColSpacing,
00186         NPackedElements     = K::NPackedElements,
00187         NActualElements     = K::NActualElements,
00188         NActualScalars      = K::NActualScalars,
00189         ImagOffset          = K::ImagOffset,
00190         RealStrideFactor    = K::RealStrideFactor,
00191         ArgDepth            = K::ArgDepth,
00192         IsScalar            = K::IsScalar,          // scalar with units, real, complex, conjugate, negator
00193         IsULessScalar       = K::IsULessScalar,     // real, complex, conjugate, negator
00194         IsNumber            = K::IsNumber,          // real, complex, conjugate
00195         IsStdNumber         = K::IsStdNumber,       // real, complex
00196         IsPrecision         = K::IsPrecision,       // real (float, double, long double)
00197         SignInterpretation  = K::SignInterpretation // 1 normally, -1 if elements are negated
00198     };
00199 
00200     static const Scalar* getData(const T& t) { return t.getData(); }
00201     static       Scalar* updData(T& t)       { return t.updData(); }
00202 
00203     static const TReal& real(const T& t) { return t.real(); }
00204     static       TReal& real(T& t)       { return t.real(); }
00205     static const TImag& imag(const T& t) { return t.imag(); }
00206     static       TImag& imag(T& t)       { return t.imag(); }
00207 
00208     // We expect to be able to negate and transpose (hermitian or
00209     // positional) with just type casting; no need for help from class
00210     // K except to tell us the appropriate types.
00211     static const TNeg& negate(const T& t)
00212       { return reinterpret_cast<const TNeg&>(t); }
00213     static       TNeg& negate(T& t)
00214       { return reinterpret_cast<TNeg&>(t); }
00215 
00216     static const THerm& transpose(const K& t)
00217       { return reinterpret_cast<const THerm&>(t); }
00218     static       THerm& transpose(K& t)
00219       { return reinterpret_cast<THerm&>(t); }
00220 
00221     static const TPosTrans& positionalTranspose(const K& t)
00222       { return reinterpret_cast<const TPosTrans&>(t); }
00223     static       TPosTrans& positionalTranspose(K& t)
00224       { return reinterpret_cast<TPosTrans&>(t); }
00225 
00226     // If the underlying scalars of this CNT are negator<N> for some numeric type N,
00227     // this method removes the negator<>, effectively negating the entire CNT. You
00228     // can still deal with the sign correctly by using the above enum SignInterpretation
00229     // which will be -1 in that case, 1 if there was no negator<> to remove. Note:
00230     // I'm not talking about TWithoutNegator::SignInterpretation -- that one is guaranteed
00231     // to be 1! T::SignInterpretation is the one you want.
00232     static const TWithoutNegator& castAwayNegatorIfAny(const T& t)
00233         {return reinterpret_cast<const TWithoutNegator&>(t);}
00234     static       TWithoutNegator& updCastAwayNegatorIfAny(T& t)
00235         {return reinterpret_cast<TWithoutNegator&>(t);}
00236 
00237     static ScalarNormSq scalarNormSqr(const K& t) {return t.scalarNormSqr();}
00238 
00239     static TSqrt      sqrt(const K& t)          {return t.sqrt();}
00240     static TAbs       abs(const K& t)           {return t.abs();}
00241     static TStandard  standardize(const K& t)   {return t.standardize();}
00242     static TNormalize normalize(const K& t)     {return t.normalize();}
00243     static TInvert    invert(const K& t)        {return t.invert();}
00244 
00245     static K getInfinity() {return K::getInfinity();}
00246     static K getNaN()      {return K::getNaN();}
00247 
00249     static bool isNaN(const K& t) {return t.isNaN();}
00252     static bool isInf(const K& t) {return t.isInf();}
00254     static bool isFinite(const K& t) {return t.isFinite();}
00255 
00263     template <class K2> static bool 
00264     isNumericallyEqual(const K& t1, const K2& t2) 
00265     {   return t1.isNumericallyEqual(t2);}
00266     template <class K2> static bool 
00267     isNumericallyEqual(const K& t1, const K2& t2, double tol)
00268     {   return t1.isNumericallyEqual(t2,tol);}
00269     static double getDefaultTolerance() {return K::getDefaultTolerance();}
00270 
00271 };
00272 
00273 } // namespace SimTK
00274 
00275 #endif // SimTK_SIMMATRIX_COMPOSITE_NUMERICAL_TYPES_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines