File Exchange

image thumbnail

Structure Cut

version 1.0 (1.56 KB) by

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

1 Download


View License

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!

Comments and Ratings (8)

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!

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

The script above is really just an example.

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

Oleg Komarov

Oleg Komarov (view profile)

There is recursion and eval is not the solution.

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.

Oleg Komarov

Oleg Komarov (view profile)

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


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.

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


MATLAB Release
MATLAB 7.11 (R2010b)

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video