我对boost :: compressed_matrix的工作原理感到困惑。假设我像这样声明compressed_matrix:
boost::numeric::ublas::compressed_matrix<double> T(1000, 1000, 3*1000);
这为1000x1000矩阵中的3 * 1000个元素分配空间。现在我该如何给它提供非零元素的位置?何时以及如何设置非零元素?是每次我在矩阵中分配一个元素,例如B(4,4)= 4,它会将该元素标记为非零?
如果可能的话,如果你能帮助我通过一个例子来帮助我学习,我将非常感激。对内部实施的一些见解会很棒。我想确保我不会通过猜测来编写次优的程序。
谢谢你!答案 0 :(得分:3)
压缩矩阵默认有一个基础线性容器(unbounded_array
,但如果需要,可以设为bounded_array
或std::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 :(得分: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 j,const_reference t)
将值t插入第i行的第j个元素。不允许重复元素。
void erase_element(size_type i,size_type j)
删除第i行第j个元素的值。