operator matrices matmul code matlab operator-overloading cell arithmetic-expressions

matrices - sum matlab



MATLAB: ¿Es posible sobrecargar los operadores en construcciones nativas(celdas, estructuras, etc.)? (1)

Estoy usando celdas para administrar datos en algunas cosas en las que estoy trabajando. Me gustaría poder hacer cosas como:

A = cellfun( @(X)( randn( 5,5 ) ), cell( 5,1 ), ''UniformOutput'', 0 ); B = cellfun( @(X)( randn( 5,5 ) ), cell( 5,1 ), ''UniformOutput'', 0 ); %# %# Each of the following would fail if cell member dimensions %# don''t match up %# %# matrix sums for each cell entry %# C = A + B; C = cellfun( @(X,Y)( X + Y ), A, B, ''UniformOutput'', 0 ); %# %# direct/hadamard product %# D = A .* B; D = cellfun( @(X,Y)( X .* Y ), A, B, ''UniformOutput'', 0 ); %# %# matrix-matrix products (not across all entries) %# E = A * B; E = cellfun( @(X,Y)( X * Y ), A, B, ''UniformOutput'', 0 );

Sin embargo, no quiero que la sintaxis extremadamente verbosa lo haga. Parece un poco exagerado crear una nueva clase para esto cuando todo lo que quiero hacer es proporcionar una definición para los operadores matemáticos en las celdas.

La pregunta: ¿Es una clase la única manera de hacerlo?

Si escribo una clase para hacer esto, ciertamente hace que sea más fácil escribir el código. Los mayores negativos que veo están relacionados con las optimizaciones, aunque hay algunas otras cosas que me molestan al respecto ...

Cualquier optimización que se realice detrás de escena (por ejemplo, cuando Jacket compila algo para ejecutarse en una GPU) podría tener más dificultades para determinar qué optimizaciones realizar. Como ejemplo, supongamos que tengo dos celdas (A, B) que contienen varias matrices de dimensión apropiada. Si escribo código para producir una nueva celda:

Z = c1*A + c2*B

... con los escalares {c1, c2}, puedo escribirlo de tal manera que Jacket (o lo que sea) determinará fácilmente que debe hacer los cálculos como:

Z{kk} = c1*A{kk} + c2*B{kk}

O tal vez una optimización aún mejor que eso. De otra manera. puede terminar con algo más lento y / o menos eficiente en memoria, por ejemplo:

temp1 = cellfun( @(X)( c1*X ), A ); temp2 = cellfun( @(X)( c2*X ), B ); Z = cellfun( @plus, temp1, temp2 );

Suponiendo que MATLAB o Jacket no puedan optimizarlo, esto terminaría usando demasiada memoria.


De hecho, es posible crear nuevos operadores o sobrecargar los existentes para los tipos de datos incorporados en MATLAB. Describo un ejemplo de esto en mi respuesta a otra pregunta SO sobre la modificación del comportamiento de desbordamiento predeterminado de los tipos de enteros .

Primero, es posible que desee ver qué métodos existen actualmente para los arreglos de celdas. Puede hacerlo utilizando la función METHODS , y esto es lo que obtengo en MATLAB R2010b:

>> methods cell Methods for class cell: aa2nt issorted regexptranslate strfind accumarray newdepfun reshape strjust cell2struct nt2aa rna2dna strmatch ctranspose nwalign seq2regexp strtok display permute setdiff transpose dna2rna regexp setxor union intersect regexpi sort unique ismember regexprep strcat

Los métodos del operador aritmético se mostrarían en la lista anterior como sus funciones equivalentes , como plus para el operador + o times para el operador. .* . Solo se define el método de transpose (operador .'' ) Para matrices de celdas. Tendría que crear el resto usted mismo, definiendo cómo se comportará un operador dado para los argumentos de matrices de celdas.

Puede hacer esto creando primero una nueva carpeta llamada @cell y colocándola en una carpeta existente en su ruta de MATLAB . Luego @cell tus nuevos métodos en la carpeta @cell . Por ejemplo, una implementación muy simple de un método plus para matrices de celdas (sin ninguna comprobación de entrada, comprobación de errores, etc.) sería esta:

function C = plus(A,B) C = cellfun(@plus,A,B,''UniformOutput'',false); %# Apply plus cell-wise end

En el código anterior, probablemente querrá primero comprobar que los operandos A y B son matrices de celdas del mismo tamaño. Sin embargo, puede crear cualquier funcionalidad única que desee, como permitir que B sea ​​un valor escalar que se agregaría a cada celda de A Depende de usted definir cómo se comportará el operador + para los arreglos de celdas.

Esto le permitiría escribir su código de una manera mucho más compacta, como en este ejemplo:

>> A = {[1 2 3] [4 5] 6}; %# One 3-element cell array >> B = {5 [4 5] 2}; %# Another 3-element cell array >> C = A+B; %# Use the new plus operator >> C{:} %# Display the cell contents ans = 6 7 8 ans = 8 10 ans = 8

Realmente no puedo hablar sobre las optimizaciones detrás de escena y cómo esto podría afectarlas. Sé que la documentación "Técnicas para mejorar el rendimiento" menciona específicamente esto sobre la sobrecarga de funciones incorporadas :

La sobrecarga de las funciones integradas de MATLAB en cualquiera de las clases de datos estándar de MATLAB puede afectar negativamente el rendimiento. Por ejemplo, si sobrecarga la función plus para manejar cualquiera de las clases de enteros de manera diferente, puede obstaculizar ciertas optimizaciones en el código de función incorporada de MATLAB para plus , y así puede ralentizar cualquier programa que haga uso de esta sobrecarga.

Sin embargo, en su caso, no está sobrecargando las funciones existentes para una clase. Simplemente estás creando nuevos que no existían para esa clase, por lo que es difícil decir qué efecto puede tener esto en última instancia en el rendimiento.