|
cisst-saw
|
Container class for the recursive engines. More...
#include <vctFixedSizeVectorRecursiveEngines.h>
Public Types | |
| typedef vctFixedSizeVectorRecursiveEngines< _size-1 >::template VoViVi< _elementOperationType > | RecursiveStep |
Static Public Member Functions | |
| template<class _outputVectorType, class _inputVector1Type, class _inputVector2Type> | |
| static void | Unfold (_outputVectorType &output, const _inputVector1Type &input1, const _inputVector2Type &input2) |
Container class for the recursive engines.
Recursive engines can be used for fixed size vectors (see vctFixedSizeVector) to apply similar operations (see vctBinaryOperations, vctUnaryOperations, vctStoreBackBinaryOperations, vctStoreBackUnaryOperations). Each engine corresponds to an operation signature.
Recursive engines are named according to the type of the parameters and their role (i.e. input/output). The order reflects the mathematical expression. For exemple, VoViVi stands for one output vector with two input vectors used in \(v_o = v_i op v_i\) and VioSi stands for one input/output vector and one scalar input used in \(v_{io} = v_{io} op s_i\).
The implementation is based on recursive templates which means that the recursion is not translated into recursive calls in an executable but the compilers "unfold" the code during the compilation. The templated format used here was somewhat imposed by the different compilers supported in cisst. Mainly, Visual C++ 6 doesn't support partial specialization. Therefore, the size parameter has to be sub-templated. It seems that the ANSI C++ forbids the specialization of a sub-templated class (inner template) if the outer template is not specialized. Therefore, the size parameter must be used to template the outer class, i.e. vctFixedSizeVectorRecursiveEngines. The inner class are templated by the operation type and allows to plug any operation with a given signature.
The operation is implemented inline using ``template metaprogramming'' in a recursive form. The order of evaluation is from index 0 to index n-1. The operation has to be declared as a static function, which means it cannot use a third object to contain additional data, and it has to be defined in compilation time.
All vector types must support operator[](unsigned int) to access their elements. The input vector types must have it as const method. The output vector type must have it as non-const method.
| size | the size of the vector (determined at compilation time). |
public:
/*! Implement operation of the form \(v_o = op(v_{i1}, v_{i2})\) for fixed size vectors
This class uses template specialization to perform binary vector operations of the form
\[ v_o = \mathrm{op}(v_{i1}, v_{i2}) \]
where \(v_o\) is the output vector, and \(v_{i1}, v_{i2}\) are input vectors, all of an equal fixed size, determined at compilation time, op stands for the a binary operation performed elementwise between \(v_{i1}\) and \(v_{i2}\), and whose result is stored elementwise into \(v_o\).
The operation type operationType must have a static method with the signature
static operationType Operate(const I1E & arg1, const I2E & arg2)
where OE, I1E, I2E are the types of vector elements in \(v_o, v_{i1} v_{i2}\) respectively. These types do not need to be defined explicitly for vctFixedSizeVectorRecursiveEngines class, as they are inferred from the signature of the corresponding operator[] for each of the vector types. However, they may need to be defined for the class operationType.
For examples of binary operations, see vctBinaryOperations.h.
Usage example for vctFixedSizeVectorRecursiveEngines::VoViVi:
enum {SIZE = 3};
int input1[SIZE];
float input2[SIZE];
double output[SIZE];
vctFixedSizeVectorRecursiveEngines<SIZE>::VoViVi<vctBinaryOperations<int,float,double>::Addition, SIZE>::Unfold(output, input1, input2);
stores the sum of elements from input1 and input2 into output.
| _elementOperationType | The type of the binary operation. |
| typedef vctFixedSizeVectorRecursiveEngines<_size-1>::template VoViVi<_elementOperationType> VoViVi< _elementOperationType >::RecursiveStep |
|
inlinestatic |
Unfold the recursion. Performs the operation _elementOperationType elementwise on the last elements of the input/output vector(s) and call Unfold for the _size - 1 elements left (i.e. unfold the recursive calls).
| output | The output vector. |
| input1 | The first input vector. |
| input2 | The second input vector. |