How to exit an optimization function without error?

I am using fsolve at two stages: first it finds the solution for problem A, and this solution is then used to solve problem B.
Sometimes it cannot find a solution for problem A, and then for sure i can not solve problem B, so I want fsolve (for B) to exit whenever problem A returns an exitflag < 1. How do I do this?
So far I only found that you can have the objective return an "inf" but then it will still try to backtrack, and waste time and resources. I would prefer to have something like:
if somecondition
exit fsolve
end

Answers (1)

Can use return.
Update: Editted the solution by using the function approach.
%% Solving Stage A Problem first
fun1 = @problem1;
x0 = 1;
[xsol1, fval, exitflag] = fminsearch(fun1, x0)
Exiting: Maximum number of function evaluations has been exceeded - increase MaxFunEvals option. Current function value: -4017345110647497376329610801883911649791527634988546654208.000000
xsol1 = 6.3383e+28
fval = -4.0173e+57
exitflag = 0
%% Test if the solution from Stage A is admissible
if exitflag <= 0
warning('Terminated due Stage A problem is infeasible.')
return % stop if condition is satisfied
else
%% Solving Stage B Problem then
fun2 = @(x) problem2(x, xsol1);
x0 = 1;
xsol2 = fsolve(fun2, x0)
end
Warning: Terminated due Stage A problem is infeasible.
%% Stage A Problem
function y = problem1(x)
y = - x.^2; % infeasible
% y = 1 - x.*exp(-x.^2); % feasible
end
%% Stage B Problem
function y = problem2(x, xsol) % cost function requires xsol from Stage A
y = x.^2 + 2*x + xsol;
end

7 Comments

@Sam Chak thank you for your quick reply. Im not sure I understand, but if I do this:
[x2,~,exitflag2] = fsolve(problem2)
function [res] = problem2(x2)
[x1,~,exitflag1] = fsolve(problem1)
if exitflag1 < 1
return
end
end
then fsolve will throw an error for problem2, saying "Output argument "res" (and maybe others) not assigned during call to ...".
And then when you add "res = NaN" or "res=inf" it will throw the error "Objective function is returning undefined values at initial point. FSOLVE cannot continue."
So I'm very confused. It seems an output function could work, but that might be very inefficient (and its not clear to me yet what you can and cannot do with the output function).
What is res? How is it defined?
Could you share the rest of your code?
I have updated my answer using the function approach, splitting the 2-stage problem into two local functions. I hope this helps. If you find the updated solution helpful, please consider clicking 'Accept' ✔ on the answer and voting 👍 for it. Thanks a bunch!
@Sam Chak thanks again for the update. but your structure is different from mine. You have sequential fsolve: when the first one fails, you simply skip the second. @Dyuman Joshi in my case problem1 is inside problem2. it should abort problem2 solving, when problem1 fails.
[x2,~,exitflag2] = fsolve(@(x2)problem2(x2,x1_ini),x2_ini)
%% Problem2 (which includes solving problem1)
function [res2] = problem2(x2,x1_ini)
[x1,~,exitflag1] = fsolve(@(x1)problem1(x1,x2),x1_ini)
if exitflag1 < 1
%i want to exit problem2 when this is trye
end
res2 = ....
end
%% Solving problem1 depends on x2
function [res1] = problem1(x1,x2)
res1 = ...
end
I have found a work around:
  • define a 'OutputFcn' with the following block:
function stop = output_fun_aggr(x,optimValues,state)
stop = false;
if optimValues.fval == 1e6
stop = true;
end
end
and then inside problem2 set:
function [res2] = problem2(x2,x1_ini)
[x1,~,exitflag1] = fsolve(@(x1)problem1(x1,x2),x1_ini)
if exitflag1 < 1
res2 = 1e6;% it seems this cannot be Inf or NaN because then fsolve throws an error
else
res2 = ...
end
end
The weird thing is that it seems the assigned value cannot be Inf or NaN because then fsolve throws an error (as described earlier).
You can solve problem1 outside of problem2 function to obtain x1 and exitflag1.
[x1,~,exitflag1] = fsolve(@(x1)problem1(x1,x2),x1_ini)
Then, from exitflag1, apply the conditional If–Else test
if exitflag <= 0
warning('Terminated due Stage A problem is infeasible.')
return % stop if condition is satisfied
else
%% Solving Stage B Problem then
x1_ini = x1;
[x2,~,exitflag2] = fsolve(@(x2) problem2(x2, x1_ini), x2_ini)
end
Can you try out this approach?
but i need to solve x1 for every value of x2, meaning when x2 changes, so will x1. your approach does not allow for that.
Okay, I got it now. It's a coupled interdependent problem. Need some time to think.

Sign in to comment.

Asked:

on 6 Nov 2023

Commented:

on 6 Nov 2023

Community Treasure Hunt

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

Start Hunting!