We can decorate all the composite types with whatever information we need, but we cannot add to the built-in types in the same way. So we define a templatized class CNT<T>, where the template parameter can be any composite numerical type whether built in or composite. Then CNT members are used to access information about class T. When T is a built-in, that information comes from specializations of CNT<T> for CNT<float>, CNT<std::complex<double>>, etc. When T is composite, CNT<T> acts as a pass-through to allow the composite type to provide its own information.
Here is the information that must be provided by a SimTK Composite Numerical Type T (or faked up for built-ins). Some of these are given friendly names and documented since they are useful in user code.
Type Meaning ------------- ------------------------------------------------
REFERENCE TYPES
RefType type of self RowRefType type of a row of this CNT ColumnRefType type of a column of this CNT ElementRefType type of elements ScalarRefType type of stored data
TransposeRefType type returned by (Hermitian) transpose() or the operator~; this is a *cast*, not a copy so will have weird spacing if Type does. PositionalTransposeRefType type returned by positionalTranspose(). This is a *cast*, not a copy, so will have weird spacing if Type does. NegateRefType a type *cast*, which negates the interpretation of the CNT's data RealPartRefType the type *cast* which is used by real() to extract the real part of this CNT if it is complex (or conjugate). ImagPartRefType the type *cast* which is used by imag() to extract the imaginary part of this CNT if it is complex (or conjugate). Note that this is not necessarily the same type as RealPartType; they can differ by a negator<>.
RESULTS (PACKED) TYPES -- these are always packed & use std numbers
PackedType least weird type that can hold a copy of this CNT object. The shape, CNT type, and numerical values will be unchanged, but elements will be packed together in columns and will use standard numbers (real & complex). ElementRefType::PackedType (ElementType) is used recursively for the elements. RowPackedType same as above but packing by rows instead of columns
RowType RowRefType::PackedType ColumnType ColumnRefType::PackedType ElementType ElementRefType::PackedType ScalarType ScalarRefType::PackedType TransposeType TransposeRefType::PackedType PositionalTransposeType PositionalTransposeRefType::PackedType
RealType same shape as CNT, but elements are real same as RealPartRefType::PackedType and ImagPartRefType::PackedType ComplexType same shape as CNT, but elements are complex
InverseType result of an invert() applied to this CNT. Looks like a cleaned up version of TransposeType. SquareType type returned by square()=~T*T; symmetric, scalar if T=Vec RowSquareType type returned by rowSquare()=T*~T; symmetric, scalar if T=Row ScalarNormType the type of ~s*s where s is the ScalarType of this CNT. This is always a standard real number. This is the result type of scalar norms, and abs(s). AbsType type returned by elementwise abs() when applied to this CNT. It has the same shape but each element is replaced by abs() of that element. The result is always real.
TNeg same shape as T, but elements are negated TReal same shape as T, but with real elements TImag same shape as T, with real elements from the imaginary part TComplex same shape as T, but with Complex or conjugate elements THerm transpose of T, with Hermitian transposed elements TPosTrans positional transpose of T, that is, elements not transposed TSqHermT type of ~T*T (default vector and matrix square; symmetric) TSqTHerm type of T*~T (row square; symmetric)
Scalar the underlying <scalar> type (see below) ScalarSq type of square of underlying scalar (always real)
Substitute<E>::Type a CNT of the same shape and container type as this one, but with elements of type E instead of ElementType. Special case: if this CNT is a scalar then Substitute<E>::Type just returns E. Result<RHS>::Mul Dvd Add Sub the type of the result of T op RHS, where RHS is *any* CNT
ENUMS (all sizes are in units of T's elements)
NRows logical number of rows in type T (i.e., # elements in a column) NCols logical number of columns in type T RowSpacing # elements from one row to the next (default 1) ColSpacing # elements from one col to the next (default NRows for Mat) NPackedElements minimum elements it would take to store this data NActualElements elements covered by T due to element spacing NActualScalars NActualElements * CNT<ElementType>::NActualScalars. This should be the physical spacing between array elements in an array containing this kind of CNT. Our big Matrix/Vector types guarantee this packing.
* * The Scalar Types * ---------------- * Here is a complete taxonomy of the scalar types we support. * * <scalar> ::= <number> | negator< <number> > * <number> ::= <standard> | <conjugate> * <standard> ::= <real> | <complex> * * <real> ::= float | double | long double * <complex> ::= std::complex< <real> > * <conjugate> ::= SimTK::conjugate< <real> > * *
With this in hand, we can build a clean facility in which scalars, vectors, matrices, vectors of vectors, matrices of vectors of matrices, etc. can all be treated uniformly.
#include "SimTKcommon/internal/common.h"
Go to the source code of this file.
Namespaces | |
namespace | SimTK |
Classes | |
class | CNT |
Specialized information about Composite Numerical Types which allows us to define appropriate templatized classes using them. More... | |
struct | CNT::Result |
struct | CNT::Substitute |
Enumerations | |
enum | { SCALAR_DEPTH = 0, SCALAR_COMPOSITE_DEPTH = 1, COMPOSITE_COMPOSITE_DEPTH = 2, COMPOSITE_3_DEPTH = 3, MAX_RESOLVED_DEPTH = COMPOSITE_3_DEPTH } |