[英]Working with both dense and sparse matrices
我正在编写一个C ++函数,它在矩阵上运行,作为参数传递,并希望代码能够处理不同类型的矩阵(例如Boost稀疏矩阵,std :: vector的std :: vectors)。 我目前的方法是为不同类型的基本矩阵操作定义重载方法,为不同类型的矩阵提供统一的接口,并将我的函数定义为仅使用这些重载方法的模板函数
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <iostream>
typedef std::vector<double> vec;
typedef std::vector<vec> mat;
typedef boost::numeric::ublas::compressed_matrix<double, boost::numeric::ublas::row_major> spmat;
namespace matrix
{
inline void set(spmat & input, u_int i, u_int j, double val)
{
input(i, j) = val;
}
inline void set(mat & input, u_int i, u_int j, double val)
{
input[i][j] = val;
}
inline u_int size1(const mat & input)
{
return input.size();
}
inline u_int size2(const mat & input)
{
return input[0].size();
}
inline u_int size1(const spmat & input)
{
return input.size1();
}
inline u_int size2(const spmat & input)
{
return input.size2();
}
inline double get(const spmat & input, u_int i, u_int j)
{
return input(i, j);
}
inline double get(const mat & input, u_int i, u_int j)
{
return input[i][j];
}
}
对于简单的任务,这种方法似乎有效。 然而,目前,我正在尝试编写一个需要迭代所有条目的函数,在密集矩阵的情况下,或者在稀疏矩阵的情况下只迭代非零条目。 我知道如何为每个案例单独执行此操作,但希望只有一个实现在两种情况下都有效。 实现这一目标的标准方法是什么?
我曾经也有过一样的问题。 由于我懒得编写迭代器(很快会遇到限制),我决定使用lambda方法,为每个元素定义一个lambda的特殊函数:
template<class Func>
void forMatrixEntries(const VecOfVecMatrix& mat, Func&& func)
{
for (auto& row : mat.getData())
for (auto& elem : row)
func(elem); // You could track and pass the indices if you want.
}
template<class Func>
void forMatrixEntries(const CompressedSparseMatrix& mat, Func&& func)
{
for (auto& elem : mat.getElements())
func(elem); // You could track and pass the indices if you want.
}
(这些也可以是成员函数,因此他们可以更轻松地访问内部 - 您的选择)。 然后,您可以以统一的方式使用它们:
template<class Mat>
void scale(const Mat& mat, double factor)
{
forMatrixEntries(mat, [factor](double& elem) {
elem *= factor;
});
}
唯一的缺点是矩阵专用函数当然需要在标题中(因为模板)。 但我认为这种方法不仅优雅而且非常具有表现力(你可以给“迭代矩阵条目”而不是复杂的循环语法,但循环体保持不变)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.