Simbody
|
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_