滑动窗口无需在犰狳中复制数据

时间:2014-03-25 14:58:23

标签: c++ armadillo

假设我有如下的大型犰狳矩阵:

9 4 8 6 7 ...
5 1 9 4 5 ...
6 6 4 1 2 ...

我想用一个宽度为3的小窗口滑过这个大矩阵,例如

9 4 8
5 1 9
6 6 4

4 8 6
1 9 4
6 4 1

8 6 7
9 4 5
4 1 2

...

但我不想将这些数据复制到新的矩阵中 我想重用RAM中已有的信息。 有办法吗?

2 个答案:

答案 0 :(得分:2)

您可以使用创建子矩阵视图的submat尝试以下操作:

using namespace arma;
const unsigned total_rows = 10;
const unsigned total_cols = 10;

mat all_data(total_rows, total_cols);
// fill your data here
// ...

const unsigned window_rows = 3;
const unsigned window_cols = 3;

const auto num_windows_w = total_cols - window_cols;
const auto num_windows_h = total_rows - window_rows;
for (unsigned row_start = 0; row_start < num_windows_h; ++row_start) {
  for (unsigned col_start = 0; col_start < num_windows_w; ++col_start) {
    auto window = all_data.submat(row_start, col_start, row_start + window_rows, col_start + window_cols);
    // process your window here
    //...
  }
}

您还可以使用mat::span执行相同类型的操作。

答案 1 :(得分:1)

这取决于您对该窗口的进一步操作。如果您使用submat视图并将其传递以进行一些进一步的矩阵操作,例如将其与另一个矩阵或向量相乘,我很确定犰狳会遗憾地创建矩阵的副本。

在您的情况下,我认为无需创建任何副本即可,但前提是您的窗口具有与原始矩阵相同数量的。原因是犰狳使用column-major数据布局(即它将列连续存储在内存中)。因此,窗口中的数据也是原始矩阵的连续行。

然后,您可以使用直接获取内存指针的高级构造函数mat(ptr_aux_mem, n_rows, n_cols, copy_aux_mem = true, strict = false)。通过设置copy_aux_mem = false,您还可以指定直接使用该内存而不是复制它。

const unsigned m = 3;
const unsigned n = 10;

mat M(m,n,fill::randn);
M.print("M");

const unsigned dpos = m;
unsigned pos = 0;
for (unsigned i = 0; i <= n-m ; ++i)
{
    mat tmp(&M.memptr()[pos],m,m,false);
    cout<<i+1<<endl;
    tmp.print();
    // your further manipulations here
    pos += dpos;
}

如果你使用它,你必须确保保持在矩阵的范围内,因为没有犰狳范围检查会捕获这里的任何错误。