是否有可能通过例如加速大型稀疏矩阵计算.最佳地放置parantheses?
我要问的是:我可以通过强制Matlab以指定顺序(例如“从右到左”或类似的东西)执行操作来加速以下代码吗?
我有一个稀疏的方形对称矩阵H,它先前已被分解,并且稀疏向量M的长度等于H的维数.我想要做的是以下内容:
编辑:一些额外的信息:H通常是4000×4000. z和c的计算大约进行了4000次,而dVa和dVaComp的计算每4000次循环进行10次,总计40000次. (迭代地解决dVa和dVaComp,其中更新P_mis).
这里M * c * M’将成为具有4个非零元素的稀疏矩阵.在Matlab中:
[L U P] = lu(H); % H is sparse (thus also L, U and P)
% for i = 1:4000 % Just to illustrate
M = sparse([bf bt],1,[1 -1],n,1); % Sparse vector with two non-zero elements in bt and bf
z = -M'*(U \ (L \ (P * M))); % M^t*H^-1*M = a scalar
c = (1/dyp + z)^-1; % dyp is a scalar
% while (iterations < 10 && ~=converged)
dVa = - (U \ (L \ (P * P_mis)));
dVaComp = (U \ (L \ (P * M * c * M' * dVa)));
% Update P_mis etc.
% end while
% end for
并且为了记录:尽管我多次使用H的倒数,但预先计算它并不快.
谢谢=)
最佳答案 有一些事情对我来说并不完全清楚:
>命令M =稀疏([t f],[1 -1],1,n,1);不可能是对的;你说在行t,f和列1,-1上应该有1;第-1列显然不能正确.
>结果dVaComp是一个完整的矩阵,因为它与P_mis相乘,而你说它应该是稀疏的.
暂时搁置这些问题,我看到了一些小的优化:
>您使用inv(H)* M两次,因此您可以预先计算它.
>否定dVa可以移出循环.
>如果您不明确需要dVa,也可以将赋值分配给变量.
>标量的反转意味着将1除以该标量(c的计算).
实现更改,并尝试公平比较(我只使用了40次迭代来保持总时间很小):
%% initialize
clc
N = 4000;
% H is sparse, square, symmetric
H = tril(rand(N));
H(H<0.5) = 0; % roughly half is empty
H = sparse(H+H.');
% M is sparse vector with two non-zero elements.
M = sparse([1 N],[1 1],1, N,1);
% dyp is some scalar
dyp = rand;
% P_mis = full vector
P_mis = rand(N,1);
%% original method
[L, U, P] = lu(H);
tic
for ii = 1:40
z = -M'*(U \ (L \ (P*M)));
c = (1/dyp + z)^-1;
for jj = 1:10
dVa = -(U \ (L \ (P*P_mis)));
dVaComp = (U \ (L \ (P*M * c * M' * dVa)));
end
end
toc
%% new method I
[L,U,P,Q] = lu(H);
tic
for ii = 1:40
invH_M = U\(L\(P*M));
z = -M.'*invH_M;
c = -1/(1/dyp + z);
for jj = 1:10
dVaComp = c * (invH_M*M.') * ( U\(L\(P*P_mis)) );
end
end
toc
这给出了以下结果:
Elapsed time is 60.384734 seconds. % your original method
Elapsed time is 33.074448 seconds. % new method