【问题标题】:Generate random matrix with eigenvalues生成具有特征值的随机矩阵
【发布时间】:2018-08-11 18:38:23
【问题描述】:

我正在执行以下操作以生成具有特定范围内特征值的随机矩阵:

function mat = randEig(dim, rReal)

    D=diff(rReal).*rand(dim,1)+rReal(1);
    P=rand(dim);
    mat=P*diag(D)/P;

end

但我也希望能够生成具有复杂(共轭)特征值的随机 实数 矩阵。如何做到这一点?相似变换技巧将返回复杂矩阵。

编辑:好的,我设法通过搭载 MATLAB 的 cdf2rdf 函数(基本上是下面的第二个函数)来做到这一点。

function mat = randEig(dim, rangeEig, nComplex)

    if 2*nComplex > dim
         error('Cannot happen');
    end

    if nComplex
        cMat=diff(rangeEig).*rand(dim-2*nComplex,1)+rangeEig(1);
        for k=1:nComplex
            rpart=(diff(rangeEig).*rand(1,1)+rangeEig(1))*ones(2,1);
            ipart=(diff(rangeEig).*rand(1,1)+rangeEig(1))*i;
            ipart=[ipart; -ipart];
            cMat=[cMat; rpart+ipart];
        end
    else
        cMat=diff(rangeEig).*rand(dim,1)+rangeEig(1);
    end

    D=cMat;
    realDform = comp2rdf(diag(D));
    P=rand(dim);
    mat=P*realDform/P;
end


function dd = comp2rdf(d)
    i = find(imag(diag(d))');
    index = i(1:2:length(i));
    if isempty(index)
        dd=d;   
    else   
    if (max(index)==size(d,1)) | any(conj(d(index,index))~=d(index+1,index+1))
      error(message('Complex conjugacy not satisfied'));
    end
    j = sqrt(-1);
    t = eye(length(d));
    twobytwo = [1 1;j -j];
    for i=index
        t(i:i+1,i:i+1) = twobytwo;
    end 
       dd=t*d/t;
    end
end

但是代码很丑,主要是rand被多次调用的方式很烦人)。如果有人想发布一次调用rand 的答案并设法做到这一点,我一定会接受并投票。

【问题讨论】:

  • dim 只是用户想要的方阵的维数,rangeEig 是该矩阵的特征值所在的实线范围,nComplex 是其频谱中复特征值的数量。
  • 我使用circshiftupsampledownsample 管理了一个对rand 的调用。谢谢!
  • Dude 只需使用 dim=10, range=[-10, 0], nComplex=3 例如
  • 顺便说一句,您是否要求在此循环中删除对 rand 的多个调用:for k=1:nComplex?我想我可以矢量化那个循环
  • 我想尽可能减少对rand 的调用。我未指定值的原因是它应该适用于例如 dim=10 和 nComplex=0,1,2,3,4,5....以及 dim=9 和 nComplex=0,1, 2,3,4。如果这就是你正在尝试的,它不是硬编码的事情。实矩阵特征值的复共轭条件必须始终满足。

标签: matlab random


【解决方案1】:

我用这个打了一个电话或两个电话:

function mat = randEig(dim, rangeEig, nComplex)

if 2*nComplex > dim
    error('Cannot happen');
end

if nComplex
    cMat=diff(rangeEig).*rand(2*nComplex,1)+rangeEig(1);
    cPart=cMat(1:nComplex)*i;
    cMat(1:nComplex)=[];
    cPart=upsample(cPart,2);
    cPart=cPart+circshift(-cPart,1);
    cMat=upsample(cMat,2);
    cMat=cMat+circshift(cMat,1);
    cMat=cMat+cPart;
    cMat=[diff(rangeEig).*rand(dim-2*nComplex,1)+rangeEig(1); cMat];
else
    cMat=diff(rangeEig).*rand(dim,1)+rangeEig(1);
end
D=cMat;
realDform = comp2rdf(diag(D));
P=rand(dim);
mat=P*realDform/P;
end


function dd = comp2rdf(d)
i = find(imag(diag(d))');
index = i(1:2:length(i));
if isempty(index)
    dd=d;
else
    if (max(index)==size(d,1)) | any(conj(d(index,index))~=d(index+1,index+1))
        error(message('Complex conjugacy not satisfied'));
    end
    j = sqrt(-1);
    t = eye(length(d));
    twobytwo = [1 1;j -j];
    for i=index
        t(i:i+1,i:i+1) = twobytwo;
    end
    dd=t*d/t;
end
end

如果有人可以通过一个电话或更短/更优雅的代码进行处理,欢迎他们发布答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-26
    • 2015-08-24
    • 2012-11-21
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多