【问题标题】:Scale every row in a sparse matrix by an element of a vector in MATLAB通过 MATLAB 中的向量元素缩放稀疏矩阵中的每一行
【发布时间】:2018-05-06 02:16:08
【问题描述】:

我有一个稀疏矩阵

obj.resOp = sparse(row,col,val); 

和一个包含矩阵中每一行之和的向量

sums = sparse(sum(obj.resOp,2));

现在我想做的是

obj.resOp = obj.resOp ./ sums;

这将缩放矩阵中的每一行,使每一行的行和为 1。

但是在最后一行中,MATLAB 内部似乎从 obj.resOp 构造了一个完整的矩阵,因此我得到了这个错误:

使用错误。/请求的 38849x231827 (17.5GB) 数组超过最大值 数组大小偏好。创建大于此限制的数组可能 花费很长时间并导致 MATLAB 无响应。请参阅数组大小限制或首选项 面板了解更多信息。

对于足够大的矩阵。

理论上,我认为没有必要扩展为完整的矩阵。在保持obj.resOp 的稀疏性的同时,是否有任何我想要实现的 MATLAB 公式?

【问题讨论】:

  • 了解您使用的是哪个版本的 MATLAB 可能很重要?
  • 我使用的是 MATLAB 2017a。
  • obj.resOp = inv(diag(sums)) * obj.resOp;应该给我同样的结果,但是被杀了。不过,这可能是我的向量中的一个错误。
  • sum 中的一些条目为零,这就是上述方法不起作用的原因。修复此问题后,一切正常!不管怎样,谢谢你的建议,@Wolfie

标签: matlab matrix sparse-matrix


【解决方案1】:

等效计算

obj.resOp = inv(diag(sums)) * obj.resOp;

工作顺利。

【讨论】:

  • 除非绝对必要,否则不惜一切代价避免使用inv。众所周知,它容易出错。因为您要找到对角矩阵的逆矩阵,所以结果只是另一个系数为逆矩阵的对角矩阵。因此:inv(diag(sums)) --> diag(1./sums)。本文来自John D. Cook should prove to be enlightening
  • 感谢您的提示。已实施。
【解决方案2】:

您可以使用类似于described in this answer 的方法来做到这一点。

从一些稀疏矩阵开始

% Random sparse matrix: 10 rows, 4 cols, density 20%
S = sprand(10,4, 0.2);

获取行总和,注意sum 从稀疏输入返回一个稀疏矩阵,因此无需额外转换 (docs)。

rowsums = sum(S,2);

查找所有非零索引及其值

[rowidx, colidx, vals] = find(S)

现在根据元素划分创建一个稀疏矩阵

out = sparse(rowidx, colidx, vals./rowsums(rowidx), size(S,1), size(S,2));

【讨论】:

  • 这个解决方案确实比我的快,而且不太容易耗尽内存。
  • 很高兴我能帮上忙,这个方法对我来说是新的太好了,知道它很有效
猜你喜欢
  • 2015-04-22
  • 2017-11-21
  • 2023-03-25
  • 1970-01-01
  • 2012-06-20
  • 2021-06-16
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
相关资源
最近更新 更多