簡體   English   中英

本征:累積可變大小的數組

[英]Eigen: Accumulating arrays of variable size

我有一個類,其中包含一個Eigen :: Array數據,以及一個通過沿第一個軸附加到數組來添加新數據(行數可能會變化)的方法。 我通過創建一個大小合適的新數組並用新舊數據進行初始化來解決了累積問題。

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_;
}

這樣做有什么問題嗎? 還是最好調整累積數據數組的大小:

  • .resize()並復制舊的和新的
  • .conservative_resize()並復制新數據(如果新數據長於1行,則需要執行塊操作)

首先,當前的實現存在兩個易於修復的缺陷:

  • Eigen默認情況下按列主順序存儲數組(和矩陣),因此,如果要追加行,則應首選RowMajor存儲順序:

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

  • 由於accu將不再使用,你應該把它移動到蓄電池: accumulated_data_ = std::move(accu);

    如果您使用的是C ++ 11之前的版本,則還可以交換數據:

    accumulated_data_.swap(accu);

那么你的方法幾乎等同於

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

每次調用時,您仍將具有內存(重新)分配和內存副本。

一個更有效的方法是調整accumulated_data_只是偶爾(最好是只有一次開頭),並跟蹤的量有多大,目前實際上是有效的:

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_;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM