使用 Armadillo 库访问矩阵列而不创建数据副本
Access column of matrix without creating copy of data, using Armadillo library
我有一个 (data/storage) class 和一个成员 arma::mat
(矩阵),我只想访问该矩阵的一列 (arma::colvec
),但我不想在列中创建数据的副本。有什么办法可以实现吗?
我的第一次尝试是使用 .col(i)
,但这个 returns 是临时的,所以参考不起作用。
使用 .colptr(i)
不会创建副本,但它也会 returns 一个 double*
而不是 vec
,所以这让我的生活有点困难。
struct Data
{
mat A;
/* constructors etc. */
// reference to temporary (this is bad)
const vec& getColumn(const uint i) { return A.col(i); }
// doesn't create a copy, but doesn't return a vec either
const double* getColumn2(const uint i) const { return A.colptr(i); }
}
想要这个的原因是 class 有向量和矩阵,我想制作统一的 getter 和 setter 方法来访问其中一个向量,或矩阵中的列,具体取决于索引(用于迭代目的)。
一个例子:
struct Data
{
mat A;
vec b;
// getter
const vec& operator()(const uint i) const
{
if (i == 0)
{
return b;
}
else if (i == 1)
{
// return first column of A
}
// etc.
}
// setter
vec& operator()(const uint i)
{
// similar to above
}
}
解决方案
基于我找到了以下实现所需功能的方法:
struct Data
{
mat A;
vec b;
// getter
subview_col<mat::elem_type> operator()(const uint i)
{
if (i == 0)
{
return b.col(0);
}
else if (i > 0 && i < (1 + A.n_cols()))
{
return A.col(i - 1);
}
else
{
// should probably do some error checking here
}
}
// setter
vec& operator()(const uint i)
{
// same as the above, but without consts in declaration
}
}
这个 returns subview_col<mat::elem_type>
而不是 vec
,但对我来说功能是 similar/identical。我不确定在 vec
上使用 .col(0)
对性能的影响,但我并不那么担心。
在 arma 中,A.col(i) 不是 return 参考,而是临时的。您可以 return 这个临时文件来获取引用语义。使用 C++14,只需编写
auto getColumn(const uint i) { return A.col(i); }
否则,你必须return代理类型,它是
subview_col<mat::elem_type> getColumn(const uint i) { return A.col(i); }
如果你必须return一个vec
而不是subview_col<...>
,你可以使用A.unsafe_col(i)
,但你必须确定,你没有在 A
的生命周期结束后尝试使用它。 see here
我有一个 (data/storage) class 和一个成员 arma::mat
(矩阵),我只想访问该矩阵的一列 (arma::colvec
),但我不想在列中创建数据的副本。有什么办法可以实现吗?
我的第一次尝试是使用 .col(i)
,但这个 returns 是临时的,所以参考不起作用。
使用 .colptr(i)
不会创建副本,但它也会 returns 一个 double*
而不是 vec
,所以这让我的生活有点困难。
struct Data
{
mat A;
/* constructors etc. */
// reference to temporary (this is bad)
const vec& getColumn(const uint i) { return A.col(i); }
// doesn't create a copy, but doesn't return a vec either
const double* getColumn2(const uint i) const { return A.colptr(i); }
}
想要这个的原因是 class 有向量和矩阵,我想制作统一的 getter 和 setter 方法来访问其中一个向量,或矩阵中的列,具体取决于索引(用于迭代目的)。
一个例子:
struct Data
{
mat A;
vec b;
// getter
const vec& operator()(const uint i) const
{
if (i == 0)
{
return b;
}
else if (i == 1)
{
// return first column of A
}
// etc.
}
// setter
vec& operator()(const uint i)
{
// similar to above
}
}
解决方案
基于
struct Data
{
mat A;
vec b;
// getter
subview_col<mat::elem_type> operator()(const uint i)
{
if (i == 0)
{
return b.col(0);
}
else if (i > 0 && i < (1 + A.n_cols()))
{
return A.col(i - 1);
}
else
{
// should probably do some error checking here
}
}
// setter
vec& operator()(const uint i)
{
// same as the above, but without consts in declaration
}
}
这个 returns subview_col<mat::elem_type>
而不是 vec
,但对我来说功能是 similar/identical。我不确定在 vec
上使用 .col(0)
对性能的影响,但我并不那么担心。
在 arma 中,A.col(i) 不是 return 参考,而是临时的。您可以 return 这个临时文件来获取引用语义。使用 C++14,只需编写
auto getColumn(const uint i) { return A.col(i); }
否则,你必须return代理类型,它是
subview_col<mat::elem_type> getColumn(const uint i) { return A.col(i); }
如果你必须return一个vec
而不是subview_col<...>
,你可以使用A.unsafe_col(i)
,但你必须确定,你没有在 A
的生命周期结束后尝试使用它。 see here