Variable number of optimizableVariables in a bayesopt function
10 views (last 30 days)
Show older comments
As an example, for two variables I am using the bayesopt function, declaring the variables and calling the function like so:
C{1} = optimizableVariable('A',[1 2],'Transform','none');
C{2} = optimizableVariable('B',[1 2],'Transform','none');
fun = @(x)myfun(x.A,x.B);
results = bayesopt(fun,[C{:}],'AcquisitionFunctionName','expected-improvement-plus','IsObjectiveDeterministic',true,'ExplorationRatio',0.1,'NumSeedPoints',10,'MaxObjectiveEvaluations',Steps,'PlotFcn',{@plotObjectiveModel,@plotMinObjective});
I would like the number optimizableVariables to be variable, such that I could define fun as fun = @(x)myfun(x.(variable number of variables)).
The x. notation has been tripping me up here, I have tried using a cell array inside the function definition, which hasn't worked.
How could I achieve this?
0 Comments
Answers (2)
Ayush Aniket
on 16 Aug 2023
You can use the cell array to store all the various variables using a custom function( getVariableValues) and then call the function inside the argument in your anonymous function in the following way:
% Define the variable names
variableNames = {'A', 'B', 'C'}; % Add more variable names as needed
% Create the optimizable variables
for i = 1:numel(variableNames)
C{i} = optimizableVariable(variableNames{i}, [1 2], 'Transform', 'none');
end
% Create the function handle
fun = @(x) myfun(getVariableValues(x, variableNames));
% Call the bayesopt function
Steps = 100; % Number of steps for optimization
results = bayesopt(fun, [C{:}], 'AcquisitionFunctionName', 'expected-improvement-plus', ...
'IsObjectiveDeterministic', true, 'ExplorationRatio', 0.1, 'NumSeedPoints', 10, ...
'MaxObjectiveEvaluations', Steps, 'PlotFcn', {@plotObjectiveModel, @plotMinObjective});
% Define the helper function to retrieve variable values
function values = getVariableValues(x, variableNames)
values = cell(1, numel(variableNames));
for i = 1:numel(variableNames)
values{i} = x.(variableNames{i}); %dynamic field reference
end
end
The code utilises the concept of dynamic field reference. See this documentation page for more information.
Hope this helps!
0 Comments
Paolo Manfredi
on 15 Mar 2025
Edited: Paolo Manfredi
on 15 Mar 2025
I don't know if this is still relevant, but I had been struggling with the same issue until I realized that bayesopt passes optimizable variables x in the form of a table (see Table class). Hence, when you pass your A and B values as x.A and x.B, you are actually passing the columns of table x. However, you can also access values in table columns as x{:,1}, x{:,2}, etc.
For example, your code could be rewritten as
C(1) = optimizableVariable('A',[1 2],'Transform','none');
C(2) = optimizableVariable('B',[1 2],'Transform','none');
results = bayesopt(@(x) myfun(x{:,1},x{:,2}),C,'AcquisitionFunctionName','expected-improvement-plus', ...
'IsObjectiveDeterministic',true,'ExplorationRatio',0.1,'NumSeedPoints',10, ...
'MaxObjectiveEvaluations',Steps,'PlotFcn',{@plotObjectiveModel,@plotMinObjective});
Note that the order of the variables in the columns of x is defined by their order in C.
In this way, you can dynamically allocate a different number of optimizable variable in C and recall them inside myfun using bracket indexing.
0 Comments
See Also
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!