Diferencia entre revisiones de «PrInf10: Bucles»
(→Primera versión del programa) |
(→Ejercicio post-práctica) |
||
| (No se muestran 19 ediciones intermedias del mismo usuario) | |||
| Línea 1: | Línea 1: | ||
{{ Práctica de Informática | Bucles con ''for'' | PrInf09: if anidados | PrInf11: Bucles while }} | {{ Práctica de Informática | Bucles con ''for'' | PrInf09: if anidados | PrInf11: Bucles while }} | ||
| − | |||
En esta práctica vamos a conocer una estructura de programación nueva, que no hemos usado hasta ahora. Se trata del concepto de ''bucles'', que sirven para repetir un conjunto de comandos varias veces. Existen muchas situaciones en las que es útil repetir un conjunto de comandos sin tener que escribirlos varias veces. Por ejemplo, muchos métodos numéricos realizan aproximaciones sucesivas a la solución, repitiendo los mismo comandos, pero con valores que se van actualizando en cada aproximación. La implementación de este tipo de cálculos requiere el uso de ''bucles''. | En esta práctica vamos a conocer una estructura de programación nueva, que no hemos usado hasta ahora. Se trata del concepto de ''bucles'', que sirven para repetir un conjunto de comandos varias veces. Existen muchas situaciones en las que es útil repetir un conjunto de comandos sin tener que escribirlos varias veces. Por ejemplo, muchos métodos numéricos realizan aproximaciones sucesivas a la solución, repitiendo los mismo comandos, pero con valores que se van actualizando en cada aproximación. La implementación de este tipo de cálculos requiere el uso de ''bucles''. | ||
| Línea 18: | Línea 17: | ||
| for | | for | ||
| sqrt | | sqrt | ||
| + | | rem | ||
|} | |} | ||
| Línea 41: | Línea 41: | ||
Vamos a ver este proceso en código. Como todos los programas, vamos a dividirlo en tres partes: entrada, algoritmo y salida. En este caso, la entrada de datos consiste en el valor cuya raíz queremos calcular: | Vamos a ver este proceso en código. Como todos los programas, vamos a dividirlo en tres partes: entrada, algoritmo y salida. En este caso, la entrada de datos consiste en el valor cuya raíz queremos calcular: | ||
| − | |||
{{#tag:source|% Entrada de datos | {{#tag:source|% Entrada de datos | ||
A = input('Introduce el numero cuya raiz quieres calcular: '); | A = input('Introduce el numero cuya raiz quieres calcular: '); | ||
|lang="matlab"}} | |lang="matlab"}} | ||
| − | |||
El siguiente paso será el algoritmo. Como hemos dicho, partimos de un rectángulo con <math>W=1</math>, y hacemos una aproximación tomando el valor medio: | El siguiente paso será el algoritmo. Como hemos dicho, partimos de un rectángulo con <math>W=1</math>, y hacemos una aproximación tomando el valor medio: | ||
| − | |||
{{#tag:source|% Algoritmo | {{#tag:source|% Algoritmo | ||
% Rectangulo inicial | % Rectangulo inicial | ||
| Línea 56: | Línea 53: | ||
W1 = A/L1; | W1 = A/L1; | ||
|lang="matlab"}} | |lang="matlab"}} | ||
| − | |||
Una vez que hemos realizado la aproximación, podemos mostrar ya el resultado en pantalla. En este caso, tomamos <math>L_1</math> como el valor aproximado de la raíz: | Una vez que hemos realizado la aproximación, podemos mostrar ya el resultado en pantalla. En este caso, tomamos <math>L_1</math> como el valor aproximado de la raíz: | ||
| − | |||
{{#tag:source|% Salida de datos | {{#tag:source|% Salida de datos | ||
fprintf('La raiz de %.4f es %.4f\n', A, L1);|lang="matlab"}} | fprintf('La raiz de %.4f es %.4f\n', A, L1);|lang="matlab"}} | ||
| − | |||
Es decir, el programa completo quedaría como sigue | Es decir, el programa completo quedaría como sigue | ||
| − | |||
{{ matlab | codigo= | {{ matlab | codigo= | ||
% Entrada de datos | % Entrada de datos | ||
| Línea 78: | Línea 71: | ||
% Salida de datos | % Salida de datos | ||
fprintf('La raiz de %.4f es %.4f\n', A, L1);}} | fprintf('La raiz de %.4f es %.4f\n', A, L1);}} | ||
| − | |||
Podemos probar este programa para calcular <math>\sqrt{10}</math>, que hemos visto que era igual a <math>3.16</math> | Podemos probar este programa para calcular <math>\sqrt{10}</math>, que hemos visto que era igual a <math>3.16</math> | ||
<pre> | <pre> | ||
| Línea 86: | Línea 78: | ||
{{ Tarea | Escribe el programa anterior en [[Octave UPM]] y comprueba que obtienes el mismo resultado al calcular la raíz de 10 }} | {{ Tarea | Escribe el programa anterior en [[Octave UPM]] y comprueba que obtienes el mismo resultado al calcular la raíz de 10 }} | ||
Como podemos ver, la aproximación es muy mala. Podemos remediarlo escribiendo varias aproximaciones seguidas. Además, ya que los valores intermedios de la aproximación <math>L_1</math> y <math>W_1</math> solo se usan al final, podemos reutilizar continuamente las mismas variables. Si hacemos cuatro aproximaciones, el programa quedaría como sigue: | Como podemos ver, la aproximación es muy mala. Podemos remediarlo escribiendo varias aproximaciones seguidas. Además, ya que los valores intermedios de la aproximación <math>L_1</math> y <math>W_1</math> solo se usan al final, podemos reutilizar continuamente las mismas variables. Si hacemos cuatro aproximaciones, el programa quedaría como sigue: | ||
| − | |||
{{ matlab | codigo= | {{ matlab | codigo= | ||
% Entrada de datos | % Entrada de datos | ||
| Línea 105: | Línea 96: | ||
% Salida de datos | % Salida de datos | ||
fprintf('La raiz de %.4f es %.4f\n', A, L);}} | fprintf('La raiz de %.4f es %.4f\n', A, L);}} | ||
| − | |||
Si volvemos a probar el programa, ahora la aproximación es bastante mejor | Si volvemos a probar el programa, ahora la aproximación es bastante mejor | ||
<pre> | <pre> | ||
| Línea 111: | Línea 101: | ||
La raiz de 10.0000 es 3.1625 | La raiz de 10.0000 es 3.1625 | ||
</pre> | </pre> | ||
| − | |||
Sin embargo, si probamos a calcular <math>\sqrt{1000}</math>, cuyo valor es <math>31.62</math>, obtenemos el siguiente resultado | Sin embargo, si probamos a calcular <math>\sqrt{1000}</math>, cuyo valor es <math>31.62</math>, obtenemos el siguiente resultado | ||
<pre> | <pre> | ||
| Línea 132: | Línea 121: | ||
=== Segunda versión del programa: ahora usamos bucles === | === Segunda versión del programa: ahora usamos bucles === | ||
| − | == | + | En este caso vamos a realizar una implementación que ejecute el conjunto de comandos un número fijo de veces. Por ejemplo, 10 veces. Vamos a ver cómo evitar tener que escribir el conjunto de comandos 10 veces, usando ''for''. La única parte del programa que vamos a cambiar es el ''algoritmo''. La ''entrada'' y ''salida de datos'' permanecen exactamente igual. El algoritmo se transformaría de esta manera: |
| + | {{#tag:source|% Algoritmo | ||
| + | L = A; | ||
| + | W = 1; | ||
| + | for k=1:10 | ||
| + | L = (L+W)/2; | ||
| + | W = A/L; | ||
| + | end|lang="matlab"}} | ||
| + | {{ Tarea | Sustituye en el programa completo anterior la parte del algoritmo por este bucle, y comprueba la raíz de 1000 es ahora mucho más cercana al valor teórico }} | ||
| + | El bucle ''for'' tiene dos elementos: | ||
| + | * La variable que hace de contador, en este caso ''k'', que va desde 1 hasta 10. | ||
| + | * El cuerpo del bucle, que son los comandos que se repiten. Aunque no es obligatorio, el cuerpo del bucle se suele escribir indentado para facilitar la lectura del código. | ||
| − | + | En general, la estructura de un bucle for es | |
| + | {{#tag:source|for [CONTADOR]=[VECTOR] | ||
| + | [CUERPO DEL BUCLE] | ||
| + | end|lang="matlab"}} | ||
| + | donde ''[CONTADOR]'' es un nombre de variable, que recibirá los valores que están dentro de ''[VECTOR]'', uno por uno. El ''[CUERPO DEL BUCLE]'' se repetirá tantas veces como elementos haya en ''[VECTOR]'', y en cada repetición el valor de ''[CONTADOR]'' será el elemento correspondiente dentro de ''[VECTOR]''. | ||
| − | + | Si comparamos la estructura genérica con el código que hemos puesto en nuestro programa, vemos que tenemos las siguientes equivalencias: | |
| + | {| class="wikitable" | ||
| + | ! Elemento | ||
| + | ! Código | ||
| + | ! Comentarios | ||
| + | |- | ||
| + | | [CONTADOR] | ||
| + | | {{#tag:source|k|lang="matlab" }} | ||
| + | | | ||
| + | |- | ||
| + | | [VECTOR] | ||
| + | | {{#tag:source|1:10|lang="matlab" }} | ||
| + | | Vector con 10 elementos, desde 1 hasta 10 separados de uno en uno | ||
| + | |- | ||
| + | | [CUERPO DEL BUCLE] | ||
| + | | {{#tag:source| L = (L+W)/2; | ||
| + | W = A/L;|lang="matlab" }} | ||
| + | | | ||
| + | |} | ||
| − | {{#tag:source| | + | En general, la estructura más habitual de un bucle es |
| + | {{#tag:source|for k=1:N | ||
| + | % Comandos | ||
| + | end|lang="matlab"}} | ||
| + | donde ''N'' es el número de veces que se repetirá el bucle. Pero es importante entender que esto funciona porque ''1:N'' es un vector, y que en cada iteración ''k'' va tomando los valores ''1, 2, 3, ...'' hasta ''N'. | ||
| − | + | === Tercera versión: número arbitrario de repeticiones === | |
| − | + | En la versión anterior hemos evitado tener que escribir el comando 10 veces para hacer 10 aproximaciones. Sin embargo, si queremos cambiar el número de aproximaciones que se realizan tenemos que cambiar el código fuente. ¿Existe el modo de ejecutar el bucle un número arbitrario de veces? Hasta ahora hemos visto que los bucles ''for'' requieren que se conozca ''a priori'' el número de veces que se va a ejecutar el bucle. Esto parece indicar que no es posible ejecutarlo un número arbitrario de veces. El término ''a priori'' se refiere al momento justamente anterior al comienzo del bucle, no al comienzo del programa. Es decir, si sabemos el número de veces que se va a ejecutar el bulce en el momento en el que vaya a comenzar, podemos usar un bucle ''for'' | |
| + | Por ejemplo: | ||
| + | {{#tag:source| | ||
| + | nPasos = 10; | ||
| + | % Algoritmo | ||
| + | L = A; | ||
| + | W = 1; | ||
| + | for k=1:nPasos | ||
| + | L = (L+W)/2; | ||
| + | W = A/L; | ||
| + | end|lang="matlab"}} | ||
| + | Justo antes de comenzar el bucle sabemos que la variable ''nPasos'' vale 10, por lo que el bucle se ejecutará 10 veces. No obstante, esta versión todavía requiere que el usuario modifique el código fuente de nuestro programa para cambiar el número de aproximaciones. Este comportamiento no es admisible en un programa que destinemos a un usuario final, por lo que es necesario remediarlo. | ||
| + | |||
| + | ¿Cómo podemos hacer que el usuario controle el número de veces que se ejecuta el bucle? Preguntemos al usuario el número de veces directamente: | ||
| + | {{#tag:source| | ||
| + | nPasos = input('Introduce el num. de aproximaciones en el calculo: '); | ||
| + | |||
| + | % Algoritmo | ||
| + | L = A; | ||
| + | W = 1; | ||
| + | for k=1:nPasos | ||
| + | L = (L+W)/2; | ||
| + | W = A/L; | ||
| + | end|lang="matlab"}} | ||
| + | Al leer el código es imposible saber cuántas veces se va a ejecutar el bucle, ya que es el usuario cuando ejecute el programa el que lo indicará. Pero al comenzar el bucle, el valor de la variable ''nPasos'' está totalmente determinado, por lo que el bucle, en el momento de la ejecución, sí sabe cuántas veces tiene que repetir el comando. La primera línea del trozo de código anterior corresponde a la ''entrada de datos'' del programa. | ||
| + | |||
| + | Ahora, por ejemplo, si queremos calcular <math>\sqrt{10^6}</math> con una buena aproximación podemos decirle al programa que el valor de ''A'' es ''1e6'', y que el número de aproximaciones es ''20''. | ||
| + | {{ Tarea | Modifica el programa para integrar el trozo de código anterior, y comprueba los valores de <math>\sqrt{10^6}</math> con 10 y 20 pasos. ¿Cuál es el error cometido con 10 y 20 pasos? }} | ||
== Ejercicio post-práctica == | == Ejercicio post-práctica == | ||
| + | Hasta ahora hemos visto dos instrucciones nativas del lenguaje [[MATLAB]]: ''if'' y ''for''. Dentro de un ''if'' vimos que podíamos poner tantos ''if'' adicionales como fuera necesario. Con los bucles ''for'' ocurre lo mismo. Es decir, dentro del cuerpo de un ''for'' puede haber otro ''for'', un ''if'', o en general cualquier otro comando, instrucción o construcción del lenguaje. Del mismo modo, podemos poner un ''for'' dentro del ''if''. | ||
| + | |||
| + | Intenta averiguar cuál es la salida de estos dos programas y después ejecútalos en [[Octave UPM]]. Si lo necesitas, puedes consultar la ayuda del comando ''rem'' ejecutando ''help rem'', o consultar [http://www.mathworks.es/es/help/matlab/ref/rem.html ayuda online de MATLAB]: | ||
| + | |||
| + | {{ matlab | codigo = | ||
| + | for l=1:20 | ||
| + | if rem(l, 2) == 0 | ||
| + | disp(l); | ||
| + | end | ||
| + | end | ||
| + | }} {{ matlab | codigo = | ||
| + | for k=3:2:30 | ||
| + | if rem(k, 3) ~= 0 | ||
| + | disp(k); | ||
| + | end | ||
| + | end}} | ||
[[Categoría:Prácticas de Informática]] | [[Categoría:Prácticas de Informática]] | ||
Revisión actual del 18:56 22 jul 2013
| Práctica de Informática | |
|---|---|
| Bucles con for | |
| Práctica anterior | Siguiente práctica |
| Este artículo es un guión de prácticas de Informática | |
En esta práctica vamos a conocer una estructura de programación nueva, que no hemos usado hasta ahora. Se trata del concepto de bucles, que sirven para repetir un conjunto de comandos varias veces. Existen muchas situaciones en las que es útil repetir un conjunto de comandos sin tener que escribirlos varias veces. Por ejemplo, muchos métodos numéricos realizan aproximaciones sucesivas a la solución, repitiendo los mismo comandos, pero con valores que se van actualizando en cada aproximación. La implementación de este tipo de cálculos requiere el uso de bucles.
Contenido
1 Requisitos previos
Es muy recomendable haber completado satisfactoriamente todas las prácticas anteriores antes de empezar con esta práctica.
El contenido de esta práctica se explica en el siguiente vídeo. Puede ser recomendable visualizar el vídeo antes de realizar esta práctica:
2 Comandos que se aprenderán en esta práctica
En esta práctica vamos a ver qué significan los siguientes comandos de MATLAB / Octave
| for | sqrt | rem |
3 Contenido de la práctica
Como ejemplo para esta práctica vamos a implementar un método numérico para aproximar raíces cuadradas. En Octave UPM ya tenemos un comando que calcula raíces cuadradas, el comando sqrt; nosotros usamos este método como ejemplo para ilustrar qué es un bucle porque es un método sencillo y muy ilustrativo. Obviamente, en situaciones reales, no usaríamos un método propio para calcular la raíz cuadrada, y usaríamos el comando sqrt, que probablemente funcione mucho mejor que el método que vamos a implementar.
3.1 Descripción del método numérico
Existen muchos métodos para aproximar raíces cuadradas. En esta práctica vamos a usar el método babilonio, que aproxima el valor de la raíz transformando sucesivamente un rectángulo en un cuadrado. Cuantas más aproximaciones hagamos, más cercano al cuadrado estaré el rectángulo, y más cercano estará el lado del cuadrado al valor de la raíz cuadrada. El proceso aparece ilustrado en la figura de la derecha.
Supongamos que queremos calcular el valor de la raíz cuadrada de [math]A[/math]. Inicialmente, dibujamos un rectángulo de área [math]A[/math], pero seleccionamos la altura de manera que sea igual a 1 (es decir, [math]W=1[/math] en la figura de la derecha). Por tanto, inicialmente tendremos que [math]L=A[/math], ya que [math]A = L\cdot W[/math].
El valor de [math]\sqrt{A}[/math] tiene que estar entre [math]1[/math] y [math]A[/math]. Por ejemplo, la raíz de [math]10[/math] es [math]3.16 \in [1,10][/math]. Por tanto, el valor [math]\sqrt{A}[/math] estará inicialmente entre [math]L[/math] y [math]W[/math].
En el siguiente paso, vamos a achatar el rectángulo, haciendo su forma más cuadrada usando un valor medio del lado. Es decir, [math]\displaystyle L_1=\frac{L+W}{2}[/math]. Como el área del rectángulo no puede cambiar, nos queda que [math]\displaystyle W_1=\frac{A}{L_1}[/math]. Si hubiéramos partido de este rectángulo inicialmente, tendríamos que el valor de la raíz cuadrada estaría entre los valores de los lados del rectángulo, igual que en el primer rectángulo que hemos usado. Es decir, [math]\sqrt{A} \in [W_1, L_1][/math]. Si repetimos este proceso varias veces, el rectángulo se convertirá cada vez más en un cuadrado, y los valores de [math]W_1[/math] y [math]L_1[/math] estarán más cercanos entre sí y más cercanos al valor de [math]\sqrt{A}[/math].
3.2 Primera versión del programa
Vamos a ver este proceso en código. Como todos los programas, vamos a dividirlo en tres partes: entrada, algoritmo y salida. En este caso, la entrada de datos consiste en el valor cuya raíz queremos calcular:
% Entrada de datos
A = input('Introduce el numero cuya raiz quieres calcular: ');El siguiente paso será el algoritmo. Como hemos dicho, partimos de un rectángulo con [math]W=1[/math], y hacemos una aproximación tomando el valor medio:
% Algoritmo
% Rectangulo inicial
W = 1;
L = A;
% Primera aproximacion
L1 = (L+W)/2;
W1 = A/L1;Una vez que hemos realizado la aproximación, podemos mostrar ya el resultado en pantalla. En este caso, tomamos [math]L_1[/math] como el valor aproximado de la raíz:
% Salida de datos
fprintf('La raiz de %.4f es %.4f\n', A, L1);Es decir, el programa completo quedaría como sigue
% Entrada de datos
A = input('Introduce el numero cuya raiz quieres calcular: ');
% Algoritmo
% Rectangulo inicial
W = 1;
L = A;
% Primera aproximacion
L1 = (L+W)/2;
W1 = A/L1;
% Salida de datos
fprintf('La raiz de %.4f es %.4f\n', A, L1);Podemos probar este programa para calcular [math]\sqrt{10}[/math], que hemos visto que era igual a [math]3.16[/math]
Introduce el numero cuya raiz quieres calcular: 10 La raiz de 10.0000 es 5.5000
| |
Tarea: | Escribe el programa anterior en Octave UPM y comprueba que obtienes el mismo resultado al calcular la raíz de 10 |
Como podemos ver, la aproximación es muy mala. Podemos remediarlo escribiendo varias aproximaciones seguidas. Además, ya que los valores intermedios de la aproximación [math]L_1[/math] y [math]W_1[/math] solo se usan al final, podemos reutilizar continuamente las mismas variables. Si hacemos cuatro aproximaciones, el programa quedaría como sigue:
% Entrada de datos
A = input('Introduce el numero cuya raiz quieres calcular: ');
% Algoritmo
% Rectangulo inicial
W = 1;L = A;
% Cuatro aproximaciones
L = (L+W)/2;
W = A/L;
L = (L+W)/2;
W = A/L;
L = (L+W)/2;
W = A/L;
L = (L+W)/2;
W = A/L;
% Salida de datos
fprintf('La raiz de %.4f es %.4f\n', A, L);Si volvemos a probar el programa, ahora la aproximación es bastante mejor
Introduce el numero cuya raiz quieres calcular: 10 La raiz de 10.0000 es 3.1625
Sin embargo, si probamos a calcular [math]\sqrt{1000}[/math], cuyo valor es [math]31.62[/math], obtenemos el siguiente resultado
Introduce el numero cuya raiz quieres calcular: 1000 La raiz de 1000.0000 es 67.7253
| |
Tarea: | Escribe el programa anterior en Octave UPM y comprueba los resultados para calcular ambas raíces |
¿Cómo podemos obtener una solución mejor? Ejecutando más aproximaciones. Sin embargo, esto requiere escribir muchas veces los mismos comandos. Si quisiéramos cambiar el número de veces que se ejecutan las aproximaciones, deberíamos modificar el programa para añadir o eliminar comandos. Esta solución no es admisible en programación. En cualquier situación donde nos veamos realizando una tarea repetitiva, y donde hubiera que modificar el programa para cambiar el número de veces que se ejecutan unos comandos, tenemos que tener claro que existe una alternativa de programación para que esas tareas las realice el ordenador. Un ordenador es muy eficiente realizando tareas repetitivas, y no puede pensar. Las personas funcionamos al contrario: somos capaces de pensar, pero somos muy malos realizando tareas muy repetitivas.
Para realizar tareas repetitivas en programación se usa una estructura conocida como bucle. Existen dos tipos principales de bucles:
- Bucles for
- Bucles while
En un bucle for tenemos que saber a priori cuántas veces hay que repetir un conjunto de comandos. Se suelen emplear, como veremos más adelante, para recorrer vectores y matrices, cuyas dimensiones son conocidas inicialmente.
Los bucles while se usan cuando conocemos la condición que tiene que cumplirse para repetir un conjunto de comandos. Mientras esa condición se cumpla, se repetirán los comandos. En muchas situaciones no podemos saber a priori cuántas veces hay que ejecutar un conjunto de comandos, pero sí podemos saber qué condición se cumple para que se sigan ejecutando. Por ejemplo, repetir unos comandos mientras el usuario no introduzca un número determinado por teclado. Sabemos que mientras no acierte el número tenemos que repetir los comandos, pero es imposible saber qué números va a introducir el usuario, y por tanto cuántas veces se ejecutará el bucle.
En esta práctica vamos a ver los bucles for, y en la siguiente veremos los bucles while.
3.3 Segunda versión del programa: ahora usamos bucles
En este caso vamos a realizar una implementación que ejecute el conjunto de comandos un número fijo de veces. Por ejemplo, 10 veces. Vamos a ver cómo evitar tener que escribir el conjunto de comandos 10 veces, usando for. La única parte del programa que vamos a cambiar es el algoritmo. La entrada y salida de datos permanecen exactamente igual. El algoritmo se transformaría de esta manera:
% Algoritmo
L = A;
W = 1;
for k=1:10
L = (L+W)/2;
W = A/L;
end| |
Tarea: | Sustituye en el programa completo anterior la parte del algoritmo por este bucle, y comprueba la raíz de 1000 es ahora mucho más cercana al valor teórico |
El bucle for tiene dos elementos:
- La variable que hace de contador, en este caso k, que va desde 1 hasta 10.
- El cuerpo del bucle, que son los comandos que se repiten. Aunque no es obligatorio, el cuerpo del bucle se suele escribir indentado para facilitar la lectura del código.
En general, la estructura de un bucle for es
for [CONTADOR]=[VECTOR]
[CUERPO DEL BUCLE]
enddonde [CONTADOR] es un nombre de variable, que recibirá los valores que están dentro de [VECTOR], uno por uno. El [CUERPO DEL BUCLE] se repetirá tantas veces como elementos haya en [VECTOR], y en cada repetición el valor de [CONTADOR] será el elemento correspondiente dentro de [VECTOR].
Si comparamos la estructura genérica con el código que hemos puesto en nuestro programa, vemos que tenemos las siguientes equivalencias:
| Elemento | Código | Comentarios |
|---|---|---|
| [CONTADOR] | k |
|
| [VECTOR] | 1:10 |
Vector con 10 elementos, desde 1 hasta 10 separados de uno en uno |
| [CUERPO DEL BUCLE] | L = (L+W)/2;
W = A/L; |
En general, la estructura más habitual de un bucle es
for k=1:N
% Comandos
enddonde N es el número de veces que se repetirá el bucle. Pero es importante entender que esto funciona porque 1:N es un vector, y que en cada iteración k va tomando los valores 1, 2, 3, ... hasta N'.
3.4 Tercera versión: número arbitrario de repeticiones
En la versión anterior hemos evitado tener que escribir el comando 10 veces para hacer 10 aproximaciones. Sin embargo, si queremos cambiar el número de aproximaciones que se realizan tenemos que cambiar el código fuente. ¿Existe el modo de ejecutar el bucle un número arbitrario de veces? Hasta ahora hemos visto que los bucles for requieren que se conozca a priori el número de veces que se va a ejecutar el bucle. Esto parece indicar que no es posible ejecutarlo un número arbitrario de veces. El término a priori se refiere al momento justamente anterior al comienzo del bucle, no al comienzo del programa. Es decir, si sabemos el número de veces que se va a ejecutar el bulce en el momento en el que vaya a comenzar, podemos usar un bucle for Por ejemplo:
nPasos = 10;
% Algoritmo
L = A;
W = 1;
for k=1:nPasos
L = (L+W)/2;
W = A/L;
endJusto antes de comenzar el bucle sabemos que la variable nPasos vale 10, por lo que el bucle se ejecutará 10 veces. No obstante, esta versión todavía requiere que el usuario modifique el código fuente de nuestro programa para cambiar el número de aproximaciones. Este comportamiento no es admisible en un programa que destinemos a un usuario final, por lo que es necesario remediarlo.
¿Cómo podemos hacer que el usuario controle el número de veces que se ejecuta el bucle? Preguntemos al usuario el número de veces directamente:
nPasos = input('Introduce el num. de aproximaciones en el calculo: ');
% Algoritmo
L = A;
W = 1;
for k=1:nPasos
L = (L+W)/2;
W = A/L;
endAl leer el código es imposible saber cuántas veces se va a ejecutar el bucle, ya que es el usuario cuando ejecute el programa el que lo indicará. Pero al comenzar el bucle, el valor de la variable nPasos está totalmente determinado, por lo que el bucle, en el momento de la ejecución, sí sabe cuántas veces tiene que repetir el comando. La primera línea del trozo de código anterior corresponde a la entrada de datos del programa.
Ahora, por ejemplo, si queremos calcular [math]\sqrt{10^6}[/math] con una buena aproximación podemos decirle al programa que el valor de A es 1e6, y que el número de aproximaciones es 20.
| |
Tarea: | Modifica el programa para integrar el trozo de código anterior, y comprueba los valores de [math]\sqrt{10^6}[/math] con 10 y 20 pasos. ¿Cuál es el error cometido con 10 y 20 pasos? |
4 Ejercicio post-práctica
Hasta ahora hemos visto dos instrucciones nativas del lenguaje MATLAB: if y for. Dentro de un if vimos que podíamos poner tantos if adicionales como fuera necesario. Con los bucles for ocurre lo mismo. Es decir, dentro del cuerpo de un for puede haber otro for, un if, o en general cualquier otro comando, instrucción o construcción del lenguaje. Del mismo modo, podemos poner un for dentro del if.
Intenta averiguar cuál es la salida de estos dos programas y después ejecútalos en Octave UPM. Si lo necesitas, puedes consultar la ayuda del comando rem ejecutando help rem, o consultar ayuda online de MATLAB:
for l=1:20
if rem(l, 2) == 0
disp(l);
end
endfor k=3:2:30
if rem(k, 3) ~= 0
disp(k);
end
end