matlab中高效的密集对角矩阵生成

时间:2015-03-18 14:30:28

标签: algorithm matlab matrix

给定一个复杂的数组data,我需要以

的形式构造一个带对角矩阵

enter image description here

使用matlab或python,其中*表示复共轭。现在我使用diag(data(k)*ones(1,n-k),k)来获得第k个对角线,然后将其置于循环中,该循环遍历k并同时对负k进行共轭,然后取总和。但是,这是在另一个循环中,并且分析显示此过程需要很长时间。矩阵不稀疏并且非常大(~2000x2000)。还有另一种有效实现这一目标的方法吗?它与this question有些相关,也许我可以在该问题中定义aa = [ data(n)^*, data(n-1)^*, ..., data(0), data(1), ...],但我们非常感谢更清晰的方法。此外,我的情况比链接问题更对称,因此可能有更好的解决方案。

我的代码的MWE,耗时约170秒。在我的电脑上运行:

tn=2000;
ats=randn(1,tn)+1j*randn(1,tn);

cm=0;
for jx=-tn+1:tn-1
    if jx>=0
        cm=cm+diag(ats(jx+1)*ones(1,tn-abs(jx)),jx);
    else
        cm=cm+diag(conj(ats(-jx+1))*ones(1,tn-abs(jx)),jx);
    end
end

2 个答案:

答案 0 :(得分:3)

这可能会解决它 -

%// Length of input data
N = numel(data)

%// Conjugate of input data
cdata = conj(data) 

%// Circulating indices
idx = mod(bsxfun(@plus,[N:-1:1]',0:N-1),N)+1 %//'

%// Fill upper triangular part with given data and lower triangular with 
%// conjugate data. The first element of data going into the main diagonal.
out = triu(data(idx)) + tril(cdata(idx.'),-1) 

示例运行 -

data =
   0.1925 + 0.8901i
   0.8126 + 0.9481i
   0.1138 + 0.3276i
   0.0469 + 0.4714i

out =
   0.1925 + 0.8901i   0.8126 + 0.9481i   0.1138 + 0.3276i   0.0469 + 0.4714i
   0.8126 - 0.9481i   0.1925 + 0.8901i   0.8126 + 0.9481i   0.1138 + 0.3276i
   0.1138 - 0.3276i   0.8126 - 0.9481i   0.1925 + 0.8901i   0.8126 + 0.9481i
   0.0469 - 0.4714i   0.1138 - 0.3276i   0.8126 - 0.9481i   0.1925 + 0.8901i

答案 1 :(得分:3)

使用linked question中提供的方法:

a = [conj(data(end:-1:2)), data];
n = (numel(a)+1)/2;
A = a(bsxfun(@minus, n+1:n+n, (1:n).'));