programmierung

yuqii

New member
4 Mai 2015
1
0
hallo ich musste in Matlab 2 programme schreiben, die mit den Newtonverfahren verbunden sind. Die Funktion lautet 2-x² mein Startwert ist 0 und toleps = toleranz ist 1e-8.
Meine Frage ist, bei meinem ersten programm gibt es mir eine FEhlermeldung und beim 2. funktioniert es. ich weiß zwar, dass ich da die Tangente immer um 0.01 verschiebe aber warum das Programm funktioniert weiß ich nicht. Müsste etwas wegen Der Näherung sein aber einen vollständigen Satz bekomme ich für meinen Prof nicht hin


Code:
function [xnaeherung, iterationen] = mynewton( toleps, startx)

abbruch=0;
n = 0;

while (abbruch==0)

y1 = myfunction(startx);
y2 = myfunctiondiff(startx);  

z = startx-(y1/y2);

if(abs(startx-z)<toleps) %abs=Betrag
    abbruch=1;
  
end

startx = z;

n = n+1; 


end

iterationen = n;
xnaeherung = startx




Code:
function [xnaeherung, iterationen] = mynewton2( toleps, startx)

abbruch=0;
n = 0;

delta=0.01;

while (abbruch==0)

y1 = myfunction(startx);
y2 = (myfunction(startx+delta)- myfunction(startx))/(delta);  %Differenz wird approximiert

z = startx-(y1/y2);

if(abs(startx-z)<toleps)
    abbruch=1;
end

startx = z;

n = n+1; 


end

iterationen = n;
xnaeherung = startx;

%y2 = (myfunction(startx+delta)-myfunction(startx))/(delta);  %Differenz wird approximiert
 
Naja, 2-x² hat als Ableitung -2x und das ist bei x=0 nun gerade Null. Du beginnst also die Suche im Maximum der Funktion. Da geht Newton schief, er weiß quasi nicht in welche Richtung er laufen soll.

Was konkret bei dem Matlab-Programm passiert ist, dass die Auswertung der Ableitung am Startwert 0 ergibt, bei Dir heißt die Variable y2. Wenn Du dann das neue x berechnest über startx-(y1/y2) wird durch null geteilt, z ist also konsequenterweise Inf. In der nächsten Runde wertest Du die Funktion und die Ableitung damit bei Inf aus, y1 und y2 sind dann beide Inf. y1/y2 wird NaN, damit auch z und dein startx. Die Abbruchbedingung wird nie erreicht und er bleibt in der Endlosschleife hängen...

Bei Deiner zweiten Variante passiert das nicht, da Du die Ableitung näherst und er damit für startx=0 nicht genau die Null in den Nenner kommt. Das ist in dem Falle aber auch nicht wirklich "die Lösung": Die zweite Variante geht auch schief aber nicht für den Startwert 0 sondern für den Startwert -delta/2...


Du könntest in der Abbruchbedingung auf inf/nan prüfen (Matlab: isfinite), falls das vorkommt abbrechen und mit einem neuen startx probieren (z.B. ein kleines delta addieren). Sowas in der Art:

Code:
function x_zero = newton(fun,fun_diff,startx,tol)

x_zero = startx;
oldx_zero = x_zero;

delta = 0.01;

while true
    x_zero = x_zero - fun(x_zero)/fun_diff(x_zero);
    
    if abs(x_zero-oldx_zero)<tol, break; end
    
    if ~isfinite(x_zero)                % divergence/singularity
        startx = startx + delta;      % move starting point
        x_zero = startx;               % restart iteration
    end

    oldx_zero = x_zero;
end