如何在非主对角线中的任何类型的矩阵中插入一般的情况

时间:2014-10-03 16:54:02

标签: matlab matrix

标题可能令人困惑,这是解释自己的一个特例。另外,我不确定你怎么称呼从(1,2)开始的对角线继续前进:(2,3); (3,4)等。非主要的,非主要的对角线,根本不确定。

3x3 case
-1  1 0
-1  0 1
 0 -1 1

4x4 case
-1  1 0 0
-1  0 1 0
-1  0 0 1
 0 -1 1 0
 0 -1 0 1
 0 0 -1 1

因此,如果原始矩阵是4x4(或任何其他大小),我可以制作与第二个示例大小相同的矩阵。我现在必须以这种方式插入-1和1。这意味着如果j = 1,则插入n-1个-1,然后在非主对角线中插入n-1个。完成后,它是相同的但是对于j = 2和下一个非主对角线,依此类推。

事情是,我一直在想循环,并且出现了太多的情况,因为我想要的是能够为任何可能的维度做这个,而不是针对特定情况。

但后来我看到了这篇文章Obtaining opposite diagonal of a matrix in Matlab

答案是:A(s:s-1:end-1)

这似乎是一种更清洁的方式,因为我自己的方式(没有完成,因为我无法计算所有的情况)有太多的条件。使用这样的句子,我可以根据需要选择对角线,插入对象,并根据需要进行多次。

这就留下了插入-1的问题,但我想我可以管理一些东西。

3 个答案:

答案 0 :(得分:2)

似乎您希望获得大小为B的以下矩阵n × (n-1)*n/2

n = 4;

idx = fliplr(fullfact([n n]));
idx(diff(idx')<=0,:) = [];

m = size(idx,1);

B = zeros(m,n);
B(sub2ind(size(B),1:m,idx(:,1)')) = -1;
B(sub2ind(size(B),1:m,idx(:,2)')) = 1;

答案 1 :(得分:1)

方法#1

这是一种矢量化方法,与非矢量化或基于for循环的方法相比,具有更多的内存要求。因此,它可以用于中小型数据集。

基本理念是这样的。以n=4为例,我们采用

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

作为基本构建块,复制它n-1,即3次,然后根据问题的要求删除不应该属于最终输出的行。由于这种性质,此解决方案具有更多内存要求,因为我们需要删除6,8,9案例的行n = 4。但这使我们有机会一次性处理所有事情。

N = n-1; %// minus 1 of the datasize, n
blksz = N*(N+1); %// number of elements in a (n-1)*n blocksize that is replicated

b1 = [-1*ones(N,1) eye(N)] %// Create that special starting (n-1)*n block

idx1 = find(b1~=0) %// find non zero elements for the starting block
idx2 = bsxfun(@plus,idx1,[0:N-1]*(blksz+N)) %// non zero elements for all blocks

b1nzr = repmat(b1(b1~=0),[1 N]) %// elements for all blocks

vald_ind = bsxfun(@le,idx2,[1:N]*blksz) %// positions of valid elements all blocks

mat1 = zeros(N,blksz) %// create an array for all blocks
mat1(idx2(vald_ind)) = b1nzr(vald_ind)  %// put right elements into right places

%// reshape into a 3D array, join/concatenate along dim3
out = reshape(permute(reshape(mat1,N,N+1,[]),[1 3 2]),N*N,[]) 

%// remove rows that are not entertained according to the requirements of problem
out = out(any(out==1,2),:) 

方法#2

这是一个基于循环的代码,如果您必须向自己或仅仅是人员解释它,并且最重要的是在不同的数据量上对性能标准进行很好的扩展,这可能更容易实现。

start_block = [-1*ones(n-1,1) eye(n-1)] %// Create that special starting (n-1)*n block

%// Find starting and ending row indices for each shifted block to be repeated
ends = cumsum([n-1:-1:1]) 
starts = [1 ends(1:end-1)+1]

out = zeros(sum(1:n-1),n) %// setup all zeros array to store output
for k1 = 1:n-1

    %// Put elements from shifted portion of start_block for creating the output
    out(starts(k1):ends(k1),k1:end) = start_block(1:n-k1,1:n-k1+1) 
end

使用n=4,输出 -

out =
    -1     1     0     0
    -1     0     1     0
    -1     0     0     1
     0    -1     1     0
     0    -1     0     1
     0     0    -1     1

答案 2 :(得分:0)

我不知道我是否理解得当,但这就是你要找的东西:

M=rand(5);

k=1; % this is to select the k-th diagonal
D=diag(ones(1,size(M,2)-abs(k)), k);

M(D==1)=-1;

M =

0.9834   -1.0000    0.8402    0.6310    0.0128
0.8963    0.1271   -1.0000    0.3164    0.6054
0.8657    0.6546    0.3788   -1.0000    0.5765
0.8010    0.8640    0.2682    0.4987   -1.0000
0.5550    0.2746    0.1529    0.7386    0.6550