C++如何对读取的二维数组执行加减、求均值等数学运算?
解决方案
1. 实现两帧逐元素相减
你使用的boost::multi_array支持直接通过索引访问行和元素,要实现第二帧减去第一帧,按以下步骤操作即可:
- 先分别读取你需要运算的两个帧数据
- 创建一个和单帧维度相同的新数组存储差值
- 逐行、逐元素做减法运算即可
如果需要频繁做这类运算,可以封装通用的运算函数,下面是完整的可运行修改代码:
#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> #include <cassert> 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"); } std::cout << "\n End of array" << std::endl; } // 两帧逐元素相减函数:返回a - b的结果 array_2d_t subtract_array(array_2d_t const& a, array_2d_t const& b) { // 校验两个数组维度一致 assert(a.shape()[0] == b.shape()[0] && a.shape()[1] == b.shape()[1]); array_2d_t res(boost::extents[a.shape()[0]][a.shape()[1]]); for (size_t i = 0; i < a.shape()[0]; ++i) { for (size_t j = 0; j < a.shape()[1]; ++j) { res[i][j] = a[i][j] - b[i][j]; } } return res; } // 行减法:将数组第target行减去第reference行,结果直接修改原数组 void subtract_row(array_2d_t& arr, size_t target_row_idx, size_t reference_row_idx) { assert(target_row_idx < arr.shape()[0] && reference_row_idx < arr.shape()[0]); for (size_t j = 0; j < arr.shape()[1]; ++j) { arr[target_row_idx][j] -= arr[reference_row_idx][j]; } } array_2d_t read_frame(std::string const& filename, unsigned frame_no) { h5xx::file xaa(filename, h5xx::file::mode::in); h5xx::group g(xaa, "particles/lipids/box/positions"); h5xx::dataset ds(g, "value"); 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; } std::string filename(argv[1]); // 读取第一帧和第二帧,注意帧序号从0开始的话,第一帧是0,第二帧是1,可根据实际情况调整序号 array_2d_t frame1 = read_frame(filename, 0); array_2d_t frame2 = read_frame(filename, 1); // 实现第二帧减第一帧 array_2d_t diff_frame = subtract_array(frame2, frame1); std::cout << "第二帧减第一帧的结果:" << std::endl; print_array(diff_frame); // 示例:把diff_frame的第3行(索引2)减去第1行(索引0) subtract_row(diff_frame, 2, 0); std::cout << "第3行减第1行后的结果:" << std::endl; print_array(diff_frame); return 0; }
2. 补充说明
- 如果你的数据量较大,不想额外拷贝数组存储结果,可以直接在原数组上做修改,不需要创建新的结果数组
boost::multi_array的索引是从0开始计数的,你操作行或者帧的时候要注意序号对应,避免越界- 求均值这类操作逻辑类似,遍历对应元素累加后除以元素个数即可,也可以直接封装成通用函数
内容的提问来源于stack exchange,提问作者Mahesh
相关产品推荐
相关产品推荐

