A.1.6.1数组和稀疏类的差异

稀疏矩阵中元素的数量被认为是非零元素的数量,而不是矩阵的尺寸。因此

SparseMatrix sm;
...
int nnz = sm.nelem ();

返回非零元素的数量(如解释器函数nnz). 如果用户真的需要矩阵中的元素数量,包括非零元素,他们应该使用numel而不是nelem。注意,对于非常大的矩阵,其中二维的乘积大于无符号int的表示,numel可以溢出。一个例子是speye(1e6)这将创建一个有一百万行和列但只有一百万个非零元素的矩阵。在这种情况下,行数乘以列数是无符号32位整数所能表示的最大值的二百倍以上。因此应该避免使用numel,除非知道它不会溢出。

使用时也需要格外小心elem方法或执行基本相同函数的运算符()。原因是,如果一个稀疏对象是非常量的,那么Octave将假设对稀疏矩阵中零元素的指定实际上是创建该元素以便填充该元素的指定。因此,一段代码

SparseMatrix sm;
...
for (int j = 0; j < nc; j++)
  for (int i = 0; i < nr; i++)
    std::cerr << " (" << i << "," << j << "): " << sm(i,j) << "\n";

是将稀疏矩阵转化为稠密矩阵的好方法,但速度非常慢,因为它为矩阵中的每个零元素重新赋值稀疏对象。

防止上述情况发生的一个简单方法是创建稀疏矩阵的临时常量版本。请注意,临时常量版本只会复制稀疏矩阵的容器,而数据的实际表示将在两个版本的稀疏矩阵之间共享;这不是一项成本高昂的操作。上面的例子是为了防止稀疏到密集的转换而重新编写的,它是

SparseMatrix sm;
...
const SparseMatrix tmp (sm);
for (int j = 0; j < nc; j++)
  for (int i = 0; i < nr; i++)
    std::cerr << " (" << i << "," << j << "): " << tmp(i,j) << "\n";

最后,从于稀疏类型不是从连续的内存块表示的,所以fortran_vec的方法Array<T>不可用。然而,它被三种不同的方法所取代ridx,cidxdata,访问存储Octave稀疏矩阵的原始压缩列格式。这些方法的使用方式类似于elem以允许访问或填充矩阵。然而,这取决于用户是否检视稀疏矩阵压缩列格式,否则矩阵将被破坏。


版权所有 © 2024 Octave中文网

ICP备案/许可证号:黑ICP备2024030411号