Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matlab how to vectorize double for loop? Setting values for nested structure array is very slow

I have a nested structure array t in the format of t.a.b = value, where and a and b are just random strings. t can have an arbitrary number of a's as field names and each a can have an arbitrary number of b's as field names. I need to make a copy of t called x, but set all x.a.b = 0. In addition I need to make another structure array in the form of y.a = 0 for all a in t. Right now I'm using a nested for loop solution but it is too slow if there are too many a's and b's. Can someone tell me if there's any way to vectorize this nested loop or any other operation in this code as to make this code run faster? Thanks.

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 

Sample:

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
like image 509
user2017502 Avatar asked Mar 01 '13 08:03

user2017502


1 Answers

You can get rid of all the loops by doing using 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); 

If you had arbitrary nesting of fields zeroSubfields could be extended to

function zeroedStruct = zeroSubfields(x)
   if(isstruct(x))
     zeroedStruct = structfun(@zeroSubfields, x, 'UniformOutput', false);
   else
     zeroedStruct = 0;
   endif
endfunction
like image 112
mfbutner Avatar answered Oct 03 '22 11:10

mfbutner