假设我有如下的大型犰狳矩阵:
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中已有的信息。 有办法吗?
答案 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;
}
如果你使用它,你必须确保保持在矩阵的范围内,因为没有犰狳范围检查会捕获这里的任何错误。