Variable number of optimizableVariables in a bayesopt function

조회 수: 12 (최근 30일)
Iwo Slodczyk
Iwo Slodczyk 2023년 7월 19일
편집: Paolo Manfredi 2025년 3월 15일
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?

답변 (2개)

Ayush Aniket
Ayush Aniket 2023년 8월 16일
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!

Paolo Manfredi
Paolo Manfredi 2025년 3월 15일
편집: Paolo Manfredi 2025년 3월 15일
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.

카테고리

Help CenterFile Exchange에서 Matrices and Arrays에 대해 자세히 알아보기

제품


릴리스

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by