不,那根本不是稀疏矩阵。您误解了稀疏矩阵何时有用。我们这些经常使用它们的人会说矩阵并不是真正稀疏的,除非它的密度小于 1%。甚至那个密度也不是很稀疏!
稀疏矩阵在使用时有额外的簿记,因为现在 MATLAB 基本上需要担心非零在哪里。因此,如果您制作一个本质上是密集矩阵的矩阵,并假装它是稀疏的,那么您就违背了该工具的价值。
让我们做一两个比较。首先,一个完全密集的矩阵。我将使用来自文件交换的 Steve Eddins timeit 工具。这可以很好地估计花费的时间,并且不需要显式循环。
A = rand(1000);
As = sparse(A);
b = rand(1000,1);
whos A As
Name Size Bytes Class Attributes
A 1000x1000 8000000 double
As 1000x1000 16008008 double sparse
看到完全密集矩阵比稀疏矩阵占用的空间要少得多。
timeit(@() A*b)
ans =
0.00039474
timeit(@() As*b)
ans =
0.0023663
简单乘法中稀疏矩阵的开销太大了。
As = sprand(1000,1000,.5);
A = full(As);
b = rand(1000,1);
whos A As
Name Size Bytes Class Attributes
A 1000x1000 8000000 double
As 1000x1000 6303448 double sparse
在这里,这两个矩阵几乎没有显示稀疏版本的大小减少。因此,就所消耗的空间而言,称其为稀疏是浪费时间。同样,正如您发现的那样,乘法所花费的时间仍然不是收益。
timeit(@() A*b)
ans =
0.00027594
timeit(@() As*b)
ans =
0.0005011
但是,当矩阵更接近我在稀疏性方面的建议时会发生什么?
As = sprand(1000,1000,.01);
A = full(As);
b = rand(1000,1);
whos A As
Name Size Bytes Class Attributes
A 1000x1000 8000000 double
As 1000x1000 167176 double sparse
timeit(@() A*b)
ans =
0.00023629
timeit(@() As*b)
ans =
5.3167e-05
好的,所以现在这节省了一些空间。还有一些严肃的时间。
但实际上,乘法的时间并不是我们使用稀疏矩阵的原因。求解线性方程组所需的时间使我们使用稀疏矩阵。这可以节省大量资金,使用完整矩阵基本上无法解决问题。我的一个常见问题可能涉及 40000x40000 矩阵,密度可能为 0.02%。我会花几天时间等待完整版完成,但在这种情况下,只需几秒钟即可完成稀疏解决。
例如,考虑 gridfit,这是我在文件交换中的一个功能。它从分散的数据创建表面。在此示例中,该工具将需要求解具有 40000 个未知数的线性方程组。
timeit(@() gridfit(rand(100,1),rand(100,1),rand(100,1),linspace(0,1,200),linspace(0,1,200)))
ans =
0.83624
所以对于一切,包括建立方程组,只用了不到 1 秒。
它解决的(在这种情况下,非方形)线性系统非常稀疏。
whos A
Name Size Bytes Class Attributes
A 80100x40000 4126408 double sparse
它有多稀疏?
nnz(A)
ans =
237900
nnz(A)/40000
ans =
5.9475
所以平均而言,每行只有 5.9475 个非零,有 40000 列。而且我们没有时间用那个系统来做一个完整的线性求解。至少我没有任何尝试的欲望。