function [lsg,wert,iteration,nfc,ngc]=steilsterabstieg(fktname,x,gradname,iterationmax,subroutine)
% ======================================================================
% Eine Implementation des Modell-Algorithmus mit der Suchrichtung
% steilster Abstieg.
%
% Erstellt fuer die Veranstaltung
% Weiterbildenes Studium fuer Ingenieure WS 98/99
%
% Helge Baumann, 22.6.1998
% ----------------------------------------------------------------------
% Aurufparameter:
%  (lediglich die ersten drei Parameter muessen zwingend angegeben werden.)
% fktname : Name der Funktion F, deren Minimum bestimmt 
%   werden soll. An <fktname> wird ein Spaltenwektor(!) uebergeben. 
%   Es wird eine reelle Zahl als Bild erwartet.
% x : aktueller Iterationspunkt. 
% gradname : Name der Funktion G, die den Gradienten von F als 
%   Spaltenvektor zurueckgibt
% iterationmax : Anzahl der maximalen Iterationen. Standard: 1000
% subroutine : Name einer Unterroutine, die in jedem Iterationsschritt
%   aufgerufen wird. Dient zum Protokolieren des Iterationsprozesses.
%   Wird <''> uebergeben, erfolgt kein Aufruf. Standard: ''
% ---------------------------------------------------------------------
% Rueckgabeparameter:
% lsg : Loesung (Spaltenvektor!)
% wert: Zielfunktionswert an der Stelle lsg
% iteration : Anzahl der benoetigten Iterationen
% nfc : Anzahl der Funktionsauswertungen, muss allerdings in der
%   Unterroutine <fktname> gesetzt werden!
% ngc : Anzahl der Gradientenauswertungen, muss allerdings in der
%   Unterroutine <gradname> gesetzt werden!
% ---------------------------------------------------------------------
% Programmvariablen:
% f : Wert der Funktion fname an der Stelle x.
% g : Wert des Gradienten von fname an der Stelle x.
% normf, normg : Die Norm von f bzw. g.
% xalt,falt : Die Werte von x bzw. f im vorherigen Schritt.
% xaktuell: Der aktuelle x-Wert wird in dieser Variable nochmal gespeichert.
%     x wird bereits als Parameter uebergeben und sollte deshalb nicht global sein.
%     xaktuell ist global und kann deshalb in phi.m ausgelesen werden.
% alpha : Schrittlaenge
% s : Suchrichtung
% epsilon : Abbruchgenauigkeit
% iterationmax : Anzahl der maximalen Iterationen
% abbruch, tf,tf2,tf3  :  Hilfsvariable
% ======================================================================
global nfc; nfc = 0;
global ngc; ngc = 0;

% fuer die eindimensionale Minimierung 
global fname; fname = fktname;
global xaktuell;
global s;
 
% Initialisierung
epsilon = 1E-10; 
abbruch = 0;
iteration = 0;
lsg = [];

% Konstanten fuer die Abbruchbedingung
tf = 10^(-8); tf2 = sqrt(tf); tf3 = tf^(1/3);

if nargin < 5, subroutine = ''; end;
if nargin < 4, iterationmax = 1000; end;
 
% ======================================================================
% Der Modellalgorithmus
% ======================================================================
[g] = feval(gradname,x);
[f] = feval(fktname,x);
% Subroutine aufrufen fuer graphische Ausgabe, Minmax Bestimmung o.ae.
if ~isempty(subroutine), feval(subroutine,x); end

while (abbruch ~= 1)

  % Suchrichtung ist die Richtung des steilsten Abstiegs
  s = -g;
  
  % Bestimmung der Schrittlaenge mit Minimierungsroutinen von MATLAB.
  % Hier wird keine(!) Schrittlaengenstrategie verwendet
  alpha = 0;
  xaktuell = x;
  alpha = fminu('phi',1);
 
  xalt = x; 
  x = x + alpha * s;

  falt = f;
  [f] = feval(fktname,x);
  normf = abs(f);
  [g] = feval(gradname,x);
  normg = norm(g);
  iteration = iteration +1;

  % Subroutine aufrufen fuer graphische Ausgabe, Minmax Bestimmung o.ae.
  if ~isempty(subroutine), feval(subroutine,x); end

  % Abbruchbedingungen ueberpruefen
  if ((falt - f) <= (tf * (1+normf))) & ( norm(xalt-x) <= (tf2 * (1 + norm(x)))) & ( normg <= (tf3 * (1+normf)) ) 
    abbruch = 1; end;
  if normg <= realmin, abbruch = 1; end;
  if iteration >=iterationmax, abbruch = 1; end;

end;

% Rueckgabewerte festlegen - Ruecksprung zum aufrufenden Programm

lsg = x;
wert = f;
return;






