5

我有一个M1只包含零的 6X4 矩阵。我还有两个一维数组Y1Y2每个数组的长度为 4。这两个数组包含所需的索引值。现在,我想设置(转换为 1)矩阵的元素,M1使其 M1(Y1:Y2)等于 1

例如:Y1=[1 2 2 1]然后Y2=[3 4 5 3]
M1应该是

 1 0 0 1
 1 1 1 1 
 1 1 1 1
 0 1 1 0
 0 0 1 0
 0 0 0 0

我可以使用 for 循环来做到这一点。但是有没有优化的方法呢?(我打算使用更大的矩阵)

4

2 回答 2

8

使用cumsum

>> szM = size(M1);
>> M1( sub2ind( szM, Y1, 1:szM(2) ) ) = 1
M1 =
 1     0     0     1
 0     1     1     0
 0     0     0     0
 0     0     0     0
 0     0     0     0
 0     0     0     0
>> M1( sub2ind( szM, Y2+1, 1:szM(2) ) ) = -1
M1 =
 1     0     0     1
 0     1     1     0
 0     0     0     0
-1     0     0    -1
 0    -1     0     0
 0     0    -1     0
>> M = cumsum(M,1)
M =
 1     0     0     1
 1     1     1     1
 1     1     1     1
 0     1     1     0
 0     0     1     0
 0     0     0     0

一个陷阱: 如果任何一个Y2等于 6,则设置Y2+1为 -1 将超过矩阵维度。
要解决此问题,您可以在将 M 的元素设置为 -1 之前添加两行:

>> cols = 1:szM(2);
>> sel = Y2 < szM(1);
>> M1( sub2ind( szM, Y2(sel)+1, cols(sel) ) ) = -1

Pavan Yalamanchili 的答案的衍生产品bsxfun:(悬停查看:)

bsxfun不使用offsets
M1 = bsxfun( @ge, (1:size(M1,1))', Y1 ) & bsxfun( @le, (1:size(M1,1))', Y2 );

于 2013-06-19T07:28:05.707 回答
6

可能还有其他技术,但这使用了非常并行的元素明智操作。

一个非常简单的解决方案。谢谢@Shai

>> [rows, cols] = size(M);
>> Y1=[1 2 2 1]; Y2=[3 4 5 3]; 
>> M = bsxfun(@ge, (1:rows)', Y1) & bsxfun(@le, (1:rows)', Y2)
M =
     1     0     0     1
     1     1     1     1
     1     1     1     1
     0     1     1     0
     0     0     1     0
     0     0     0     0

不必要的复杂代码

[rows, cols] = size(M);
offsets = ((1 : cols) - 1) * rows
Y1 = offsets + Y1;
Y2 = offsets + Y2;

M = reshape(1:numel(M), rows, cols);
M = bsxfun(@ge, M, Y1) & bsxfun(@le, M, Y2);
于 2013-06-19T07:33:47.407 回答