%% minmax2dsol.m 
%  Solutions to ex4.
% 
%% Unconstrained Optimization Example
% Consider the problem of finding a minimum of the function:
% 
% $$x\exp(-(x^2+y^2))+(x^2+y^2)/20.$$
% 
% Plot the function to get an idea of where it is minimized

f = @(x,y) x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20;
fsurf(f,[-2,2],'ShowContours','on')
%% Just use min for matrix elements (no fancy methods):
x=linspace(-2,2,200); y=x;
[X,Y]=meshgrid(x,y);
z=f(X,Y);
[minval,minind]=min(z(:));
[maxval,maxind]=max(z(:));
minpt=[X(minind),Y(minind),minval]
maxpt=[X(maxind),Y(maxind),maxval]
hold on
plot3(X(minind),Y(minind),minval,'or','Markersize',10)
plot3(X(maxind),Y(maxind),maxval,'or','Markersize',10)


%% Run fminsearch with 200 x 200 = 40000 initial points.
%
% fminsearch wants fun to have one vector input instead of (x,y).
% (Compare with Globalmin, where we did just vice versa.)
% 
fun = @(x) f(x(1),x(2));
[m,n]=size(X);
X1=X(:);Y1=Y(:);
z=zeros(3,m*n);
for k=1:m*n  
       [x,val]=(fminsearch(fun,[X1(k) Y1(k)]));
       z(:,k)=[x';val];
end    
%% How many lead to a minimum value?
vals=z(3,:);
minval=min(vals)
[min(vals) max(vals)]
%% How many are close to minval?
nr_close=sum(abs(vals-minval)<.0001)
nr_all=length(vals)
nr_close/nr_all
%% Which are "far"?
Logindclose=abs(vals-minval)<.0001;
Farind=~Logindclose;
%z([Farind;Farind;Farind])
x=z(1,:);y=z(2,:);mins=z(3,:);
Farpoints=[z(Farind);y(Farind);mins(Farind)]
plot3(Farpoints(1,:),Farpoints(2,:),Farpoints(3,:),'*b')
%% Q: Which init. pts lead to these "far points"?

%% Change for to parfor
% Measure tic-toc-timing difference especially
% on Triton. (parfor uses all available (24) workers.)
%% Now repeat with Rosenbrock:
close all
a=1;b=100;
f=@(x,y)(a-x).^2 + b*(y-x.^2).^2
fsurf(f,[-1.5,1.5 -1.5 3],'ShowContours','on')
zlim([0 1000])
%%
figure
fcontour(f,[-1.5,1.5 -1.5 3],MeshDensity',221)
%%
figure
x=linspace(-1.5,1.5,200);
y=linspace(-1.5,3,200);
[X,Y]=meshgrid(x,y);
contour(x,y,f(X,Y),60)
contour(x,y,f(X,Y),[0,0.1])
%%
%figure
x=linspace(0.5,1.5,200);
y=linspace(0.5,1.5,200);
[X,Y]=meshgrid(x,y);
contour(x,y,f(X,Y),60)
hold on
contour(x,y,f(X,Y),[0,0.001 0.005 0.01 0.02 0.1])
grid on
%%
Z=f(X,Y);
[min(Z(:)),max(Z(:))];
%% Minimization algorithm: "brute force" vectorization
%
N=200;
N=400;
N=800;
N=1600;
tic
x=linspace(0.5,1.5,N);
y=linspace(0.5,1.5,N);
[X,Y]=meshgrid(x,y);
Z=f(X,Y);
[minz,minind]=min(Z(:))
minxy=[X(minind),Y(minind)]
T=toc

%%
figure
x=linspace(-1.5,1.5,50);
y=linspace(-1.5,3,50);
[X,Y]=meshgrid(x,y);
surf(x,y,f(X,Y))

%%
a=1;b=100;
f=@(x,y)(a-x).^2 + b*(y-x.^2).^2
fun = @(x) f(x(1),x(2));
%opts=optimset('Display','final-detailed')
opts=optimset('Display','iter-detailed')
opts.TolFun=1e-10;
opts.TolX=1e-10;
opts.MaxIter=200;
opts.UseParallel=1;
%opts=optimset('TolFun',1e-10);
%opts=optimset('TolX',1e-10);
% opts=optimset('UseParallel');
% opts=optimset('MaxFunEvals',1000);
% opts=optimset('MaxIter',200);
%%
%[x,val]=(fminsearch(fun,[-1 1],opts))
tic
[x,fval,EXITFLAG,OUTPUT]=fminsearch(fun,[-1 1],opts);
toc

