fmincon freezing (no NaN or Inf is involved)
4 views (last 30 days)
Show older comments
Hello,
Here is a short description about the problem I'm facing and what I know so far.
The problem is associated with a master minimizing code implementing Simulating Method of Moments. This code (and its variants) uses a solver (e.g. fmincon) to minimize the error between a set of variables and the outputs of a core function. This core is MEXed (turned to c based matlab functions for higher speeds) and is used in other applications with no problem at running. However, by using this code in this application, the code freezes with no further improvement, while its status is running.
The place at which the code freezes is in a calculation and RAM intensive loop inside the core function, in a sub function that involves another minimization (this minimization is done with fmincon to be compatible wit MEX).
It seems that on average the codes pause after an average amount of time is passed. This is because by reducing the code scale, I see that the average iteration that code is stopped, increases relative to the scale down.
Also when the code itself (without using MEX) is run the code pauses at the very first iteration.
Also there is no Inf or NaN received from the function that the inner minimization is minimizing and freezes.
Here is a sketch of my code:
main function
1st optimization(core code)
core function
2nd optimization (where code freezes)
and this is the 2nd optimization and the function I try to optimize:
function [G_Max,b_pol_offg,k_pol_offg,n_pol_offg] = ...
VFI_uni_offg1(max_iter_vfi,pr,G0,G_Max,div,b_pol_or,k_pol_or,n_pol_or,...
b,k,nl,y,nb,nk,nn,ny,p_exit,k_2,b_2,prob_1,tol_vfi_offg,mode,ZZ)
%%%%%%%%%%%%%%%%%%%% off grid solution for uniform shock
res = ones(1,max_iter_vfi);
G_Max(G_Max<0) = -1;
vfi_time = zeros(1,'int16');
A = [1,-pr.lambda,0];
B = 0;
lb_spline = [0,0,0];
lb_linear = [1*min(b),1*min(k),1*min(nl)];
lb = lb_linear*(mode==1) + lb_spline*(mode~=1);
ub_linear = [1*max(b),1*max(k),1*max(nl)];
ub_spline = [1*max(b),1.4*max(k),1.2*max(nl)];
ub = ub_linear*(mode==1) + ub_spline*(mode~=1);
b_pol_offg = b_pol_or;
k_pol_offg = k_pol_or;
n_pol_offg = n_pol_or;
checkpoints = linspace(0,.6,ZZ);
% ZZ = 5;
options = optimoptions(@fmincon,'display','off','Algorithm','sqp');
tic
for ii=1:max_iter_vfi
G0(G0<=0) = -1;
G = div+pr.beta.*((1-p_exit).*kron(ones(1,nn),kron((prob_1*G0'),ones(nb*nk,1)))...
+(p_exit)*(1-pr.zeta).*(kron(ones(nb*nk*ny,1),k_2)-kron(ones(nb*nk*ny,1),b_2)));
% G(:,nb*nk+1:nb*nk*ns) = pr.beta.*kron((prob_1*G0'),ones(nb*nk,1));
% G = div + G;
fprintf('%5i \n',ii);
for jj=1:nb*nk*ny
x0 = [b_pol_offg(jj)+0.001,k_pol_offg(jj)*(k_pol_offg(jj)>0)+1*(k_pol_offg(jj)==0)...
,n_pol_offg(jj)*(n_pol_offg(jj)>0)+2*(n_pol_offg(jj)==0)];
g = G(jj,:);
% g(g==-inf) = -1;
g_temp = reshape(g,nb,nk,nn);
x00 = x0;
G_Max_temp = zeros(1,ZZ);
b_pol_offg_temp = zeros(1,ZZ);
k_pol_offg_temp = zeros(1,ZZ);
n_pol_offg_temp = zeros(1,ZZ);
% fprintf('%5.2f , ',jj);
for zz=1:1:ZZ
[x,fval,exitflag] = fmincon(@(x)Vfunction(b,k,nl,g_temp,x(1),x(2),x(3),mode),x0,A,B,...
[],[],lb,ub,@(x)nonlinconst(b,k,y,nb,nk,pr,x(1),x(2),x(3),jj),options);
if (exitflag>=1 && -fval>=0 && -fval>=G_Max(jj))
x0 = x00*(.7+checkpoints(zz));
G_Max_temp(zz) = -fval;
b_pol_offg_temp(zz) = x(1);
k_pol_offg_temp(zz) = x(2);
n_pol_offg_temp(zz) = x(3);
elseif (exitflag<1 || -fval<0 || -fval<G_Max(jj))
x0 = x00*(.7+checkpoints(zz));
G_Max_temp(zz) = G_Max(jj);
b_pol_offg_temp(zz) = b_pol_offg(jj);
k_pol_offg_temp(zz) = k_pol_offg(jj);
n_pol_offg_temp(zz) = n_pol_offg(jj);
end
% if mod(jj,100)==0
% fprintf('%5i',jj);
% end
% fprintf('%5.4f , ',G_Max_temp(zz));
end
[G_Max(jj),max_ind] = max(G_Max_temp);
b_pol_offg(jj) = b_pol_offg_temp(max_ind);
k_pol_offg(jj) = k_pol_offg_temp(max_ind);
n_pol_offg(jj) = n_pol_offg_temp(max_ind);
end
vfi_time = ii;
if max(max(abs((reshape(G_Max,nb*nk,ny))-G0)))<tol_vfi_offg
break
end
res(ii)=max(max(abs((reshape(G_Max,nb*nk,ny))-G0)));
G0 = reshape(G_Max,nb*nk,ny);
end
time2 = toc;
fprintf('=========================================================\n');
fprintf('Offgrid Value Function converged with accuracy %6.8f in %5i iterations in %6.8f second \n',...
res(vfi_time-1),vfi_time-1,time2);
fprintf('=========================================================\n');
end
where the code freezes at
```
[x,fval,exitflag] = fmincon(@(x)Vfunction(b,k,nl,g_temp,x(1),x(2),x(3),mode),x0,A,B,...
[],[],lb,ub,@(x)nonlinconst(b,k,y,nb,nk,pr,x(1),x(2),x(3),jj),options);
```
and vfunction is :
```
function [value] = Vfunction(b,k,nl,g_temp,b_var,k_var,n_var,mode)
if mode==1
vq = interp3(k,b,nl,g_temp,k_var,b_var,n_var,'linear',0);
else
vq = interp3(k,b,nl,g_temp,k_var,b_var,n_var,'spline');
end
value = -vq;
if isnan(value)
value = 0;
end
if isinf(value)
value = -100;
end
end
```
14 Comments
Walter Roberson
on 3 Nov 2021
You are right, I got confused over which function was which. I had discovered the issue while working on some user code that set everything up for fmincon, but then called ga instead, and the rest of their code had been using fmincon() .
The actual random generation was in boxdirections(), called by mutationadaptfeasible() which looks to be the default mutation function for ga() and related functions. The code does some odd stuff with matrices that appear to be up to (2 * number of variables) on a side [not sure of the actual upper bound, typically number-of-variables on a side but I saw half again that large sometimes.] On large numbers of variables (over 27000 for the user!) that phase turned out to be the slowest part, and it gave me the impression that the code was "freezing" until I dug down into it.
Answers (2)
Matt J
on 4 Nov 2021
Edited: Matt J
on 4 Nov 2021
You might try getting rid of these lines in Vfunction()
value = -vq;
if isnan(value)
value = 0;
end
if isinf(value)
value = -100;
end
Because you are using the sqp algorithm, you are losing one of the advantages of the algorithm by hiding the NanNs and Infs. The sqp algorithm is supposed to be able to backtrack from NaNs and Infs when it encounters them and search elsewhere.
Because your algorithm has stochastic behavior when it shouldn't ( i.e., freezing at random, non-reproducible times) , I also think you need to trace the origin of that stochasticity. My recommendation is that you save the sequence of iteration vectors [x1,x2,x3] and make sure that they are following the same sequence every time you run. You can save them using the OutputFcn option, as illustrated in this example,
4 Comments
Matt J
on 6 Nov 2021
problem here is that although the first few steps of fmincon are the same in the main code and debug code, the they diverge and I don't know why this happens for the same input.
That's not supposed to be a problem because the x0 that I requested you isolate and include in debug_input.mat is the vector that fmincon reaches right before the freeze. In other words, I should be able to run only a single iteration of fmincon starting at x0 to make the freeze happen.
Alireza Azampour
on 8 Nov 2021
4 Comments
Walter Roberson
on 12 Nov 2021
Notice:
PI = pi;
PI_STRING = sprintf('%.999g', PI)
length(PI_STRING)
Is it really 48 digits (after the decimal place) precision? No! -- that is just the decimal expansion of something that is binary.
num2hex(PI)
next2PI = typecast(typecast(PI, 'uint64')+1, 'double')
next2PI_string = sprintf('%.999g', next2PI)
length(next2PI_string)
num2hex(next2PI)
fprintf('%.999g\n', next2PI - PI)
2^(-51)
next2PI is the next representable number adjacent to pi -- you can see in the num2hex displays that the 8 increments to 9 and there is no other change. Does that somehow increase the number of digits of precision by 3 (according to length())? Not really -- that's just how it comes out if you expand the binary to decimal. The actual difference between the numbers is about 4.4E-16, 2^-51 -- you only have 51 bits of fraction resolution at that point in floating point numbers.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!