Post date: Apr 21, 2015 1:42:19 PM
Seguimos con el tema solicitado por Matías: control de flujo. Ahora vamos a ver como repetir un grupo de instrucciones utilizado el lazo for (yo les digo "loops", no lazos).
La idea es sencilla: uno tiene que repetir una acción muchas veces y no quiere escribir el código correspondiente a cada una de ellas.
Por ejemplo, supongamos que queremos sumar todos los valores en un vector:
x = rand (100,1)
El vector x
contiene 100 números entre 1 y 0 elegidos al azar (ver ayuda de la función rand
y preguntar en el foro si algo no se entiende). El objetivo es sumar todos estos valores. La forma ingenua de hacer esto sería escribir las 100 líneas:
y = x(1);
y += x(2);
y += x(3);
...
Y así hasta sumar todo los números. Está claro que esto no nos lleva muy lejos. Los lazos nos permiten repetir un grupo de comandos sin tener que escribir todas estas líneas. Utilizando el loop for podemos hacer la suma:
x = rand (100,1);
y = 0;
for i = 1:100
y += x(i);
endfor
El loop define una variable de iteración i
e indica que esta variable va desde 1 a 100. Esta variable se utiliza luego para indexar el vector x
y acceder a cada uno de sus valores. Para vectores de otros tamaños el programa es casi el mismo
x = rand (500,1);
y = 0;
for i =1:500
y += x(i);
endfor
Pregunta 1:
¿Cómo podemos escribir el loop para que funcione con cualquier tamaño del vector x?
GNU Octave se basa en un paradigma de programación vectorial. Esto quiere decir que operaciones entre vectores y matrices son veloces y las iteraciones explicitas, como el loop for, son lentas. La idea es que en vez de hacer una iteración, podemos hacer operaciones muy rápidas utilizando más memoria. Es decir, cambiamos iteraciones por espacio en memoria.
El ejemplo anterior se puede escribir de manera vectorial de la siguiente manera:
x = rand (500,1);
y = sum (x);
Este ejemplo en particular no cuesta más memoria que el loop porque en ambos casos construimos el vector x
. Sin embargo, el loop podría ahorrar memoria si lo escribiésemos así:
y = 0;
for i =1:500
y += rand ();
endfor
En este caso nunca construimos el vector x
y ahorramos esa memoria. Esto podría ser útil en el caso que necesitas una cantidad tan grande de números aleatorios que no entran en la memoria de tu PC (si tienes 1Gb de memoria puedes tener alrededor de 1 millón de estos números). Sin embargo esto tiene un precio en tiempo y lo podemos verificar utilizando las funciones tic y toc. El siguiente programa compara los tiempos de ejecución de las dos formas de hacer esta suma:
N = 1000;
disp ('Loop')
tic
y = 0;
for i =1:1000
y += rand ();
endfor
toc
disp ('Vectorizado')
tic
x = rand (1000,1);
y = sum (x);
toc
En mi PC esto da
Loop
Elapsed time is 0.0164838 seconds.
Vectorizado
Elapsed time is 7.60555e-05 seconds.
¿Cuánto da en la tuya? Puedes descargar el script al pié de la página.