2011-07-01 28 views
8

Tengo una matriz de números enteros, y quiero dividir esta matriz donde viene 0 y una función que me da puntos de división.Dividir una matriz en MATLAB

Ejemplo: matriz: 0 0 0 1 2 4 5 6 6 0 0 0 0 0 22 4 5 6 6 0 0 0 4 4 0

La función debe devolver estos números:

[ 3 10 ;14 20 ;22 25 ] 

Estos números son un índice de inicio y final de números distintos de cero.

+0

@amro - esto se parece más a la inversa de ese problema donde OP está tratando de encontrar islas de valores distintos de cero. – Kev

+0

@Kev: para convertir al otro, es tan simple como agregar 'array = (array == 0);' al inicio (o al revés 'array ~ = 0', dependiendo de qué dirección esté mirando) it) ... – Amro

+0

@amro - cierto, pero no es un duplicado "exacto". – Kev

Respuesta

5

Aquí hay una solución vectorizado simple usando las funciones DIFF y FIND:

>> array = [0 0 0 1 2 4 5 6 6 0 0 0 0 0 22 4 5 6 6 0 0 0 4 4 0]; %# Sample array 
>> edgeArray = diff([0; (array(:) ~= 0); 0]); 
>> indices = [find(edgeArray > 0)-1 find(edgeArray < 0)] 

indices = 

    3 10 
    14 20 
    22 25 

El código anterior funciona creando primero una matriz de columna con los que indican elementos no nulos, rellenando esta matriz con ceros (en caso de que cualquiera de los tramos no nulos se extienda a los bordes de la matriz), y tomando las diferencias entre los elementos. Esto da un vector edgeArray con 1 que indica el inicio de un tramo distinto de cero y -1 que indica el final de un tramo no nulo. Luego se usa la función FIND para obtener los índices de inicio y fin.

Una nota lateral/nitpick: estos no son los índices de inicio y final de los tramos distintos de cero como usted dice. Son técnicamente los índices justo antes de los inicios y justo después de los extremos de los tramos distintos de cero. Usted puede realidad desea que el siguiente en su lugar:

>> indices = [find(edgeArray > 0) find(edgeArray < 0)-1] 

indices = 

    4  9 
    15 19 
    23 24 
2

probar este

a = [0 0 0 1 2 4 5 6 6 0 0 0 0 0 22 4 5 6 6 0 0 0 4 4 0]; 

%#Places where value was zero and then became non-zero 
logicalOn = a(1:end-1)==0 & a(2:end)~=0; 

%#Places where value was non-zero and then became zero 
logicalOff = a(1:end-1)~=0 & a(2:end)==0; 

%#Build a matrix to store the results 
M = zeros(sum(logicalOn),2); 

%#Indices where value was zero and then became non-zero 
[~,indOn] = find(logicalOn); 

%#Indices where value was non-zero and then became zero 
[~,indOff] = find(logicalOff); 

%#We're looking for the zero AFTER the transition happened 
indOff = indOff + 1; 

%#Fill the matrix with results 
M(:,1) = indOn(:); 
M(:,2) = indOff(:); 

%#Display result 
disp(M); 
2

Sobre el tema, pero con una ligera variación:

>>> a= [0 0 0 1 2 4 5 6 6 0 0 0 0 0 22 4 5 6 6 0 0 0 4 4 0]; 
>>> adjust= [0 1]'; 
>>> tmp= reshape(find([0 diff(a== 0)])', 2, []) 
tmp = 
    4 15 23 
    10 20 25 
>>> indices= (tmp- repmat(adjust, 1, size(tmp, 2)))' 
indices = 
    4 9 
    15 19 
    23 24 

Como gnovice ya se señaló en la semántica de posición relacionados con indices, voy Solo agregue que, con esta solución, varios esquemas pueden manejarse de manera muy directa, al calcular indices. Por lo tanto, para su solicitud:

>>> adjust= [1 0]'; 
>>> tmp= reshape(find([0 diff(a== 0)])', 2, []); 
>>> indices= (tmp- repmat(adjust, 1, size(tmp, 2)))' 
indices = 
    3 10 
    14 20 
    22 25