function func = numdiff ( iord )
% NumDiff
%
% This m-file is part of the material of the lectures on
%   Numerical Methods in Nonlinear Optimization
% at the Math Department of Halle University, Germany.
%
% Author :      Martin Arnold, martin.arnold@mathematik.uni-halle.de
% Version of :  May 7, 2009
%
% Plot for illustration of numerical differentiation
%
% Parameter
%   iord   (input)  : control flag "order"
%                       =1 .. first order finite differences
%                       =2 .. second order finite differences
%
% Example
%   numdiff ( 1 );    %  print -dpng ../png/numdiff1.png
%   numdiff ( 2 );    %  print -dpng ../png/numdiff2.png

%
% -> Steuerparameter Ausgabe Bildschirm / PostScript
graphwidth  = 24.0;
graphheight = 12.0;
fac         =  1.0;
shift       =  0.5;
papershift  =  0.0;

ActFontSize   = 14;
ActMarkerSize =  8;
ActLineWidth  =  2;
RatioFlag     =  0;

border      = 1.0;

%
% -> Bestimme Groesse des Bildschirms und Skalierungsfaktor fuer die Ausgabe
root = 0;
set ( root, 'Units', 'centimeters' );
screensize = get ( root, 'ScreenSize' );
left   = screensize(1);
bottom = screensize(2);
width  = screensize(3);
height = screensize(4);
set ( root, 'Units', 'pixels' );
if RatioFlag==0,
  screenscale = 1.0;
elseif RatioFlag==1,
  screenscale = (width-2*border) / graphwidth;
elseif RatioFlag==-1,
  screenscale = (height-2*border) / graphheight;
end;

%
% -> Definiere den Bildschirmausschnitt
if length ( get ( root, 'Children' ) ) == 0,
  h = figure;
else
  h = gcf;
  clf;
end;
stdunits = get ( h, 'Units' );
set ( h, 'Units',    'centimeters' );
set ( h, 'Position', ...
  [ left+width-screenscale*graphwidth-border height-2*border-screenscale*graphheight ...
    screenscale*graphwidth                   screenscale*graphheight ] );
set ( h, 'Units', stdunits );

%
% -> Skalierung der Ausgabe in PostScript
%
set ( gcf, 'PaperUnits',    'centimeters' );
set ( gcf, 'PaperPosition', [ papershift papershift graphwidth graphheight ] );

% -> parameter
delmin = 1.0e-15;
delmax = 1.0e+00;
errmin = 1.0e-12;
errmax = 1.0e+00;

x1 = pi;
x2 = 1.0e+04 * pi;

% -> get data
del = logspace ( log10(delmin), log10(delmax), 1001 );

switch iord
    case 1
        diff1 = ( sin(x1*pi+del) - sin(x1*pi) ) ./ del;
        diff2 = ( sin(x2*pi+del) - sin(x2*pi) ) ./ del;
        tstr = 'Differenzenapproximation erster Ordnung';
    case 2
        diff1 = ( sin(x1*pi+del) - sin(x1*pi-del) ) ./ (2*del);
        diff2 = ( sin(x2*pi+del) - sin(x2*pi-del) ) ./ (2*del);
        tstr = 'Differenzenapproximation zweiter Ordnung';
end

err1 = abs ( diff1 - cos(x1*pi) );
err2 = abs ( diff2 - cos(x2*pi) );

% -> plot
loglog ( del, err1, '-b', del, err2, '-r' );

axis ( [ delmin delmax errmin errmax ] );
title ( tstr );
xlabel ( '\Delta' );
ylabel ( '|  ( sin(x+\Delta) - sin(x) ) / \Delta  -  cos(x)  |' );

%
% -> Korrektur der Groesse und Lage der Koordinatensysteme, Aenderung der Schriftgroesse
allax = get ( gcf, 'Children' )';
for ax = allax,
  rect    = get ( ax, 'Position' );
  rect(2) = rect(2) + shift * (1-fac) * rect(4);
  rect(4) = fac * rect(4);
  set ( ax, 'Position', rect );
  set ( ax, 'FontSize', [ActFontSize] );
  set ( get ( ax, 'title' ), 'FontSize', [ActFontSize] );
  set ( get ( ax, 'xlabel' ), 'FontSize', [ActFontSize] );
  set ( get ( ax, 'ylabel' ), 'FontSize', [ActFontSize] );
  allline = get ( ax, 'Children' )';
  for al=allline,
    if get ( al, 'Type' ) == 'line',
      set ( al, 'MarkerSize', [ ActMarkerSize ] );
      set ( al, 'LineWidth',  [ ActLineWidth ] );
    end;
    if get ( al, 'Type' ) == 'text',
      set ( al, 'FontSize', [ ActFontSize ] );
    end;
  end;
end;

% -> legend
legend (                                  ... 
         '  x = \pi^2'                    ...
       , '  x = 10^4 * \pi^2'             ...
       , 'Location', 'SouthWest'          ...
       )

