矩阵数组的快速胆甾分解

时间:2014-09-11 12:40:51

标签: arrays matlab

我想知道如何在矩阵数组上执行快速Cholesky分解。假设我有一个pdx矩阵的3x3x1000阵列A,并希望找到这1000个矩阵的cholesky factorzations。我知道我可以很容易地写出像

这样的东西
for n=1:1000
    cl(:,:,n) = chol(A(:,:,n);
end

但是,由于for循环,这是一个相当慢的过程。有没有什么方法可以加快这个速度,避免出现这种情况。完全循环。任何想法都表示赞赏。

我的一个想法是将数组转换为块对角矩阵并对其进行chol因子分解,因此会有一个cholesky因子分解的块矩阵,但我还不知道如何执行此操作而无需创建完整的3000x3000矩阵(这样的矩阵大小也会使程序变慢)。我不熟悉在matlab上使用稀疏矩阵,也许这可能是解决方案之一。

1 个答案:

答案 0 :(得分:1)

似乎确实有可能通过构建一个如你所描述的稀疏矩阵来获得一些计算时间(可能,因为matlab理解这种矩阵的漂亮块结构):

N=10000;
D=3;
A=zeros(D,D,N);
for n=1:N, a=rand(D); A(:,:,n)=a'*a; end

tic
cl=zeros(D,D,N);
for n=1:N, cl(:,:,n)=chol(A(:,:,n)); end
toc
% Elapsed time is 0.0919061 seconds.

B=zeros(D*N);
for n=1:N, B(D*(n-1)+1:D*(n-1)+D,D*(n-1)+1:D*(n-1)+D)=A(:,:,n); end
C=sparse(B);
tic, cl2 = chol(C); toc
% Elapsed time is 0.006457 seconds.

现在的问题是如何构造稀疏矩阵C.如果D和N更大,上面描述的方法非常慢并且需要大量内存(我想,在你的情况下,D和N大于你的例)。一般来说,要在matlab中构造稀疏矩阵,你必须指定(1)它的维度,即你的情况下的DN x DN(2)所有非零元素使用数组rowinds,colinds,values(都是相同的长度),这样C (rowinds(k),colinds(k))= values(k),即

values = A(:);
C=sparse(rowinds,colinds,values,D*N,D*N);

问题是如何构造数组rowinds和colinds,在你的情况下看起来像rowinds = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 ... DN DN DN]和colinds = [1 2 3 1 2 3 1 2 3 4 5 6 4 5 6 4 5 6 7 8 9 7 8 9 ... DN-2 DN-1 DN]。这是一个可能的解决方案

tic,
temp = repmat(1:D*N,D,1); rowinds = temp(:);
cols = zeros(D,D*N);
for j=1:D
  tempj = repmat(j:D:D*N-D+j,D,1); cols(j,:)=tempj(:)';
end
colinds=cols(:);
C=sparse(rowinds,colinds,A(:),D*N,D*N);
toc
% Elapsed time is 0.017159 seconds.
tic,
cl2 = chol(C);
toc
% Elapsed time is 0.006926 seconds.

我相信,应该有一种更快的方法来构建索引数组。