Matlab - Attempted to acces numel

 
Vista:
Imágen de perfil de Sinc90

Attempted to acces numel

Publicado por Sinc90 (3 intervenciones) el 05/04/2018 16:53:56
Hola, tengo un problema en mi código que me está comiendo la cabeza y no sé por qué está pasando.

Como veréis más abajo, estoy usando la función findpeaks para encontrar los picos en una señal. Además, a partir de la diferencia entre picos consecutivos, estoy intentando que, si se cumple que el tiempo entre ambos está dentro de 50 ms, se borre el pico de menor amplitud.

El problema aparece cuando intento recorrer el vector diff y comparar los valores de los picos a la vez, ya que por lo visto exceden del tamaño del mismo.

Código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
%% Rechazo de picos adicionales en intervalos de 50ms
 
T_int = 0.05;  % Intervalo de tiempo de 50ms
m_int = round(fs*T_int); % Muestras en 50ms
 
[pks,locs] = findpeaks(P_t);
diff = diff(locs); % Distancia entre picos consecutivos
 
e = 0.2;  % +/- 0.2. Para hacer coincidir valores de picos cuyos valores son aproximados
inc = 0.1;
 
for w = 1:length(diff)
    if diff(w) <= m_int
        if pks(w) < pks(w+1)
            pks(w) = [];
            locs(w) = [];
        else
            pks(w+1) = [];
            locs(w+1) = [];
        end
    end
end
 
x = 0:1/fs*N/2:(length(P_t)-1)*1/fs*N/2;
x_peaks = x(locs);
figure
plot(x,P_t, x_peaks,pks,'pg');
xlim([0,5]);
grid

P.D.: Es posible que el código sea mejorable, es una primera aproximación a lo que quiero conseguir.

Muchas gracias de antemano y cualquier duda sobre el código no olviden en preguntármelo.

Aquí el error:
21212
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Daniel
Val: 269
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

Attempted to acces numel

Publicado por Daniel (264 intervenciones) el 06/04/2018 00:41:11
Hay varias cosas para cambiar. Primero y principal cuando pones

1
2
pks(w) = [];
locs(w) = [];
o
1
2
pks(w+1) = [];
locs(w+1) = [];

Supón que originalmente,luego de calcular findpeaks, pks es igual a [1 7 4 7 10 8] y su longitud es por tanto 6 y el ciclo for va de 1 a 5.

considera que w=4 y se cumple que los picos 4 y 5 estan dentro de rango de los 50 ms entonces segun tu codigo hay que eliminar el pico numero 4 (es decir el valor 7) entonces si pones pks(4) = []; el nuevo vector pks= [1 7 4 10 8], con lo cual cambió el numero de elementos de vector pks pero el ciclo ahora debe tomar el valor w=5 que corresponde al pks(5)=8. Es decir que te salteaste el valor 10 y que en algun momento el ciclo va a fallar, ademas de que ahora w ya no se corresponde con el orden de los picos.
Cada vez que eliminas un punto de pks cambia la asignacion:
originalmente pks(5) era 10, ahora pks(5)=8
originalmente pks(6) era 8, ahora pks(6) esta fuera del rango del vector pks (que es el error que te marca)

Hay varias formas de arreglar esto, pero la idea general es NO CAMBIAR EL VECTOR PKS (ni LOCS) HASTA TERMINAR EL CICLO

Para esto puedes guardar el un vector auxiliar las posiciones que deseas eliminar y luego eliminarlas cuando terminas el ciclo.

si luego del ciclo aux=[3 5] puedes ponerlo:

1
2
3
4
5
6
7
8
9
pks=[1 7 4 7 10 8]
pks =
     1     7     4     7    10     8
>> aux=[3 5]
aux =
     3     5
>> pks(aux)=[]
pks =
     1     7     7     8


Hay algunos detalles mas en el codigo que dependen un poco de la P_t que deberas evaluar que criterio tomar si hace falta:
que hacer si hay mas de dos picos en el intervalo de 50 ms
que hacer si originalmente hay por ejemplo tres picos que difieren temporalmente 40 ms entre si (no son tres picos dentro de los 50 ms) y yo elimino el pico central...

Comentanos como te fue

Saludos

Daniel

Si necesitas algo mas especifico carga los datos de P_t, fs, N ya que sino es dificil ser mas concreto
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Sinc90

Attempted to acces numel

Publicado por Sinc90 (3 intervenciones) el 06/04/2018 13:52:19
Hola Daniel, antes de nada gracias por la rápida respuesta.

He estado toqueteando el código para implementar lo que me dijiste y cuando intento borrar las variables introducidas en el vector aux (después del bucle) me sale un error informando de que los valores deben ser reales o enteros. A expensas de ello te dejo los valores de P_t, N y fs como me dijiste.

P.D.: Como verá, en el vector P_t se encuentran muchas variables a 0, esto es debido al haberle implementado un threshold a la señal para eliminar los picos de menor amplitud formados por ruido.

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Daniel
Val: 269
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

Attempted to acces numel

Publicado por Daniel (264 intervenciones) el 06/04/2018 22:39:13
Prueba con este codigo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
% Rechazo de picos adicionales en intervalos de 50ms
clc
clear
load('matlab.mat','P_t','fs','N')
 
T_int = 0.05;  % Intervalo de tiempo de 50ms
m_int = round(fs*T_int); % Muestras en 50ms
 
[pks,locs] = findpeaks(P_t);
diferencia = diff(locs,1,2); % Distancia entre picos consecutivos
disp(length(locs))
e = 0.2;  % +/- 0.2. Para hacer coincidir valores de picos cuyos valores son aproximados
inc = 0.1;
w=1;
 
x = 0:1/fs*N/2:(length(P_t)-1)*1/fs*N/2;
plot(x,P_t),hold on
plot(x(locs),pks,'sk');
 
while w <(length(diferencia))
    if diferencia(w) <= m_int
        if pks(w) < pks(w+1)
            pks(w) = nan;
            locs(w) = nan;
        else
            pks(w+1) = nan;
            locs(w+1) = nan;
            w=w+1;
        end
 
    end
    w=w+1;
end
 
 
x_peaks = locs(not(isnan(locs)));
y_peaks = pks(not(isnan(pks)));
plot(x(x_peaks),y_peaks,'pg');
legend({'Señal Original','Total de picos detectados','Picos luego del filtro'})
grid

Comentanos como te fue

Saludos

Daniel
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de Sinc90

Attempted to acces numel

Publicado por Sinc90 (3 intervenciones) el 07/04/2018 18:03:20
Hola Daniel,

En efecto algo así era lo que pretendía conseguir como una primera aproximación. Ahora faltaría mejorarlo para conseguir el propósito que buscaba.

Muchas gracias por su ayuda,

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar