Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Caderno 9

Método de Newton para sistemas não-lineares

Este método determina, a cada iteração, a solução aproximada do sistema não-linear através de uma linearização das funções-alvo com a matriz Jacobiana associada ao sistema.

Passos

Para o método de Newton não-linear, basicamente criamos uma espécie de “caminho” onde somamos um vetor de deslocamento s{\bf s} às aproximações sucessivas que dá a direção para onde os vetores devem prosseguir a fim de atingir convergência.

Obs.: este processo iterativo usa critérios de parada naturais em algoritmos iterativos.

Para encontrarmos o vetor solução, devemos resolver a equação matricial linearizada

J(x(i))s(i)=F(x(i)){\bf J}({\bf x}^{(i)}){\bf s}^{(i)} = - {\bf F}({\bf x}^{(i)})

Em seguida, atualizamos o novo vetor da sequencia como:

x(i+1)=x(i)+s(i).{\bf x}^{(i+1)}={\bf x}^{(i)} + {\bf s}^{(i)}.

Acima, J(x(i)){\bf J}({\bf x}^{(i)}) é a matriz Jacobiana formada a partir das derivadas parciais das funções componentes do vetor F{\bf F}.

No caso de um sistema em que F=[f1(x1,x2)  f2(x1,x2)]T{\bf F} = [f_1(x_1,x_2) \ \ f_2(x_1,x_2)]^T, teríamos o sistema abaixo:

[f1(x1,x2)x1f1(x1,x2)x2f2(x1,x2)x1f2(x1,x2)x2][s0s1]=[f1(x1,x2)f2(x1,x2)]\begin{bmatrix} \frac{\partial f_1(x_1,x_2)}{\partial x_1} & \frac{\partial f_1(x_1,x_2)}{\partial x_2} \\ \frac{\partial f_2(x_1,x_2)}{\partial x_1} & \frac{\partial f_2(x_1,x_2)}{\partial x_2} \\ \end{bmatrix} \begin{bmatrix} s_0 \\ s_1 \\ \end{bmatrix} = \begin{bmatrix} -f_1(x_1,x_2)\\ -f_2(x_1,x_2) \\ \end{bmatrix}
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import sympy as sy
from scipy.optimize import root

No exemplo a seguir, mostramos como podemos resolver um sistema de equações não-lineares usando o scipy.

Procuramos as soluções para o sistema não-linear

{f1(x,y):x2+y2=2f2(x,y):x2y29=1\begin{cases}f_1(x,y) &: x^2 + y^2 = 2 \\ f_2(x,y) &: x^2 - \frac{y^2}{9} = 1\end{cases}

Vamos plotar o gráficos das funções:

x = np.linspace(-2,2,50,endpoint=True)
y = x[:]
X,Y = np.meshgrid(x,y)

# define funções para plotagem
F1 = X**2 + Y**2 - 2
F2 = X**2 - Y**2/9 - 1

# curvas de nível
C = plt.contour(X,Y,F1,levels=[0],colors='k')
C = plt.contour(X,Y,F2,levels=[0],colors='g')
plt.grid(True)
<Figure size 432x288 with 1 Axes>

Pela figura, vemos que existem 4 pontos de interseção entre as curvas e, portanto, 4 soluções, as quais formam o conjunto

S={(x1,y1),(x2,y2),(x3,y3),(x4,y4))S = \{(x_1^{*},y_1^{*}),(x_2^{*},y_2^{*}),(x_3^{*},y_3^{*}),(x_4^{*},y_4^{*}))

Agora, vamos usar a função root do scipy para computar essas soluções com base em estimativas iniciais.

# define função para o vetor F(x)
def F(x):
    return [ x[0]**2 + x[1]**2 - 2,
             x[0]**2 - x[1]**2/9 - 1 ]


x,y = sy.symbols('x,y')

# usa computação simbólica para determinar a matriz Jacobiana
f1 = x**2 + y**2 - 2
f2 = x**2 - y**2/9 - 1

# gradientes

f1x,f1y = sy.diff(f1,x),sy.diff(f1,y)
f2x,f2y = sy.diff(f2,x),sy.diff(f2,y)

# imprime derivadas parciais
print(f1x)
print(f1y)
print(f2x)
print(f2y)

# monta matriz Jacobiana
def jacobian(x):
    return np.array([[2*x[0], 2*x[1]], [2*x[0],-2*x[1]/9]])

# resolve o sistema não-linear por algoritmo de Levenberg-Marqardt modificado

inicial = [[2,2],[-2,2],[-2,-2],[2,-2]]

S = []
i = 1
for vetor in inicial: 
    aux = root(F,vetor,jac=jacobian, method='lm')
    S.append(aux.x) 
    s = 'Solução x({0})* encontrada: {1}'
    print(s.format(i,aux.x))
    i +=1
2*x
2*y
2*x
-2*y/9
Solução x(1)* encontrada: [1.04880885 0.9486833 ]
Solução x(2)* encontrada: [-1.04880885  0.9486833 ]
Solução x(3)* encontrada: [-1.04880885 -0.9486833 ]
Solução x(4)* encontrada: [ 1.04880885 -0.9486833 ]

Em seguida, vamos plotar as soluções e as curvas

# curvas de nível
C = plt.contour(X,Y,F1,levels=[0],colors='k')
C = plt.contour(X,Y,F2,levels=[0],colors='g')
plt.grid(True)

# imprime interseções
for i in range(len(S)):
        plt.plot(S[i][0],S[i][1],'or')
<Figure size 432x288 with 1 Axes>

Exercício:

Resolva os sistemas não-lineares da Lista de Exercícios 4 usando a mesma abordagem acima.

Nota: Raízes de sistemas não-lineares

  • Uma equação linear tem a forma:

f(x)=a1x1+a2x2++anxnf(x) = a_1 x_1 + a_2 x_2 + \ldots + a_n x_n
  • Uma equação não-linear possui “produtos de incógnitas”, e.g.

f2(x)=a1x1x2+a2x22+anxnx1f_2(x) = a_1 x_1 x_2 + a_2 x_2^2 + a_n x_nx_1
  • Um sistema de equações não-lineares é composto de várias equações não-lineares

f1(x1,x2,,xn)=0f_1(x_1,x_2,\ldots,x_n) = 0
f2(x1,x2,,xn)=0f_2(x_1,x_2,\ldots,x_n) = 0
\vdots
fn(x1,x2,,xn)=0f_n(x_1,x_2,\ldots,x_n) = 0
  • A solução do sistema é o vetor (x1,x2,,xn) (x_1^{*},x_2^{*},\ldots,x_n^{*}) que satisfaz as n n equações simultaneamente.

Iteração de Ponto Fixo para sistemas não-lineares

  • Aplicar o algoritmo iterativo em cada componente:

x1i+1=f~1(x1i,x2i,,xni)x_1^{i+1} = \tilde{f}_1(x_1^{i},x_2^{i},\ldots,x_n^{i})
x2i+1=f~2(x1i,x2i,,xni)x_2^{i+1} = \tilde{f}_2(x_1^{i},x_2^{i},\ldots,x_n^{i})
\vdots
x3i+1=f~3(x1i,x2i,,xni)x_3^{i+1} = \tilde{f}_3(x_1^{i},x_2^{i},\ldots,x_n^{i})

As formas funcionais mudam porque devemos isolar a variável xi x_i .

Exemplo: encontrar a raiz do sistema abaixo:

f1(x,y)=x2+xy10=0f_1(x,y) = x^2 + xy - 10 = 0
f2(x,y)=y+3xy257=0f_2(x,y) = y + 3xy^2 - 57 = 0

Solução:

Reescrevamos as equações na forma

x=f~1(x,y)=10xyx = \tilde{f}_1(x,y) = \sqrt{10 - xy}
y=f~2(x,y)=57y3xy = \tilde{f}_2(x,y) = \sqrt{\frac{57-y}{3x}}

de onde temos a iteração de ponto fixo dada por

xi+1=10xiyix^{i+1} = \sqrt{10 - x^iy^i}
yi+1=57yi3xi,i=0,1,2,,y^{i+1} = \sqrt{\frac{57-y^i}{3x^i}}, \quad i = 0,1,2,\ldots,

Usando (x0,y0)=(1.5,3.5) (x^0,y^0) = (1.5,3.5) como “chute” inicial, computamos

x1=10x0y0=101.5(3.5)=2.17945x^{1} = \sqrt{10 - x^0y^0} = \sqrt{10 - 1.5(3.5)} = 2.17945
y1=57y03x1=573.53(2.17945)=2.86051y^{1} = \sqrt{\frac{57-y^0}{3x^1}} = \sqrt{\frac{57-3.5}{3(2.17945)}} = 2.86051

(o valor de x1 x^1 pode ser usado diretamente em vez de x0 x^0 .)

x2=10x1y1=102.17945(2.86051)=1.94053x^{2} = \sqrt{10 - x^1y^1} = \sqrt{10 - 2.17945(2.86051)} = 1.94053
y2=57y13x2=572.860513(1.94053)=3.04955y^{2} = \sqrt{\frac{57-y^1}{3x^2}} = \sqrt{\frac{57-2.86051}{3(1.94053)}} = 3.04955
\ldots

O processo iterativo converge para a solução (x,y)=(2,3) (x^{*},y^{*}) = (2,3) .

Notas:

  • A convergência por iteração de PF depende de como as equações f~1,f~2,,f~n \tilde{f}_1,\tilde{f}_2,\ldots,\tilde{f}_n são formuladas, bem como de um bom “chute” inicial.

  • A iteração de PF é bastante restritiva nas soluções de sistemas não-lineares.

Newton-Raphson para sistema não-linear

  • Depende de série de Taylor em n n-dimensões.

  • Para 2 dimensões, por exemplo, o método de Newton-Raphson pode ser escrito como:

ui+1=ui+(xi+1xi)uix+(yi+1yi)uiyu_{i+1} = u_i + (x_{i+1} - x_i)\frac{\partial u_i}{\partial x} +(y_{i+1} - y_i)\frac{\partial u_i}{\partial y}
vi+1=vi+(xi+1xi)vix+(yi+1yi)viyv_{i+1} = v_i + (x_{i+1} - x_i)\frac{\partial v_i}{\partial x} +(y_{i+1} - y_i)\frac{\partial v_i}{\partial y}
  • A estimativa da raiz corresponde aos valores de x x e y y para os quais ui+1=0 u_{i+1} = 0 e vi+1=0 v_{i+1} = 0 . Então,

uixxi+1+uiyyi+1=ui+uixxi+uiyyi\frac{\partial u_i}{\partial x} x_{i+1} + \frac{\partial u_i}{\partial y} y_{i+1} = - u_i + \frac{\partial u_i}{\partial x}x_i + \frac{\partial u_i}{\partial y}y_i
vixxi+1+viyyi+1=vi+vixxi+viyyi,\frac{\partial v_i}{\partial x} x_{i+1} + \frac{\partial v_i}{\partial y} y_{i+1} = - v_i + \frac{\partial v_i}{\partial x}x_i + \frac{\partial v_i}{\partial y}y_i,

que é um sistema nas incógnitas xi+1 x_{i+1} e yi+1 y_{i+1} .

  • Manipulações algébricas permitem solucionar este sistema (e.g. regra de Cramer):

xi+1=xiJ1(uiviyviuiy)x_{i+1} = x_i - J^{-1}\left(u_i\frac{\partial v_i}{\partial y} - v_i\frac{\partial u_i}{\partial y}\right)
yi+1=yiJ1(viuixuivix),y_{i+1} = y_i - J^{-1}\left(v_i\frac{\partial u_i}{\partial x} - u_i\frac{\partial v_i}{\partial x}\right),

onde

J=uixviyuiyvixJ = \frac{\partial u_i}{\partial x}\frac{\partial v_i}{\partial y} - \frac{\partial u_i}{\partial y}\frac{\partial v_i}{\partial x}

é o determinante da matriz Jacobiana do sistema.

Exemplo: resolver o mesmo sistema do PF

Solução:

  • Inicialmente, calculemos as derivadas parciais no ponto inicial:

u0x=2x0+y0=2(1.5)+3.5=6.5,    u0y=x0=1.5\frac{\partial u_0}{\partial x} = 2x_0 + y_0 = 2(1.5) + 3.5 = 6.5, \ \ \ \ \frac{\partial u_0}{\partial y} = x_0 = 1.5
v0x=3y02=3(3.5)2=36.75,    v0y=1+6x0y0=1+6(1.5)(3.5)=32.5\frac{\partial v_0}{\partial x} = 3y_0^2 = 3(3.5)^2 = 36.75, \ \ \ \ \frac{\partial v_0}{\partial y} = 1 + 6x_0y_0 = 1 + 6(1.5)(3.5) = 32.5
  • O determinante é J=6.5(32.5)1.5(36.75)=156.125 J = 6.5(32.5) - 1.5(36.75) = 156.125 .

  • Calculamos os valores da função no ponto inicial

u(x0,y0)=u0=2.5,v(x0,y0)=v0=1.625u(x_0,y_0) = u_0 = -2.5, \quad v(x_0,y_0) = v_0 = 1.625
  • Calculamos os valores no próximo passo, i.e., (x1,y1) (x^1,y^1) .

x1=1.5156.125=2.03603x^1 = 1.5 - \frac{\cdots}{156.125} = 2.03603
y1=3.5156.125=2.84388y^1 = 3.5 - \frac{\cdots}{156.125} = 2.84388
  • O processo iterativo converge para a solução (x,y)=(2,3) (x^{*},y^{*}) = (2,3) .

Ref.: Chapra & Canale, sec. 6.6