How do I set up fmincon correctly for parallel computation? “Supplied objective function must return a scalar value”
I have an expensive objective function which takes in multiple parameters, while the contraints are constant. It looks something like this:
out1, out2 = obj_func(in1, in2)
in1 has 1000 different cases. For each possible value of in1, I want to minimize out1 by adjusting in2. At the same time, out2 has to be < 1 in all cases. Because obj_func takes a while to run, I want to parallelize the computation, either by calculating several gradients at the same time, or solve the problem for several in1.
Below is my simplified code:
nPoints = length(INVARS(:,1));
odInputNames = {‘DISA’; ‘ALT’; ‘MACH’};
% Number of batches depending on given batch size:
sizeBatch = 20;
nBatch = floor( nPoints/sizeBatch ) + 1; % Last batch contains remaining points
% Define constraints
CONSTR = struct(…
‘param_A’, ‘…’,…
‘param_B’, ‘…’,…
‘param_C’, ‘…’,…
CONSTR_REQ = [ 1800; …
1.10; …
1.15; …
];
for i = 1:nBatch
% Create batchwise input vectors
for iODVar = 1:length(odInputNames)
if i < nBatch
OD.(odInputNames{iODVar}) = INVARS(sizeBatch*(i-1)+1:sizeBatch*i, iODVar);
else
OD.(odInputNames{iODVar}) = INVARS(sizeBatch*(i-1)+1:end, iODVar); % Last batch has fewer points
end
end
% Setup of FMINCON Optimizer
% ———————————————————————
A = [];
b = [];
Aeq = [];
beq = [];
lb = ones(size(OD.DISA)) * 120;
ub = ones(size(OD.DISA)) * 80;
options = optimoptions(@fmincon, …
‘Algorithm’, ‘active-set’,…
‘MaxIter’, 200,…
‘ConstraintTolerance’, 1e-8,…
‘OptimalityTolerance’, 1e-8,…
‘Display’, ‘off’,…
‘UseParallel’, true);
x0 = ones(size(OD.DISA)) * 85;
% Declare constraint results to be shared between obj_fun and con_fun
constr_fields = fieldnames(CONSTR);
con_res = zeros(length(constr_fields), length(OD.DISA));
% Execute Optimizer
[PLA_max, obj_min,exitflag,~,~] = fmincon( @(x)obj_fun(x), x0, A, b, Aeq, beq, lb, ub, @(x)con_fun(), options );
% Objective:
function [obj] = obj_fun( PLA )
OD.PLA = PLA;
[OD.OUT, OD.IN] = expensive_function( DES, OD );
obj = – OD.OUT.param_obj;
for i=1:length(constr_fields)
con_res(i,:) = eval([‘OD.’ CONSTR.(constr_fields{i})]);
end
end
% Constraints:
function [c,ceq] = con_fun()
exp_CONSTR_REQ = repmat(CONSTR_REQ, 1, length(OD.DISA));
c = (con_res – exp_CONSTR_REQ); % Non-Equality constraint ( !<= 0 )
ceq = [];
end
It works fine when I solve one case at a time, but when I try to parallelize it I got this error. How can I fix it?
Error using fminunc (line 348)
Supplied objective function must return a scalar value.I have an expensive objective function which takes in multiple parameters, while the contraints are constant. It looks something like this:
out1, out2 = obj_func(in1, in2)
in1 has 1000 different cases. For each possible value of in1, I want to minimize out1 by adjusting in2. At the same time, out2 has to be < 1 in all cases. Because obj_func takes a while to run, I want to parallelize the computation, either by calculating several gradients at the same time, or solve the problem for several in1.
Below is my simplified code:
nPoints = length(INVARS(:,1));
odInputNames = {‘DISA’; ‘ALT’; ‘MACH’};
% Number of batches depending on given batch size:
sizeBatch = 20;
nBatch = floor( nPoints/sizeBatch ) + 1; % Last batch contains remaining points
% Define constraints
CONSTR = struct(…
‘param_A’, ‘…’,…
‘param_B’, ‘…’,…
‘param_C’, ‘…’,…
CONSTR_REQ = [ 1800; …
1.10; …
1.15; …
];
for i = 1:nBatch
% Create batchwise input vectors
for iODVar = 1:length(odInputNames)
if i < nBatch
OD.(odInputNames{iODVar}) = INVARS(sizeBatch*(i-1)+1:sizeBatch*i, iODVar);
else
OD.(odInputNames{iODVar}) = INVARS(sizeBatch*(i-1)+1:end, iODVar); % Last batch has fewer points
end
end
% Setup of FMINCON Optimizer
% ———————————————————————
A = [];
b = [];
Aeq = [];
beq = [];
lb = ones(size(OD.DISA)) * 120;
ub = ones(size(OD.DISA)) * 80;
options = optimoptions(@fmincon, …
‘Algorithm’, ‘active-set’,…
‘MaxIter’, 200,…
‘ConstraintTolerance’, 1e-8,…
‘OptimalityTolerance’, 1e-8,…
‘Display’, ‘off’,…
‘UseParallel’, true);
x0 = ones(size(OD.DISA)) * 85;
% Declare constraint results to be shared between obj_fun and con_fun
constr_fields = fieldnames(CONSTR);
con_res = zeros(length(constr_fields), length(OD.DISA));
% Execute Optimizer
[PLA_max, obj_min,exitflag,~,~] = fmincon( @(x)obj_fun(x), x0, A, b, Aeq, beq, lb, ub, @(x)con_fun(), options );
% Objective:
function [obj] = obj_fun( PLA )
OD.PLA = PLA;
[OD.OUT, OD.IN] = expensive_function( DES, OD );
obj = – OD.OUT.param_obj;
for i=1:length(constr_fields)
con_res(i,:) = eval([‘OD.’ CONSTR.(constr_fields{i})]);
end
end
% Constraints:
function [c,ceq] = con_fun()
exp_CONSTR_REQ = repmat(CONSTR_REQ, 1, length(OD.DISA));
c = (con_res – exp_CONSTR_REQ); % Non-Equality constraint ( !<= 0 )
ceq = [];
end
It works fine when I solve one case at a time, but when I try to parallelize it I got this error. How can I fix it?
Error using fminunc (line 348)
Supplied objective function must return a scalar value. I have an expensive objective function which takes in multiple parameters, while the contraints are constant. It looks something like this:
out1, out2 = obj_func(in1, in2)
in1 has 1000 different cases. For each possible value of in1, I want to minimize out1 by adjusting in2. At the same time, out2 has to be < 1 in all cases. Because obj_func takes a while to run, I want to parallelize the computation, either by calculating several gradients at the same time, or solve the problem for several in1.
Below is my simplified code:
nPoints = length(INVARS(:,1));
odInputNames = {‘DISA’; ‘ALT’; ‘MACH’};
% Number of batches depending on given batch size:
sizeBatch = 20;
nBatch = floor( nPoints/sizeBatch ) + 1; % Last batch contains remaining points
% Define constraints
CONSTR = struct(…
‘param_A’, ‘…’,…
‘param_B’, ‘…’,…
‘param_C’, ‘…’,…
CONSTR_REQ = [ 1800; …
1.10; …
1.15; …
];
for i = 1:nBatch
% Create batchwise input vectors
for iODVar = 1:length(odInputNames)
if i < nBatch
OD.(odInputNames{iODVar}) = INVARS(sizeBatch*(i-1)+1:sizeBatch*i, iODVar);
else
OD.(odInputNames{iODVar}) = INVARS(sizeBatch*(i-1)+1:end, iODVar); % Last batch has fewer points
end
end
% Setup of FMINCON Optimizer
% ———————————————————————
A = [];
b = [];
Aeq = [];
beq = [];
lb = ones(size(OD.DISA)) * 120;
ub = ones(size(OD.DISA)) * 80;
options = optimoptions(@fmincon, …
‘Algorithm’, ‘active-set’,…
‘MaxIter’, 200,…
‘ConstraintTolerance’, 1e-8,…
‘OptimalityTolerance’, 1e-8,…
‘Display’, ‘off’,…
‘UseParallel’, true);
x0 = ones(size(OD.DISA)) * 85;
% Declare constraint results to be shared between obj_fun and con_fun
constr_fields = fieldnames(CONSTR);
con_res = zeros(length(constr_fields), length(OD.DISA));
% Execute Optimizer
[PLA_max, obj_min,exitflag,~,~] = fmincon( @(x)obj_fun(x), x0, A, b, Aeq, beq, lb, ub, @(x)con_fun(), options );
% Objective:
function [obj] = obj_fun( PLA )
OD.PLA = PLA;
[OD.OUT, OD.IN] = expensive_function( DES, OD );
obj = – OD.OUT.param_obj;
for i=1:length(constr_fields)
con_res(i,:) = eval([‘OD.’ CONSTR.(constr_fields{i})]);
end
end
% Constraints:
function [c,ceq] = con_fun()
exp_CONSTR_REQ = repmat(CONSTR_REQ, 1, length(OD.DISA));
c = (con_res – exp_CONSTR_REQ); % Non-Equality constraint ( !<= 0 )
ceq = [];
end
It works fine when I solve one case at a time, but when I try to parallelize it I got this error. How can I fix it?
Error using fminunc (line 348)
Supplied objective function must return a scalar value. fmincon, optimization, parallel computing MATLAB Answers — New Questions