function []=startnm(fktname,x0,iterationmax,nlines);
% ======================================================================
% Startroutine fuer das Nelder-Mead-Verfahren.
%
% Erstellt fuer die Veranstaltung
% Weiterbildenes Studium fuer Ingenieure WS 98/99
%
% Helge Baumann, 11.8.1998
% ----------------------------------------------------------------------
% Aurufparameter:
%  
% fktname : Name der Funktion F, deren Minimum bestimmt 
%   werden soll. An <fktname> wird ein Spaltenwektor(!) uebergeben. 
%   F ist eine Funktion von R^n -> R. Standard : 'rosenbrock'
% x0 : Spaltenvektor der Dimension n oder eine n x (n+1) Matrix.
%   Bei Vorgabe nur eines Spaltenvektors wird ein regelmaessiges 
%   Startpolyeder mit dem Abstand 1 erzeugt. Standard: [-2; 2]
% iterationmax : Anzahl der maximalen Iterationen. Standard: 100
% nlines : Anzahl der zu zeichnenden Hoehenlinien. Standard: 40

%% Initialisierung 
% xmin haelt fuer jede Dimension die kleinste waehrend der Iteration
%      auftretende Zahl fest.
% xmax haelt fuer jede Dimension die groeste waehrend der Iteration
%      auftretende Zahl fest.
% xmin und xmax werden benoetigt um den richtigen Bildschirmausschnitt
% bei der Darstellung des Iterationsverlaufes anzuzeigen.
global xmin
global xmax

% Anzahl der Funktionsauswertungen
global nfc 
nfc = 0;

% Anzahl der Hoehenlinien
if nargin < 4, nlines = 40; end;

% Anzahl der maximalen Iterationen
if nargin < 3, iterationmax = 200; end

% Startvektor
if nargin < 2, x0 = [-2;2]; end
[n,m] = size(x0); % n = Dimension des Startvektors/ der Startvektoren

% Name der zu minimierenden Funktion
if nargin < 1, fktname = 'rosenbrock'; end

   
% Name der Ausgaberoutine
outputname = '';

% Konstanten
xpoints = 21;   % Anzahl der Gitterpunkte in x Richtung fuer contour-plot
ypoints = 21;   % Anzahl der Gitterpunkte in y Richtung fuer contour-plot
%zgitter = zeros(xpoints,ypoints);

% Im Fall n==2 kann eine graphische Ausgabe erfolgen. Dafuer sind einige
% Vorarbeiten noetig, die fuer die eigentliche Minimierung keine Rolle
% spielen. Der gesamte 'if'-Block dient ausschliesslich diesen Vorbereitungen.
if n==2
   % Fuer xmin (xmax) werden die groestmoeglichen (kleinstmoeglichen) Zahlen
   % vorgegeben. Dient nur dazu einen Vektor in entsprechender
   % Groesse bereitzustellen.
   xmin = ones(n,1)*realmax;
   xmax = -ones(n,1)*realmax;

   % Der erste Durchlauf ist nur zur Bestimmung von xmin und xmax gedacht.
   [lsg,iterationen,nfc] = neldermead(fktname,x0,iterationmax,1,'minmax');
   if iterationen == 0, return; end;
   nfc = 0;
   
   % Beobachtungsfenster festlegen, um 10% groesser als ermittelte Werte.
   xlaenge = (xmax-xmin)/2; xmitte = (xmax+xmin)/2;
   xmin = xmitte -(xlaenge* 1.1); xmax = xmitte + (xlaenge*1.1);

   % Einheitliches Koordinatensystem und Graphikausgabe in ein Fenster
   clf;
   axis([xmin(1), xmax(1), xmin(2), xmax(2)]);
   hold on
   
   %% Hoehenlinien einzeichnen
   % Gitter erzeugen; zu den Knoten wird der Funktionswert ermittelt.
   xrange = xmin(1):(xmax(1)-xmin(1))/(xpoints-1):xmax(1);
   yrange = xmin(2):(xmax(2)-xmin(2))/(ypoints-1):xmax(2);
   [xgitter,ygitter] = meshgrid(xrange,yrange);
   for i=1:xpoints
      [zgitter(i,1:ypoints)] = feval(fktname,[xrange(i)*ones(1,ypoints);yrange(1:ypoints)]);     
   end
   nfc = 0;
   % Erzeugzung der Hoehenlinien
   contour(xgitter,ygitter,zgitter',nlines);
   
   % Erklaerungen einzeichnen
   title('Das Nelder-Mead Verfahren');
   if iterationen < iterationmax % nur wenn ein Minimum gefunden wurde, wird es eingezeichnet
       plot(lsg(1),lsg(2),'g*');
       legend('berechnetes Minimum');
    end   
   outputname = 'zeichnung'; % Name der Ausgaberoutine
end

%% Aufruf des Verfahrens
% Der Durchlauf, bei dem in jedem Iterationsschritt eine Ausgabe
% erfolgen kann.
[lsg,iterationen,nfc] = neldermead(fktname,x0,iterationmax,1,outputname);

hold off;


%% Ergebnisse anzeigen
%sprintf('%s %d %s','Das Ergebnis nach ',iterationen,'Iterationen:')
lsg
disp(strcat(int2str(iterationen),' Iterationen'))
disp(strcat(int2str(nfc),' Funktionsauswertungen fuer einen Durchlauf.'))
if iterationen>=iterationmax
	disp('ACHTUNG!!! Maximale Anzahl der Iterationen erreicht!')
end
