Code covered by the BSD License

Highlights from Structure Cut

Be the first to rate this file! 1 Download (last 30 days) File Size: 1.56 KB File ID: #29074 Version: 1.0

Structure Cut

Sean Bryan (view profile)

Utility function that applies the same cut to specified elements of a structure.

File Information
Description

As an example, suppose you had taken 155 seconds of data of the location (x,y,z) of a particle as a function of time (t). It is convenient to put that all into a struct, such as this one:

>> data

data =

t: [155000x1 double]
x: [155000x1 double]
y: [155000x1 double]
z: [155000x1 double]

If you wanted to extract the data taken between 15 and 20 seconds, you would normally need to type

index = find((data.t > 15) & (data.t < 20));
cut_data.t = data.t(index);
cut_data.x = data.x(index);
cut_data.y = data.y(index);
cut_data.z = data.z(index);

Tedious, and prone to typos! Using the function "struct_cut" you can do the same thing by just typing

index = find((data.t > 15) & (data.t < 20));
cut_data = struct_cut(data,{'t','x','y','z'},index);

If you want to apply different cuts to each element of the structure, just type

cut_data = struct_cut(data,{'t','x','y','z'},{i_t,i_x,i_y,i_z});

where "i_t", "i_x", etc are four different cut arrays you make elsewhere.

I tested this with ~10-100 megabyte data sets, and it runs really fast. Hopefully it will work well for larger arrays also, please let me know!

MATLAB release MATLAB 7.11 (R2010b)
Other requirements Written on a Mac, but there is no reason to expect any platform-dependency. Let me know if there is though!
21 Oct 2010 Sean Bryan

Sean Bryan (view profile)

So, that occurred to me too, but then the structure gets passed around a lot. Plus, recursive functions might be as scary as eval, because of the looping potential there.

I guess it's just a matter of taste either way. Fee free to write recursive_struct_cut.m and post it too!

Comment only
21 Oct 2010 Oleg Komarov

Oleg Komarov (view profile)

Assuming that you can use recursion infinitely, the concept is that you can call a function and the same function can call itself till it reaches the deepest level.

Suppose we have the struct "s" (as created above), then this hypothetical recursive function will apply the cut to the deepest level.

function struct = recursiveScut(struct, idx)

fnames = fieldnames(struct)

if isstruct(sstruct.(fnames{1}))
struct = recursiveScut(sstruct.(fnames{1}),idx)
else
% Apply cut
s.(fnames{1})(...idx...)
end
end

The script above is really just an example.

Comment only
20 Oct 2010 Sean Bryan

Sean Bryan (view profile)

Is there a way to recursively create a command, and then evaluate whatever you've created? I thought that was what eval was for actually...

Comment only
20 Oct 2010 Oleg Komarov

Oleg Komarov (view profile)

There is recursion and eval is not the solution.

Comment only
19 Oct 2010 Sean Bryan

Sean Bryan (view profile)

Right, so the code constructs a string that has that syntax, and "eval" evaluates it.

To do this without eval, I would have needed lots of if statements. If the number of dots in the input string is 1, then run the hardcoded s.(sub). If the number of dots is 2, then run hardcoded s.(sub).(subsub), etc. Then if someone put in an input string with more dots than I hardcoded, the code wouldn't work.

Comment only
19 Oct 2010 Oleg Komarov

Oleg Komarov (view profile)

sub = 'a'
subsub = 'b'
s.a.b = 10;
s.(sub).(subsub)

Oleg

Comment only
19 Oct 2010 Sean Bryan

Sean Bryan (view profile)

Thanks for the feedback, Oleg! I'll definitely work on adding checks, better help, and a better example, because those are very important. Hopefully I'll have time... You're right that this isn't necessarily the most efficient way to store data, but I find it personally convenient for small to midsized datasets where ease of code reading is more important than cpu cycles.

The reason for the "eval" is that I don't think that dynamic field indexing supports substructures, which is weird. So, if I want to get to a field like data.particle_a.x, it throws an error if I type "data.('particle_a.x')". Access to substructures was important for my particular application, so I had to settle for second best. Any other ideas on this would be much appreciated.

Comment only
19 Oct 2010 Oleg Komarov

Oleg Komarov (view profile)

First, you don't mention that the dataset should be "squared" (but you can easily understand that by the way you apply the index) therefore I wouldn't recommend to store it separately in diffierent fields, it's not efficient.

Second you're using eval. Dynamic filed indexing is the way to go.

What it lacks:
- H1 line doesn't fit on one line
- checks
- help is not really explanatory
- examples