c++ - 使用密集矩阵和稀疏矩阵

标签 c++ matrix

我正在编写一个对矩阵进行操作的 C++ 函数,作为参数传递,并希望代码能够处理不同类型的矩阵(例如 Boost 稀疏矩阵、std::vectors of std::vectors)。我目前的方法是为不同类型的基本矩阵操作定义重载方法,为不同类型的矩阵提供统一的接口(interface),并将我的函数定义为仅使用这些重载方法的模板函数

#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;
    });
}

唯一的缺点是矩阵专用函数当然需要在标题中(因为模板)。但我认为这种方法不仅优雅而且表现力很强(你可以命名为“迭代矩阵条目”而不是复杂的循环语法,但循环体保持不变)。

关于c++ - 使用密集矩阵和稀疏矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50643270/

相关文章:

php - 使用循环 PHP、对角线检查增加 IF 语句中的条件

c++ - 我们可以访问一个不存在的联盟的成员吗?

C++ 无法解析变量 BOOST_FOREACH

c++ - 不同类型之间的模板类分配

php - 寻找积极维护的 php 矩阵数学库

c - 如何在 C 中将矩阵乘以矩阵?为什么这不起作用?

python - 在同一个图上一起绘制两个距离矩阵?

c++ - C++函数更改传递参数的值

c++ - 该程序的输出是什么?

python - 跨python矩阵的行和列获取最大值