Somone's SO question: "Is there an existing library for dynamically-determineddimensional array in c

  • Thread starter Alf P. Steinbach
  • Start date

A

Alf P. Steinbach

This question was closed as off-topic on Stack Overflow.
The OP was anonymous.

http://stackoverflow.com/questions/...dynamically-determined-dimensional-array-in-c
I am looking for a good existing library for dynamically-determined dimensional
array in c++. Blitz++ and other similars provide array with fixed dimensionality,
like the following

int m = 2, n = 3; p = 4;
blitz::Array<double, 3> a(m, n, p); // A 3D array

What I am looking for is

int d = 3;
Array<double> a(d, m, n, p); // An array of 3D

where the array's dimensionality d and size of all the dimensions (here m, n, p)
are all determined dynamically.



I don't know of any such library, and I wouldn't advice using such a
class since it incurs some overhead and opens the door for bugs, but
here is a working sketch of how you can do it yourself:


Code:
#include <assert.h>             // assert
#include <vector>               // std::vector
#include <initializer_list>     // std::initializer_list
#include <stddef.h>             // ptrdiff_t
#include <iterator>             // std::begin, std::end

namespace my{
using std::vector;
using std::initializer_list;

typedef ptrdiff_t Size;
typedef Size Index;

template< class Item >
auto item( Index const i, initializer_list<Item> const& items )
-> Item const
{ return *(items.begin() + i); }

// Needs to be more elaborate for general implementation.
template< class Container >
auto size( Container const& c )
-> Size
{ return end( c ) - begin( c ); }

typedef double Item;
class Array
{
private:
vector<Size>    extents_;
vector<Item>    items_;

auto n_items() const
-> Size
{
Size result = 1;
for( auto const n : extents_ ) { result *= n; }
return result;
}

auto index_for( initializer_list<int> const& indices ) const
-> Index
{
assert( indices.size() == extents_.size() );
Size sub_array_size = 1;
Index result = 0;
for( Index i = 0;  i < size( indices ); ++i )
{
result += item( i, indices )*sub_array_size;
sub_array_size *= extents_[i];
}
return result;
}

public:
auto n_dimensions() const
-> int
{ return extents_.size(); }

auto extent( Index const i ) const
-> Size
{ return extents_[i]; }

template< class... Int >
auto operator()( Int const... indices )
-> double&
{ return items_[ index_for({indices...}) ]; }

template< class... Int >
auto operator()( Int const... indices ) const
-> double const&
{ return items_[ index_for({indices...}) ]; }

template< class... Int >
Array( Int const... extents )
: extents_( { extents... } )
{ items_.resize( n_items() ); }
};
}  // namespace my

#include <iostream>
#include <iomanip>
using namespace std;

auto main() -> int
{
my::Array a( 3, 3, 3 );
cout << a.n_dimensions() << " dimensions" << endl;

a( 1, 2, 1) = 3.14;
a( 2, 2, 1) = 3.15;
for( int z = 0;  z < 3;  ++z )
{
for( int y = 0;  y < 3;  ++y )
{
for( int x = 0;  x < 3;  ++x )
{
cout << setw( 5 ) << a( x, y, z );
}
cout << endl;
}
cout << endl;
}

cout << a( 1, 2, 1) << endl;
}


Cheers & hth.,

- Alf
 
Ad

Advertisements

L

Larry Evans

This question was closed as off-topic on Stack Overflow.
The OP was anonymous.

http://stackoverflow.com/questions/...dynamically-determined-dimensional-array-in-c

I am looking for a good existing library for dynamically-determined
dimensional
array in c++. Blitz++ and other similars provide array with fixed
dimensionality,
like the following

int m = 2, n = 3; p = 4;
blitz::Array<double, 3> a(m, n, p); // A 3D array

What I am looking for is

int d = 3;
Array<double> a(d, m, n, p); // An array of 3D

where the array's dimensionality d and size of all the dimensions
(here m, n, p)
are all determined dynamically.



I don't know of any such library, and I wouldn't advice using such a
class since it incurs some overhead and opens the door for bugs, but
here is a working sketch of how you can do it yourself:


Code:
#include <assert.h>             // assert
#include <vector>               // std::vector
#include <initializer_list>     // std::initializer_list
#include <stddef.h>             // ptrdiff_t
#include <iterator>             // std::begin, std::end

namespace my{
using std::vector;
using std::initializer_list;

typedef ptrdiff_t Size;
typedef Size Index;

template< class Item >
auto item( Index const i, initializer_list<Item> const& items )
-> Item const
{ return *(items.begin() + i); }

// Needs to be more elaborate for general implementation.
template< class Container >
auto size( Container const& c )
-> Size
{ return end( c ) - begin( c ); }

typedef double Item;
class Array
{
private:
vector<Size>    extents_;
vector<Item>    items_;

auto n_items() const
-> Size
{
Size result = 1;
for( auto const n : extents_ ) { result *= n; }
return result;
}

auto index_for( initializer_list<int> const& indices ) const
-> Index
{
assert( indices.size() == extents_.size() );
Size sub_array_size = 1;
Index result = 0;
for( Index i = 0;  i < size( indices ); ++i )
{
result += item( i, indices )*sub_array_size;
sub_array_size *= extents_[i];
}
return result;
}

public:
auto n_dimensions() const
-> int
{ return extents_.size(); }

auto extent( Index const i ) const
-> Size
{ return extents_[i]; }

template< class... Int >
auto operator()( Int const... indices )
-> double&
{ return items_[ index_for({indices...}) ]; }

template< class... Int >
auto operator()( Int const... indices ) const
-> double const&
{ return items_[ index_for({indices...}) ]; }

template< class... Int >
Array( Int const... extents )
: extents_( { extents... } )
{ items_.resize( n_items() ); }
};
}  // namespace my

#include <iostream>
#include <iomanip>
using namespace std;

auto main() -> int
{
my::Array a( 3, 3, 3 );
cout << a.n_dimensions() << " dimensions" << endl;

a( 1, 2, 1) = 3.14;
a( 2, 2, 1) = 3.15;
for( int z = 0;  z < 3;  ++z )
{
for( int y = 0;  y < 3;  ++y )
{
for( int x = 0;  x < 3;  ++x )
{
cout << setw( 5 ) << a( x, y, z );
}
cout << endl;
}
cout << endl;
}

cout << a( 1, 2, 1) << endl;
}


Cheers & hth.,

- Alf

Hi Alf,

The following code:

http://svn.boost.org/svn/boost/sandbox/variadic_templates/sandbox/array_dyn/array_dyn.hpp

has comments that appear to satisfy that need.

-regards,
Larry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top