Matlab: Est-il possible de surcharger les opérateurs sur les constructions indigènes (cellules, structs, etc.)?

StackOverflow https://stackoverflow.com/questions/5365464

Question

J'utilise les cellules pour gérer les données dans des choses que je travaille sur. Je voudrais pouvoir faire des choses comme:

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 );

Cependant, je ne veux pas la syntaxe extrêmement verbeux pour le faire. Il semble un peu trop loin de créer une nouvelle classe pour quand tout ce que je veux faire est de fournir une définition pour les opérateurs de mathématiques sur les cellules.

La question: est une classe la seule façon d'aller à ce sujet

Si j'écris une classe pour ce faire, il est certainement plus facile d'écrire le code. Les plus grands négatifs que je vois sont liés à des optimisations, mais il y a quelques autres choses qui me bug à ce sujet ..

Les optimisations en cours dans les coulisses (par exemple, quand veste compile quelque chose à exécuter sur un GPU) serait potentiellement avoir plus de difficulté à déterminer les optimisations à faire. A titre d'exemple, supposons que j'ai deux cellules (A, B) contenant un certain nombre de matrices de dimension appropriée. Si je écrire du code pour produire une nouvelle cellule:

Z = c1*A + c2*B

... avec {scalaires, c2} c1, je peux l'écrire dans une telle façon que veste (ou autre) détermineront facilement qu'il devrait faire les calculs:

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

ou peut-être une optimisation encore mieux que cela. Autrement. il peut se retrouver avec quelque chose de plus lent et / ou moins efficace de la mémoire, par exemple:

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

En supposant Matlab ou veste ne parviennent pas à optimiser, cela finirait par utiliser trop de mémoire.

Était-ce utile?

La solution

Il est en effet possible de créer de nouveaux opérateurs ou surcharge ceux qui existent déjà pour les types de données intégrés dans MATLAB. Je décris un exemple dans ma réponse à une autre question de SO à propos de modifier le comportement de débordement par défaut de types entiers .

D'abord, vous voudrez peut-être regarder quelles méthodes existent actuellement pour réseaux de cellules. Vous pouvez le faire en utilisant la fonction METHODES , et ce qui est ici, je reçois dans 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           

Les méthodes de l'opérateur arithmétique apparaîtrait dans la liste ci-dessus que leurs équivalents de fonction , comme plus pour l'opérateur de + ou times pour l'opérateur .*. Seule la méthode de transpose (opérateur .') est définie pour des réseaux de cellules. Vous devez créer le reste vous-même, comment définir un opérateur donné se comportera pour les arguments des réseaux de cellules.

Vous pouvez le faire en faisant d'abord un nouveau dossier appelé @cell et en le plaçant dans un dossier existant sur votre chemin Matlab. Vous pouvez ensuite placer vos nouvelles méthodes dans le dossier @cell. Par exemple, très mise en œuvre simple d'une méthode plus pour réseaux de cellules (sans vérification d'entrée, vérification des erreurs, etc.) serait ceci:

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

Dans le code ci-dessus, vous auriez probablement d'abord vouloir vérifier que les opérandes A et B sont des réseaux de cellules de la même taille. Cependant, vous pouvez créer toutes les fonctionnalités uniques que vous voulez, par exemple en permettant B d'être une valeur scalaire qui sont ajoutés à chaque cellule de A. Il est tout à fait à vous de définir comment l'opérateur + se comportera pour les tableaux de cellules.

Cela vous permettra d'écrire votre code d'une manière beaucoup plus compacte, comme dans cet exemple:

>> 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

Je ne peux pas vraiment parler aux arrière-scènes optimisations et comment cela pourrait les affecter. Je sais que la documentation « Techniques pour améliorer les performances » spécifique mentionne ceci à propos surcharge des fonctions intégrées :

Surcharge intégré Matlab fonctions sur l'une des données standard Matlab les classes peuvent avoir une incidence négative performance. Par exemple, si vous surcharger la fonction de poignée pour plus une des classes entières autrement, vous pouvez empêcher certains optimisations du Matlab intégré dans code de fonction pour plus, et peut donc ralentir tous les programmes qui utilisent de cette surcharge.

Cependant, dans votre cas, vous ne surchargez pas existants fonctions pour une classe. Vous créez simplement de nouvelles qui n'existaient pas pour cette classe, il est donc difficile de dire quel effet cela peut en fin de compte sur les performances.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top