MATLAB Language
Para bucles
Buscar..
Observaciones
Iterar sobre el vector de columna
Una fuente común de errores está intentando hacer un bucle sobre los elementos de un vector de columna. Un vector de columna se trata como una matriz con una columna. (En realidad no hay distinción en Matlab). El bucle for
ejecuta una vez con la variable de bucle establecida en la columna.
% Prints once: [3, 1]
my_vector = [1; 2; 3];
for i = my_vector
display(size(i))
end
Alterar la variable de iteración.
La modificación de la variable de iteración cambia su valor para la iteración actual, pero no tiene impacto en su valor en iteraciones posteriores.
% Prints 1, 2, 3, 4, 5
for i = 1:5
display(i)
i = 5; % Fail at trying to terminate the loop
end
Caso especial de a:b
en el lado derecho.
El ejemplo básico trata 1:n
como una instancia normal de crear un vector de fila y luego iterar sobre él. Por razones de rendimiento, Matlab en realidad trata cualquier a:b
o a:c:b
especialmente al no crear el vector de fila por completo, sino a cada elemento de uno en uno.
Esto se puede detectar alterando ligeramente la sintaxis.
% Loops forever
for i = 1:1e50
end
% Crashes immediately
for i = [1:1e50]
end
Lazo 1 a n
El caso más simple es simplemente realizar una tarea para un número fijo de veces conocido. Digamos que queremos mostrar los números entre 1 a n, podemos escribir:
n = 5;
for k = 1:n
display(k)
end
El bucle se ejecute la instrucción (s) interior, todo entre el for
y la end
, por n
veces (5 en este ejemplo):
1
2
3
4
5
Aquí hay otro ejemplo:
n = 5;
for k = 1:n
disp(n-k+1:-1:1) % DISP uses more "clean" way to print on the screen
end
esta vez usamos tanto n
como k
en el bucle para crear una pantalla "anidada":
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
Iterar sobre elementos de vector
El lado derecho de la asignación en un bucle for
puede ser cualquier vector de fila. El lado izquierdo de la asignación puede ser cualquier nombre de variable válido. El bucle for
asigna un elemento diferente de este vector a la variable de cada ejecución.
other_row_vector = [4, 3, 5, 1, 2];
for any_name = other_row_vector
display(any_name)
end
La salida mostraría
4
3
5
1
2
(La versión 1:n
es un caso normal de esto, porque en Matlab 1:n
es solo una sintaxis para construir un vector de fila de [1, 2, ..., n]
.)
Por lo tanto, los dos bloques de código siguientes son idénticos:
A = [1 2 3 4 5];
for x = A
disp(x);
end
y
for x = 1:5
disp(x);
end
Y los siguientes también son idénticos:
A = [1 3 5 7 9];
for x = A
disp(x);
end
y
for x = 1:2:9
disp(x);
end
Cualquier vector de fila servirá. No tienen que ser números.
my_characters = 'abcde';
for my_char = my_characters
disp(my_char)
end
dará salida
a
b
c
d
e
Iterar sobre columnas de matriz.
Si el lado derecho de la asignación es una matriz, en cada iteración se asignan columnas subsiguientes a esta variable.
some_matrix = [1, 2, 3; 4, 5, 6]; % 2 by 3 matrix
for some_column = some_matrix
display(some_column)
end
(La versión de vector de fila es un caso normal de esto, porque en Matlab un vector de fila es solo una matriz cuyas columnas son de tamaño 1.)
La salida mostraría
1
4
2
5
3
6
es decir, cada columna de la matriz iterada mostrada, cada columna impresa en cada llamada de display
.
Loop sobre índices
my_vector = [0, 2, 1, 3, 9];
for i = 1:numel(my_vector)
my_vector(i) = my_vector(i) + 1;
end
La mayoría de las cosas simples hechas con for
bucles se puede hacer más rápido y más fácil por las operaciones vectorizadas. Por ejemplo, el bucle anterior se puede reemplazar por my_vector = my_vector + 1
.
Bucles anidados
Los bucles se pueden anidar para realizar una tarea iterada dentro de otra tarea iterada. Considere los siguientes bucles:
ch = 'abc';
m = 3;
for c = ch
for k = 1:m
disp([c num2str(k)]) % NUM2STR converts the number stored in k to a charachter,
% so it can be concataneted with the letter in c
end
end
usamos 2 iteradores para mostrar todas las combinaciones de elementos de abc
y 1:m
, que producen:
a1
a2
a3
b1
b2
b3
c1
c2
c3
También podemos usar bucles anidados para combinar entre las tareas que se realizarán cada vez y las tareas que se realizarán una vez en varias iteraciones:
N = 10;
n = 3;
a1 = 0; % the first element in Fibonacci series
a2 = 1; % the secound element in Fibonacci series
for j = 1:N
for k = 1:n
an = a1 + a2; % compute the next element in Fibonacci series
a1 = a2; % save the previous element for the next iteration
a2 = an; % save ht new element for the next iteration
end
disp(an) % display every n'th element
end
Aquí queremos calcular toda la serie de Fibonacci , pero para mostrar sólo el n
-ésimo elemento cada vez, por lo que tenemos
3
13
55
233
987
4181
17711
75025
317811
1346269
Otra cosa que podemos hacer es usar el primer iterador (externo) dentro del bucle interno. Aquí hay otro ejemplo:
N = 12;
gap = [1 2 3 4 6];
for j = gap
for k = 1:j:N
fprintf('%d ',k) % FPRINTF prints the number k proceeding to the next the line
end
fprintf('\n') % go to the next line
end
Esta vez usamos el bucle anidado para formatear la salida y frenar la línea solo cuando se introdujo un nuevo espacio ( j
) entre los elementos. Recorremos el ancho de la brecha en el bucle externo y lo usamos dentro del bucle interno para iterar a través del vector:
1 2 3 4 5 6 7 8 9 10 11 12
1 3 5 7 9 11
1 4 7 10
1 5 9
1 7
Aviso: Extraños bucles anidados del mismo contador.
Esto no es algo que verá en otros entornos de programación. Lo encontré hace algunos años y no podía entender por qué estaba sucediendo, pero después de trabajar con MATLAB por un tiempo pude resolverlo. Mira el fragmento de código a continuación:
for x = 1:10
for x = 1:10
fprintf('%d,', x);
end
fprintf('\n');
end
no esperaría que esto funcione correctamente pero lo hace, produciendo el siguiente resultado:
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
La razón es que, como con todo lo demás en MATLAB, el contador x
también es una matriz, un vector para ser preciso. Como tal, x
es solo una referencia a una 'matriz' (una estructura de memoria coherente y consecutiva) a la que se hace referencia apropiada con cada bucle consecuente (anidado o no). El hecho de que el bucle anidado use el mismo identificador no hace ninguna diferencia en la forma en que se hace referencia a los valores de esa matriz. El único problema es que dentro del bucle anidado, la x
externa está oculta por la x
anidada (local) y, por lo tanto, no se puede hacer referencia a ella. Sin embargo, la funcionalidad de la estructura de bucle anidado permanece intacta.