Ho pensato di applicare il semplice metodo della bisezione a sistemi di equazioni (nel mio caso lineare, in forma matriciale, nel caso generale anche non lineare scrivendolo come f()=0).
Il punto è che c'è qualcosa che non torna! L'algoritmo (semplice, che ho controllato 100 volte, di per sé non ha errori) non porta a convergenza. Ovviamente per risolvere sistemi (lineari e non) si possono usare molti altri metodi es. iterazioni di punto fisso, volevo però provare ad applicare la bisezione o quantomeno capire perché non la si possa applicare in questo modo (non trovo documentazione a riguardo, solo per la classica f(x)=0 e non per il caso sistema di equazioni).
Nel caso di esempio, ho preso 2 equazioni in 2 incognite, ovvero:
- f1(x1,x2)=0 --> x1+2x2-1=0
- f2(x1,x2)=0 --> 3x1+4x2-2=0
In forma matriciale:
Dovevo quindi ottenere come risultato X=[0,0.5], soluzione che soddisfa AX=b. Invece con le iterazioni si arriva ad una convergenza sbagliata!
Come valori di partenza ho preso x1 e x2 compresi fra -5 e 5 (intervallo che contiene sicuramente entrambe le soluzioni). Anche cambiando l'intervallo comunque non arrivo a convergenza!
Riporto il codice (Python 3):
import numpy as np
N=20
A=[[1,2],[3,4]]
b=[1,2]
def f1(x1,x2):
return A[0][0]*x1+A[1][0]*x2-b[0]
def f2(x1,x2):
return A[0][1]*x1+A[1][1]*x2-b[1]
#estremi intervallo
x1min=-5
x2min=-5
x1max=5
x2max=5
for i in range(N):
c1=(x1min+x1max)*0.5
c2=(x2min+x2max)*0.5
if(f1(c1,c2)*f1(x1max,c2)<0):
x1max=c1
else:
x1min=c1
if(f2(c1,c2)*f2(c1,x2max)<0):
x2max=c2
else:
x2min=c2
x=[c1,c2]
print("x[]=",x)
print("r=",np.dot(A,x)-b)
A parte il codice, concettualmente ciò che ho fatto è questo:
- N iterazioni (poco cambia, non arrivo comunque alla convergenza corretta)
- per ogni iterazione (NB questo punto, forse è qui l'aspetto critico!!):
- f1(x1,x2)=0 , x2 fissato e x1 che poi viene "aggiustato" come nella bisezione per un'unica equazione quindi punto medio fra x1min e x1max (come appunto farei avendo un'unica equazione)
- f2(x1,x2)=0, x1 fissato e x2 che viene "aggiustato" in modo analogo a quanto fatto con f1() e x1
Avete qualche idea? Se si possa applicare la bisezione per sistemi di equazioni e in caso dove ho sbagliato? Ad occhio mi sembra che, fatta variare una delle due incognite (es. x1) nel frattempo calcola x2 con un valore che potrebbe far "sballare" il tutto, ma non sono sicuro dipenda da ciò e non saprei in caso come aggiustarlo.