【问题标题】:Efficient multiplication of very large matrices in MATLABMATLAB 中超大矩阵的高效乘法
【发布时间】:2023-03-27 05:23:01
【问题描述】:

我没有足够的内存来简单地创建一个对角 D-by-D 矩阵,因为 D 很大。我不断收到“内存不足”错误。

我没有在第一次乘法中执行 M x D x D 运算,而是执行 M x D 运算,但我的代码仍然需要很长时间才能运行。

谁能找到更有效的方法来执行乘法A'*B*A?到目前为止,这是我尝试过的:

D=20000
M=25

A = floor(rand(D,M)*10);
B = floor(rand(1,D)*10);

for i=1:D
    for j=1:M
        result(i,j) = A(i,j) * B(1,j);
    end
end    

manual = result * A';
auto = A*diag(B)*A';
isequal(manual,auto)

【问题讨论】:

  • 我很困惑。矩阵 B 应该是 D-by-D 还是 M-by-M?您的图片显示的是前者,但您的代码显示的是后者。
  • 另外,您是否尝试计算 A'BA,这会给您一个 M×M 结果?
  • 是的,这就是我想要实现的目标

标签: algorithm matlab linear-algebra octave matrix-multiplication


【解决方案1】:

也许我在这里有点脑残,但你不能把你的 DxD 矩阵变成一个 DxM 矩阵(你给定向量的 M 个副本)然后 .* 最后两个矩阵而不是将它们相乘(当然,通常将第一个乘以找到的产品数量)?

【讨论】:

  • 我没有创建 D x D 因为“内存不足错误”,那会很容易。您的解决方案几乎在现场给了我一个“内存不足”错误,我的需要更长的时间,但效果完全相同。它们都是正确的,但是矩阵很大。
  • 我的解决方案和 gnovice 都只需要 O(DxM) 存储。我不明白为什么我的解决方案不正确,而他的解决方案很好。事实上,他的 repmat 解决方案正是我的(直到乘法的顺序,这无关紧要)。
  • 感谢您的回答。为了清楚起见,我确实尝试了您的解决方案,但无法克服“内存不足”错误。
【解决方案2】:

应该解决您的问题的一个选项是使用sparse matrices。这是一个例子:

D = 20000;
M = 25;
A = floor(rand(D,M).*10);    %# A D-by-M matrix
diagB = rand(1,D).*10;       %# Main diagonal of B
B = sparse(1:D,1:D,diagB);   %# A sparse D-by-D diagonal matrix
result = (A.'*B)*A;         %'# An M-by-M result

另一种选择是沿B 的主对角线复制 D 元素,以使用函数 REPMAT 创建 M-by-D 矩阵,然后使用 element-wise multiplicationA.'

B = repmat(diagB,M,1);   %# Replicate diagB to create an M-by-D matrix
result = (A.'.*B)*A;    %'# An M-by-M result

还有一个选择是使用函数BSXFUN

result = bsxfun(@times,A.',diagB)*A;  %'# An M-by-M result

【讨论】:

  • 如果内存是个问题,bsxfunrepmat 更受欢迎,因为它不会生成复制矩阵。然而,bsxfun 直到 Matlab 2006 年左右才可用......
【解决方案3】:
  1. 您正在“内存不足”,因为 MATLAB 找不到足够大的内存块来容纳整个矩阵。 in MATLAB documentation 描述了不同的技术来避免此错误。

  2. 在 MATLAB 中,您显然不需要在大多数情况下编写显式循环,因为您可以使用运算符 *。如果使用显式循环完成矩阵乘法,则存在一种加速矩阵乘法的技术,这里是an example in C#。它很好地了解如何将(可能很大的)矩阵拆分为更小的矩阵。要在 MATLAB 中包含这些较小的矩阵,您可以使用单元矩阵。系统更有可能找到足够的 RAM 来容纳两个较小的子矩阵,然后是生成的大矩阵。

【讨论】:

  • 我是个大笨蛋,暂时没有考虑过缓存未命中、循环展开或分支预测,但感谢您的提醒
  • @matcheek:将大矩阵拆分为较小矩阵的技术可以应用于 RAM,就像应用于缓存一样。对你来说,缓存根本不重要,但 RAM 确实如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 2014-02-25
相关资源
最近更新 更多