2

我需要编写一个脚本来自动设置一个矩阵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

谢谢

4

3 回答 3

3

通过一些代数操作:

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).');
于 2013-09-12T09:07:01.950 回答
1

更新

性能版本,包括预分配。

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);
于 2013-09-12T07:50:22.297 回答
0

谢谢大家!我将在这里发布我自己的解决方案(虽然没有预先分配)。可能会将其调整为@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
于 2013-09-12T09:43:01.227 回答