2013-03-01 6 views
6

Ho un array di struttura nidificato t nel formato di t.a.b = value, dove a e b sono solo stringhe casuali. t può avere un numero arbitrario di a come nomi di campi e ognuno può avere un numero arbitrario di b come nomi di campi. Ho bisogno di fare una copia di t chiamato x, ma impostare tutti x.a.b = 0. Inoltre ho bisogno di creare un'altra matrice di struttura nella forma di y.a = 0 per tutti a in in t. In questo momento sto usando una soluzione annidata per loop ma è troppo lenta se ci sono troppe a e b's. Qualcuno può dirmi se esiste un modo per vettorizzare questo ciclo annidato o qualsiasi altra operazione in questo codice per rendere questo codice più veloce? Grazie.Matlab come vettorializzare doppio per ciclo? L'impostazione dei valori per l'array della struttura nidificata è molto lenta

names1 = fieldnames(t); 
x = t; 
y = {}; 
for i=1:length(names1) 
    y.(names1{i}) = 0; 
    names2 = fieldnames(x.(names1{i})); 
    for j=1:length(names2) 
     x.(names1{i}).(names2{j}) = 0; 
    end 
end 

Esempio:

if t is such that 
t.hello.world = 0.5 
t.hello.mom = 0.2 
t.hello.dad = 0.8 
t.foo.bar = 0.7 
t.foo.moo = 0.23 
t.random.word = 0.38 

then x should be: 
x.hello.world = 0 
x.hello.mom = 0 
x.hello.dad = 0 
x.foo.bar = 0 
x.foo.moo = 0 
x.random.word = 0 

and y should be: 
y.hello = 0 
y.foo = 0 
y.random = 0 
+1

Potresti dare alcuni input di esempio con le uscite corrispondenti ? E dare un'indicazione di cosa intendi per "molti" e "lento"? –

+0

Molti possono essere fino a decine di migliaia della combinazione t.a.b e lenti come in ore. – user2017502

+1

Corretto errore nel codice, a prima vista l'unica cosa che noto è che non hai pre-allocato y, non sono sicuro di quanto l'impatto sarebbe. Potresti eseguirlo per alcuni minuti e dare i risultati del profiler? –

risposta

0

per costruire y, si può fare qualcosa di simile:

>> t.hello.world = 0.5; 
>> t.hello.mom = 0.2; 
>> t.hello.dad = 0.8; 
>> t.foo.bar = 0.7; 
>> t.foo.moo = 0.23; 
>> t.random.word = 0.38; 
>> f = fieldnames(t); 
>> n = numel(f); 
>> fi = cell(1,n*2); 
>> fi(1:2:(n*2-1)) = f; 
>> fi(2:2:(n*2)) = num2cell(zeros(n,1)) 
fi = 
    'hello' [0] 'foo' [0] 'random' [0] 
>> y = struct(fi{:}) 
y = 
    hello: 0 
     foo: 0 
    random: 0 

In sostanza si sta solo ricevendo le fieldnames, li interleaving con zeri in una cella array, quindi costruendo direttamente la struttura con un elenco separato da virgole di nomi e valori di campo, da quella matrice di celle.

Per x, temo che avresti ancora bisogno di ricorrere al primo livello di nomi di campo, penso. Ma dovresti essere in grado di fare qualcosa di simile al precedente all'interno di ogni iterazione del ciclo.

2

È possibile liberarsi di tutti i loop facendo utilizzando structfun

function zeroed = always0(x) 
    zeroed = 0; 
endfunction 

function zeroedStruct = zeroSubfields(x) 
    zeroedStruct = structfun(@always0, x, 'UniformOutput', false); 
endfunction 

y = structfun(@always0, t, 'UniformOutput', false); 
x = structfun(@zeroSubfields, t, 'UniformOutput', false); 

Se tu avessi nidificazione arbitraria di campi zeroSubfields potrebbe essere esteso a

function zeroedStruct = zeroSubfields(x) 
    if(isstruct(x)) 
    zeroedStruct = structfun(@zeroSubfields, x, 'UniformOutput', false); 
    else 
    zeroedStruct = 0; 
    endif 
endfunction 
+0

E le prestazioni di questo metodo rispetto a quelle del richiedente? –

+0

Suppongo che sia più veloce perché non ci sono cicli espliciti ma non so quanto sia più veloce questo metodo. Il richiedente ha chiesto una vettorizzazione del proprio codice ed è quello che ho fornito. – mfbutner

Problemi correlati