2013-06-19 2 views
5

У меня есть матрица 6X4 M1, содержащая только нули. У меня также есть два массива 1D Y1 и Y2 каждый с длиной 4. Два массива содержат требуемые значения индекса. Теперь я хочу, чтобы установить (преобразовать в 1) элементы матрицы M1 таким образом, что M1(Y1:Y2) равно 1Индексирование 2D-массива в matlab

для бывших: 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 

я могу сделайте это, используя для цикла. Но есть ли оптимизированный способ сделать это? (Я намерен использовать гораздо большие матрицы)

ответ

6

Там может быть дру er, но это использует элементарные операции, которые безумно параллельны.

Очень простое решение. Благодаря @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); 
+0

большое использование 'bsxfun' - но вы можете сделать это без использования' offsets' – Shai

+0

@shai Существует еще ошибка, я фиксируя Это. –

+0

ответ на мой вопрос можно найти, если вы наведите указатель на нижнюю часть моего ответа ;-) – Shai

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 превысит матрицу размерности.
Чтобы исправить это, вы можете добавить две строки перед установкой -1 элементов М:

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

Спин-офф за Pavan Yalamanchili's answer с помощью bsxfun: (парение, чтобы увидеть :)

используя bsxfun без offsets:
M1 = bsxfun(@ge, (1:size(M1,1))', Y1) & bsxfun(@le, (1:size(M1,1))', Y2);

Смежные вопросы