如何将犰狳矩阵转换为立方体?
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
的生命周期中。这很难确保,尤其是当 a
和 c
都在堆上创建时。
您还可以允许 c
复制 a
的数据,方法是省略最后一个参数或将其设置为 true
.这比无复制构造函数花费更多时间,但可能比从 a
的数据分配每个切片要少,因为此构造函数对基础数据进行单个批量 memcpy
。
所有这些都取决于@ewcz 的回答提出的行与列主要观点。确保你知道重塑时会得到什么,尤其是当你使用高级构造函数时。
我正在尝试重新创建以下 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
的生命周期中。这很难确保,尤其是当 a
和 c
都在堆上创建时。
您还可以允许 c
复制 a
的数据,方法是省略最后一个参数或将其设置为 true
.这比无复制构造函数花费更多时间,但可能比从 a
的数据分配每个切片要少,因为此构造函数对基础数据进行单个批量 memcpy
。
所有这些都取决于@ewcz 的回答提出的行与列主要观点。确保你知道重塑时会得到什么,尤其是当你使用高级构造函数时。