2013-03-01 19 views
6

Mam zagnieżdżoną tablicę struktury t w formacie t.a.b = wartość, gdzie a i a są po prostu losowymi ciągami. t może mieć dowolną liczbę a jako nazwy pól, a każda z nich może mieć dowolną liczbę b jako nazwy pól. Muszę wykonać kopię t, zwaną x, ale ustawić wszystkie x.a.b = 0. Dodatkowo potrzebuję stworzyć kolejną tablicę struktury w postaci y.a = 0 dla wszystkich wt. W tej chwili używam zagnieżdżonego rozwiązania pętli for, ale jest zbyt wolny, jeśli jest ich zbyt wiele a i b. Czy ktoś może mi powiedzieć, czy istnieje sposób na wektorowanie tej zagnieżdżonej pętli lub jakiejkolwiek innej operacji w tym kodzie, aby ten kod działał szybciej? Dzięki.Matlab jak wektorować podwójną pętlę? Ustawianie wartości dla macierzy zagnieżdżonych jest bardzo wolne.

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 

Próbka:

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

może Pan podać kilka przykładowych wejść z odpowiednimi wyjściami ? I wskazać, co masz na myśli przez "wiele" i "wolno"? –

+0

Wiele może zawierać nawet do kilkudziesięciu tysięcy kombinacji t.a.b i powolnych, jak w godzinach. – user2017502

+1

Naprawiono literówkę w kodzie, na pierwszy rzut oka jedyne co zauważyłem, to to, że nie dokonałeś wstępnej alokacji y, nie wiesz ile będzie tego wpływu. Czy możesz uruchomić go na kilka minut i podać wyniki profilera? –

Odpowiedz

0

Aby skonstruować y, można zrobić coś takiego:

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

Zasadniczo jesteś dopiero się fieldnames, przeplatanie ich zerami w komórce array, a następnie bezpośrednio konstruując strukturę z rozdzieloną przecinkami listą nazw pól i wartości, z tej tablicy komórek.

Dla x, obawiam się, że nadal trzeba pętli na pierwszym poziomie nazw pól, tak myślę. Ale powinieneś być w stanie zrobić coś podobnego do powyższego w ramach każdej iteracji pętli.

2

można pozbyć się wszystkich pętlach wykonując przy użyciu 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); 

Gdybyś arbitralne zagnieżdżanie pól zeroSubfields może zostać przedłużony do

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

Co powiesz na wydajność tej metody w porównaniu do metody pytającego? –

+0

Zakładam, że szybciej, ponieważ nie ma żadnych wyraźnych pętli, ale nie wiem, ile szybciej ta metoda jest. Pytający poprosił o wektoryzację ich kodu i to jest to, co dostarczyłem. – mfbutner