Simbody  3.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CompositeNumericalTypes.h
Go to the documentation of this file.
1 #ifndef SimTK_SIMMATRIX_COMPOSITE_NUMERICAL_TYPES_H_
2 #define SimTK_SIMMATRIX_COMPOSITE_NUMERICAL_TYPES_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2005-12 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
107 
108 namespace SimTK {
109 
110 // These are CNT "depths". 0 means the corresponding CNT is a scalar,
111 // 1 means it is a composite with scalar elements, 2 means a composite
112 // with composite elements, and 3 means a composite with depth-2
113 // composite elements. Beyond that the user will have to diambiguate
114 // operations by using named routines rather than operators.
115 enum {
121 };
122 
136 template <class K> class CNT : private K {
137 public:
138  typedef K T;
139  typedef typename K::TNeg TNeg;
140  typedef typename K::TWithoutNegator TWithoutNegator;
141  typedef typename K::TReal TReal;
142  typedef typename K::TImag TImag;
143  typedef typename K::TComplex TComplex;
144  typedef typename K::THerm THerm;
145  typedef typename K::TPosTrans TPosTrans;
146  typedef typename K::TSqHermT TSqHermT;
147  typedef typename K::TSqTHerm TSqTHerm;
148  typedef typename K::TElement TElement;
149  typedef typename K::TRow TRow; // type of a row or column
150  typedef typename K::TCol TCol;
151 
152  // These are the results of calculations and should be packed regardless
153  // of the spacing of this CNT.
154  typedef typename K::TSqrt TSqrt; // also turns unit^2 to unit
155  typedef typename K::TAbs TAbs;
156  typedef typename K::TStandard TStandard; // packed, StdNumbers
157  typedef typename K::TInvert TInvert; // also turns units into 1/units
158  typedef typename K::TNormalize TNormalize; // TODO: what effect on units?
159 
160  typedef typename K::Scalar Scalar; // quantity< units, <unitlessScalar> >
161  typedef typename K::ULessScalar ULessScalar; // <number> or negator<number>
162  typedef typename K::Number Number; // <real>, <complex> or <conjugate>
163  typedef typename K::StdNumber StdNumber; // <real>, <complex>
164  typedef typename K::Precision Precision; // float, double, long double
165 
166  typedef typename K::ScalarNormSq ScalarNormSq; // type of conjugate square of underlying scalar or
167  // numeric value (squares the units too)
168 
169  template <class P> struct Result {
170  typedef typename K::template Result<P>::Mul Mul;
171  typedef typename K::template Result<P>::Dvd Dvd;
172  typedef typename K::template Result<P>::Add Add;
173  typedef typename K::template Result<P>::Sub Sub;
174  };
175 
176  // Shape-preserving element substitution
177  template <class P> struct Substitute {
178  typedef typename K::template Substitute<P>::Type Type;
179  };
180 
181  enum {
192  IsScalar = K::IsScalar, // scalar with units, real, complex, conjugate, negator
193  IsULessScalar = K::IsULessScalar, // real, complex, conjugate, negator
194  IsNumber = K::IsNumber, // real, complex, conjugate
195  IsStdNumber = K::IsStdNumber, // real, complex
196  IsPrecision = K::IsPrecision, // real (float, double, long double)
197  SignInterpretation = K::SignInterpretation // 1 normally, -1 if elements are negated
198  };
199 
200  static const Scalar* getData(const T& t) { return t.getData(); }
201  static Scalar* updData(T& t) { return t.updData(); }
202 
203  static const TReal& real(const T& t) { return t.real(); }
204  static TReal& real(T& t) { return t.real(); }
205  static const TImag& imag(const T& t) { return t.imag(); }
206  static TImag& imag(T& t) { return t.imag(); }
207 
208  // We expect to be able to negate and transpose (hermitian or
209  // positional) with just type casting; no need for help from class
210  // K except to tell us the appropriate types.
211  static const TNeg& negate(const T& t)
212  { return reinterpret_cast<const TNeg&>(t); }
213  static TNeg& negate(T& t)
214  { return reinterpret_cast<TNeg&>(t); }
215 
216  static const THerm& transpose(const K& t)
217  { return reinterpret_cast<const THerm&>(t); }
218  static THerm& transpose(K& t)
219  { return reinterpret_cast<THerm&>(t); }
220 
221  static const TPosTrans& positionalTranspose(const K& t)
222  { return reinterpret_cast<const TPosTrans&>(t); }
224  { return reinterpret_cast<TPosTrans&>(t); }
225 
226  // If the underlying scalars of this CNT are negator<N> for some numeric type N,
227  // this method removes the negator<>, effectively negating the entire CNT. You
228  // can still deal with the sign correctly by using the above enum SignInterpretation
229  // which will be -1 in that case, 1 if there was no negator<> to remove. Note:
230  // I'm not talking about TWithoutNegator::SignInterpretation -- that one is guaranteed
231  // to be 1! T::SignInterpretation is the one you want.
232  static const TWithoutNegator& castAwayNegatorIfAny(const T& t)
233  {return reinterpret_cast<const TWithoutNegator&>(t);}
235  {return reinterpret_cast<TWithoutNegator&>(t);}
236 
237  static ScalarNormSq scalarNormSqr(const K& t) {return t.scalarNormSqr();}
238 
239  static TSqrt sqrt(const K& t) {return t.sqrt();}
240  static TAbs abs(const K& t) {return t.abs();}
241  static TStandard standardize(const K& t) {return t.standardize();}
242  static TNormalize normalize(const K& t) {return t.normalize();}
243  static TInvert invert(const K& t) {return t.invert();}
244 
245  static K getInfinity() {return K::getInfinity();}
246  static K getNaN() {return K::getNaN();}
247 
249  static bool isNaN(const K& t) {return t.isNaN();}
252  static bool isInf(const K& t) {return t.isInf();}
254  static bool isFinite(const K& t) {return t.isFinite();}
255 
263  template <class K2> static bool
264  isNumericallyEqual(const K& t1, const K2& t2)
265  { return t1.isNumericallyEqual(t2);}
266  template <class K2> static bool
267  isNumericallyEqual(const K& t1, const K2& t2, double tol)
268  { return t1.isNumericallyEqual(t2,tol);}
269  static double getDefaultTolerance() {return K::getDefaultTolerance();}
270 
271 };
272 
273 } // namespace SimTK
274 
275 #endif // SimTK_SIMMATRIX_COMPOSITE_NUMERICAL_TYPES_H_