Hi sorry if this isn't the best place to be asking this,
I need to create a vector-like container which is arbitrarily
multi-dimensional, the number of dimensions has to be determined at run
time. Is there a preexisting library to do this (I've tried MultiArray
in Boost but templating seems to require compile time dimension
setting) or will it come down to implementing one myself?
What about something like this?
#include <cassert>
#include <numeric>
#include <functional>
#include <cstddef>
#include <vector>
template < typename T >
struct dyn_array {
typedef std::size_t size_type;
typedef T value_type;
typedef std::vector<size_type> subscript_type;
typedef T & reference;
typedef T const & const_reference;
typedef T * pointer;
typedef T const * const_pointer;
private:
subscript_type the_bounds;
pointer the_data;
template < typename Iter >
static
size_type product ( Iter from, Iter to ) {
return ( std::accumulate( from, to, 1,
std::multiplies<size_type>() ) );
}
size_type index ( subscript_type const & subscript ) {
assert( this->dimensions() == subscript.size() );
size_type result = 0;
for ( size_type i = 0; i < this->dimensions(); ++i ) {
assert( subscript
< the_bounds );
result *= the_bounds;
result += subscript;
}
assert( result < this->size() );
return ( result );
}
public:
dyn_array ( subscript_type const & bounds )
: the_bounds ( bounds )
, the_data ( new T [ product( bounds.begin(), bounds.end() ) ] )
{}
~dyn_array ( void ) {
delete [] the_data;
}
reference
operator[] ( subscript_type const & subscript ) {
return ( the_data[ index( subscript ) ] );
}
const_reference
operator[] ( subscript_type const & subscript ) const {
return ( the_data[ index( subscript ) ] );
}
size_type dimensions ( void ) const {
return ( the_bounds.size() );
}
size_type size ( void ) const {
return ( product( the_bounds.begin(), the_bounds.end() ) );
}
};
#include <iostream>
#include <kubux/sequenceio>
int main ( void ) {
dyn_array<int>::subscript_type bounds;
bounds.push_back( 5 );
bounds.push_back( 12 );
dyn_array<int> M ( bounds );
dyn_array<int>::subscript_type subscript ( 2, 0 );
for ( subscript[0] = 0; subscript[0] < bounds[0]; ++ subscript[0] ) {
for ( subscript[1] = 0; subscript[1] < bounds[1]; ++ subscript[1] ) {
M[ subscript ] = 0;
}
}
}
Now, if you need to do linear algebra on those beasts, I would have a look
into the available linear algebra an numerics libraries, like Blitz++ or
MTL. They should provide some way of viewing an array as a tensor of sorts.
Best
Kai-Uwe Bux