Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm MATLAB中超大矩阵的高效乘法_Algorithm_Matlab_Linear Algebra_Octave_Matrix Multiplication - Fatal编程技术网

Algorithm MATLAB中超大矩阵的高效乘法

Algorithm MATLAB中超大矩阵的高效乘法,algorithm,matlab,linear-algebra,octave,matrix-multiplication,Algorithm,Matlab,Linear Algebra,Octave,Matrix Multiplication,我没有足够的内存来简单地创建一个对角的D-by-D矩阵,因为D很大。我不断出现“内存不足”错误 我没有在第一次乘法中执行mxddxd操作,而是执行mxd操作,但我的代码仍然需要很长时间才能运行 有谁能找到一种更有效的方法来执行乘法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(

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

我没有在第一次乘法中执行mxddxd操作,而是执行mxd操作,但我的代码仍然需要很长时间才能运行

有谁能找到一种更有效的方法来执行乘法
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)

也许我有点傻,但是你不能把你的DxD矩阵转换成DxM矩阵(有给定向量的m个副本),然后。*最后两个矩阵,而不是将它们相乘(当然,通常是将第一个矩阵与找到的乘积相乘)?

解决问题的一个方法是使用。下面是一个例子:

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元素,使用函数创建M-by-D矩阵,然后与
A一起使用。

B = repmat(diagB,M,1);   %# Replicate diagB to create an M-by-D matrix
result = (A.'.*B)*A;    %'# An M-by-M result
另一种选择是使用该功能:

  • 因为MATLAB找不到足够大的内存块来容纳整个矩阵,所以会出现“内存不足”的情况。有不同的技术可以避免上述错误

  • 在MATLAB中,显然在大多数情况下不需要编程显式循环,因为可以使用运算符
    *
    。如果使用显式循环进行矩阵乘法,则存在一种加速矩阵乘法的技术,如下所示。它有一个好主意,如何(潜在的大)矩阵可以分裂成更小的矩阵。要在MATLAB中包含这些较小的矩阵,可以使用单元矩阵。更可能的是,系统找到足够的RAM来容纳两个较小的子矩阵,而不是生成的大矩阵


  • 我很困惑。矩阵B应该是D-by-D还是M-by-M?你的图像显示的是前者,但你的代码显示的是后者。另外,你是否在尝试计算A'BA,这会给你一个M-by-M的结果?是的,这就是我试图实现的。我不会创建D x D,因为“内存不足错误”,这很容易。你的解决方案给了我一个“内存不足”的错误,几乎当场我的需要稍长一点,但效果完全相同。它们都是正确的,但是矩阵是巨大的。我的解决方案和gnovice都只需要O(DxM)存储。我不明白为什么我的解决方案是错误的,而他的解决方案是好的。事实上,他的repmat解决方案正是我的(直到乘法的顺序,这并不重要)。谢谢你的回答。为了明确起见,我尝试了您的解决方案,但无法克服“内存不足”错误。如果内存有问题,则首选
    bsxfun
    而不是
    repmat
    ,因为它不会生成复制矩阵。然而,
    bsxfun
    直到Matlab 2006年左右才开始使用……我是一个非常无知的人,一刻也没有想过缓存未命中、循环展开或分支预测,但是谢谢你的邀请reminder@matcheek:将大矩阵拆分为小矩阵的技术可以应用于RAM,与应用于缓存的方式相同。对于您来说,缓存根本不重要,但RAM重要。
    result = bsxfun(@times,A.',diagB)*A;  %'# An M-by-M result