Diferencia entre revisiones de «PrInf12: Bucles anidados»

De MateWiki
Saltar a: navegación, buscar
(Ejercicio post-práctica)
Línea 65: Línea 65:
 
Comprueba que la versión con bucles y la vectorizada del programa proporcionan el mismo resultado.
 
Comprueba que la versión con bucles y la vectorizada del programa proporcionan el mismo resultado.
 
== Ejercicio post-práctica ==
 
== Ejercicio post-práctica ==
Modifica el programa anterior para que calcule el producto de todos los elementos, en vez de la suma. Vectoriza tu programa usando la función ''prod''. Consulta la ayuda con ''help prod'' para entender cómo funciona el comando. Comprueba que el resultado es el mismo usando bucles y con el código vectorizado.
+
* Modifica el programa anterior para que calcule el producto de todos los elementos, en vez de la suma. Vectoriza tu programa usando la función ''prod''. Consulta la ayuda con ''help prod'' para entender cómo funciona el comando. Comprueba que el resultado es el mismo usando bucles y con el código vectorizado.
 +
* Modifica los dos programas anteriores para usar bucles ''while'' en vez de bucles ''for''. ¿Se puede transformar de manera general un bucle ''for'' en un bucle ''while''? ¿Y al contrario, un bucle ''while'' en un bucle ''for''?
  
 
[[Categoría:Prácticas de Informática]]
 
[[Categoría:Prácticas de Informática]]

Revisión del 09:31 2 ago 2013

Práctica de Informática
Bucles con anidados
Práctica anterior Siguiente práctica
Este artículo es un guión de prácticas de Informática


En métodos numéricos es muy habitual trabajar con matrices. En esta práctica vamos a ver una técnica para trabajar con todos los elementos de una matriz, usando dos bucles anidados. Esta técnica es muy habitual en muchos programas. En general, las operaciones que se realicen con matrices es mejor intentar hacerlas de manera vectorizada, es decir, con comandos directamente y sin usar bucles. En algunos casos, como el que veremos en esta práctica, el código equivalente vectorizado es sencillo de obtener. Pero no existe una regla general, y muchas veces es muy complicado, incluso imposible, obtener un código vectorizado. En esos casos, tendremos que usar dos bucles anidados para trabajar con todos los elementos de una matriz.

1 Requisitos previos

Es importante haber realizado las dos prácticas sobre bucles con anterioridad a esta práctica:

2 Vídeos posteriores

Tras realizar esta práctica, el siguiente vídeo te ayudará a afianzar conocimientos:

3 Comandos que se aprenderán en esta práctica

sum prod

4 Contenido de la práctica

En esta práctica vamos a generar una matriz aleatoria y sumar todos los elementos de la matriz. Como la matriz tiene dos dimensiones, filas y columnas, será necesario usar dos bucles anidados para recuperar todos los elementos de la matriz.

Vamos a ver primero una prueba para ver cómo funcionan dos bucles anidados.

nFilas = 5; % Número de filas
nColumnas = 5; % Número de columnas

for f=1:nFilas
 for c=1:nColumnas
  fprintf('Fila: %d  Columna: %d\n', f, c);
 end
end

¿En qué orden se recorren las filas y las columnas? Como podemos comprobar, se recuperan los elementos en orden de filas. Es decir, primero los elementos de la primera fila, luego los de la segunda fila, etc.

¿Qué ocurre ahora si cambiamos el orden de los bucles?

nFilas = 5; % Número de filas
nColumnas = 5; % Número de columnas

for c=1:nColumnas
 for f=1:nFilas
  fprintf('Fila: %d  Columna: %d\n', f, c);
 end
end

Al cambiar el orden, ahora se recuperan los elementos en orden de columnas. El intérprete del lenguaje M siempre guarda en la memoria los elementos de las matrices en orden de columnas. Por este motivo es más eficiente recuperarlos también en el mismo orden.

Vamos entonces a sumar los elementos de una matriz, recuperándolos en orden de filas o de columnas. El primer paso será la entrada de datos, que en este caso consistirá en una matriz aleatoria.

Lapiz.png Tarea: Crea una matriz aleatoria de orden 5 que contenga números sin parte decimal entre el 0 y el 10


Aunque en este ejercicio partimos de una matriz con 5 filas y 5 columnas, en general nuestros programas deberían funcionar para matrices de cualquier tamaño.

Lapiz.png Tarea: Usa la función size para obtener el número de filas y columnas de la matriz. Haz que los resultados se guarden en dos variables de nombres nFilas y nColumnas


Para poder sumar todos los elementos de la matriz, necesitaremos una variable, que llamaremos s, que vaya acumulando los valores de los elementos de la matriz. Inicialmente tendremos s=0, y luego, en cada iteración haremos que

   s = s + A(f,c);

donde A es la matriz aleatoria que hemos creado.

Lapiz.png Tarea: Crea los dos bucles anidados para que se acumule la suma de todos los elementos en la variable s


Lapiz.png Tarea: Escribe como salida de datos: El valor de la suma es X, donde X es la suma. Ten en cuenta que la suma no tendrá parte decimal.


Una vez que hayas escrito la salida de datos, el programa está terminado.

Usar dos bucles anidados para recorrer una matriz es una técnica de programación lenta. Si existe una alternativa que pueda evitar bucles, es mejor usar esa alternativa, ya que será más rápida. Esta estrategia de programación recibe el nombre de vectorización. Se trata de evitar bucles intentando operar directamente con vectores y matrices. En el caso de la suma de elementos de una matriz, existe la función sum.

Lapiz.png Tarea: Consulta la ayuda del comando sum con help sum


¿Qué resultado obtienes al ejecutar sum(A)? ¿Es la suma de todos los elementos?

Lapiz.png Tarea: ¿Cómo podrías usar sum para obtener la suma de todos los elementos de la matriz?


Comprueba que la versión con bucles y la vectorizada del programa proporcionan el mismo resultado.

5 Ejercicio post-práctica

  • Modifica el programa anterior para que calcule el producto de todos los elementos, en vez de la suma. Vectoriza tu programa usando la función prod. Consulta la ayuda con help prod para entender cómo funciona el comando. Comprueba que el resultado es el mismo usando bucles y con el código vectorizado.
  • Modifica los dos programas anteriores para usar bucles while en vez de bucles for. ¿Se puede transformar de manera general un bucle for en un bucle while? ¿Y al contrario, un bucle while en un bucle for?