03.1 Metodo di Bisezione

3.1 Il metodo di Bisezione


Il metodo di bisezione è un metodo numerico che consiste nel dimezzare di volta in volta l'Intervallo di separazione e usare il punto medio di tale intervallo come approssimazione della soluzione ξ.
Consente di costruire una successione {xk} di approssimazioni di ξ, ottenute assumendo xk come punto medio di un intervallo [ak1,bk1] con kN+.

☑️ Ipotesi

ipotesi
  1. I=[a,b] Intervallo di separazione
  2. f(x)C0[a,b]
  3. f(a)f(b)<0

Algoritmo

GraficoMetodoBisezione 1.png

Individuato unIntervallo di separazione [a0,b0] ne calcolo il punto medio che chiamerò x1:

x1=b0+a02

Ora controllo in quale tra gli intervalli [a0,x1] e [x1,b0] appartiene la soluzione ξ, verificando che il prodotto f(ak1)f(xk) oppure il prodotto f(bk1)f(xk) sia negativo.

Una volta individuato l'intervallo, ripeto il procedimento usando quello come nuovo intervallo di separazione. Supponiamo ad esempio che la soluzione cada nell'intervallo [a0,x1], questo sarà proprio il nuovo intervallo di separazione [a1,b1]=[a0,x1].

Chiamo x2 il punto medio tra a1 e b1:

x2=a1+b12

Continuando a ripetere questo processo, ammesso che il metodo converga, xk sarà man mano sempre più vicino alla soluzione ξ.

Errori

Errore di troncamento

Nell'applicazione del metodo di bisezione, compiamo un Errore di troncamento dovuto quindi al numero di iterazioni che compiamo

Convergenza

Calcolo l'errore ek tenendo presente che esso dovrà per forza essere minore della metà dell'ampiezza dell'intervallo.
A sua volta l'ampiezza dell'intervallo [ak1,bk1] sarà la metà dell'intervallo della iterazione predente [ak2,bk2] e così via

|ek|=|ξxk|bk1ak1212bk2ak2212k(b0a0)|ek|=|ξxk|12k(b0a0)

Converge?

limk|ek|=limk|12k(b0a0)|=0

Ordine di convergenza

ordine di convergenza

Il metodo di bisezione ha ordine di convergenza pari a 1:
p=1


Dimostrazione:

Ricordo che:
|ek+1|=bkak2=12bk1ak12=bk1ak122
e che:
|ek|=bk1ak12
per cui
|ek+1||ek|pbk1ak1222bk1ak1=12
con p=1.

Stima iterazioni necessarie

Per ottenere l'approssimazione della soluzione con una tolleranza scelta ε sono necessarie almeno un certo numero k di iterazioni. Questo numero può essere stimato a partire dalla relazione:

|ek|=12k(ba)ε

Risolvendo per k otteniamo infatti:

2kbaεlog2(2k)log2(baε)klog2(baε)

Tenendo presente che k deve per definizione essere un numero intero positivo.

Criterio di arresto

Criterio di arresto a posteriori

Posso interrompere l'algoritmo quando l'errore al passo k è minore di una tolleranza scelta ε.

|ek|ε

Implementazione in Matlab

function [soluzioneApprox,erroreStimato, iterazioniNecessarie] = MetodoBisezioneNonLineari(estremoInferiore, estremoSuperiore, funzione, tolleranza, numeroMaxIterazioni)

% Questa funzione serve ad applicare il metodo di bisezione a una funzione
% assegnata per ricavarne la soluzione approssimata.
% Input:
% estermoInferiore, estremoSuperiore: Estremi dell'intervallo di separazione
% funzione: la funzione, definita come anonymous function, a cui
% applicare il metodo
% tolleranza: La tolleranza con la quale si vuole trovare la soluzione
% numeroMaxIterazioni: Il numero max di iterazioni che si vogliono
% provare prima di interrompere il calcolo. (Se non specificato è
% inizializzato a 100

% ------------

% Outpu:
% soluzioneApprox: la soluzione approssimata
% erroreStimato: la media degli errori calcolati come b-a e come f(xn)
% iterazioniNecessarie: Il numero di iterazioni necessarie alla stima
% dell'errore
% Cerco la radice di una funzione f nell'intervallo [a,b] con il metodo di
% bisezione
% Suppongo di aver già individuato gli estremi degli intervalli di
% separazione
% Sfrutteremo un criterio di arresto basato sulla tolleranza:
% f = Funzione della quale vogliamo cercare la radice
% a = Estremo inferiore in cui è stata isolata la radice
% b = Estremo superiore in cui è stata isolata la radice
% toll = Tolleranza (\tollilon)
% numeroMaxIterazioni = Massimo numero di iterazioni

f = funzione;

% So che nell'intervallo definito sotto sicuremante ci sarà una soluzione
a = estremoInferiore;
b = estremoSuperiore;

% Definisco la tolleranza
toll = tolleranza;
maxIter = 100;
maxIter = numeroMaxIterazioni;

% Vogliamo calcolare:
% xn: Approx della radice
% err1 = |x(n) - x(n-1)|
% err2 = f(xn)
% iter = Numero di iterazioni

format long

% Inizializzo i parametri necessari
iter = 0; err1 = b-a; err2 = toll+1; x0 = a;

% Verifico che la radice esista
if f(a)*f(b) > 0
	error('Non ci sono soluzioni nellintervallo [a,b]') % Con questo comando blocco l'esecuzione dello script
elseif f(a)*f(b) == 0
	if f(a) == 0
		xn = a;
	elseif f(b) == 0
		xn = b;
	end
	return % Return perché non voglio andare avanti se queste condizioni del secondo if sono rispettate
end

% Calcolo successione
while (err1 > toll) && iter < maxIter
	xn = (a+b)/2;
	if f(a)*f(xn) < 0
		b = xn;
	elseif f(xn)*f(b) < 0
		a = xn;
end

iter = iter + 1;
err1 = abs(xn-x0);
err2 = abs(f(xn));
x0 = xn;
end

soluzioneApprox = xn;
erroreStimato = abs((err1 + err2)/2);
iterazioniNecessarie = iter;

end