【问题标题】:Matlab - convert sparse matrix to complex-sparse matrixMatlab - 将稀疏矩阵转换为复杂稀疏矩阵
【发布时间】:2017-07-02 11:46:36
【问题描述】:

我有稀疏矩阵A,我需要通过将其虚部设置为零来将其转换为复稀疏矩阵。

A = sprand(3,3,0.5);
A_c = complex(A,0);

但是,这会引发一个错误,即 A 应该已满。

使用复杂的错误

实数输入 A 必须是数字、实数和完整的。

有什么变通方法可以实现这一点吗?

【问题讨论】:

  • 这种低效的方式当然是A_c = sparse(complex(full(A)));

标签: matlab


【解决方案1】:

当我第一次回答这个问题时,我没有考虑在 MATLAB 中实现复杂稀疏矩阵的方式。我欺骗自己得到以下答案。

天真的解决方案

您可以将complex() 应用于矩阵的每个元素。

A_c = spfun(@(x)complex(x,0),A)

这里@(x)complex(x,0) 表示一个匿名函数,它应用于矩阵A 的每个元素x,返回一个带有Re=xIm=0 的复数。而spfun 只是返回一个新的稀疏矩阵,该矩阵是通过将我们的匿名函数应用于矩阵A 的非零元素而生成的。

发生的情况是该解决方案返回一个与原始矩阵相同的对象。矩阵A_c占用相同的字节数,等于原矩阵A

>> whos A A_c
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
        A           3x3                         76  double
        A_c         3x3                         76  double

Florian Roemer 的评论让我重新考虑我的答案。

说明

1991 年发表的paper by Gilbert, Moler and Schreiber 中描述了 MATLAB 中稀疏矩阵的表示。

实矩阵表示为按列顺序存储的相应存储类(即双精度或复数)的非零元素的单个向量加上这些元素在其各自列中的索引的整数向量加上一个整数向量新列开始的位置索引。 IE。具有k 非零元素的m*n 稀疏矩阵将占用n*4 + k*12 字节,其中4 字节用于整数,8 字节用于将实数存储为双精度。这是一个 3x3 实稀疏矩阵,有 5 个非零项,占用 (4+5)*4+8*5 = 76 个字节。

一个复杂的稀疏矩阵将有另一个实数数组,用于矩阵的所有非零项的虚部,但前提是至少一个元素具有非零虚部。

考虑

>> B = sprand(3,3,0.5)
B =    
Compressed Column Sparse (rows = 3, cols = 3, nnz = 5 [56%])    
  (1, 1) ->  0.46883
  ....
>> B_c = B ; B_c(1,1) += 1e-100i
B_c =
Compressed Column Sparse (rows = 3, cols = 3, nnz = 5 [56%])
   (1, 1) ->  4.6883e-01 + 1.0000e-100i
    ....

现在我们让 MATLAB 为原始矩阵的每个非零项的虚部分配额外的存储空间,即使只有一个项具有非零虚部。

>> whos B B_c
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
        B           3x3                         76  double
   c    B_c         3x3                        116  double

现在B_c 是一个适当的复杂稀疏矩阵,占据

   (4+5)*4 + 8 * 5 + 8 * 5 = 116 bytes

结论

如果你只需要一个虚部为零的稀疏矩阵,那么对原始矩阵什么都不做。

如果您需要一个实际为复杂条目分配存储空间并带有complex 属性的矩阵,则将一个小的虚值添加到原始矩阵的至少一个非零条目中。

Matlab 备注:我没有在实际的 Matlab 中对此进行测试,但 Octave 对此解决方案非常满意。

【讨论】:

  • 它看起来非常正确,但不知何故,零虚部被截断,并且 A_c 保持“双倍”而不是“双倍,复数”(在 R2014a 和 R2016b 中测试)。也就是说,A_c = spfun(@(x)complex(x,eps),A) 工作正常。
  • @Florian 感谢您的更正。看起来一个复稀疏矩阵被表示为一对实稀疏矩阵,所以每个实稀疏矩阵都完全等价于一个虚部为 0 的复矩阵。 sparse(complex(full(A))) == spfun(@(x)complex(x),A)sparse(complex(full(A))) == A.
  • @Dmitri 这很好用。谢谢!但是,如果我有另一个稀疏矩阵 B 作为虚部 A = sprand(3,3,0.5); B = sprand(3,3,0.5); A_c = complex(A,B);,我该怎么办?
  • @SaravanaKumar 也许,A+B*1i 将是您要求的矩阵。
猜你喜欢
  • 2023-04-10
  • 2021-11-25
  • 2018-01-19
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
  • 1970-01-01
  • 2019-11-14
  • 2020-12-07
相关资源
最近更新 更多