function [min_x,min_y,X,Y]=gridsearch(Min,Max,Grid,nloops,fun,varargin)
% GRIDSEARCH Function minimization using grid search.
%
% Synopsis:
% [min_x,min_y,X,Y]=gridsearch(Min,Max,Grid,nloops,fun)
% [min_x,min_y,X,Y]=gridsearch(Min,Max,Grid,nloops,fun,varargin)
%
% Descritpion:
% This function implements the grid search to find the minimum
% of a given function y = fun(x), x \in X.
% The domain X is discretized to the grid with minimal and
% maximal point given by Min and Max respectively. Number of points
% of the grid is given by Grid. The Max, Min and Grid are vectors
% their entries correspond to individual dimensions of X.
% After the mininum is found then the grid search is recursively
% repeated with a finer grid. Number of nested loops is given by nloops.
% The string fun determines function to be minimized. The function is
% called as y=feval(fun,x,varargin{:}).
%
% Input:
% Min [dim x 1] Minimum point of the grid.
% Max [dim x 1] Maximum point of the grid.
% Grid [dim x 1] Number of point in the grid, i.e. grid density.
% nloops [1x1] Number of nested loops of the grid search.
% fun [string] Identifies the minimized function.
% varargin [cell] Additional arguments of the minimized function.
%
% Output:
% min_x [dim x 1] Found minimum.
% min_y [1x1] min_y = fun(min_x).
% X [dim x n] Points which the grid search checked through.
% Y [1 x n] Y(i)=fun(X(:,i)).
%
% Example:
% [min_x,min_y,X,Y]=gridsearch(0,10,10,3,'sin');
% figure; grid on; hold on;
% plot(X,Y,'.');
% plot(min_x,min_y,'+r');
%
% About: Statistical Pattern Recognition Toolbox
% (C) 1999-2003, Written by Vojtech Franc and Vaclav Hlavac
% <a href="http://www.cvut.cz">Czech Technical University Prague</a>
% <a href="http://www.feld.cvut.cz">Faculty of Electrical Engineering</a>
% <a href="http://cmp.felk.cvut.cz">Center for Machine Perception</a>
% Modifications:
% 18-July-2003, VF
% 17-July-2003, VF
num_variables=length(Min);
if num_variables > length(Grid),
Grid = Grid*ones(size(Min));
end
if Grid > 1, step=(Max-Min)./(Grid-1); else step = 0; end
x=Min;
min_y = inf;
stop = 0;
X = [];
Y = [];
while ~stop,
y = feval(fun, x, varargin{:});
X = [X,x(:)];
Y = [Y,y];
if y < min_y,
min_y = y;
min_x = x;
end
x(1) = x(1) + step(1);
if Grid > 1,
for i=1:num_variables,
if x(i)-step(i)/2 > Max(i),
x(i)=Min(i);
if i+1 <= length(x),
x(i+1)=x(i+1)+step(i+1);
else
stop=1;
end
end
end
else
stop = 1;
end
end
if nloops > 1,
tmp=2*step./Grid;
Min = min_x - step + tmp;
Max = min_x + step - tmp;
[x, y, tmpX, tmpY]=gridsearch( Min, Max, Grid, nloops-1, fun, varargin{:});
if y < min_y,
min_y = y;
min_x = x;
end
X = [X,tmpX];
Y = [Y,tmpY];
end
return;