Matlab - Optimización de código(MATLAB)

 
Vista:

Optimización de código(MATLAB)

Publicado por Carlos María (5 intervenciones) el 18/02/2019 11:41:29
Buenos días,

Estoy programando un código para ver si el modelo matemático que he construido se asemeja a lo que hace el código que adjunto.

Me gustaría optimizar el código ya que necesito un numero elevado de simulaciones 10^12-10^14 para verificar el modelo. Os adjunto el código por si me podéis ayudar (con 1000 simulaciones).

Muchas gracias.

Saludos.

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
41
%%Comienzo del código%%
 
n=32;
 
m=32;
 
alfa=7;
 
ncheck=min(alfa+4,n);
 
nsim=1000;
 
z=2;
s=2;
    for j= 1:nsim
 
        ne=zeros(1,n);
 
        vals=ceil(rand(1,n)*m);
 
        counts=zeros(1,m);
 
        for i=1:n
            counts(vals(i))=counts(vals(i))+1;
        end
 
        for i=alfa:ncheck
 
            ne(i)=ne(i)+length(find(counts==(i-1)));
        end
 
        if sum(ne(alfa+1:ncheck))>=s
            z=z+1;
 
        end
 
    end
 
    sim=z/nsim
 
%%Fin de Código%%
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
sin imagen de perfil
Val: 918
Bronce
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

Optimización de código(MATLAB)

Publicado por Daniel (354 intervenciones) el 18/02/2019 13:53:12
Hola,

Hay dos cosas rápidas que pueden mejorar el rendimiento considerablemente.

1. Eliminar los bucles for que no son necesarios, por ejemplo, no es necesario iterar sobre counts, sino que con esta línea se obtiene lo mismo más rápido. En lugar de

1
2
3
for i=1:n
    counts(vals(i))=counts(vals(i))+1;
end

usa

1
counts(vals) = counts(vals) + 1;

2. Puedes sumar los verdaderos en una condición lógica en lugar de usar find. En lugar de

1
2
3
for i=alfa:ncheck
    ne(i)=ne(i)+length(find(counts==(i-1)));
end

usa

1
2
3
for i=alfa:ncheck
    ne(i)=ne(i)+sum(counts==(i-1));
end

Saludos,
Daniel Rodríguez.
Analytics Lane
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

Optimización de código(MATLAB)

Publicado por Carlos (5 intervenciones) el 18/02/2019 14:38:55
Gracias por tu respuesta.

Hice lo que comentaste y el código tarda más en ejecutarse :S.

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
sin imagen de perfil
Val: 918
Bronce
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

Optimización de código(MATLAB)

Publicado por Daniel (354 intervenciones) el 18/02/2019 19:36:06
Hola ,

Aplica únicamente el punto 2. No me había fijado que en vals puede tener valores duplicados, en tal caso el punto 1 es incorrecto y más lento que el bucle for.

Saludos,
Daniel Rodríguez Pérez.
Analytics Lane
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

Optimización de código(MATLAB)

Publicado por Carlos (5 intervenciones) el 18/02/2019 19:58:14
Gracias por tu comentario de nuevo, pero sigue sin mejorar el tiempo de ejecución.

Yo me refería a si existía algún tipo de código equivalente sin bucles, por que creo que lo que provoca tanto tiempo de iteraciones el primer bucle.

Reitero mis gracias.

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
sin imagen de perfil
Val: 918
Bronce
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

Optimización de código(MATLAB)

Publicado por Daniel (354 intervenciones) el 18/02/2019 22:31:41
Hola,

Realmente la mejora 2 aumenta un 25% el tiempo de ejecución. Pero es necesario subir el número de simulaciones dos o tres ordenes de magnitud para que las medidas de tiempo sean fiables. Con el número de simulaciones que tienes los tiempos no son fiables. En mi maquina el tiempo de ejecución de la función original era 12 milisegundos, lo que no es suficiente para tomar conclusiones.

Efectivamente, los bucles for son lo que más degrada el rendimiento en Matlab. Así que siempre que se pueda evitar son una buena opción.

Para contar el número de ocurrencias en un vector hay múltiples soluciones. Pero no son más rápidas o consumen mucha memoria. Por ejemplo, tienes la función histograma.

1
[num, value] = hist(vals,unique(vals));

Donde tendrás en num el número de ocurrencias y en values lo valores únicos del vector vals. Por otro lado, puede usar

1
num = sum(vals==vals')

para obtener le numero de ocurrencias, pero crea una matriz cuadrad de la longitud de vals por la longitud de vals.

Saludos,
Daniel Rodríguez Pérez.
Analytics Lane
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

Optimización de código(MATLAB)

Publicado por Carlos María (5 intervenciones) el 19/02/2019 11:18:18
No entiendo como gestionar el segundo punto para probarlo.

Te refieres a quitar el if de la línea 32 de código y reemplazarlo por lo que dices?

Muchas gracias.

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
sin imagen de perfil
Val: 918
Bronce
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

Optimización de código(MATLAB)

Publicado por Daniel (354 intervenciones) el 19/02/2019 14:58:28
Hola ,

Por ejemplo, sean los siguientes valores

1
2
3
4
vars = [1, 2, 1, 3, 3, 1];
[u, p] = unique(vars);
nums = sum(vars == vars');
nums = nums(p);

Primero se obtiene los valores únicos (u) y la primera aparición de cada uno (p). Luego se obtiene el número de apariciones de cada elemento del vector vars sumando el cruce de este con su transposición. Como este valor da un registro para cada aparición de un valor en vars se usa la primera aparición de cada valor para contar los datos.

Al ejecutar el código se tiene

1
2
u = [1, 2, 3]
nums = [3, 1, 2]

el vector u tiene los valores diferentes de vars y en nums esta el número de veces que aparece cada uno.

El problema de este método es que unique es algo lento y el tamaño de la matriz vars == vars’ crece muy rápido con el número de registros.

Saludos,
Daniel Rodríguez
Analytics Lane
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