【问题标题】:How to set up a matrix with a fixed pattern如何设置具有固定模式的矩阵
【发布时间】:2013-09-12 07:45:10
【问题描述】:

我需要编写一个脚本来自动设置矩阵A。该矩阵的大小与工作区中另一个变量N 的值相关联。一般来说,A 将有N + N*(N-1)/2 行和N 列。

第一个N 行和N 列基本上只是一个对角矩阵,使用diag 很容易设置。

我在设置矩阵的下部时遇到问题。基本上,它需要具有以下形式:

-1  0  0  0
 0 -1  0  0
 0  0 -1  0
 0  0  0 -1
 1 -1  0  0
 1  0 -1  0
 1  0  0 -1
 0  1 -1  0
 0  1  0 -1
 0  0  1 -1

我确定模式很清楚。

如何编写代码以便 Matlab 为 N 的任意值设置此矩阵?

谢谢

【问题讨论】:

    标签: matlab matrix


    【解决方案1】:

    通过一些代数操作:

    L=(N*(N+1)/2):-1:1;
    R=ceil((sqrt(8*L+1)-1)/2);
    A=bsxfun(@eq, N-1:-1:0, R')-bsxfun(@eq, N:-1:1, (L-(R.*(R-1))/2).');
    

    【讨论】:

    • 虽然我个人觉得它更难阅读,但肯定要快一些。
    【解决方案2】:

    更新

    性能版本,包括预分配。

    N=4;
    result = zeros(N*(N+1)/2,N+1);
    t = N;
    endpos = 0;
    for t = N:-1:1 
        result(endpos+1:endpos+t,:) = [zeros(t, N-t) ones(t,1) -eye(t)];
        endpos = endpos + t;
    end
    result = result(:,2:end);
    

    请注意,我已经替换了 while 循环,因为您似乎更喜欢 for


    我也将原件留在这里进行比较:

    给你:

    result = [];
    N = 4;
    t = MaxN;
    while t > 0
        block = [zeros(t, N-t) ones(t,1) -eye(t)];
        result = [result; block];
        t = t-1;
    end
    result = result(:,2:end);
    

    【讨论】:

    • 谢谢!有没有办法通过避免while 循环来做到这一点?
    • @Fayyaadh 将其更改为For 循环并不难,但您希望实现什么? (以及为什么)
    • 我只是希望一切都尽可能地可读和高效。我个人更喜欢for 循环而不是while,我几乎不会在任何代码中使用while 循环,所以我只想使用我自己编写的代码类型。此外,MATLAB 抱怨 result 矩阵未预先分配。
    • 然后您可以使用for N = MaxN:-1:1,但这主要是个人喜好问题。如果您想要更高的效率,您实际上应该 preallocate result 并跟踪您想要将结果放在循环内的位置。 (我将把它作为练习)---我不确定是否可以一起避免循环,但我怀疑它会让你的代码更具可读性。
    • OK 似乎代码并没有完全符合我的要求。将您的示例与N = 4 一起使用,矩阵A 的下部(即在我的OP 中描述的4x4 对角方阵下方)应该是6x4(即N*(N-1)/2xN)但它实际上是@ 987654338@.
    【解决方案3】:

    谢谢大家!我将在这里发布我自己的解决方案(虽然没有预先分配)。可能会将其调整为@Dennis 的解决方案。

    N = max(size(a));
    P = N*(N-1)/2;
    
    A = zeros(N+P,N);
    
    A(1:N,1:N) = diag(-a);
    
    B=[];
    
    for i = N-1:-1:1
        Block = [zeros(i,N-1-i) ones(i,1) -eye(i)];
        B = [B; Block];
        clear Block
    end
    
    A(N+1:end,:) = B;
    clear N P B i
    

    【讨论】:

    • 请注意,对于N = 1000,我的解决方案现在需要大约 8 秒,但如果没有预分配,这将超过 800 秒!
    猜你喜欢
    • 2021-04-28
    • 2016-03-14
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    相关资源
    最近更新 更多