在Matlab中更快的矩阵递归

时间:2015-11-12 14:03:47

标签: performance matlab recursion matrix

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

你能想到一种更有效的方法吗?

2 个答案:

答案 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),我的速度提高了两倍。我很好奇它在你的机器上的表现如何。