Generating Exaustive Parameter Combinations

Hi Everyone.
I want to create many Simulink.SimulationInput Objekts to simulate with many parameters.
To achieve this I am looking for a way to create exhaustive combinations of parameters.
I have not yet decided but thought, that structs might be usefull here. So far the Idea looks like this:
%function simIn = createSimIn(ModelName,Parameters)
% ParameterNames = fieldnames(Parameters);
% simIn(1:length(Parameters)) = Simulink.SimulationInput(ModelName);
% for i = 1:length(Parameters)
% for ii = 1:length(ParameterNames)
% simIn(i) = simIn(i).setVariable(ParameterNames(ii),Paramters(i).(ParameterNames(ii)),'Workspace',simIn(i).ModelName);
% end
% end
%end
To get this running I would need a way to create a struct with and exhaustive combination of the parameters.
Lets say I have parameters:
a = 1:5;
b= 0:0.1:0.4;
Example = struct('a',num2cell(a),'b',num2cell(b))
Example = 1×5 struct array with fields:
a b
I would want to create a struct that contains an exhaustive combinations, for a known number of parameters and equal lengths i can do:
Example = struct('a',num2cell(sort(repmat(a,1,length(b)))), ...
'b',num2cell(repmat(b,1,length(a),1)))
Example = 1×25 struct array with fields:
a b
But I would want to do it for an arbitrary number of parameters and arbitrary multiplicities for the parameters. Is there an easier way to do this?

2 Comments

What about using meshgrid or loops?
Loops are my fallback option, but they are ugly, so i hoped there might be a nicer way to doing this.
Meshgrids i never heard of before, but I just looked it up, looks like you can only use that for 2 and 3D Data.

Sign in to comment.

 Accepted Answer

I start with a scalar structure s rather than the structure array, since paramereters might have different lengths
s=struct('a', 1:3, ...
'b', 1:4, ...
'c', 1:5)
s = struct with fields:
a: [1 2 3] b: [1 2 3 4] c: [1 2 3 4 5]
c = struct2cell(s);
n = length(c);
[c{:}] = ndgrid(c{:});
A = reshape(cat(n+1,c{:}),[],n);
sarg = [fieldnames(s)'; num2cell(num2cell(A),1)];
Sexpand = struct(sarg{:})'
Sexpand = 1×60 struct array with fields:
a b c

5 Comments

Thank You! I do not yet understand how it works, but it works perfectly.
How did you come up with this?
Hey, I realized one quirk with your code.
When one parameter in s is a string, then the cat() turns everything into strings. I guess this is due to cats output beeing an array, that requires contents to have the same datatype.
Is there an easy work around?
Example:
s=struct('a', 1:3, ...
'b', 1:4, ...
'c', 1:5, ...
'str', "Test")
s = struct with fields:
a: [1 2 3] b: [1 2 3 4] c: [1 2 3 4 5] str: "Test"
c = struct2cell(s);
n = length(c);
[c{:}] = ndgrid(c{:});
A = reshape(cat(n+1,c{:}),[],n);
sarg = [fieldnames(s)'; num2cell(num2cell(A),1)];
Sexpand = struct(sarg{:})'
Sexpand = 1×60 struct array with fields:
a b c str
Sexpand(2)
ans = struct with fields:
a: "2" b: "1" c: "1" str: "Test"
Sorry my code is never intended to work on anything different than numerical data.
Here is the fix:
s=struct('a', 1:3, ...
'b', 1:4, ...
'c', 1:5, ...
'str', "Test")
s = struct with fields:
a: [1 2 3] b: [1 2 3 4] c: [1 2 3 4 5] str: "Test"
c = cellfun(@num2cell,struct2cell(s),'unif',0);
n = length(c);
[c{:}] = ndgrid(c{:});
A = reshape(cat(n+1,c{:}),[],n);
sarg = [fieldnames(s)'; num2cell(A,1)];
Sexpand = struct(sarg{:});
Sexpand(1)
ans = struct with fields:
a: 1 b: 1 c: 1 str: "Test"
Sexpand(end)
ans = struct with fields:
a: 3 b: 4 c: 5 str: "Test"

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!