[Risolto]Ordine di convergenza metodo delle secanti.
Buongiorno a tutti,
dopo aver implementato con MatLab il metodo delle secanti, ho letto che l'ordine di convergenza per esso è $p=(1+sqrt(5))/2$.
Incuriosito, ho testato l'algoritmo su due o più funzioni di cui avevo già calcolato gli zeri (tramite newton, iterazione di punto fisso, bisezione) e questo trovava correttamente lo zero.
Per calcolare l'ordine di convergenza per il metodo secanti ho utilizzato la formula che abbiamo ricavato per la teoria:
$ p_s=log(|x_(k+1)-alpha|)/log(|x_k-alpha|) $
Il problema è che non mi risulta un valore approssimato di $(1+sqrt(5))/2 \approx 1.61803...$.
Per esempio, per la funzione $f=x^2 -2x -log(x)$, risulta che secanti ha ordine di convergenza $p_s=1.080550886573186$ con
$x_0=0.25$
$x_1=1$
tol=$1e-8$;
max-iter=$200$
Mi sembra strano che non si avvicini nemmeno a $1.6...$
A questo punto mi è venuto il dubbio che possa aver commesso un errore nell'implementare il metodo:
Temo di aver sbagliato il ciclo principale, in particolare la gestione dei due guess iniziali $x0$ e $x1$.
dopo aver implementato con MatLab il metodo delle secanti, ho letto che l'ordine di convergenza per esso è $p=(1+sqrt(5))/2$.
Incuriosito, ho testato l'algoritmo su due o più funzioni di cui avevo già calcolato gli zeri (tramite newton, iterazione di punto fisso, bisezione) e questo trovava correttamente lo zero.
Per calcolare l'ordine di convergenza per il metodo secanti ho utilizzato la formula che abbiamo ricavato per la teoria:
$ p_s=log(|x_(k+1)-alpha|)/log(|x_k-alpha|) $
Il problema è che non mi risulta un valore approssimato di $(1+sqrt(5))/2 \approx 1.61803...$.
Per esempio, per la funzione $f=x^2 -2x -log(x)$, risulta che secanti ha ordine di convergenza $p_s=1.080550886573186$ con
$x_0=0.25$
$x_1=1$
tol=$1e-8$;
max-iter=$200$
Mi sembra strano che non si avvicini nemmeno a $1.6...$
A questo punto mi è venuto il dubbio che possa aver commesso un errore nell'implementare il metodo:
function [x,xhist,flag] = secanti(f,x0,x1,tol,maxit)
% %
% DESCRIZIONE/IDEA:
%E' newton con al posto della derivata il rapporto incrementale.
%
% INPUT:
% f: funzione di cui trovare gli zeri
% x0=approssimazione iniziale
% x1=seconda approssimazione iniziale
% tol:tolleranza di arresto
% maxit:numero massimo di iterazioni
% nome della funzione di punto fisso
%
%
%
% OUTPUT:
% x:% zero trovato
% xhist: successione delle x trovate
% flag: se 0 il metodo termina in meno di maxit iterazioni,
% se 1 il metodo non converge in meno di maxit iterazioni
x = NaN; % Not a Number
xhist = []; % Vuoto
flag = 1; % Non convergenza
% Inizializzazione
iter = 0;
xhist = repmat(NaN,maxit,1);
scarto = tol+1;
% approssimazione iniziale come primo punto della successione
xold = x0;
xhist(1) = xold;
xold1=x1;
xhist(2)=xold1;
% Ciclo principale
while scarto>tol && maxit>iter
% Aggiorno contatore delle iterazioni
iter = iter +1;
% Calcolo del nuovo punto
xnew = xold1 - (feval(f,xold1))*((xold1-xold)/(feval(f,xold1)-feval(f,xold)));
% Calcolo scarto
scarto = abs(xnew-xold1);
% Aggiorno punto vecchio come punto nuovo
xold1 = xnew;
% Salvataggio dati
xhist(iter+1) = xnew;
end
if(iter<=maxit)
flag = 0;
end
% Calcolo del valore finale
x = xnew;
xhist = xhist(1:iter); % taglio il vettore fino al nuemro di iterazioni che il metodo ha raggiunto
Temo di aver sbagliato il ciclo principale, in particolare la gestione dei due guess iniziali $x0$ e $x1$.
Risposte
risolto !
Ho dimenticato di aggiornare il valore di xold !
Ho dimenticato di aggiornare il valore di xold !