MATLAB: est-il possible de surcharger les opérateurs sur des constructions natives (cellules, structures, etc.)?

j'utilise des cellules pour gérer des données dans des trucs sur lesquels je travaille. J'aimerais être capable de 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 que la syntaxe extrêmement verbeuse le fasse. Il semble un peu exagéré de créer une nouvelle classe pour cela alors que tout ce que je veux faire est de fournir une définition pour les opérateurs mathématiques sur les cellules.

la question: une classe est-elle la seule façon de s'y prendre?

Si j'écris une classe pour ce faire, il est certainement plus facile d'écrire du code. Les plus grands négatifs que je vois sont liés aux optimisations, bien qu'il y ait quelques autres choses qui me tracassent à ce sujet..

toutes les optimisations en coulisse (par exemple, quand Jacket compile quelque chose à exécuter sur un GPU) auraient potentiellement plus de difficulté à déterminer quelles optimisations faire. À titre d'exemple, supposons que j'ai deux cellules (A,B) contenant un certain nombre de matrices de dimension appropriée. Si j'écris du code de produire une nouvelle cellule:

Z = c1*A + c2*B

... avec les scalaires {c1,c2}, je peux l'écrire de telle manière que la Veste (ou autre) va déterminer facilement qu'il doit faire de calculs:

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

ou peut-être une meilleure optimisation que cela. Autrement. il peut finir avec quelque chose de plus lent et/ou moins efficace en mémoire, par exemple:

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

en supposant que MATLAB ou Jacket ne soient pas en mesure de l'optimiser, cela finirait par utiliser trop de mémoire.

17
demandé sur gnovice 2011-03-20 01:50:29

1 réponses

il est en effet possible de créer de nouveaux opérateurs ou de surcharger les opérateurs existants pour les types de données intégrées dans MATLAB. Je décrire un exemple de ce dans ma réponse à l'autre question à propos de modifier la valeur par défaut de débordement de comportement des types d'entiers.

tout d'abord, vous voudrez peut-être examiner quelles méthodes existent actuellement pour les réseaux de cellules. Vous pouvez le faire en utilisant la fonction méthodes, et voici ce que J'obtiens à 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           

L'opérateur arithmétique des méthodes apparaîtra dans la liste ci-dessus comme leur equivalents de fonctions, comme plus pour les + opérateur ou times pour les .* opérateur. Seul le transpose méthode (.' opérateur) est défini pour les matrices de cellules. Vous devez créer le reste vous-même, définissant comment un opérateur donné se comportera pour les arguments de tableaux de cellules.

Vous pouvez le faire en faisant d'abord un nouveau dossier appelé @cell et le placer dans un dossier existant sur votre chemin MATLAB. Vous placerez alors vos nouvelles méthodes dans le @cell dossier. Par exemple, un très simple implémentation d'un plus méthode pour les tableaux de cellules (sans aucune entrée-vérification, erreur-vérification, etc.) serait la suivante:

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 tout d'abord vérifier que les opérandes A et B sont des réseaux cellulaires de même taille. Toutefois, vous pouvez créer tout ce que fonctionnalité unique que vous voulez, comme permettre B pour être une valeur scalaire qui serait ajouté à chaque cellule de A. Il est totalement à vous de définir comment l' + l'opérateur se comporte pour les tableaux de cellules.

cela vous permettrait alors d'écrire votre code de façon 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 des optimisations en coulisse et de la façon dont cela pourrait les affecter. Je sais que la documentation "Techniques d'Amélioration de la Performance" mentionne spécifiquement ceci à propos de surcharge des fonctions intégrées:

Overloading fonctions intégrées de MATLAB sur l'une des données MATLAB standard les classes peuvent affecter négativement performance. Par exemple, si vous la surcharge de l' plus fonction à manipuler tout entier classes autrement, vous pouvez entraver certains optimisations dans le MATLAB intégré code de fonction pour plus, et ainsi peut ralentir les programmes qui utilisent de cette surcharge.

Toutefois, dans votre cas, vous n'êtes pas surcharger existant fonctions de classe. Vous en créez simplement de nouveaux qui n'existaient pas pour cette classe, donc il est difficile de dire quel effet cela peut avoir sur la performance.

25
répondu gnovice 2017-05-23 11:46:42