Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Estructuras de control

Control condicional: if, else, switch

Las instrucciones condicionales permiten seleccionar en tiempo de ejecución qué bloque de código se va a ejecutar. La instrucción condicional más simple es una instrucción if. Por ejemplo, este programa genera un número entero al azar, y si es par lo divide por 2:

% Generate a random number
a = randi(100, 1);

% If it is even, divide by 2
if rem(a, 2) == 0
    disp('a is even')
    b = a/2;
end

Las instrucciones if pueden incluir opciones alternativas mediante el uso de las palabras clave opcionales elseif o else. Por ejemplo:

a = randi(100, 1);

if a < 30
    disp('small')
elseif a < 80
    disp('medium')
else
    disp('large')
end

Alternativamente, cuando desee probar la igualdad frente a un conjunto de valores conocidos, use una instrucción switch. Por ejemplo:

[dayNum, dayString] = weekday(date, 'long', 'en_US');

switch dayString
   case 'Monday'
      disp('Start of the work week')
   case 'Tuesday'
      disp('Day 2')
   case 'Wednesday'
      disp('Day 3')
   case 'Thursday'
      disp('Day 4')
   case 'Friday'
      disp('Last day of the work week')
   otherwise
      disp('Weekend!')
end

Tanto para if como para switch, MATLAB® ejecuta el código que corresponde a la primera condición verdadera y luego sale del bloque de código. Cada instrucción condicional requiere la palabra clave end.

En general, cuando los valores posibles tienen muchas opciones discretas y conocidas, las instrucciones switch son más fáciles de leer que las instrucciones if. Sin embargo, no es posible buscar desigualdades entre valores de switch y case. Por ejemplo, este tipo de condición no se puede implementar con un switch:

yourNumber = input('Enter a number: ');

if yourNumber < 0
    disp('Negative')
elseif yourNumber > 0
    disp('Positive')
else
    disp('Zero')
end

Comparaciones de arreglos en instrucciones condicionales

Es importante comprender cómo funcionan los operadores relacionales y las instrucciones if con las matrices. Cuando desee comprobar la igualdad entre dos variables, podría usar la siguiente condición:

if A == B, ...

Esto es código válido de MATLAB, y actúa según lo esperado cuando A y B son escalares. Pero cuando A y B son matrices, A == B no prueba si son iguales, sino dónde son iguales. El resultado es otra matriz de ceros y unos que muestra la igualdad elemento por elemento.

A = magic(4);
B = A;
B(1,1) = 0;

A == B

ans =

  4×4 logical array

   0   1   1   1
   1   1   1   1
   1   1   1   1
   1   1   1   1

La forma adecuada de comprobar la igualdad entre dos variables es usando la función isequal:

if isequal(A, B), ...

isequal devuelve un valor escalar lógico de 1 (que representa la variable true) o 0 (false), en lugar de una matriz, como la expresión a evaluar por la función if. Si se utilizan las matrices A y B anteriores, se obtiene:

isequal(A,B)

ans =

  logical

   0

El siguiente ejemplo ayuda a enfatizar este punto. Si A y B son escalares, el siguiente programa nunca alcanzará la “situación inesperada” del final. Sin embargo, para la mayoría de los pares de matrices, incluyendo nuestros cuadrados mágicos con columnas intercambiadas, ninguna de las condiciones A > B, A < B o A == B resulta válida para todos los elementos de las matrices. Por lo tanto, se ejecuta la cláusula else:

if A > B
   'greater'
elseif A < B
   'less'
elseif A == B
   'equal'
else
   error('Unexpected situation')
end

Hay varias funciones que ayudan a convertir comparaciones de matrices en condiciones escalares utilizables con if, incluyendo:

isequal
isempty
all
any

Control de bucle: for, while, continue, break

Esta sección trata las funciones de MATLAB que proporcionan control sobre bucles de programas.

for

El bucle for repite un grupo de instrucciones una cantidad de veces fija y predeterminada. Una función end correspondiente delimita las instrucciones:

for n = 3:32
   r(n) = rank(magic(n));
end
r

El punto y coma que finaliza la instrucción interna suprime la impresión repetida, y la r que aparece después del bucle muestra el resultado final.

Es recomendable sangrar los bucles para mejorar su legibilidad, en especial cuando están anidados:

for i = 1:m
   for j = 1:n
      H(i,j) = 1/(i+j);
   end
end

while

El bucle while repite un grupo de instrucciones una cantidad indefinida de veces bajo control de una condición lógica. Una función end correspondiente delimita las instrucciones.

El siguiente es un programa completo, que ilustra el uso de while, if, else y end, y utiliza la bisección de intervalos para buscar un cero de un polinomio:

a = 0; fa = -Inf;
b = 3; fb = Inf;
while b-a > eps*b
   x = (a+b)/2;
   fx = x^3-2*x-5;
   if sign(fx) == sign(fa)
      a = x; fa = fx;
   else
      b = x; fb = fx;
   end
end
x

El resultado es una raíz del polinomio x3 – 2x – 5, es decir:

x =
   2.09455148154233

Las precauciones asociadas a las comparaciones de matrices que se analizan en la sección de la instrucción if también se aplican a la instrucción while.

continue

La instrucción continue traslada el control a la siguiente iteración del bucle for o del bucle while en el cual aparece, y omite cualquier instrucción restante en el cuerpo del bucle. Lo mismo ocurre para las instrucciones continue dentro de bucles anidados. Es decir, la ejecución continúa al comienzo del bucle en el cual se encontró la instrucción continue.

El siguiente ejemplo muestra un bucle continue que cuenta las líneas de código del archivo magic.m y omite todos los comentarios y líneas en blanco. La instrucción continue se utiliza para avanzar a la siguiente línea de magic.m, sin incrementar la cuenta cuando se encuentra un comentario o una línea en blanco.

fid = fopen('magic.m','r');
count = 0;
while ~feof(fid)
    line = fgetl(fid);
    if isempty(line) || strncmp(line,'%',1) || ~ischar(line)
        continue
    end
    count = count + 1;
end
fprintf('%d lines\n',count);
fclose(fid);

break

La instrucción break le permite salir temprano de un bucle for o un bucle while. En bucles anidados, break sale solo del bucle más interno.

La siguiente alternativa mejora el ejemplo ofrecido en la sección anterior. ¿Por qué es recomendable este uso de break?

a = 0; fa = -Inf;
b = 3; fb = Inf;
while b-a > eps*b
   x = (a+b)/2;
   fx = x^3-2*x-5;
   if fx == 0
      break
   elseif sign(fx) == sign(fa)
      a = x; fa = fx;
   else
      b = x; fb = fx;
   end
end
x

Finalización del programa: return

Esta sección trata la función return de MATLAB, la cual permite terminar el programa antes de que este complete su ciclo.

return

La función return finaliza la secuencia actual de comandos y devuelve el control a la función invocadora o al teclado. return también se utiliza para terminar el modo keyboard (teclado). Normalmente, una función llamada transfiere el control a la función que la invocó cuando llega al final de la función. Es posible insertar una instrucción return dentro de la función llamada para forzar una finalización temprana y transferir el control a la función invocadora.

Vectorización

Una forma de lograr que los programas de MATLAB funcionen más rápidamente es vectorizar los algoritmos usados para la construcción de los programas. Donde otros lenguajes de programación usarían bucles for o bucles DO, MATLAB puede utilizar operaciones con vectores o matrices. Un ejemplo simple incluye la creación de una tabla de logaritmos:

x = .01;
for k = 1:1001
   y(k) = log10(x);
   x = x + .01;
end

Una versión vectorizada del mismo código es

x = .01:.01:10;
y = log10(x);

Para códigos más complicados, las opciones de vectorización no siempre son tan obvias.

Preasignación

Si no puede vectorizar una sección de código, puede hacer que sus bucles for funcionen más rápido mediante la preasignación de los vectores o arreglos que contienen los resultados de salida. Por ejemplo, este código utiliza la función zeros para preasignar el vector creado en el bucle for. Con esto, el bucle for se ejecuta significativamente más rápido:

r = zeros(32,1);
for n = 1:32
    r(n) = rank(magic(n));
end

Sin la preasignación del ejemplo anterior, el intérprete de MATLAB amplía el vector r, añadiéndole un elemento cada vez que ejecuta el código del bucle La preasignación de vectores elimina este paso, lo cual resulta en una ejecución más rápida.