n x n
矩阵Y_t
的矩阵递归如下所示:
Y_{t} = A + \sum_{i=1}^{p} B_{i} * Y_{t-i}
给出A和B.
这是我的尝试,但运行缓慢:
Y = zeros(n,n,T); %Going to fill the 3rd dimension for Y_t, t=1:T
Y(:,:,1:p) = initializingY
for t=(p+1):T
Y(:,:,t) = A;
for i=1:p
Y(:,:,t) = Y(:,:,t) + B(:,:,i)*Y(:,:,t-i);
end
end
你能想到一种更有效的方法吗?
答案 0 :(得分:5)
在某些reshaping
之后,您可以使用matrix-multiplication
杀死内部循环。 permuting
,就像这样 -
Y = zeros(n,n,T);
%// Y(:,:,1:p) = initializingY
for t=(p+1):T
Br = reshape(B(:,:,1:p),n,[]);
Yr = reshape(permute(Y(:,:,t-(1:p)),[1 3 2]),[],n);
Y(:,:,t) = A + Br*Yr;
end
答案 1 :(得分:3)
如果不使用巧妙的数学技巧来减少操作次数,最好的方法是优化内存访问。那就是:避免subsref
,增加代码的位置,通过操纵短数组而不是大数组来减少缓存未命中。
n = 50;
T = 1000;
p = 10;
Y = zeros(n,n,T);
B = zeros(n,n,p);
A = rand(n);
for t = 1:p
Y(:,:,t) = rand(n);
B(:,:,t) = rand(n);
end
fprintf('Original attempt: '); tic;
for t=(p+1):T
Y(:,:,t) = A;
for k=1:p
Y(:,:,t) = Y(:,:,t) + B(:,:,k)*Y(:,:,t-k);
end;
end;
toc;
%'This solution was taken from Divakar'
fprintf('Using reshaping: '); tic;
Br = reshape(B(:,:,1:p),n,[]);
for t=(p+1):T
Yr = reshape(permute(Y(:,:,t-(1:p)),[1 3 2]),[],n);
Y(:,:,t) = A + Br*Yr;
end;
toc;
%'proposed solution'
Y = cell(1,T);
B = cell(1,p);
A = rand(n);
for t = 1:p
Y{t} = rand(n);
B{t} = rand(n);
end
fprintf('Using cells: '); tic;
for t=(p+1):T
U = A;
for k=1:p
U = U + B{k}*Y{t-k};
end;
Y{t} = U;
end;
toc;
对于我的示例中给出的设置,对于一台体面的机器(i5 + 4Gb,MATLAB R2012a),我的速度提高了两倍。我很好奇它在你的机器上的表现如何。