2010-12-12 187 views
12

由于D很大,我没有足够的内存来简单地创建对角线D-D矩阵。我不断收到'内存不足'错误。MATLAB中非常大的矩阵的高效乘法

不是在第一次乘法中执行M×D×D操作,而是执行M×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) 

alt text

+0

我很困惑。矩阵B应该是D-by-D还是M-by-M?你的形象说前者,但你的代码暗示了后者。 – gnovice 2010-12-12 04:12:15

+0

斑点,现在纠正 – matcheek 2010-12-12 04:21:21

+0

另外,你是否试图计算A'* B * A,这会给你一个M-M的结果? – gnovice 2010-12-12 04:47:38

回答

12

应该解决您的问题的一个选项是使用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-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 
+0

非常感谢,我花了几个小时来到这里 – matcheek 2010-12-12 05:34:19

+2

如果内存是一个问题,'bsxfun'优于'repmat',因为它不生成复制矩阵。然而,'bsxfun'在Matlab 2006之前还没有变得可用...... – shabbychef 2010-12-12 06:59:40

+0

比解释了很多,每天都在学习 – matcheek 2010-12-12 07:10:55

3

也许我有一点这里brainfart的,但不能你把你的DXD矩阵划分成DXM矩阵(其中M份*最后两个矩阵,而不是将它们相乘(然后,当然,通常将第一个矩阵乘以找到的产品数量)?

+0

由于'内存不足错误',我不会创建D x D,那么很容易。您的解决方案几乎在现场发现“内存不足”错误,但需要更长的时间,但完全一样。 他们都是正确的,但矩阵是巨大的。 – matcheek 2010-12-12 04:50:53

+0

我的解决方案和gnovice都只需要O(DxM)存储。我不明白为什么我的解决方案不正确,而他很好。 事实上,他的repmat解决方案完全是我的(达到乘法的顺序,这并不重要)。 – 2010-12-12 06:52:10

+0

感谢您的回答。为了说清楚,我确实尝试了您的解决方案,但无法克服“内存不足”错误。 – matcheek 2010-12-12 07:09:54

3
  1. 由于MATLAB无法找到足够大的内存来容纳整个矩阵,因此您正在“内存不足”。有不同的技术可以避免描述in MATLAB documentation这个错误。

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

+1

我是一个很大的无知,对于缓存未命中,循环展开或分支预测,但感谢提醒 – matcheek 2010-12-12 08:29:58

+0

@matcheek:将大型矩阵拆分为较小矩阵的技术可以应用于RAM,方式与应用于缓存的方式相同。对于你来说,缓存并不重要,但是RAM确实如此。 – Mikhail 2010-12-12 08:39:32