【问题标题】:boost compressed matrix basicsboost压缩矩阵基础知识
【发布时间】:2010-09-21 22:40:06
【问题描述】:

我对 boost::compressed_matrix 的工作原理感到困惑。假设我这样声明压缩矩阵:

boost::numeric::ublas::compressed_matrix<double> T(1000, 1000, 3*1000);

这会为 1000x1000 矩阵中的 3*1000 个元素分配空间。现在我如何给它非零元素的位置?何时以及如何设置非零元素?每次我在矩阵中分配一个元素时,例如B(4,4)=4,它会将该元素标记为非零吗?

如果可能的话,如果您能通过示例帮助我了解这一点,我将不胜感激。对内部实现的一些见解会很棒。我想确保我不会编写通过猜测工作的次优程序。

谢谢!

【问题讨论】:

    标签: c++ optimization boost matrix sparse-matrix


    【解决方案1】:

    压缩矩阵有一个底层线性容器(默认为unbounded_array,但如果需要,您可以将其设为bounded_arraystd::vector),其中包含矩阵的所有非零元素,以行为主(默认)顺序。这意味着,每当您将新的非零元素写入压缩矩阵时,它都会插入到该底层数组中。如果您没有按(行优先)顺序填充矩阵,则每个插入都是 O(n)。当你改变一个现有的非零元素时,它只是在底层数组中改变。

    这是一个简单的测试,看看底层结构是什么样子的:

    #include <boost/numeric/ublas/matrix_sparse.hpp>
    #include <boost/numeric/ublas/storage.hpp>
    namespace ublas = boost::numeric::ublas;
    void show_array(const ublas::unbounded_array<double>& a)
    {
        for(size_t i=0; i<a.size(); ++i)
                std::cout << a[i] << ' ';
        std::cout << '\n';
    }
    int main()
    {
        ublas::compressed_matrix<double> m (10, 10, 3 * 10);
        m(0, 5) = 1; // underlying array is {1, 0, 0, 0, ...}
        show_array(m.value_data());
        m(0, 6) = 2; // underlying array is {1, 2, 0, 0, ...}
        show_array(m.value_data());
        m(0, 4) = 3;  // underlying array is {3, 1, 2, 0, ...}
        show_array(m.value_data());
        m(0, 4) = 7;  // underlying array is {7, 1, 2, 0, ...}
        show_array(m.value_data());
    }
    

    【讨论】:

    • 指定第三个构造函数参数有什么好处 - 没有非零元素?如果我不指定会怎样?
    • 如果您以unbounded_array 开头,它太短而无法容纳所有非零值,它会根据需要自动增长,导致每次非零元素时都会发生内存分配和大量复制写入超出容量的矩阵。好吧,在实践中,它以块的形式增长,就像 std::vectorpush_back 上所做的那样,所以不会在每次写入时都看到它:用上面的例子做实验:制作我的压缩矩阵 (3, 3),并添加非零到四个不同的元素。
    【解决方案2】:

    您可以使用(i,j) 运算符隐式创建非零元素,也可以使用 insert_element 函数显式插入元素。

    最好的地方实际上是看内部实现:

    http://www.tena-sda.org/doc/5.2.2/boost/d2/db7/matrix__sparse_8hpp-source.html#l02761

    true_reference insert_element (size_type i, size_type j, const_reference t)

    在第 i 行的第 j 个元素处插入值 t。不允许重复元素。


    void erase_element (size_type i, size_type j)

    删除第 i 行的第 j 个元素的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-16
      • 2018-05-25
      • 2014-11-28
      • 2014-02-14
      • 2023-04-10
      相关资源
      最近更新 更多