Template-Based Helper Classes: An application to Multidimensional Arrays
An Implementation of Multidimensional Arrays via Template-Based Helper Classes
Introduction
Multidimensional arrays provide a simple reshaping matrix structures. It could be created and initialized as a vector, and read as 3D matrix. However, subscripting is not that easy. Subscripting operators should reduce dimension of entire multi-array. The problem becomes harder when adding region-of-interest scripting facility. Region-of-interest scripting facility allows selecting separate rows, columns, and plates in different orders. More complexities may be added to support reference indexing. A typical solution is helper classes. Boost library has implemented a helper class to multi_array We need more encapsulation of helper classes with original interfacing class. This could be accomplished by adding more template arguments. Classes with different template arguments lead to separate classes. However, it makes the whole class more cohesive and prevent user from using helper classes in a wrong way. In my master thesis I needed a flexible multidimensional array with the following specs. 1. array-like subscripting operators[]. This piece of code declaresa a new initialized 3D multi-dimensional array. Where and Actually Other implemetations for multi-arrays makes use of helper classes named Region of interest (roi) lets you to select first and third rows for all columns. Consider the following: Now consider selecting all rows and cols numbered [0, 4, 2, 3] where and This means subscripting operator should return tensor Other implemetations make use of friend helper classes, and usually named as Reference containers capture addresses of selected entries and allow you to modify them. This was usually implemented with helper classes named Consider the following class header: and this returns a lowerdimensioned referenced tensor: Now consider the region-of-interest subscripting operator. It should return a matrix of chosen rows, and next subscripting operator should iterate on the next dimension. and this is a referenced copy too. Thanks a lot for your time. I just want to clarify that this is a testing version; I hope you enjoy this. Problem Statement and Basic Idea
2. matlab-like region of interests subscripting facility.
3. reference-like array to allow editing a set of selected entries.1. Array-like subscripting operators[]
tensor<double, 3, 1, false> itns3(dblbegin
5, 7, 3, 1, 2,
4, 7, 2, 1, 2,
1, 8, 9, 3, 6,
1, 3, 5, 7, 8,
1, 7, 3, 8, 2,
1, 7, 3, 8, 2,
1, 7, 3, 8, 2,
1, 7, 3, 8, 2,
5, 7, 3, 1, 2,
4, 7, 2, 1, 2,
1, 8, 9, 3, 6,
1, 3, 5, 7, 8
clend, sizebegin 3, 4, 5 clend);
dblbegin
, sizebegin
, and clend
are defined as follows: #define dblbegin clbegin(double)
#define sizebegin clbegin(_sizetype)
#define clend )
clbegin
macro is defined as: #define clbegin(T) (commalist<T>(),
cl
-prefix stands for comma-list. commalist<T>
template class was developed to allow comma-concatenation. I guess comma-concatenation is simpler on gnu-C++.
Now the container itns3 has three dimensions [3, 4, 5] which is 3-plates, 4-rows each, and 5-cols for each row. Now consider using subscripting operator getting first plate, how many dimensions shall this array hold? Yup, tensortensor<T, N-1, D, true> operator[](const _sizetype& i);
const tensor<T, N-1, D, false> operator[](const _sizetype& i) const;
subset
, rows
, cols
, rowset
, colset
, ...
Now moving to second facility;2. Matlab-like region-of-interests subscripting facility
tensor<double, 2> itns2(dblbegin
5, 7, 3, 1, 2,
4, 7, 2, 1, 2,
1, 8, 9, 3, 6,
1, 3, 5, 7, 8
clend, sizebegin 4, 5 clend);
itns2[all][select(0, 4, 2, 3, -1)]=3.0;
select
, and all
are defined as follows:#define all ixrange()
#define select rangelist<_indextype>
ixrange()
is defined as follows:typedef range<_indextype> ixrange;
This means that we need a new helper class presenting the new dimension we iterate on. In simple words, we first select two rows, and the new subscripting shall select three cols. That is why we need the D
template parameter! And roi-subscripting operator should be declared as follows:const tensor<T, N, D+1, false> operator[](const tensor<_indextype, 1> idx) const;
tensor<T, N, D+1, true> operator[](const tensor<_indextype, 1> idx);
rowset
and colset
.
Lets move to next requirement: 3. Reference-like array to allow editing a set of selected entries
reference_container
, array<smart_ptr<T> >
, or ref_array
.
A tensor has one of two states if const subscripting operators should return a copy of entries, if not, a reference to entries should be returned. One more boolean template argument is added describing the entire tensor as a reference or not.Class and Operator Headers
// tensor<typename, # dims, dim to iterate on, being ref or not>
template<class T, _sizetype N=1, _sizetype D=1, _booltype REF=false>
class tensor : public io
then consider the subscripting operator. It should return a lower dimensioned non-reference tensorconst tensor<T, N-1, 1, false> operator[](const _sizetype& i) const
tensor<T, N-1, 1, true> operator[](const _sizetype& i)
const tensor<T, N, D+1> operator[](const tensor<_indextype, 1> idx) const
tensor<T, N, D+1, true> operator[](const tensor<_indextype, 1> idx)
Thank You