%% Rosenbrock constrained
%
%{
Rosenbrock's function is a standard test function in optimization. It has 
a unique minimum value of 0 attained at the point [1,1]. 
Finding the minimum is a challenge for some algorithms because the function 
has a shallow minimum inside a deeply curved valley. 
The solution for this problem is not at the point [1,1] because that point 
does not satisfy the constraint.
%}
close all
format compact
%%
rosenbrock = @(x)100*(x(:,2) - x(:,1).^2).^2 + (1 - x(:,1)).^2; 
 %{
 The rosenbrock function handle calculates Rosenbrock's function at any 
 number of 2-D points at once. This “Vectorization” speeds the 
 plotting of the function, .
 The function f(x) is called the objective function. The objective function 
is the function you want to minimize.
 %}
figure1 = figure('Position',[1 200 600 300]);
%%
colormap('gray');axis square;
R = 0:.002:1;TH = 2*pi*(0:.002:1); 
X = R'*cos(TH);Y = R'*sin(TH); % This is the way to produce polar 
%                          coordinate-grid, think of column*row
Z = log(1 + rosenbrock([X(:),Y(:)])); % Take logarithmic scale.
Z = reshape(Z,size(X));
%% Create subplot
%
subplot1 = subplot(1,2,1,'Parent',figure1);
view([124 34]);grid on;hold on

 % Create surface
 surf(X,Y,Z,'Parent',subplot1,'Linestyle','none')
 % Create contour
 contour(X,Y,Z,'Parent',subplot1)
 % Create subplot
 subplot2 = subplot(1,2,2,'Parent',figure1);
 view([234 34]);grid('on');hold on
 
 % Create surface
 surf(X,Y,Z,'Parent',subplot2,'LineStyle','none');
 
 % Create contour
 contour(X,Y,Z,'Parent',subplot2);
  
 %%
 % The inequality $x_1^2+x_2^2 \leq 1$
 % is called constraint. 
 % You can have any number of constraints, which are inequalities or equations
 type unitdisk
 %{
 function [c,ceq] = unitdisk(x)
c = x(1)^2 + x(2)^2 - 1;  % LHS of inequality c(x) <= 0
ceq = [ ];                % No equality constraints
 %}
 %% optimoptions
 options = optimoptions(@fmincon,'Display','iter',...
     'Algorithm','interior-point');
 % options is now a struct. See it:
 options
 % Alternatively you can change any option by an
 % assignment of the type: options.Algorithm ='interior-point'
 %% Run:
 [x,fval] = fmincon(rosenbrock,[0 0],...
    [],[],[],[],[],[],@unitdisk,options)
% The six sets of empty brackets represent optional constraints that are 
% not being used in this example. See the fmincon function reference 
% pages for the syntax. 
 %% Complete the picture in a fancy way.
 % Create textarrow
 annotation(figure1,'textarrow',[0.4 0.31],...    
     [0.055 0.16],...    
     'String',{'Minimum at (0.7864,0.6177)'});
 
 % Create arrowrrow
 annotation(figure1,'arrow',[0.59 0.62],[0.065 0.34]);
 title("Rosenbrock's Function: Two Views")
 