Code covered by the BSD License  

Highlights from
Structure Cut

Be the first to rate this file! 8 Downloads (last 30 days) File Size: 1.56 KB File ID: #29074

Structure Cut

by

 

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

| Watch this File

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!
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (8)
21 Oct 2010 Sean Bryan

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!

21 Oct 2010 Oleg Komarov

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}))
% Jump to the next depth level
struct = recursiveScut(sstruct.(fnames{1}),idx)
else
% Apply cut
s.(fnames{1})(...idx...)
end
end

The script above is really just an example.

20 Oct 2010 Sean Bryan

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

20 Oct 2010 Oleg Komarov

There is recursion and eval is not the solution.

19 Oct 2010 Sean Bryan

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.

19 Oct 2010 Oleg Komarov

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

Oleg

19 Oct 2010 Sean Bryan

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.

19 Oct 2010 Oleg Komarov

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
- see also line
- history section author details

Oleg

Contact us