主要内容

访问稀疏矩阵

非零元素

有几个命令提供了关于稀疏矩阵非零元素的高级信息:

  • nnz返回稀疏矩阵中非零元素的个数。

  • 非零返回包含稀疏矩阵中所有非零元素的列向量。

  • nzmax返回为稀疏矩阵的非零项分配的存储空间量。

要尝试其中的一些方法,请加载所提供的稀疏矩阵west0479是哈维尔-波音(Harwell-Boeing)系列之一。

负载west0479
名称大小字节类属性west0479 479x479 34032双稀疏

这个矩阵模拟了一个八级化学蒸馏塔。

试试这些命令。

nnz (west0479)
Ans = 1887
格式ewest0479
West0479 = (25,1) 1.0000e+00 (31,1) -3.7648e-02 (87,1) -3.4424e-01 (26,2) 1.0000e+00 (31,2) -2.4523e-02 (88,2) -3.7371e-01 (27,3) 1.0000e+00 (31,3) -3.6613e-02 (89,3) -8.3694e-01 (28,4) 1.3000e+02…
非零(west0479)
Ans = 1.0000e+00 -3.7648e-02 -3.4424e-01 1.0000e+00 -2.4523e-02 -3.7371e-01 1.0000e+00 -3.6613e-02 -8.3694e-01 1.3000e+02…

请注意

使用Ctrl + C为了阻止非零随时上市。

请注意最初nnznzmax默认情况下。也就是说,非零元素的数量等同于分配给非零元素的存储位置的数量。然而,MATLAB®如果将额外的数组元素归零,则不会动态释放内存。将某些矩阵元素的值更改为零将更改的值nnz,但不是nzmax

但是,您可以根据需要向矩阵中添加任意数量的非零元素。你不受原始值的约束nzmax

指数和数值

对于任何矩阵,无论是满矩阵还是稀疏矩阵,都有找到函数返回非零元素的索引和值。它的语法是

[i,j,s] = find(s);

找到返回vector中非零值的行索引,表示向量中的列索引j,以及向量中的非零值本身年代.下面的示例使用找到在稀疏矩阵中定位非零的索引和值。的稀疏的函数使用找到输出,以及矩阵的大小,以重新创建矩阵。

S1 = west0479;[i,j,s] = find(S1);[m,n] = size(S1);S2 =稀疏(i,j,s,m,n);

稀疏矩阵操作中的索引

因为稀疏矩阵是以压缩的稀疏列格式存储的,所以索引到稀疏矩阵的代价与索引到完整矩阵的代价不同。当你只需要改变稀疏矩阵中的几个元素时,这样的代价是可以忽略不计的,所以在这种情况下,使用常规数组索引来重新分配值是正常的:

B = speye(4);[i,j,s] = find(B);(i, j s)
Ans = 1 1 1 2 2 1 3 3 1 4 4 1
B(3,1) = 42;[i,j,s] = find(B);(i, j s)
Ans = 1 1 1 3 1 42 2 2 1 3 3 1 4 4 1
为了存储新的矩阵42(3,1), MATLAB在非零值向量和下标向量中插入额外一行,然后移位所有矩阵值(3,1)

使用线性索引访问或分配大型稀疏矩阵中的元素将失败,如果线性索引超过2 ^ 48-1,这是当前矩阵中允许的元素数量的上限。

S = spalloc(2^30,2^30,2);S(end) = 1
超过了程序允许的最大变量大小。

访问线性下标大于的元素intmax,使用数组索引:

S(2^30,2^30) = 1
S = (1073741824,1073741824

虽然在稀疏矩阵中建立索引以更改单个元素的成本可以忽略不计,但在循环上下文中,它会变得非常缓慢,对于大型矩阵来说。因此,在需要更改许多稀疏矩阵元素的情况下,最好对操作进行向量化,而不是使用循环。例如,考虑一个稀疏单位矩阵:

N = 10000;A = 4*speye(n);
改变元素一个在循环中比类似的向量化操作慢:
tic A(1:n-1,n) = -1;A(n,1:n-1) = -1;toc
运行时间为0.003344秒。
抽搐C(k,n) = -1;C(n,k) = -1;结束toc
运行时间为0.448069秒。
由于MATLAB以压缩稀疏列格式存储稀疏矩阵,因此需要移动多个条目一个在每次循环期间。

为一个稀疏矩阵预分配内存,然后以元素的方式填充它,同样会导致索引到稀疏数组的大量开销:

S1 = spalloc(1000,1000,100000);抽搐;N = 1:100000 I = ceil(1000*rand(1,1));J = cell (1000*rand(1,1));S1(i,j) = rand(1,1);结束toc
运行时间为2.577527秒。

构造索引和值的向量消除了索引到稀疏数组的需要,因此明显更快:

I = ceil(1000*rand(100000,1));J = ceil(1000*rand(100000,1));V = 0 (size(i));N = 1:10万v(N) = rand(1,1);结束抽搐;S2 =稀疏(i,j,v,1000,1000);toc
运行时间为0.017676秒。

因此,最好使用构造函数(如稀疏的spdiags功能。

例如,假设您需要坐标矩阵的稀疏形式C

C 4 0 0 0 1 0 4 0 0 1 0 0 4 0 1 0 1 0 1 0 1 4 1 1 4

函数直接构造五列矩阵稀疏的函数使用行下标、列下标和值的三重组合对:

I = [1 5 2 5 3 5 4 5 1 2 3 4 5]';J = [1 1 2 2 3 3 4 4 5 5 5 5 5 5 5]';S = [4 1 4 1 4 1 4 1 -1 -1 -1 4]';C =稀疏(i,j,s)
C =(1,1) 4(5、1)1(2,2)4(5,2)1(3、3)4(5,3)1(4,4)4(5,4)1(1、5)1(2、5)1(3、5)1(4、5)1 (5,5)4
输出中值的顺序按列反映了底层存储。有关MATLAB如何存储稀疏矩阵的更多信息,请参阅John R. Gilbert, Cleve Moler和Robert Schreiber的文章稀疏矩阵在MATLAB中的设计与实现, (矩阵分析与应用杂志, 13:1, 333-356(1992))。

稀疏矩阵可视化

使用图形格式查看稀疏矩阵中非零元素的分布通常是有用的。MATLAB间谍函数生成稀疏结构的模板视图,其中图上的每个点表示非零数组元素的位置。

例如:

加载所提供的稀疏矩阵west0479是哈维尔-波音(Harwell-Boeing)系列之一。

负载west0479

查看稀疏结构。

间谍(west0479)

图中包含一个轴对象。axis对象包含一个line类型的对象。

另请参阅

相关的话题