Saltar al contenido

Cómo escribir funciones vectorizadas en MATLAB

Encontramos el hallazgo a esta obstáculo, o por lo menos eso pensamos. Si sigues con inquietudes dínoslo, que sin dudas

Solución:

Actualización 2(para abordar su pregunta actualizada)

MATLAB está optimizado para funcionar bien con arreglos. Una vez que te acostumbras, en realidad es muy bueno tener que escribir una línea y hacer que MATLAB haga todo el bucle 4D por sí mismo sin tener que preocuparse por eso. MATLAB se usa a menudo para la creación de prototipos/cálculos únicos, por lo que tiene sentido ahorrar tiempo a la persona que codifica y renunciar a algo de C.[++|#]la flexibilidad.

Esta es la razón por MATLAB hace internamente algunos bucles muy bien – a menudo codificándolos como una función compilada.

El fragmento de código que das realmente no contiene la línea de código relevante que hace el trabajo principal, a saber

% Sort along given dimension
x = sort(x,dim);

En otras palabras, el código que muestra solo necesita acceder a los valores medianos por su índice correcto en el multidimensional ahora ordenado array x (que no toma mucho tiempo). El trabajo real accediendo a todos array elementos fue hecho por sortque es una función incorporada (es decir, compilada y altamente optimizada).

respuesta original(sobre cómo construir sus propias funciones rápidas trabajando en matrices)

En realidad, hay bastantes integrados que toman un parámetro de dimensión: min(stack, [], n), max(stack, [], n), mean(stack, n), std(stack, [], n), median(stack,n), sum(stack, n)… junto con el hecho de que otras funciones integradas como exp(), sin() trabajar automáticamente en cada elemento de su conjunto array (es decir sin(stack) automáticamente hace cuatro bucles anidados para usted si stack es 4D), puede crear muchas funciones que podría necesitar simplemente confiando en las funciones integradas existentes.

Si esto no es suficiente para un caso particular, debe echar un vistazo a repmat, bsxfun, arrayfun y accumarray que son funciones muy poderosas para hacer las cosas “a la manera de MATLAB”. Simplemente busque en SO preguntas (o más bien respuestas) usando uno de estos, aprendí mucho sobre los puntos fuertes de MATLAB de esa manera.

como un ejemplodigamos que desea implementar la norma p de pila a lo largo de la dimensión npodrías escribir

function result=pnorm(stack, p, n)
result=sum(stack.^p,n)^(1/p);

… donde efectivamente reutiliza la “capacidad de qué dimensión” de sum.

Actualizar

Como señala Max en los comentarios, también eche un vistazo al operador de dos puntos (:) que es una herramienta muy poderosa para seleccionar elementos de una array (o incluso cambiándolo de forma, que generalmente se hace con reshape).

En general, eche un vistazo a la sección Operaciones de matriz en la ayuda: contiene repmat et al. mencionado anteriormente, pero también cumsum y algunas funciones de ayuda más oscuras que debe usar como bloques de construcción.

¿Podría explicarme por qué este código es tan efectivo en comparación con los bucles anidados simples? Tiene bucles anidados al igual que la otra función.

El problema con los bucles anidados no son los bucles anidados en sí mismos. Son las operaciones que realizas en el interior.

Cada llamada de función (especialmente a una función no integrada) genera un poco de sobrecarga; más aún si la función realiza, por ejemplo, una comprobación de errores que lleva la misma cantidad de tiempo independientemente del tamaño de entrada. Por lo tanto, si una función tiene una sobrecarga de solo 1 ms, si la llama 1000 veces, habrá perdido un segundo. Si puede llamarlo una vez para realizar un cálculo vectorizado, paga los gastos generales solo una vez.

Además, el compilador JIT (pdf) puede ayudar a vectorizar sencillo for-loops, donde, por ejemplo, solo realiza operaciones aritméticas básicas. Por lo tanto, los bucles con cálculos simples en su publicación se aceleran mucho, mientras que los bucles que llaman median no son.

Vectorización

Además de lo que ya se ha dicho, también debe comprender que la vectorización implica la paralelización, es decir, realizar operaciones concurrentes en los datos en lugar de la ejecución secuencial (piense en las instrucciones SIMD), e incluso aprovechar los subprocesos y los multiprocesadores en algunos casos…

Archivos MEX

Ahora bien, aunque el punto “interpretado versus compilado” ya se ha discutido, nadie mencionó que puede extender MATLAB escribiendo archivos MEX, que son ejecutables compilados escritos en C, que se pueden llamar directamente como función normal desde dentro de MATLAB. Esto le permite implementar partes críticas para el rendimiento utilizando un lenguaje de nivel inferior como C.

Orden de columna principal

Finalmente, cuando intente optimizar algún código, recuerde siempre que MATLAB almacena matrices en orden de columnas principales. Acceder a los elementos en ese orden puede generar mejoras significativas en comparación con otros órdenes arbitrarios.

Por ejemplo, en su pregunta vinculada anterior, estaba calculando el median de conjunto de imágenes apiladas a lo largo de alguna dimensión. Ahora, el orden en que se ordenan esas dimensiones afecta en gran medida el rendimiento. Ilustración:

%# sequence of 10 images
fPath = fullfile(matlabroot,'toolbox','images','imdemos');
files = dir( fullfile(fPath,'AT3_1m4_*.tif') );
files = strcat(fPath,filesep,files.name');      %'

I = imread( files1 );

%# stacked images along the 1st dimension: [numImages H W RGB]
stack1 = zeros([numel(files) size(I) 3], class(I));
for i=1:numel(files)
    I = imread( filesi );
    stack1(i,:,:,:) = repmat(I, [1 1 3]);   %# grayscale to RGB
end

%# stacked images along the 4th dimension: [H W RGB numImages]
stack4 = permute(stack1, [2 3 4 1]);

%# compute median image from each of these two stacks
tic, m1 = squeeze( median(stack1,1) ); toc
tic, m4 = median(stack4,4); toc
isequal(m1,m4)

La diferencia de tiempo fue enorme:

Elapsed time is 0.257551 seconds.     %# stack1
Elapsed time is 17.405075 seconds.    %# stack4

Reseñas y puntuaciones

Recuerda que tienes la capacidad de agregar una reseña si diste con la contestación.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *