Main Content

Vectorización

Usar la vectorización

MATLAB® está optimizado para las operaciones con matrices y vectores. El proceso de revisión del código basado en bucles y orientado a escalares para usar las operaciones matriciales y vectoriales de MATLAB se denomina vectorización. Vectorizar el código merece la pena por varias razones:

  • Apariencia: El código matemático vectorizado se parece más a las expresiones matemáticas que aparecen en los libros de texto, lo que hace que el código sea más fácil de entender.

  • Menos propenso a errores: Sin bucles, el código vectorizado suele ser más corto. Con menos líneas de código, se dan menos oportunidades de introducir errores de programación.

  • Rendimiento: El código vectorizado a menudo se ejecuta mucho más rápido que el código correspondiente que contiene bucles.

Vectorizar código para el cálculo en general

Este código calcula el seno de 1001 valores que oscilan entre 0 y 10:

i = 0;
for t = 0:.01:10
    i = i + 1;
    y(i) = sin(t);
end

Esta es una versión vectorizada del mismo código:

t = 0:.01:10;
y = sin(t);

El segundo ejemplo de código se ejecuta más rápido que el primero y supone un uso más eficiente de MATLAB. Pruebe la velocidad de ejecución del sistema creando scripts que contengan el código que se muestra y, después, utilice las funciones tic y toc para medir el tiempo de ejecución.

Vectorizar código para tareas específicas

Este código calcula la suma acumulativa de un vector en cada quinto elemento:

x = 1:10000;
ylength = (length(x) - mod(length(x),5))/5;
y(1:ylength) = 0;
for n= 5:5:length(x)
    y(n/5) = sum(x(1:n));
end 

Mediante la vectorización, puede escribir un proceso de MATLAB mucho más conciso. Este código muestra una forma de realizar la tarea:

x = 1:10000;
xsums = cumsum(x);
y = xsums(5:5:length(x)); 

Operaciones con arreglos

Los operadores de arreglos realizan la misma operación para todos los elementos del conjunto de datos. Estos tipos de operaciones son útiles para cálculos repetitivos. Por ejemplo, suponga que recopila el volumen (V) de varios conos registrando su diámetro (D) y altura (H). Si recopila la información de un solo cono, puede calcular el volumen de ese único cono:

V = 1/12*pi*(D^2)*H;

Ahora, recopile información de 10.000 conos. Los vectores D y H contienen 10.000 elementos cada uno y desea calcular 10.000 volúmenes. En la mayoría de los lenguajes de programación, tiene que configurar un bucle similar a este código de MATLAB:

for n = 1:10000
   V(n) = 1/12*pi*(D(n)^2)*H(n);
end

Con MATLAB, puede realizar el cálculo de cada elemento de un vector con una sintaxis similar a la del caso del escalar:

% Vectorized Calculation
V = 1/12*pi*(D.^2).*H;

Nota

Si coloca un punto (.) antes de los operadores *, / y ^, se transforman en operadores de arreglos.

Los operadores de arreglos también le permiten combinar matrices de diferentes dimensiones. Esta expansión automática de las dimensiones de tamaño 1 es útil para vectorizar la creación de cuadrículas, las operaciones matriciales y vectoriales, etc.

Suponga que la matriz A representa puntuaciones de exámenes, cuyas filas denotan diferentes clases. Desea calcular la diferencia entre la puntuación media y las puntuaciones individuales de cada clase. Con un bucle, la operación es la siguiente:

A = [97 89 84; 95 82 92; 64 80 99;76 77 67;...
 88 59 74; 78 66 87; 55 93 85];

mA = mean(A);
B = zeros(size(A));
for n = 1:size(A,2)
    B(:,n) = A(:,n) - mA(n);
end

Una forma más directa de hacerlo es con A - mean(A), que evita la necesidad de un bucle y es significativamente más rápido.

devA = A - mean(A)
devA =

    18    11     0
    16     4     8
   -15     2    15
    -3    -1   -17
     9   -19   -10
    -1   -12     3
   -24    15     1

Aunque A es una matriz de 7 por 3 y mean(A) es un vector de 1 por 3, MATLAB amplía implícitamente el vector como si tuviera el mismo tamaño que la matriz y la operación se ejecuta como una operación normal de resta elemento por elemento.

El requisito de tamaño de los operandos es que, en cada dimensión, los arreglos deben tener el mismo tamaño o que uno de ellos sea 1. Si se cumple este requisito, las dimensiones en las que uno de los arreglos tiene un tamaño de 1 se amplían para tener el mismo tamaño que la dimensión correspondiente en el otro arreglo. Para obtener más información, consulte Tamaños de arreglos compatibles para operaciones básicas.

Otra área en la que la ampliación implícita es útil para la vectorización es si está trabajando con datos multidimensionales. Suponga que desea evaluar una función, F, de dos variables, x e y.

F(x,y) = x*exp(-x2 - y2)

Para evaluar esta función en todas las combinaciones de puntos de los vectores x e y, tiene que definir una cuadrícula de valores. En esta tarea, debe evitar usar bucles para iterar a través de las combinaciones de puntos. En su lugar, si uno de los vectores es una columna y el otro es una fila, MATLAB crea automáticamente la cuadrícula cuando los vectores se utilizan como un operador de arreglo, como x+y o x-y. En este ejemplo, x es un vector de 21 por 1 e y es un vector de 1 por 16, por lo que la operación produce una matriz de 21 por 16 ampliando la segunda dimensión de x y la primera dimensión de y.

x = (-2:0.2:2)'; % 21-by-1
y = -1.5:0.2:1.5; % 1-by-16
F = x.*exp(-x.^2-y.^2); % 21-by-16

Cuando desee crear de forma explícita las cuadrículas, puede usar las funciones meshgrid y ndgrid.

Operaciones lógicas con arreglos

Una ampliación lógica del procesamiento masivo de arreglos es vectorizar las comparaciones y la toma de decisiones. Los operadores de comparación de MATLAB aceptan entradas vectoriales y devuelven salidas vectoriales.

Por ejemplo, suponga que, mientras recopila los datos de 10.000 conos, registra varios valores negativos del diámetro. Puede determinar qué valores de un vector son válidos con el operador >=:

D = [-0.2 1.0 1.5 3.0 -1.0 4.2 3.14];
D >= 0
ans =

     0     1     1     1     0     1     1
Puede aprovechar directamente la potencia de la indexación lógica de MATLAB para seleccionar los volúmenes de cono válidos, Vgood, para los que los elementos correspondientes de D no son negativos:
Vgood = V(D >= 0);

MATLAB le permite realizar una operación lógica con AND u OR en los elementos de todo un vector con las funciones all y any, respectivamente. Puede lanzar una advertencia si todos los valores de D son inferiores a cero:

if all(D < 0)
   warning('All values of diameter are negative.')
   return
end

MATLAB también puede comparar dos vectores con tamaños compatibles, lo que le permite imponer más restricciones. Este código encuentra todos los valores en los que V no es negativo y D es mayor que H:

V((V >= 0) & (D > H))
El vector resultante tiene el mismo tamaño que las entradas.

Para ayudar con la comparación, MATLAB contiene valores especiales para denotar desbordamiento, subdesbordamiento y operadores indefinidos, como Inf y NaN. Los operadores lógicos isinf e isnan ayudan a realizar pruebas lógicas de estos valores especiales. Por ejemplo, a menudo resulta útil excluir valores NaN de los cálculos:

x = [2 -1 0 3 NaN 2 NaN 11 4 Inf];
xvalid = x(~isnan(x))
xvalid =

     2    -1     0     3     2    11     4   Inf

Nota

Inf == Inf devuelve valores “true”; sin embargo, NaN == NaN siempre devuelve valores “false”.

Operaciones con matrices

Al vectorizar código, a menudo se ha de crear una matriz con un tamaño o una estructura particulares. Existen técnicas para crear matrices uniformes. Por ejemplo, imagine que necesita una matriz de 5 por 5 de elementos iguales:

A = ones(5,5)*10;
Imagine también que necesita una matriz de valores repetidos:
v = 1:5;
A = repmat(v,3,1)
A =

     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5

La función repmat dispone de flexibilidad a la hora de crear matrices a partir de matrices o vectores más pequeños. repmat crea matrices repitiendo una matriz de entrada:

A = repmat(1:3,5,2)
B = repmat([1 2; 3 4],2,2)
A =

     1     2     3     1     2     3
     1     2     3     1     2     3
     1     2     3     1     2     3
     1     2     3     1     2     3
     1     2     3     1     2     3


B =

     1     2     1     2
     3     4     3     4
     1     2     1     2
     3     4     3     4

Operaciones de orden, configuración y recuento

En muchas aplicaciones, los cálculos realizados en un elemento de un vector dependen de otros elementos del mismo vector. Por ejemplo, un vector, x, puede representar un conjunto. El modo en que se ha de iterar a través de un conjunto sin un bucle for o while no es evidente. El proceso se aclara mucho más y la sintaxis es menos compleja cuando se utiliza código vectorizado.

Eliminar elementos redundantes

Existen varias formas de encontrar los elementos redundantes de un vector. Una forma implica utilizar la función diff. Después de ordenar los elementos del vector, los elementos adyacentes iguales producen una entrada de cero cuando se utiliza la función diff en dicho vector. Debido a que diff(x) produce un vector con un elemento menos que x, debe agregar un elemento que no sea igual que otro elemento del conjunto. NaN siempre cumple esta condición. Finalmente, puede utilizar el indexado lógico para elegir los elementos únicos del conjunto:

x = [2 1 2 2 3 1 3 2 1 3];
x = sort(x);
difference  = diff([x,NaN]);
y = x(difference~=0)
y =

     1     2     3
También puede realizar la misma operación usando la función unique:
y=unique(x);
Sin embargo, la funcionalidad unique puede proporcionar más funcionalidad de la necesaria y ralentizar la ejecución del código. Utilice las funciones tic y toc si desea medir el rendimiento de cada fragmento de código.

Contar elementos en un vector

En lugar de simplemente devolver el conjunto, o subconjunto, de x, puede contar el número de veces que aparece un elemento en un vector. Después de ordenar el vector, puede utilizar la función find para determinar los índices de los valores cero en diff(x) y mostrar dónde cambian de valor los elementos. La diferencia entre los índices posteriores de la función find indica el número de veces que aparece un elemento en particular:

x = [2 1 2 2 3 1 3 2 1 3];
x = sort(x);
difference  = diff([x,max(x)+1]);
count = diff(find([1,difference]))
y = x(find(difference))
count =

     3     4     3


y =

     1     2     3
La función find no devuelve índices de elementos NaN. Puede contar el número de valores NaN e Inf que utilizan las funciones isnan e isinf.

count_nans = sum(isnan(x(:)));
count_infs = sum(isinf(x(:)));

Funciones que se utilizan habitualmente en vectorización

FunciónDescripción
all

Determinar si todos los elementos de un arreglo son distintos a cero o verdaderos

any

Determinar si algún elemento de un arreglo es distinto a cero

cumsum

Suma acumulativa

diff

Diferencias y derivadas aproximadas

find

Encontrar índices y valores de elementos distintos a cero

ind2sub

Subíndices de índice lineal

ipermute

Invertir dimensiones permutables de arreglo en ND

logical

Convertir valores numéricos en lógicos

meshgrid

Cuadrícula rectangular en espacio en 2D y 3D

ndgrid

Cuadrícula rectangular en espacio en ND

permute

Reorganizar dimensiones de arreglo en ND

prod

Producto de los elementos del arreglo

repmat

Repetir copias del arreglo

reshape

Remodelar arreglo

shiftdim

Desplazar dimensiones

sort

Ordenar los elementos del arreglo

squeeze

Eliminar dimensiones del conjunto unitario

sub2ind

Convertir subíndices en índices lineales

sum

Suma de los elementos del arreglo

Temas relacionados

Sitios web externos