function OptimalControl(verbose)

% use dynamic programming to compute costs-to-go, optimal control strategy,
% and optimal controlled trajectories for a very simple toy system

  % time and space dimensions
  NT = 4; NX = 5;

  % these matrices store the cost of implementing a + or - control strategy
  % at each point in spacetime
  costminus = ones(NT,NX);
  costplus = ones(NT,NX);
  costminus(1,2) = 100; costminus(2,2) = 100; costminus(4,2) = 100;
  costplus(1,1) = 100; costplus(2,1) = 100; costplus(4,1) = 100;
  
  % initialise the matrices for cost-to-go and optimal strategy
  J = zeros(NT+1,NX);
  ustar = zeros(NT,NX);

  % report
  if(verbose >= 1)
      disp('Backwards computing costs-to-go.')
  end
  
  % the last set of elements of the cost-to-go matrix are just the final
  % costs -- here we penalise distance from x = 1
  for x=1:NX
      J(NT+1,x) = 2*(x-1)+(x-1)*(x-1);
  end

  % backwards loop through time
  for t=NT:(-1):1
      % loop over all states
      for x=1:NX
          % assign cost of using a "+" control strategy
          if(x == NX)
              uplus = 1000;
          else
              uplus = costplus(t,x) + J(t+1,x+1);
          end
          % assign cost of using a "-" control strategy
          if(x == 1)
              uminus = 1000;
          else
              uminus = costminus(t,x) + J(t+1,x-1);
          end
          % assign cost of using no control strategy
          uzero = 0 + J(t+1,x);
        
          % pick the optimal strategy by cost-to-go and update optimal
          % strategy and cost-to-go matrices accordingly
          if(uplus < uminus && uplus < uzero)
              ustar(t,x) = 1;
              J(t,x) = uplus;
          elseif(uminus < uplus && uminus < uzero)
              ustar(t,x) = -1;
              J(t,x) = uminus;
          else 
              ustar(t,x) = 0;
              J(t,x) = uzero;
          end
        
          % report
          if(verbose >= 1) 
              outputstr = sprintf('At t = %i, x = %i. costplus = %i, costminus = %i. Overall costs plus %i, minus %i, zero %i. Choosing %i.', t, x, costplus(t,x), costminus(t,x), uplus, uminus, uzero, ustar(t,x));
              disp(outputstr);
          end
      end
  end

  % report
  if(verbose >= 2)
      disp('Forward computing optimal trajectories.');
  end
  
  % loop through possible initial conditions
  for x0=1:NX
      x = x0;
      % forward loop through time
      for t=1:NT
          % report
          if(verbose >= 2)
              outputstr = sprintf('At t = %i, x = %i. Move %i.', t, x, ustar(t,x));
              disp(outputstr);
          end
          % update current state according to optimal control strategy
          x = x + ustar(t,x);
      end
      
      if(verbose >= 2)
          outputstr = sprintf('Finished at t = %i, x = %i.', t, x);
          disp(outputstr);
      end
  end
end
    
