C++ boost压缩矩阵基础

C++ boost压缩矩阵基础,c++,optimization,boost,matrix,sparse-matrix,C++,Optimization,Boost,Matrix,Sparse Matrix,我对boost::compressed_矩阵的工作原理感到困惑。假设我这样声明压缩的_矩阵: boost::numeric::ublas::compressed_matrix<double> T(1000, 1000, 3*1000); boost::numeric::ublas::compressed_矩阵T(1000,1000,3*1000); 这为1000x1000矩阵中的3*1000元素分配了空间。现在我如何给它非零元素的位置?何时以及如何设置非零元素?是不是每次我在矩阵

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

boost::numeric::ublas::compressed_matrix<double> T(1000, 1000, 3*1000);
boost::numeric::ublas::compressed_矩阵T(1000,1000,3*1000);
这为1000x1000矩阵中的3*1000元素分配了空间。现在我如何给它非零元素的位置?何时以及如何设置非零元素?是不是每次我在矩阵中指定一个元素,例如B(4,4)=4,它都会将该元素标记为非零

如果可能的话,你能用一个例子来帮助我学习这一点,我将不胜感激。对内部实现进行一些深入了解将非常有用。我想确保我写的程序不会因为猜测工作而处于次优状态

谢谢大家!

可以使用
(i,j)
运算符隐式创建非零元素,也可以使用insert\u element函数显式插入元素

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

真参考插入元素(尺寸类型i、尺寸类型j、常数参考t)

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


无效删除元素(尺寸类型i,尺寸类型j)

擦除第i行第j个元素处的值


压缩矩阵有一个底层线性容器(默认情况下为
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());
}
#包括
#包括
名称空间ublas=boost::numeric::ublas;
void show_数组(const ublas::unbounded_数组&a)
{

对于(size_t i=0;iis指定第三个构造函数参数有什么好处吗?没有非零元素?如果我不指定它会发生什么?如果你从
无界数组开始,它太短了,不能容纳所有非零,它会根据需要自动增长,导致内存分配和每次复制都会发生非零元素被写入超出容量的矩阵。实际上,它会成片增长,就像
std::vector
push_back
上所做的那样,因此不会在每次写入时都看到它:使用上面的示例进行实验:生成压缩矩阵(3,3),并将非零添加到四个不同的元素。