标题可能令人困惑,这是解释自己的一个特例。另外,我不确定你怎么称呼从(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的问题,但我想我可以管理一些东西。
答案 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