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.
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 pourplus
, 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.