本征:累积可变大小的数组 [英] Eigen: Accumulating arrays of variable size

查看:76
本文介绍了本征:累积可变大小的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个保存数据Eigen :: Array的类,以及一个通过沿第一个轴附加到数组中来添加新数据(行数可能会变化)的方法.我通过创建一个合适大小的新Array并使用旧数据和新数据初始化它来解决累积问题.

I have a class holding an Eigen::Array of data and a method that adds new data (number of rows may vary) by appending to the array along the first axis. I solved the accumulation by creating a new Array of the right size and initializing it with the old and the new data.

typedef Eigen::Array<double, Eigen::Dynamic, 3> DataArray

class Accumulator {
    void add(DataArray &new_data) {
        DataArray accu(accumulated_data_.rows() + new_data.rows(), 3)
        accu << accumulated_data_, new_data;
        accumulated_data_ = accu;
    }

    DataArray accumulated_data_;
}

这样做有什么问题吗?还是最好调整累积数据数组的大小:

Is there anything wrong with doing it like this? Or is it preferred to resize the accumulated data array:

  • .resize()并同时复制新旧
  • .conservative_resize()并复制新数据(如果新数据长于1行,则需要执行块操作)
  • .resize() and copy in both old and new
  • or .conservative_resize() and copy in the new data (requires block operations if new data is longer than 1 row)

推荐答案

首先,您当前的实现存在两个易于修复的缺陷:

First of all, two easy-to-fix flaws with your current implementation:

  • Eigen默认情况下按列主顺序存储数组(和矩阵),因此,如果要追加行,则应首选 RowMajor 存储顺序:

Eigen :: Array< double,Eigen :: Dynamic,3,Eigen :: RowMajor>

由于将不再使用 accu ,因此应将其移至累加器: accumulated_data_ = std :: move(accu);

Since accu will not be used anymore, you should move it to the accumulator: accumulated_data_ = std::move(accu);

如果您使用的是C ++ 11之前的版本,则还可以交换数据:

If you are pre-C++11, you can also swap the data:

accumulated_data_.swap(accu);

那么您的方法几乎等同于

Then your approach is nearly equivalent to

accumulated_data_.conservativeResize(accumulated_data_.rows() + new_data.rows(), 3);
accumulated_data_.bottomRows(new_data.rows()) = new_data;

在每次调用时,您仍将具有内存(重新)分配和内存副本.

You will still have memory (re-)allocations and memory-copies at every call.

一种更有效的方法是仅偶尔(理想情况下仅在开始时一次)调整 accumulated_data _ 的大小,并跟踪其中当前实际有效的数量:

A more efficient approach would be to resize the accumulated_data_ only occasionally (ideally just once at the beginning), and keep track of how much of it is currently actually valid:

typedef Eigen::Array<double, Eigen::Dynamic, 3, Eigen::RowMajor> DataArray;

class Accumulator {
public:
    Accumulator(Eigen::Index initialCapacity=10000) : accumulated_data_(initialCapacity, 3), actual_rows_(0) {}
    void add(DataArray &new_data) {
        if(actual_rows_+new_data.rows() > accumulated_data_.rows())
        { // TODO adapt memory-growing to your use case
             accumulated_data_.conservativeResize(2*actual_rows_+new_data.rows(), 3);
        }
        accumulated_data_.midRows(actual_rows, new_data.rows()) = new_data;
        actual_rows_+=new_data.rows();
    }

    DataArray accumulated_data_;
    Eigen::Index actual_rows_;
};

这篇关于本征:累积可变大小的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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