Domanda

Sto usando le celle per gestire i dati in alcune cose su cui sto lavorando. Mi piacerebbe poter fare cose come:

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

Tuttavia, non voglio che la sintassi estremamente verbosa lo faccia. Sembra un po 'esagerato creare una nuova classe per questo quando tutto quello che voglio fare è fornire una definizione per gli operatori di matematica sulle celle.

La domanda: una classe è l'unico modo per farlo?

Se scrivo una classe per farlo, certamente rende più facile scrivere il codice. I maggiori negativi che vedo sono legati alle ottimizzazioni, anche se ci sono alcune altre cose che mi infastidiscono ..

Eventuali ottimizzazioni in corso dietro le quinte (ad esempio, quando la giacca compila qualcosa da eseguire su una GPU) avrebbe potenzialmente più difficile determinare quali ottimizzazioni fare. Ad esempio, supponiamo di avere due cellule (a, b) contenenti una serie di matrici di dimensione appropriata. Se scrivo codice per produrre una nuova cella:

Z = c1*A + c2*B

... Con gli scalari {C1, C2}, posso scriverlo in modo tale che la giacca (o qualsiasi altra cosa) determinerà facilmente che dovrebbe fare i calcoli come:

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

O forse un'ottimizzazione ancora migliore di così. Altrimenti. Può finire con qualcosa di più lento e/o meno efficiente della memoria, ad esempio:

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

Supponendo che matlab o giacca non siano in grado di ottimizzarlo, ciò finirebbe per usare troppa memoria.

È stato utile?

Soluzione

È in effetti possibile creare nuovi operatori o sovraccaricare quelli esistenti per tipi di dati integrati in MATLAB. Descrivo un esempio di questo in la mia risposta a un'altra domanda così su Modifica del comportamento di overflow predefinito dei tipi interi.

Innanzitutto, potresti voler guardare quali metodi esistono attualmente per gli array di celle. Puoi farlo usando la funzione Metodi, ed ecco cosa ottengo in 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           

I metodi dell'operatore aritmetico verrebbero visualizzati nell'elenco sopra come loro Equivalenti della funzione, piace plus per il + operatore o times per il .* operatore. Solo il transpose metodo (.' operatore) è definito per gli array di celle. Dovresti creare il resto da solo, definendo come un determinato operatore si comporterà per gli argomenti di array di celle.

Puoi farlo prima creando una nuova cartella chiamata @cell e posizionandolo in una cartella esistente sul tuo Matlab Path. Positeresti quindi i tuoi nuovi metodi in @cell cartella. Ad esempio, a molto semplice implementazione di a plus Metodo per array di celle (senza alcun controllo input, controllo degli errori, ecc.) Sarebbe questo:

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

Nel codice sopra, probabilmente vorresti prima verificare che gli operandi A e B sono array di celle della stessa dimensione. Tuttavia, potresti creare qualsiasi funzionalità unica che desideri, come consentire B essere un valore scalare che verrebbe aggiunto a ogni cella di A. Sta totalmente a te definire come il + L'operatore si comporterà per gli array di celle.

Ciò ti consentirebbe quindi di scrivere il tuo codice in un modo molto più compatto, come in questo esempio:

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

Non posso davvero parlare con le ottimizzazioni dietro le quinte e come ciò possa influenzarle. So che la documentazione "Tecniche per migliorare le prestazioni" lo menziona specificamente su sovraccarico di funzioni integrate:

Il sovraccarico di funzioni integrate MATLAB su una qualsiasi delle classi di dati MATLAB standard può influire negativamente sulle prestazioni. Ad esempio, se sovraccarichi il plus Funzione per gestire una qualsiasi delle classi intera in modo diverso, è possibile ostacolare alcune ottimizzazioni nel codice funzione integrato MATLAB per plus, e quindi può rallentare tutti i programmi che utilizzano questo sovraccarico.

Tuttavia, nel tuo caso non stai sovraccaricando esistente funzioni per una classe. Stai semplicemente creando di nuovi che non esistevano per quella classe, quindi è difficile dire quale effetto ciò possa avere alla fine sulle prestazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top