如何从 2d Boost.MultiArray 中取出子数组?
How to take subarray from 2d Boost.MultiArray?
我正在开发一个需要使用 2d Boost.MultiArray 的程序。我设法初始化它并用数据填充它。但是我不明白如果多数组的大小为 m
、n
,如何获取大小为 i
、j
的子数组。其中 i<=m
和 j<=n
。谁能帮帮我?
代码:
matrix_type matrix(boost::extents[width][height]);
read_matrix_from_file(file_content, matrix);
for (int rank = 1; rank < workers; rank++) {
auto subarray_size = (rest > 0) ? lines_per_worker + 1 : lines_per_worker;
rest--;
typedef boost::multi_array_types::index_range range;
size_t finish_line = subarray_size + bias - 1;
finish_line = (finish_line==bias)? finish_line+1:finish_line;
matrix_type::array_view<2>::type
current_process_batch = matrix[boost::indices[range(bias, subarray_size + bias - 1)][range(0, width)]];
}
文档https://www.boost.org/doc/libs/1_73_0/libs/multi_array/doc/user.html#sec_generators
Boost.MultiArray provides the facilities for creating a sub-view of an
already existing array component. It allows you to create a sub-view
that retains the same number of dimensions as the original array or
one that has less dimensions than the original as well.
Sub-view
creation occurs by placing a call to operator[], passing it an
index_gen type. The index_gen is populated by passing index_range
objects to its operator[]. The index_range and index_gen types are
defined in the multi_array_types namespace and as nested members of
every array type. Similar to boost::extents, the library by default
constructs the object boost::indices. You can suppress this object by
defining BOOST_MULTI_ARRAY_NO_GENERATORS before including the library
header. A simple sub-view creation example follows.
样本:
#include <boost/multi_array.hpp>
#include <iostream>
template <typename Ma>
auto dump(Ma const& r) -> std::enable_if_t<1 == Ma::dimensionality> {
for (auto c: r)
std::cout << " " << c;
std::cout << "\n";
}
template <typename Ma>
auto dump(Ma const& ma) -> std::enable_if_t<2 == Ma::dimensionality> {
for (auto const& r: ma)
dump(r);
}
int main() {using range = boost::multi_array_types::index_range;
using boost::extents;
using boost::indices;
auto mn = extents[7][4];
boost::multi_array<int, 2> ma(mn);
// fill with numbers from 10..37
std::iota(ma.data(), ma.data() + ma.num_elements(), 10);
dump(ma);
std::cout << "Slice [3..5][1..3]\n";
dump(ma[ indices[range(3,5)][range(1,3)] ]);
std::cout << "Slice [2..4][2..3]\n";
dump(ma[ indices[range(2,4)][range(2,3)] ]);
std::cout << "Slice [1,3,5][2..3]\n";
dump(ma[ indices[range(1,7,2)][range(2,3)] ]);
std::cout << "Degenerate views (reduced dimensionality):\n";
std::cout << "Slice [1,3,5][2]\n";
dump(ma[ indices[range(1,7,2)][2] ]);
std::cout << "Slice [0][1,3]\n";
dump(ma[ indices[0][range(1,4,2)] ]);
}
版画
10 11 12 13
14 15 16 17
18 19 20 21
22 23 24 25
26 27 28 29
30 31 32 33
34 35 36 37
Slice [3..5][1..3]
23 24
27 28
Slice [2..4][2..3]
20
24
Slice [1,3,5][2..3]
16
24
32
Degenerate views (reduced dimensionality):
Slice [1,3,5][2]
16 24 32
Slice [0][1,3]
11 13
更新
回复。评论:
如果你想避免退化维度,方法如下:
靠 Coliru 生活
std::cout << "Degenerate views (reduced dimensionality):\n";
std::cout << "Slice [1,3,5][2]\n";
dump(ma[ indices[range(1,7,2)][2] ]);
std::cout << "Slice [0][1,3]\n";
dump(ma[ indices[0][range(1,4,2)] ]);
// RE: Comment
std::cout << "NON-Degenerate views (reduced dimensionality):\n";
std::cout << "Slice [1,3,5][2]\n";
dump(ma[ indices[range(1,7,2)][range(2,3)] ]);
std::cout << "Slice [0][1,3]\n";
dump(ma[ indices[range(0,1)][range(1,4,2)] ]);
版画
Degenerate views (reduced dimensionality):
Slice [1,3,5][2]
16 24 32
Slice [0][1,3]
11 13
NON-Degenerate views (reduced dimensionality):
Slice [1,3,5][2]
16
24
32
Slice [0][1,3]
11 13
基本上,不要使用文字 [i][j]
但 [range(i,i+1)][range(j,j+1)]
我正在开发一个需要使用 2d Boost.MultiArray 的程序。我设法初始化它并用数据填充它。但是我不明白如果多数组的大小为 m
、n
,如何获取大小为 i
、j
的子数组。其中 i<=m
和 j<=n
。谁能帮帮我?
代码:
matrix_type matrix(boost::extents[width][height]);
read_matrix_from_file(file_content, matrix);
for (int rank = 1; rank < workers; rank++) {
auto subarray_size = (rest > 0) ? lines_per_worker + 1 : lines_per_worker;
rest--;
typedef boost::multi_array_types::index_range range;
size_t finish_line = subarray_size + bias - 1;
finish_line = (finish_line==bias)? finish_line+1:finish_line;
matrix_type::array_view<2>::type
current_process_batch = matrix[boost::indices[range(bias, subarray_size + bias - 1)][range(0, width)]];
}
文档https://www.boost.org/doc/libs/1_73_0/libs/multi_array/doc/user.html#sec_generators
Boost.MultiArray provides the facilities for creating a sub-view of an already existing array component. It allows you to create a sub-view that retains the same number of dimensions as the original array or one that has less dimensions than the original as well.
Sub-view creation occurs by placing a call to operator[], passing it an index_gen type. The index_gen is populated by passing index_range objects to its operator[]. The index_range and index_gen types are defined in the multi_array_types namespace and as nested members of every array type. Similar to boost::extents, the library by default constructs the object boost::indices. You can suppress this object by defining BOOST_MULTI_ARRAY_NO_GENERATORS before including the library header. A simple sub-view creation example follows.
样本:
#include <boost/multi_array.hpp>
#include <iostream>
template <typename Ma>
auto dump(Ma const& r) -> std::enable_if_t<1 == Ma::dimensionality> {
for (auto c: r)
std::cout << " " << c;
std::cout << "\n";
}
template <typename Ma>
auto dump(Ma const& ma) -> std::enable_if_t<2 == Ma::dimensionality> {
for (auto const& r: ma)
dump(r);
}
int main() {using range = boost::multi_array_types::index_range;
using boost::extents;
using boost::indices;
auto mn = extents[7][4];
boost::multi_array<int, 2> ma(mn);
// fill with numbers from 10..37
std::iota(ma.data(), ma.data() + ma.num_elements(), 10);
dump(ma);
std::cout << "Slice [3..5][1..3]\n";
dump(ma[ indices[range(3,5)][range(1,3)] ]);
std::cout << "Slice [2..4][2..3]\n";
dump(ma[ indices[range(2,4)][range(2,3)] ]);
std::cout << "Slice [1,3,5][2..3]\n";
dump(ma[ indices[range(1,7,2)][range(2,3)] ]);
std::cout << "Degenerate views (reduced dimensionality):\n";
std::cout << "Slice [1,3,5][2]\n";
dump(ma[ indices[range(1,7,2)][2] ]);
std::cout << "Slice [0][1,3]\n";
dump(ma[ indices[0][range(1,4,2)] ]);
}
版画
10 11 12 13
14 15 16 17
18 19 20 21
22 23 24 25
26 27 28 29
30 31 32 33
34 35 36 37
Slice [3..5][1..3]
23 24
27 28
Slice [2..4][2..3]
20
24
Slice [1,3,5][2..3]
16
24
32
Degenerate views (reduced dimensionality):
Slice [1,3,5][2]
16 24 32
Slice [0][1,3]
11 13
更新
回复。评论:
如果你想避免退化维度,方法如下:
靠 Coliru 生活
std::cout << "Degenerate views (reduced dimensionality):\n";
std::cout << "Slice [1,3,5][2]\n";
dump(ma[ indices[range(1,7,2)][2] ]);
std::cout << "Slice [0][1,3]\n";
dump(ma[ indices[0][range(1,4,2)] ]);
// RE: Comment
std::cout << "NON-Degenerate views (reduced dimensionality):\n";
std::cout << "Slice [1,3,5][2]\n";
dump(ma[ indices[range(1,7,2)][range(2,3)] ]);
std::cout << "Slice [0][1,3]\n";
dump(ma[ indices[range(0,1)][range(1,4,2)] ]);
版画
Degenerate views (reduced dimensionality):
Slice [1,3,5][2]
16 24 32
Slice [0][1,3]
11 13
NON-Degenerate views (reduced dimensionality):
Slice [1,3,5][2]
16
24
32
Slice [0][1,3]
11 13
基本上,不要使用文字 [i][j]
但 [range(i,i+1)][range(j,j+1)]