function [k,xk,fk,Tk]=osc_example_sim_anneal(x0)
% Syntax:  [k,xk,fk,Tk]=osc_example_sim_anneal(x0)
%
% Purpose: m file for the simulated annealing example of the
%          lecture notes "Optimization in Systems and Control".
%
% Inputs:  x0  initial point
%
% Outputs: k   iteration step range
%          xk  iteration points
%          fk  function values
%          Tk  temperatures

if ( nargin < 1 )
   x0=10;
end;

% Define annealing parameters.
T_init=70;
T_end=2;
T_period=10;
alpha=0.7;

% Pre-allocate variables.
n_steps=T_period*(1+floor((T_init-T_end)/(alpha*T_period)));
xk=zeros(1,n_steps+1);
fk=zeros(1,n_steps+1);
Tk=zeros(1,n_steps+1);

% Initialization.
x_current=x0;
f_current=osc_example_sim_anneal_obj_fun(x_current);
T=T_init;

% Store values.
k=1;
xk(k)=x0;
fk(k)=f_current;
Tk(k)=T;

% Simulated annealing loop.
while ( T >= T_end )
   j=1;
   while ( j <= T_period )
      % Select a new feasible point x_new in the neighborhood of the current
      % point x_current.
      x_new=min(63,max(0,x_current+randn*6));
      f_new=osc_example_sim_anneal_obj_fun(x_new);
      delta=f_new-f_current;
      % Jump to the new point if the new function value is lower than the
      % current or if an uphill step can be made.
      if ( ( delta < 0 ) || ( rand < exp(-delta/T) ) )
         x_current=x_new;
         f_current=f_new;
      end;
      % Store values.
      k=k+1;
      xk(k)=x_current;
      fk(k)=f_current;
      Tk(k)=T;
      j=j+1;
   end;
   % Adapt the temperature.
   T=alpha*T;
end;

k=0:n_steps;

return;

function f=osc_example_sim_anneal_obj_fun(x)
% Syntax:  f=osc_example_sim_anneal_obj_fun(x)
%
% Purpose: Compute the value of the objective function.

f=85+(1-x).*sin(x/5)+x.*cos(x/2);
