2016-07-11 1 views
1

Например, у меня есть матрица 4x4экстракт элементов между двумя числом от матрицы/вектор

A = [1, 2, 3, 4; 
     2, 1, 4, 3; 
     1, 2, 4, 3; 
     4, 1, 2, 3;]; 

Для каждой строки, я хочу, чтобы извлечь элементы между 1 и 3 (предположим, что матрица всегда имеет некоторые элементы между 1 и 3, а 1 всегда до 3). Например, возвращать ячейку, как [{2}, {4}, {2,4}, {2}], или даже лучше с матрицей

B= [0, 1, 0, 0; 
    0, 0, 0, 1; 
    0, 1, 0, 1; 
    0, 1, 0, 0;]; 

Теперь я делаю петлю для каждой строки, найти индекс 1 и 3, а затем установить индекс между ними равен нулю, т.е.

B = zeros(4,4); 
    for i = 1 : size(A,1) 
     ind1 = find(A(i,:) ==1); 
     ind2 = find(A(i,:) ==3); 
     B(i, A(i,ind1+1:ind2-1)) = 1; 
    end 

Любой простой способ генерировать эту матрицу B или только клетку? Любое предложение приветствуется.

+1

Я не udnerstand, как между определенными. вы имеете в виду точку, где вы можете найти '[1 2 3]'? Я не понимаю третий ряд 'B'. –

+1

, а также четвертый, я бы сказал – shamalaia

+2

GameOfThrows's B ​​кажется мне правильным – shamalaia

ответ

4

Хорошо, это не может быть проще решение, но это удалить петлю, поэтому она должна быть вычислительно быстрее:

Идея заключается в том, вместо того, чтобы пытаться найти число между 1 и 3, и установить их 1, я собираюсь найти номера за пределами 1 и 3 и установите те, 0:

B=zeros(4,4); 
B(A == 1) = 1; 
B(A == 3) = 1; 
C = cumsum(B')'; 
B(C>=2) =1; 
B(C< 1) =1; 

%finally you want to invert this: 
B = (B-1)*-1; 

>> B = 

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

========== Эта часть относится после второго EDIT ======= ===

D = A.*B % this seems to be the cell indexes you are after? 

D = 

0  2  0  0 
0  0  4  0 
0  2  4  0 
0  0  2  0 

E = zeros(4,4); 
for t = 1:size(A,1) 
    E(t,D(t,D(t,:)>0)) = 1; %This re-applies the index numbers and create a new index matrix through a loop........ 
    %or you can use E(t,D(t,~~D(t,:))) = 1 to same effect, Thanks to @Dev-iL 
end 


>> E = 

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

Это даст вам индексы элементов между 1 и 3 для A, затем вы можете использовать логические индексы для поиска нужных номеров ячеек.

+1

Но этот B отличается от OPs B –

+0

@AnderBiguri, потому что он сделал A. * B в конце, позвольте мне положить это. – GameOfThrows

+1

Но ... Это все еще отличается от того, что показывает OP на своем посту, rigth? (он был отредактирован, теперь я вижу) –

2

Мое решение не сильно отличается от того, что уже было предложено, но оно имеет bsxfun, поэтому я говорю - почему бы и нет? :)

function B = q38307616 

A = [1, 2, 3, 4; 
    2, 1, 4, 3; 
    1, 2, 4, 3; 
    4, 1, 2, 3;]; 

At = A.'; 

tmp = arrayfun(@colon,find(At==1)+1,find(At==3)-1,'UniformOutput',false); 
% [tmp{:}] gives us the indices of the elements we should be considering 

B = 0*A; %preallocation 
for ind1 = 1: numel(tmp) 
    B(ind1,:) = sum(bsxfun(@eq,At(tmp{ind1}).',1:4),1); %1:4 are the allowable values 
end 

«Бонус»: еще один способ получения логической карты элементов между 1 и 3 на каждой строке, которая идентична GameOfThrows'B, является:

tmp2 = reshape(full(sparse(~~[tmp{:}],[tmp{:}],~~[tmp{:}],1,numel(A)).'),size(A)); 

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

  • Нет связанных вопросов^_^