提升压缩矩阵基础知识

use*_*215 7 c++ optimization boost matrix sparse-matrix

我对boost :: compressed_matrix的工作原理感到困惑.假设我像这样声明compressed_matrix:

boost::numeric::ublas::compressed_matrix<double> T(1000, 1000, 3*1000);
Run Code Online (Sandbox Code Playgroud)

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

如果可能的话,如果你能帮助我学习这个例子,我将非常感激.对内部实施的一些见解会很棒.我想确保我不会通过猜测来编写次优的程序.

谢谢!

Cub*_*bbi 4

压缩矩阵有一个底层线性容器(默认情况下,但您可以根据需要unbounded_array制作它),其中包含矩阵的所有非零元素,按行优先(默认情况下)顺序。这意味着每当您向压缩矩阵写入新的非零元素时,它都会被插入到该基础数组中。如果您不按(行优先)顺序填充矩阵,则每次插入都将是 O(n)。当您更改现有的非零元素时,它只是在底层数组中进行更改。bounded_arraystd::vector

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

#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());
}
Run Code Online (Sandbox Code Playgroud)

  • 指定第三个构造函数参数有什么好处 - 没有非零元素?如果我不指定会发生什么? (2认同)
  • 如果您从“unbounded_array”开始,它太短而无法容纳所有非零值,它会根据需要自动增长,导致每次将非零元素写入超出范围的矩阵时都会发生内存分配和大量复制。容量。好吧,实际上,它会成块增长,就像 `std::vector` 在 `push_back` 上所做的那样,所以不会在每次写入时看到它:用上面的例子进行实验:制作我的压缩矩阵 (3, 3),然后将非零添加到四个不同的元素。 (2认同)