2013-06-19 43 views
5

Tôi có ma trận 6X4 M1 chỉ chứa số không. Tôi cũng có hai mảng 1D Y1Y2 mỗi dải có chiều dài 4. Hai mảng chứa giá trị chỉ mục mong muốn. Bây giờ, tôi muốn thiết lập (chuyển đổi sang 1) các yếu tố của ma trận M1M1(Y1:Y2) bằng 1Lập chỉ mục mảng 2D trong MATLAB

cho ví dụ: Y1=[1 2 2 1]Y2=[3 4 5 3]
sau đó, M1 nên

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

tôi có thể làm điều này bằng cách sử dụng cho vòng lặp. Nhưng có cách nào tối ưu hóa để làm điều đó không? (Tôi dự định sử dụng nhiều ma trận lớn hơn)

Trả lời

6

có thể có oth er kỹ thuật, nhưng điều này sử dụng các hoạt động khôn ngoan yếu tố mà là điên rồ song song.

Một giải pháp rất đơn giản. Cảm ơn @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 

đang quá phức tạp

[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); 
+0

sử dụng tuyệt vời của 'bsxfun' - nhưng bạn có thể làm điều đó mà không cần sử dụng' offsets' – Shai

+0

@shai Vẫn là một lỗi, tôi đang sửa chữa nó. –

+0

một câu trả lời cho câu hỏi của tôi có thể được tìm thấy nếu bạn di chuột qua phần dưới cùng của câu trả lời của tôi ;-) – Shai

8

sử dụng 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 

Một cạm bẫy: Nếu bất kỳ Y2 bằng 6 so với thiết Y2+1 -1 sẽ vượt quá chiều ma trận.
Để khắc phục điều này, bạn có thể thêm hai dòng trước khi thiết đến -1 các yếu tố của M:

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

Một spin-off cho Pavan Yalamanchili's answer sử dụng bsxfun: (di chuột để xem :)

sử dụng bsxfun mà không offsets:
M1 = bsxfun(@ge, (1:size(M1,1))', Y1) & bsxfun(@le, (1:size(M1,1))', Y2);

Các vấn đề liên quan