Matlab中带重复元素矩阵的优化运算

Matlab中带重复元素矩阵的优化运算,matlab,matrix,sparse-matrix,Matlab,Matrix,Sparse Matrix,我想得到一个大矩阵(a)的exp(),它的值在不同的索引处重复。为了加速exp()操作,我只对A的唯一值执行它,然后重新组装矩阵。然而,矩阵的重新组装相当缓慢。以下代码提供了一个工作示例: % defintion of a grid gridSp = 5:5:35*5; X = repmat(gridSp,35,1); Z = repmat(gridSp',1,35); % calculation of the distances locMat = [X(:) Z(:)]; dist=sqr

我想得到一个大矩阵(a)的exp(),它的值在不同的索引处重复。为了加速exp()操作,我只对A的唯一值执行它,然后重新组装矩阵。然而,矩阵的重新组装相当缓慢。以下代码提供了一个工作示例:

% defintion of a grid
gridSp = 5:5:35*5;

X = repmat(gridSp,35,1);
Z = repmat(gridSp',1,35);

% calculation of the distances
locMat = [X(:) Z(:)];
dist=sqrt(bsxfun(@minus,locMat(:,1),locMat(:,1)').^2 +...
bsxfun(@minus,locMat(:,2),locMat(:,2)').^2); 

sizeDist = size(dist);
uniqueDist = unique(dist,'stable');
[~, Locb] = ismember(dist,uniqueDist);

nn_A = exp(1i*2*pi*rand(sizeDist(1),100));
H_A = zeros(size(nn_A));

freq = linspace(10^-3,10,100);

psdA = 4096*length(freq).*10.*4.*22.6./((1 + 6.*freq*22.6).^(5/3));

for jj=1:100 
    b = exp(-8.8*uniqueDist*sqrt((freq(jj)/15).^2 + 10^-7));
    b = b.*psdA(jj);
    A = b(Locb);
    droptol = max(A(:))*10^-10;
    if min(A(:))<droptol
        A = sparse(A);
        HH_A = ichol(A,struct('type','ict','shape','lower','droptol',droptol));
    else
        HH_A = chol(A,'lower');
    end
    H_A(:,jj) = HH_A*nn_A(:,jj);
end
以及矩阵到稀疏矩阵的转换

A = sparse(A);
在最后一个for循环中会占用很多时间。有没有更快的方法?有趣的是:

B = A + A;
比以前快多了

A = b(Locb);
我必须比示例中的100次迭代更频繁地执行这些操作

这里是一个压缩版本的代码在要求(如下)


在您的示例中,dist的维数仅为980 x 980,在这种情况下,您最好只执行密集矩阵运算,即

for jj=1:100
   A=exp(jj*dist);
end
这比你想象的快2倍

for jj=1:100 
    b = exp(jj.*uniqueDist);
    A = b(Locb);
end

对于您给出的示例。

希望这里有人能提供一些提示,但我的初步反应是,您的matlab代码非常好,要获得显著的性能改进,唯一的方法是编写一个c程序,并将其编译为mex文件。您的问题看起来很有趣。然而,似乎您的代码比您在文本中所说的做了更多的事情。所以我有两个问题:你确定
exp
-和重新组装是瓶颈吗?如果是的话,你能不能只为那部分提供较短的代码?是的,我确信他们重新组装是瓶颈。缩短的代码发布在上述问题的编辑中。在这个例子中,exp实际上比重新组装要快。在原始代码中,当exp应用于不同的值范围时,重组速度更快。我相信您的算法可能存在数值问题
dist*sqrt((freq(jj)/15)。^2+10^-7)
假设值高达160,但
exp(-8.8*x)
x
的值开始出现数值下溢,低至85。由于这种下溢,生成的矩阵只是稀疏的。
for jj=1:100
   A=exp(jj*dist);
end
for jj=1:100 
    b = exp(jj.*uniqueDist);
    A = b(Locb);
end