如何将犰狳矩阵转换为立方体?

How do I convert an Armadillo matrix to cube?

我正在尝试重新创建以下 Python numpy 代码:

num_rows, num_cols = data.shape
N = 4
data = data.reshape(N, num_rows/N, num_cols)

在 C++ 中使用犰狳矩阵和立方体?如何最有效地做到这一点。我不认为 resize/reshape 操作直接支持从 2d 矩阵移动到 3d 立方体?

由于犰狳使用数据的列主要排序(与依赖行主要排序的 numpy 相反),只需将矩阵放入具有 1 个切片的立方体中并对其进行整形会产生不同的结果(矩阵 B 以下)。另一种方法可能是手动构建切片:

#include <iostream>
#include <armadillo>

int main(){

    const arma::uword N = 2;
    const arma::uword num_rows = 4;
    const arma::uword num_cols = 3;

    arma::mat A(num_rows, num_cols, arma::fill::randu);

    std::cout << A;

    arma::cube B(num_rows, num_cols, 1);
    B.slice(0) = A;
    B.reshape(num_rows/N, num_cols, N);
    std::cout << B;

    arma::cube C(num_rows/N, num_cols, N);
    for(arma::uword i = 0; i < N; ++i){
        C.slice(i) = A.rows(i*N, (i+1)*N-1);
    }
    std::cout << C;


    return 0;
}

构造这样一个立方体的最快方法是使用advanced constructors之一。这些允许您直接从内存的任意部分创建一个新对象,甚至无需复制任何数据。这在本质上最接近 NumPy 重塑的方式,其中返回原始数据的 view,而不是副本。

您将像这样使用构造函数:

// Assuming a is an arma::mat.
int N = 4;
arma::cube c(a.memptr(), N, a.n_rows / N, a.n_cols, false);

这直接从 a 中获取内存,无需复制,并将其用作 c 的数据。

当然,这很快,但也很危险。只要 c 存在,您就有责任保证指向的内存有效。这意味着 c 的生命周期必须严格嵌套在 a 的生命周期中。这很难确保,尤其是当 ac 都在堆上创建时。

您还可以允许 c 复制 a 的数据,方法是省略最后一个参数或将其设置为 true .这比无复制构造函数花费更多时间,但可能比从 a 的数据分配每个切片要少,因为此构造函数对基础数据进行单个批量 memcpy

所有这些都取决于@ewcz 的回答提出的行与列主要观点。确保你知道重塑时会得到什么,尤其是当你使用高级构造函数时。