是否可以从数据文件中读取 add/subtract 数组?
Is it possible to add/subtract arrays read from a data file?
我想对从文件中读取的数据进行一些数学运算,例如addition/subtraction、均值等。数据是二维的,看起来像这样:
所以现在例如我想从第 3 行或第 4 行中减去第一行,在 python 中使用索引非常简单,但我不知道如何在 C++ 中执行。
这是我正在使用的代码。
#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>;
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
}
std::cout << "\n End of file" << std::endl;
}
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]};
//std::vector<hsize_t> strid{1, arr.shape()[0], arr.shape()[1]};
// slice ohne stride:
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;
}
std::string filename(argv[1]);
print_array(read_frame(filename, 1));
return 0;
}
read_frame 函数采用参数文件名和 frame_no。该文件被分成多个帧,每个帧包含 (11214) 行,但了解这里并不重要。所以 read_frame returns 每一帧的二维数据。在 main() 函数中,我可以打印每一帧的数据,但现在假设我想从第二帧中减去第一帧,我该怎么做?
有谁知道ho
因此,文本形式的数据看起来如何是非常无关紧要的。相关的是,您必须对相同维度的数组进行元素级算术运算。
您可以使用适当的 Matrix 库(例如 Boost UBlas、Eigen、Armadillo 等)。
或者您可以为 Boost MultiArray 编写它们:How to execute mathematical operations between two boost::multi_arrays (C++)?
这是一个示例:
#include <algorithm>
#include <boost/multi_array.hpp>
#include <boost/range/irange.hpp>
#include <boost/timer/timer.hpp>
#include <h5xx/h5xx.hpp>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
namespace ArrayOperators {
template <typename Op> struct ArrayOp {
Op op;
constexpr explicit ArrayOp(Op op) : op(op) {}
template <typename T, typename Scalar, size_t Dim>
constexpr inline auto operator()(
boost::multi_array<T, Dim> const& l,
Scalar const& v) const
{
std::array<int, Dim> shape;
std::copy_n(l.shape(), Dim, shape.data());
using R = boost::multi_array<decltype(op(T{}, v)), Dim>;
R result(shape);
std::transform(
l.data(), l.data()+l.num_elements(),
result.data(),
[&op=op,v](auto const& el) { return op(el, v); });
return result;
}
template <typename T, typename U, size_t Dim>
constexpr inline auto operator()(
boost::multi_array<T, Dim> const& l,
boost::multi_array<U, Dim> const& r) const
{
std::array<int, Dim> shape;
std::copy_n(l.shape(), Dim, shape.data());
assert(std::equal(shape.begin(), shape.end(), r.shape()));
using R = boost::multi_array<decltype(op(T{}, U{})), Dim>;
R result(shape);
std::transform(
l.data(), l.data()+l.num_elements(),
r.data(), result.data(),
[&op=op](auto const& v1, auto const& v2) { return op(v1, v2); });
return result;
}
};
template <typename L, typename R>
static constexpr inline auto operator+(L const& l, R const& r) {
return ArrayOp {std::plus<>{}} (l, r); }
template <typename L, typename R>
static constexpr inline auto operator-(L const& l, R const& r) {
return ArrayOp {std::minus<>{}} (l, r); }
template <typename L, typename R>
static constexpr inline auto operator/(L const& l, R const& r) {
return ArrayOp {std::divides<>{}} (l, r); }
template <typename L, typename R>
static constexpr inline auto operator*(L const& l, R const& r) {
return ArrayOp {std::multiplies<>{}} (l, r); }
}
using array_2d_t = boost::multi_array<float, 2>;
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
}
std::cout << "\n End of file" << std::endl;
}
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]};
//std::vector<hsize_t> strid{1, arr.shape()[0], arr.shape()[1]};
// slice ohne stride:
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;
}
std::string filename(argv[1]);
using namespace ArrayOperators;
auto avg4 = //
(read_frame(filename, 0) + read_frame(filename, 1) +
read_frame(filename, 2) + read_frame(filename, 3)) /
4.0;
print_array(read_frame(filename, 4) - avg4);
return 0;
}
打印:
-0.610001 0.410004 -0.150000
0.372501 -0.395000 -0.037500
-0.062500 0.027500 -0.122500
0.307503 0.184998 -0.212500
0.150000 0.009995 0.362500
-0.497500 0.197500 0.217500
0.405003 -0.185000 0.115000
-0.072500 0.247498 0.237500
-0.480000 0.034998 0.107500
-0.130000 -0.162499 -0.087500
(...)
-0.340000 -0.280001 -0.040000
-0.572502 -0.747505 -0.005000
0.392494 0.012500 0.045000
0.500000 -0.040000 -0.162500
0.355000 0.700000 0.065000
End of file
我想对从文件中读取的数据进行一些数学运算,例如addition/subtraction、均值等。数据是二维的,看起来像这样:
#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>;
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
}
std::cout << "\n End of file" << std::endl;
}
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]};
//std::vector<hsize_t> strid{1, arr.shape()[0], arr.shape()[1]};
// slice ohne stride:
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;
}
std::string filename(argv[1]);
print_array(read_frame(filename, 1));
return 0;
}
read_frame 函数采用参数文件名和 frame_no。该文件被分成多个帧,每个帧包含 (11214) 行,但了解这里并不重要。所以 read_frame returns 每一帧的二维数据。在 main() 函数中,我可以打印每一帧的数据,但现在假设我想从第二帧中减去第一帧,我该怎么做? 有谁知道ho
因此,文本形式的数据看起来如何是非常无关紧要的。相关的是,您必须对相同维度的数组进行元素级算术运算。
您可以使用适当的 Matrix 库(例如 Boost UBlas、Eigen、Armadillo 等)。
或者您可以为 Boost MultiArray 编写它们:How to execute mathematical operations between two boost::multi_arrays (C++)?
这是一个示例:
#include <algorithm>
#include <boost/multi_array.hpp>
#include <boost/range/irange.hpp>
#include <boost/timer/timer.hpp>
#include <h5xx/h5xx.hpp>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
namespace ArrayOperators {
template <typename Op> struct ArrayOp {
Op op;
constexpr explicit ArrayOp(Op op) : op(op) {}
template <typename T, typename Scalar, size_t Dim>
constexpr inline auto operator()(
boost::multi_array<T, Dim> const& l,
Scalar const& v) const
{
std::array<int, Dim> shape;
std::copy_n(l.shape(), Dim, shape.data());
using R = boost::multi_array<decltype(op(T{}, v)), Dim>;
R result(shape);
std::transform(
l.data(), l.data()+l.num_elements(),
result.data(),
[&op=op,v](auto const& el) { return op(el, v); });
return result;
}
template <typename T, typename U, size_t Dim>
constexpr inline auto operator()(
boost::multi_array<T, Dim> const& l,
boost::multi_array<U, Dim> const& r) const
{
std::array<int, Dim> shape;
std::copy_n(l.shape(), Dim, shape.data());
assert(std::equal(shape.begin(), shape.end(), r.shape()));
using R = boost::multi_array<decltype(op(T{}, U{})), Dim>;
R result(shape);
std::transform(
l.data(), l.data()+l.num_elements(),
r.data(), result.data(),
[&op=op](auto const& v1, auto const& v2) { return op(v1, v2); });
return result;
}
};
template <typename L, typename R>
static constexpr inline auto operator+(L const& l, R const& r) {
return ArrayOp {std::plus<>{}} (l, r); }
template <typename L, typename R>
static constexpr inline auto operator-(L const& l, R const& r) {
return ArrayOp {std::minus<>{}} (l, r); }
template <typename L, typename R>
static constexpr inline auto operator/(L const& l, R const& r) {
return ArrayOp {std::divides<>{}} (l, r); }
template <typename L, typename R>
static constexpr inline auto operator*(L const& l, R const& r) {
return ArrayOp {std::multiplies<>{}} (l, r); }
}
using array_2d_t = boost::multi_array<float, 2>;
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
}
std::cout << "\n End of file" << std::endl;
}
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]};
//std::vector<hsize_t> strid{1, arr.shape()[0], arr.shape()[1]};
// slice ohne stride:
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;
}
std::string filename(argv[1]);
using namespace ArrayOperators;
auto avg4 = //
(read_frame(filename, 0) + read_frame(filename, 1) +
read_frame(filename, 2) + read_frame(filename, 3)) /
4.0;
print_array(read_frame(filename, 4) - avg4);
return 0;
}
打印:
-0.610001 0.410004 -0.150000
0.372501 -0.395000 -0.037500
-0.062500 0.027500 -0.122500
0.307503 0.184998 -0.212500
0.150000 0.009995 0.362500
-0.497500 0.197500 0.217500
0.405003 -0.185000 0.115000
-0.072500 0.247498 0.237500
-0.480000 0.034998 0.107500
-0.130000 -0.162499 -0.087500
(...)
-0.340000 -0.280001 -0.040000
-0.572502 -0.747505 -0.005000
0.392494 0.012500 0.045000
0.500000 -0.040000 -0.162500
0.355000 0.700000 0.065000
End of file