2010-09-21 84 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