function minimization_demo
%  Simple script that illustrates how the MATLAB optimizer works.
 close all
 % Plot a surface plot of the function to be minimized
 x = [-2*pi:0.2:2*pi];
 y = x;
 z = transpose(sin(y))*sin(x);
 figure
 contour(x,y,z);
 % You can also try surf(x,y,z)
 hold on
 
 % Show a simple minimization with no constraints
 % Repeat this test with different initial guesses to show
 % how MATLAB marches downhill to the nearest minimum
 initial_guess = [0,-2];
 %
 %  Minimize with no constraints.  Explain what the output
 % from the function is (the optimal x,y, and the value of z)
  [opt_sol,opt_val] = fminunc(@zfunc,initial_guess)
  
% Plot the minimum that MATLAB found on the surface plot
  plot3(opt_sol(1),opt_sol(2),opt_val,'ro','MarkerSize',11,...
     'MarkerFaceColor',[1 0 0]);
% Plot the initial guess as a blue dot
  plot3(initial_guess(1),initial_guess(2),opt_val,'ro','MarkerSize',11,...
     'MarkerFaceColor',[0 0 1]);
% Plot an arrow from the initial guess to the optimal solution 
  quiver(initial_guess(1),initial_guess(2),opt_sol(1)-initial_guess(1),opt_sol(2)-initial_guess(2),...
      'Color','b','LineWidth',2,'MaxHeadSize',0.8);
title('Minimizing with no constraints')
xlabel('x');
ylabel('y');
  
  
  
%% Now set up a simple constraint that forces MATLAB to look
% for a minimum inside a box
% Explain what min_var and max_var do...
% You can change the box and the initial guess to show their effects.

 initial_guess = [1,-2];
 min_var = [3.5,0];
 max_var = [4.,4];
 A = [];
 b = [];
 [opt_sol,opt_val] = fmincon(@zfunc,initial_guess,...
    A,b,[],[],min_var,max_var);
figure
contour(x,y,z);
hold on
% Plot the minimum that MATLAB found as a red dot on the surface plot
  plot3(opt_sol(1),opt_sol(2),opt_val,'ro','MarkerSize',11,...
     'MarkerFaceColor',[1 0 0]);
% Plot the initial guess as a blue dot
  plot3(initial_guess(1),initial_guess(2),opt_val,'ro','MarkerSize',11,...
     'MarkerFaceColor',[0 0 1]);
% Plot an arrow from the initial guess to the optimal solution 
  quiver(initial_guess(1),initial_guess(2),opt_sol(1)-initial_guess(1),opt_sol(2)-initial_guess(2),...
      'Color','b','LineWidth',2,'MaxHeadSize',0.8);
% Plot the constraints as green lines
  plot3([min_var(1),min_var(1)],[-2*pi,2*pi],[0,0],'LineWidth',2,...
      'Color',[0,1,0]);
  plot3([max_var(1),max_var(1)],[-2*pi,2*pi],[0,0],'LineWidth',2,...
      'Color',[0,1,0]);
  plot3([-2*pi,2*pi],[min_var(2),min_var(2)],[0,0],'LineWidth',2,...
      'Color',[0,1,0]);
  plot3([-2*pi,2*pi],[max_var(2),max_var(2)],[0,0],'LineWidth',2,...
      'Color',[0,1,0]);  
title('Minimizing with x,y inside a box')
xlabel('x');
ylabel('y');
%
%% Now add an inequality constraint.  Here we
% force MATLAB to look for a solution with x>-1, y>-1
% and 4x + 3y <= 6
 initial_guess = [-1,0];
 min_var = [-2,-1];
 max_var = [inf,inf];
 A = [4,3];
 b = 6;
 [opt_sol,opt_val] = fmincon(@zfunc,initial_guess,...
    A,b,[],[],min_var,max_var)
 x1 = -2*pi;
 y1 = (b-A(1)*(-2*pi))/A(2);
 if (y1>2*pi)
     y1 = 2*pi; 
     x1 = (b-A(2)*(2*pi))/A(1);
 end
 if (y1<-2*pi)
     y1 = -2*pi;
     x1 = (b-A(2)*(-2*pi))/A(1);
 end
 x2 = 2*pi;
 y2 = (b-A(1)*(2*pi))/A(2);
 if (y2>2*pi)
     y2 = 2*pi;
     x2 = (b-A(2)*(2*pi))/A(1);
 end
 if (y2<-2*pi)
   y2=-2*pi;
   x2 = (b-A(2)*(-2*pi))/A(1);
 end
 xx = [x1,x2];
 yy = [y1,y2];

 
figure
contour(x,y,z)
hold on
plot3([min_var(1),min_var(1)],[-2*pi,2*pi],[0,0],'LineWidth',2,...
      'Color',[0,1,0]);
  plot3([-2*pi,2*pi],[min_var(2),min_var(2)],[0,0],'LineWidth',2,...
      'Color',[0,1,0]);
 plot3(xx,yy,[0,0],'LineWidth',2,...
      'Color',[0,1,0]);  
  plot3(opt_sol(1),opt_sol(2),opt_val,'ro','MarkerSize',11,...
     'MarkerFaceColor',[1 0 0]);
% Plot the initial guess as a blue dot
  plot3(initial_guess(1),initial_guess(2),opt_val,'ro','MarkerSize',11,...
     'MarkerFaceColor',[0 0 1]);
% Plot an arrow from the initial guess to the optimal solution 
  quiver(initial_guess(1),initial_guess(2),opt_sol(1)-initial_guess(1),opt_sol(2)-initial_guess(2),...
      'Color','b','LineWidth',2,'MaxHeadSize',0.8);
title('Minimizing with an inequality and a lower bound')
xlabel('x');
ylabel('y');


end
function zval = zfunc(Des_vars)
% The objective function
        x = Des_vars(1); y = Des_vars(2);
        zval = sin(x)*sin(y);
    end