DEV Community

monty5811
monty5811

Posted on • Originally published at deanmontgomery.com on

3 1

Matlab: getting rid of nested loops

Ever seen matlab code that looks like this? Maybe you are doing a grid search?

for x = 1:10
  for y = 1:5
    for z = 1:100
      for t = 1:2
        do_something(x, y, z, t)
      end
    end
  end
end

Enter fullscreen mode Exit fullscreen mode

This is pretty nasty, can we make this look better?

How about something like this?

params.X = 1:10;
params.Y = [2, 4, 8];

vectorized_parameters = build_vecd_params(params);
N = size(vectorised_parameters, 1);
for x = 1:N
    candidate = get_row_as_struct(params, vectorised_parameters, x);
    do_something(candidate);
end

Enter fullscreen mode Exit fullscreen mode

This looks much nicer, we don’t have nested loops and adding a new parameter to loop over is much cleaner.

We can even randomise the looping order pretty easily:

N = size(vectorised_parameters, 1);
iteration_order = randperm(N);
for x = 1:N
    idx = iteration_order(x);
    candidate = get_row_as_struct(params, vectorised_parameters, idx);
    do_something(candidate);
end

Enter fullscreen mode Exit fullscreen mode

How it works

We need to create the two functions:

  • build_vecd_params to create a matrix where each row is a single permutation of all variables we want to loop over
  • get_row_as_struct: to extract a row of the matrix and give us back a struct we can use to easily access each looping variable
function [vectorised_parameters] = build_vecd_params(params)
% params is a struct like
% params.X = 1:10;
% params.Y = [2, 4, 8];

all_ranges = struct2cell(params);
N = numel(all_ranges);
[grid{1:N}] = ndgrid(all_ranges{:});
vectorised_parameters = reshape(cat(N + 1, grid{:}), [], N);
end

function [candidate] = get_row_as_struct(params, vectorised_parameters, idx)
% return a `candidate` permutation of our loop variables
row = vectorised_parameters(idx, :);
fns = fieldnames(params)';
assert(numel(row) == numel(fns)); % sanity check
c = 1;
for fn_ = fns
    fn = char(fn_);
    candidate.(fn) = row(c);
    c = c + 1;
end
assert(c - 1 == numel(row)) % sanity check
end

Enter fullscreen mode Exit fullscreen mode

How to use it

Just copy the two functions above into your matlab file and you’re off to the races.

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay