维度无关的过度的boost :: multi_array的循环? [英] Dimension-independent loop over boost::multi_array?

查看:152
本文介绍了维度无关的过度的boost :: multi_array的循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个N维的boost :: multi_array中(的类型为int为简单起见),其中 N 在编译时已知的,但可以改变(即是非类型模板参数)。让我们假设所有的尺寸相等的大小 M

Say I've got an N-dimensional boost::multi_array (of type int for simplicity), where N is known at compile time but can vary (i.e. is a non-type template parameter). Let's assume that all dimensions have equal size m.

typedef boost::multi_array<int, N> tDataArray;
boost::array<tDataArray::index, N> shape;
shape.fill(m);
tDataArray A(shape);

现在我想遍历所有条目在 A ,例如将它们打印出来。如果N为2为例,我想我会写这样的事情

Now I would like to loop over all entries in A, e.g. to print them. If N was 2 for example I think I would write something like this

  boost::array<tDataArray::index, 2> index;
  for ( int i = 0; i < m; i++ )
  {
    for ( int j = 0; j < m; j++ )
    {
      index = {{ i, j }};
      cout << A ( index ) << endl;
    }
  }

我使用一个索引对象来访问元素,我觉得这是比[] - 运算符在这里。更灵活

I've used an index object to access the elements as I think this is more flexible than the []-operator here.

但我怎么能写这个不知道维数 N 。是否有任何内置的方式吗? multi_array的文档不是很清楚哪些类型的迭代器的存在,等等。
或者,我将不得不诉诸一些自定义的方法,自定义指针,由指针等计算指数?如果是这样的 - 任何建议,这样的算法能看怎么样

But how could I write this without knowing the number of dimensions N. Is there any built-in way? The documentation of multi_array is not very clear on which types of iterators exist, etc. Or would I have to resort to some custom method with custom pointers, computing indices from the pointers, etc.? If so - any suggestions how such an algorithm could look like?

推荐答案

好吧,立足的谷歌小组讨论在评论之一,对的的例子之一,从库本身的,这里是一个可能的解决方案,让您遍历多阵列中的所有值在一个循环提供了一种方法来检索每个元素的索引(在此情况下,需要对一些其他的东西,如我的情况)。

Ok, based on the Google groups discussion already mentioned in one of the comments and on one of the examples from the library itself, here is a possible solution that lets you iterate over all values in the multi-array in a single loop and offers a way to retrieve the index for each of these elements (in case this is needed for some other stuff, as in my scenario).

#include <iostream>
#include <boost/multi_array.hpp>
#include <boost/array.hpp>

const unsigned short int DIM = 3;
typedef double tValue;
typedef boost::multi_array<tValue,DIM> tArray;
typedef tArray::index tIndex;
typedef boost::array<tIndex, DIM> tIndexArray;

tIndex getIndex(const tArray& m, const tValue* requestedElement, const unsigned short int direction)
{
  int offset = requestedElement - m.origin();
  return(offset / m.strides()[direction] % m.shape()[direction] +  m.index_bases()[direction]); 
}

tIndexArray getIndexArray( const tArray& m, const tValue* requestedElement )
{
  tIndexArray _index;
  for ( unsigned int dir = 0; dir < DIM; dir++ )
  {
    _index[dir] = getIndex( m, requestedElement, dir );
  }

  return _index;
}


int main()
{ 
  double* exampleData = new double[24];
  for ( int i = 0; i < 24; i++ ) { exampleData[i] = i; }

  tArray A( boost::extents[2][3][4] );
  A.assign(exampleData,exampleData+24);

  tValue* p = A.data();
  tIndexArray index;
  for ( int i = 0; i < A.num_elements(); i++ )
  {
    index = getIndexArray( A, p );
    std::cout << index[0] << " " << index[1] << " " << index[2] << " value = " << A(index) << "  check = " << *p << std::endl;
    ++p;
  }

  return 0;
}

输出应

0 0 0 value = 0 check = 0
0 0 1 value = 1 check = 1
0 0 2 value = 2 check = 2
0 0 3 value = 3 check = 3
0 1 0 value = 4 check = 4
0 1 1 value = 5 check = 5
0 1 2 value = 6 check = 6
0 1 3 value = 7 check = 7
0 2 0 value = 8 check = 8
0 2 1 value = 9 check = 9
0 2 2 value = 10 check = 10
0 2 3 value = 11 check = 11
1 0 0 value = 12 check = 12
1 0 1 value = 13 check = 13
1 0 2 value = 14 check = 14
1 0 3 value = 15 check = 15
1 1 0 value = 16 check = 16
1 1 1 value = 17 check = 17
1 1 2 value = 18 check = 18
1 1 3 value = 19 check = 19
1 2 0 value = 20 check = 20
1 2 1 value = 21 check = 21
1 2 2 value = 22 check = 22
1 2 3 value = 23 check = 23

所以内存布局从外侧进入内侧索引。请注意, getIndex 函数依赖于的boost :: multi_array中提供的默认内存布局。万一阵列基或存储顺序被改变,这将必须调整。

so the memory layout goes from the outer to the inner indices. Note that the getIndex function relies on the default memory layout provided by boost::multi_array. In case the array base or the storage ordering are changed, this would have to be adjusted.

这篇关于维度无关的过度的boost :: multi_array的循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆