2010-09-21 75 views
7

我很困惑boost :: compressed_matrix是如何工作的。假设我声明这样的compressed_matrix:boost压缩矩阵基础

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

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

我真的很感激,如果你可以帮助我学习这个例子,如果可能的话。对内部实施的一些洞察力会很好。我想确保我不会编写通过猜测工作而不是最优的程序。

谢谢!

回答

3

压缩基具有潜在的线性容器(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()); 
} 
+1

是否有任何指定第三个构造函数参数的优点 - 非零元素的否?如果我没有指定它,会发生什么? – user236215 2010-09-22 04:14:22

+2

如果你从'unbounded_array'开始,它太短而不能容纳所有的非零值,它将自动增长为必要的,导致内存分配和大量的复制发生,每当非零元素被写入矩阵超过容量。那么,在实践中,它会以块的形式增长,就像'push_back'上的'std :: vector'一样,所以在每次写入时都不会看到它:试验上面的例子:使我的压缩矩阵(3,3)和给四个不同的元素添加非零。 – Cubbi 2010-09-22 10:15:24

1

您可以使用(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Ĵ,为const_reference吨)

插入在所述第j个要素的值t第i行。不允许复制元素。


空隙erase_element(SIZE_TYPE I,SIZE_TYPE j)的

擦除在第i行的第j个要素的值。

+0

是源代码参考很有帮助。谢谢 – user236215 2010-09-21 23:35:25