如何在 boost multi_array 容器中存储值?
How to store values in the boost multi_array container?
我正在努力访问这些值并将它们存储在 boost multi_array 容器中。我尝试使用索引方法([] 和 .at())访问元素,但抛出 error: no matching function for call to 'boost::multi_array<float, 2>::data(int)',但是我可以打印数据(见代码)但不知道如何存储它并再次访问它以进行进一步计算。数据是二维的 (11214, 3),但与此同时我只想将其展平并获得一系列值。所以我的问题是如何访问元素以及如何将它们存储在容器中?
#include <boost/multi_array.hpp>
#include <boost/timer/timer.hpp>
#include <boost/range/irange.hpp>
#include <h5xx/h5xx.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
using array_2d_t = boost::multi_array<float, 2>;
//using array_2d_t = boost::multi_array<float, 3>;
template <typename T>
void print_array(T const& array)
{
for (auto const& row : array)
{ for (auto v : row)
printf("%10f ", v);
printf("\n"); //prints a new line similar t0 \n
}
}
h5xx::dataset open_dataset(std::string const& filename) {
h5xx::file xaa(filename, h5xx::file::mode::in);
h5xx::group g(xaa, "particles/lipids/box/positions");
return h5xx::dataset(g, "value");
}
std::vector<float> cell_from_all_frames(h5xx::dataset& ds, size_t row, size_t col) {
// determine dataset shape: frames, particle count, space dimension
auto ds_shape = h5xx::dataspace(ds).extents<3>();
std::vector<float> cells(ds_shape[0]); // number of frames
std::vector<hsize_t> offsets{0, row, col};
std::vector<hsize_t> counts{ds_shape[0], 1, 1};
h5xx::slice slice(offsets, counts);
h5xx::read_dataset(ds, cells, slice);
return cells;
}
array_2d_t read_frame(std::string const& filename, unsigned frame_no) {
//h5xx::file xaa("../../data/xaa.h5", h5xx::file::mode::in);
h5xx::file xaa(filename, h5xx::file::mode::in);
h5xx::group g(xaa, "particles/lipids/box/positions");
h5xx::dataset ds(g, "value");
// determine dataset shape: frames, particle count, space dimension
auto ds_shape = h5xx::dataspace(ds).extents<3>();
array_2d_t arr(boost::extents[ds_shape[1]][ds_shape[2]]);
std::vector<hsize_t> offsets{frame_no, 0, 0};
std::vector<hsize_t> counts{1, arr.shape()[0], arr.shape()[1]};
h5xx::slice slice(offsets, counts);
h5xx::read_dataset(ds, arr, slice);
return arr;
}
int main(int argc, char const* argv[])
{
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " input.h5" << std::endl;
return -1;
}
auto ds = open_dataset(argv[1]);
std::vector<float> first_cells = cell_from_all_frames(ds, 0, 0);
// set up multi-tau correlator for the computation of time correlation functions
size_t nsamples = 10; // FIXME obtain these parameters from HDF5 file. These 10 elements would be first element of first row, first element of 11214 row, first element of 11214*2 row, first element of 11214*3 row ,..., first element of 11214*10 row.
return 0;
}
在 main() 中,我从函数 read_frame 中读取数据并尝试将其传递给 nsamples。我已经尝试了一些方法,但没有用!!
你可以选择。
存储它?
array_2d_t frame = read_frame(filename, 1);
访问一个元素?
// access individual elements:
float ele = frame[0][3];
// or with index list:
std::array<int, 2> indices{0,3};
ele = frame(indices);
或者,如您所愿,提供数组的平面视图:
boost::multi_array_ref<float, 1> sequence(frame.origin(), boost::extents[frame.num_elements()]);
fmt::print("Sum of all {} elements: {}\n",
sequence.size(),
std::accumulate(sequence.begin(), sequence.end(), 0.f));
事实上你可能会就地重塑,但你不能改变维度,所以你得到所有单元格的 1“行”:
frame.reshape(std::array<size_t, 2> {1, frame.num_elements()});
// now the first "row" is the full sequence:
auto&& sequence = frame[0];
fmt::print("Sum of all {} elements: {}\n",
sequence.size(),
std::accumulate(sequence.begin(), sequence.end(), 0.f));
slicing/reindex 有多种选择,有或没有大步前进,但我 refer to the Boost documentation 以防止在这里不必要地使事情复杂化。
现场演示
#include <boost/multi_array.hpp>
#include <fmt/ranges.h>
#include <h5xx/h5xx.hpp>
#include <iostream>
#include <iterator>
using array_2d_t = boost::multi_array<float, 2>;
h5xx::dataset open_dataset(std::string const& filename) {
h5xx::file xaa(filename, h5xx::file::mode::in);
h5xx::group g(xaa, "particles/lipids/box/positions");
return h5xx::dataset(g, "value");
}
array_2d_t read_frame(h5xx::dataset& ds, unsigned frame_no) {
auto ds_shape = h5xx::dataspace(ds).extents<3>();
array_2d_t arr(boost::extents[ds_shape[1]][ds_shape[2]]);
std::vector<hsize_t> offsets{frame_no, 0, 0};
std::vector<hsize_t> counts{1, arr.shape()[0], arr.shape()[1]};
h5xx::slice slice(offsets, counts);
h5xx::read_dataset(ds, arr, slice);
return arr;
}
std::vector<float> cell_from_all_frames(h5xx::dataset& ds, size_t row, size_t col) {
// determine dataset shape: frames, particle count, space dimension
auto ds_shape = h5xx::dataspace(ds).extents<3>();
std::vector<float> cells(ds_shape[0]); // number of frames
std::vector<hsize_t> offsets{0, row, col};
std::vector<hsize_t> counts{ds_shape[0], 1, 1};
h5xx::slice slice(offsets, counts);
h5xx::read_dataset(ds, cells, slice);
return cells;
}
int main(int argc, char const* argv[])
{
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " input.h5" << std::endl;
return -1;
}
auto ds = open_dataset(argv[1]);
array_2d_t frame = read_frame(ds, 1);
// access individual elements:
[[maybe_unused]] float ele = frame[0][2];
// or with index list:
std::array<int, 2> indices{0,2};
ele = frame(indices);
{
boost::multi_array_ref<float, 1> sequence(frame.origin(), boost::extents[frame.num_elements()]);
fmt::print("Sum of all {} elements: {}\n",
sequence.size(),
std::accumulate(sequence.begin(), sequence.end(), 0.f));
}
{
// in fact yuou might reshape in-place, but then you cannot change dimensiaonality
frame.reshape(std::array<size_t, 2> {1, frame.num_elements()});
// now the first "row" is the full sequence:
auto&& sequence = frame[0];
fmt::print("Sum of all {} elements: {}\n",
sequence.size(),
std::accumulate(sequence.begin(), sequence.end(), 0.f));
}
{
std::vector<float> first_cells = cell_from_all_frames(ds, 0, 0);
fmt::print("Sum of all {} first cells: {}\n",
first_cells.size(),
std::accumulate(first_cells.begin(), first_cells.end(), 0.f));
}
}
用你刚才的 xaa.h5:
Sum of all 33642 elements: 737589.1
Sum of all 33642 elements: 737589.1
Sum of all 75 first cells: 6053.3496
我正在努力访问这些值并将它们存储在 boost multi_array 容器中。我尝试使用索引方法([] 和 .at())访问元素,但抛出 error: no matching function for call to 'boost::multi_array<float, 2>::data(int)',但是我可以打印数据(见代码)但不知道如何存储它并再次访问它以进行进一步计算。数据是二维的 (11214, 3),但与此同时我只想将其展平并获得一系列值。所以我的问题是如何访问元素以及如何将它们存储在容器中?
#include <boost/multi_array.hpp>
#include <boost/timer/timer.hpp>
#include <boost/range/irange.hpp>
#include <h5xx/h5xx.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
using array_2d_t = boost::multi_array<float, 2>;
//using array_2d_t = boost::multi_array<float, 3>;
template <typename T>
void print_array(T const& array)
{
for (auto const& row : array)
{ for (auto v : row)
printf("%10f ", v);
printf("\n"); //prints a new line similar t0 \n
}
}
h5xx::dataset open_dataset(std::string const& filename) {
h5xx::file xaa(filename, h5xx::file::mode::in);
h5xx::group g(xaa, "particles/lipids/box/positions");
return h5xx::dataset(g, "value");
}
std::vector<float> cell_from_all_frames(h5xx::dataset& ds, size_t row, size_t col) {
// determine dataset shape: frames, particle count, space dimension
auto ds_shape = h5xx::dataspace(ds).extents<3>();
std::vector<float> cells(ds_shape[0]); // number of frames
std::vector<hsize_t> offsets{0, row, col};
std::vector<hsize_t> counts{ds_shape[0], 1, 1};
h5xx::slice slice(offsets, counts);
h5xx::read_dataset(ds, cells, slice);
return cells;
}
array_2d_t read_frame(std::string const& filename, unsigned frame_no) {
//h5xx::file xaa("../../data/xaa.h5", h5xx::file::mode::in);
h5xx::file xaa(filename, h5xx::file::mode::in);
h5xx::group g(xaa, "particles/lipids/box/positions");
h5xx::dataset ds(g, "value");
// determine dataset shape: frames, particle count, space dimension
auto ds_shape = h5xx::dataspace(ds).extents<3>();
array_2d_t arr(boost::extents[ds_shape[1]][ds_shape[2]]);
std::vector<hsize_t> offsets{frame_no, 0, 0};
std::vector<hsize_t> counts{1, arr.shape()[0], arr.shape()[1]};
h5xx::slice slice(offsets, counts);
h5xx::read_dataset(ds, arr, slice);
return arr;
}
int main(int argc, char const* argv[])
{
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " input.h5" << std::endl;
return -1;
}
auto ds = open_dataset(argv[1]);
std::vector<float> first_cells = cell_from_all_frames(ds, 0, 0);
// set up multi-tau correlator for the computation of time correlation functions
size_t nsamples = 10; // FIXME obtain these parameters from HDF5 file. These 10 elements would be first element of first row, first element of 11214 row, first element of 11214*2 row, first element of 11214*3 row ,..., first element of 11214*10 row.
return 0;
}
在 main() 中,我从函数 read_frame 中读取数据并尝试将其传递给 nsamples。我已经尝试了一些方法,但没有用!!
你可以选择。
存储它?
array_2d_t frame = read_frame(filename, 1);
访问一个元素?
// access individual elements:
float ele = frame[0][3];
// or with index list:
std::array<int, 2> indices{0,3};
ele = frame(indices);
或者,如您所愿,提供数组的平面视图:
boost::multi_array_ref<float, 1> sequence(frame.origin(), boost::extents[frame.num_elements()]);
fmt::print("Sum of all {} elements: {}\n",
sequence.size(),
std::accumulate(sequence.begin(), sequence.end(), 0.f));
事实上你可能会就地重塑,但你不能改变维度,所以你得到所有单元格的 1“行”:
frame.reshape(std::array<size_t, 2> {1, frame.num_elements()});
// now the first "row" is the full sequence:
auto&& sequence = frame[0];
fmt::print("Sum of all {} elements: {}\n",
sequence.size(),
std::accumulate(sequence.begin(), sequence.end(), 0.f));
slicing/reindex 有多种选择,有或没有大步前进,但我 refer to the Boost documentation 以防止在这里不必要地使事情复杂化。
现场演示
#include <boost/multi_array.hpp>
#include <fmt/ranges.h>
#include <h5xx/h5xx.hpp>
#include <iostream>
#include <iterator>
using array_2d_t = boost::multi_array<float, 2>;
h5xx::dataset open_dataset(std::string const& filename) {
h5xx::file xaa(filename, h5xx::file::mode::in);
h5xx::group g(xaa, "particles/lipids/box/positions");
return h5xx::dataset(g, "value");
}
array_2d_t read_frame(h5xx::dataset& ds, unsigned frame_no) {
auto ds_shape = h5xx::dataspace(ds).extents<3>();
array_2d_t arr(boost::extents[ds_shape[1]][ds_shape[2]]);
std::vector<hsize_t> offsets{frame_no, 0, 0};
std::vector<hsize_t> counts{1, arr.shape()[0], arr.shape()[1]};
h5xx::slice slice(offsets, counts);
h5xx::read_dataset(ds, arr, slice);
return arr;
}
std::vector<float> cell_from_all_frames(h5xx::dataset& ds, size_t row, size_t col) {
// determine dataset shape: frames, particle count, space dimension
auto ds_shape = h5xx::dataspace(ds).extents<3>();
std::vector<float> cells(ds_shape[0]); // number of frames
std::vector<hsize_t> offsets{0, row, col};
std::vector<hsize_t> counts{ds_shape[0], 1, 1};
h5xx::slice slice(offsets, counts);
h5xx::read_dataset(ds, cells, slice);
return cells;
}
int main(int argc, char const* argv[])
{
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " input.h5" << std::endl;
return -1;
}
auto ds = open_dataset(argv[1]);
array_2d_t frame = read_frame(ds, 1);
// access individual elements:
[[maybe_unused]] float ele = frame[0][2];
// or with index list:
std::array<int, 2> indices{0,2};
ele = frame(indices);
{
boost::multi_array_ref<float, 1> sequence(frame.origin(), boost::extents[frame.num_elements()]);
fmt::print("Sum of all {} elements: {}\n",
sequence.size(),
std::accumulate(sequence.begin(), sequence.end(), 0.f));
}
{
// in fact yuou might reshape in-place, but then you cannot change dimensiaonality
frame.reshape(std::array<size_t, 2> {1, frame.num_elements()});
// now the first "row" is the full sequence:
auto&& sequence = frame[0];
fmt::print("Sum of all {} elements: {}\n",
sequence.size(),
std::accumulate(sequence.begin(), sequence.end(), 0.f));
}
{
std::vector<float> first_cells = cell_from_all_frames(ds, 0, 0);
fmt::print("Sum of all {} first cells: {}\n",
first_cells.size(),
std::accumulate(first_cells.begin(), first_cells.end(), 0.f));
}
}
用你刚才的 xaa.h5:
Sum of all 33642 elements: 737589.1
Sum of all 33642 elements: 737589.1
Sum of all 75 first cells: 6053.3496