use*_*404 5 matlab matrix matrix-indexing
我有一个M1只包含0 的6X4矩阵.我还有两个1D数组Y1,Y2每个数组的长度为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
Run Code Online (Sandbox Code Playgroud)
我可以使用for循环来做到这一点.但有没有优化的方法呢?(我打算使用更大的矩阵)
用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
Run Code Online (Sandbox Code Playgroud)
陷阱:
如果任何Y2等于6而不是设置Y2+1为-1将超过矩阵维度.
要解决此问题,您可以在将M的元素设置为-1之前添加两行:
>> cols = 1:szM(2);
>> sel = Y2 < szM(1);
>> M1( sub2ind( szM, Y2(sel)+1, cols(sel) ) ) = -1
Run Code Online (Sandbox Code Playgroud)
Pavan Yalamanchili的答案分拆使用bsxfun:(悬停看:)
bsxfun没有使用offsets:
M1 = bsxfun( @ge, (1:size(M1,1))', Y1 ) & bsxfun( @le, (1:size(M1,1))', Y2 );
可能还有其他技术,但这使用了疯狂并行的元素操作.
一个非常简单的解决方 谢谢@ 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
Run Code Online (Sandbox Code Playgroud)
不必要的复杂代码
[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);
Run Code Online (Sandbox Code Playgroud)