Dados:
Saída:
Salve no arquivo sislinlib.py
# Rotina para resolução de sistema Triangular Superior.
def ts(A,B):
"""
Resolve o sistema linear AX=B, onde A é uma matriz triangular superior.
Entrada:
A - matrix triangular superior
B - vetor coluna
Saida:
X - vetor coluna com a solução
"""
# Copia os argumentos para poder manipula-los
# Isso é necessário em Python quando os argumentos são vetores e matrizes.
a=A.copy()
b=B.copy()
# Obtem dimensionalidade de B
n=B.size
# x será do mesmo tamanho que B mas inicializado com zeros
x=B.copy()
x[:]=0
# Em python, vetores e matrizes tem índices começando a partir do 0.
# ou seja, x(i) será x(0), x(1), ..., x(n-1)
# A função "range(a,b)" gera uma sequência de números de a até b-1 !
# Para se criar uma sequência 1,2,3,4 temos range(1,5)
# A função "range(b,a,-1)" gera uma sequência de b descendo até a+1 !
# Para se criar uma sequência 4,3,2,1 temos range(4,0,-1)
x[n-1]=b[n-1]/a[n-1,n-1];
for k in range(n-1,0,-1):
soma=b[k-1]
for j in range(k+1,n+1):
soma=soma-a[k-1,j-1]*x[j-1]
x[k-1]=soma/a[k-1,k-1]
return x
import numpy as np
import sislinlib as sl
# Teste
A=np.array([[2,-1,1],[0,1,2],[0,0,1]])
B=np.array([2,3,1])
x=sl.ts(A,B)
Este método transforma um sistema linear geral em um sistema triangular superior.
Dados:
Saída:
Nota: Porque o pivoteamento funciona. A equação matricial é da forma: \[ AX=B,\] ou em forma de somatório fica \[ \Sigma_j A_{ij}X_j = B_i,\] ou seja, para cada linha \(i\) da matrix \(A\) e do vetor \(B\), temos a somatória acima. Se trocarmos quem uma linha por outra, por exemplo, trocarmos os números da linha 1 com a linha 3, de ambos \(A\) e \(B\), a soma ainda vai ser a mesma para os mesmos valores de \(X\).
Salve no arquivo sislinlib.py
# Eliminação Gaussiana.
def eg(A,B):
"""Usa o método da Eliminação Gaussiana para
transformar o sistema linear AX=B em um sistema Triangular superior,
retornando a nova matriz At, triangular superior, e o vetor Bt,
tal que AtX=Bt tem a mesma solução."""
# Necessário em Python quando trabalhando com matrizes e vetores
a=A.copy()
b=B.copy()
# Obtem número de equacões a partir do tamanho do vetor b
n=B.size
# Loop da primeira até a penúltima linha (de 1 até n-1)
for klin in range(1,n-1+1):
#######################################
# Aplica Pivoteamento
w=abs(a[klin-1,klin-1])
for jlin in range(klin,n+1):
if abs(a[jlin-1,klin-1])>w:
w=abs(a[jlin-1,klin-1])
rlin=jlin
# Terminado, troca as linhas "k" e "r"
for jlin in range(1,n+1):
vj=a[klin-1,jlin-1]
a[klin-1,jlin-1]=a_[rlin-1,jlin-1]
a[rlin-1,jlin-1]=vj
#########################################
# Calcula novos valores de A e B
for ilin in range(klin+1,n+1):
m=a[ilin-1,klin-1]/a[klin-1,klin-1]
b[ilin-1]=b[ilin-1]-m*b[klin-1]
for jlin in range(k+1,n+1):
a[ilin-1,jlin-1]=a[ilin-1,jlin-1]-m*a[klin-1,jlin-1]
return a,b
import numpy as np
import sislinlib as sl
a=np.array([[1,0,1],[1,1,0],[2,3,1]])
b=np.array([0,1,1]);
print('A=',a)
print('B=',b)
# Executa Eliminação Gaussiana:
a1,b1=sl.eg(a,b)
print('A1=',a)
print('B1=',b)
# Resolve o sistema triangular
x=sl.ts(a1,b1)
print('X=',x);
import matplotlib.pyplot at plt
import numpy as np
###############
# Define a funcao a ser estudada
def f(x):
return x**3-2*x-5
################
# Faz uma figura da funcao
x = np.arange(-5,5,.1);
plt.plot(x,f(x));
plt.grid()
plt.ion()
plt.show()
Dados
Retorno:
Salvar em um arquivo chamado zeroslib.py
#####################
# Método da Bissetriz
#####################
def bissetriz(f, a, b, tol):
"""Aplica o método da Bissetriz para encontra o zero da função f(x).
f - função de uma variável real: y=f(x).
a - ponto 'x' mais a esquerda.
b - ponto 'x' mais a direita.
tol- valor de tolerância.
"""
for j in range(0,50):
x=(a+b)/2
if f(a)*f(x)<0:
b=x
else:
a=x
#print([a,b])
if abs(b-a)<tol:
return (b+a)/2
print('Cheguei no final de 50 iterações...');
return (b+a)/2
import matplotlib.pyplot as plt
import numpy as np
import zeroslib as zz
###############
# Define a funcao a ser estudada
def f(x):
return x**3-2*x-5
################
# Faz uma figura da funcao
x=np.arange(-5,5,.1);
plt.plot(x,f(x))
plt.grid()
plt.ion()
plt.show()
################
print('Teste da Bissetriz')
zero = zz.bissetriz(f, 2, 3,1e-5)
print('x=',zero,'f(x)=',f(zero))
Dados:
Retorno:
Salvar em no mesmo arquivo chamado zeroslib.py
####################################
# Método da Newton
def newton(f,df,x0,tol, imet):
"""Aplica o método de Newton para encontra o zero da função f(x).
f - função de uma variável real: y=f(x).
df - derivada da função f(x): df/dx
x0 - ponto 'x' inicial.
tol- valor de tolerância.
imet- Seleciona qual método de parada usar:
imet=1 - para quando |f(x)|<e
imet=2 - para quando |x(n)-x(n-1)|<e
"""
for k in range(0,50):
x1 = x0-f(x0)/df(x0)
#print('x=',x0,'dx=',x1-x0)
if imet==1:
if abs(f(x1))<tol:
return x1
if imet==2:
if abs(x1-x0)<tol:
return x1
x0 = x1
print('Cheguei no final das 50 iterações...');
return x0
import matplotlib.pyplot as plt
import numpy as np
import zeroslib as zz
###############
# Define a funcao a ser estudada
def f(x):
return x**3-2*x-5
################
# Define a derivada de f para o metodo de newton
def df(x):
return 3*x**2-2
################
# Metodo de Newton
################
# Teste no valor absoluto da função
print('Newton - teste |f|<e')
zero = zz.newton(f, df, 3, 1e-5, 1)
print('x=',zero,'f(x)=',f(zero))
################
# Test na tamanho do passo
print('Newton - teste |dx|<e')
zero = zz.newton(f, df, 3, 1e-5, 2)
print('x=',zero,'f(x)=',f(zero))
Este método é equivalente ao método de Newton, quando voce substitui a derivada analítica por uma derivada numérica, sem tomar o limite:
\(f'(x_1)=\lim_{x_1->x_0}\frac{f(x_1)-f(x_0)}{x_1-x_0} \rightarrow f'(x_1)\approx \frac{f(x_1)-f(x_0)}{x_1-x_0}\).
Dados:
Retorno:
Salvar em no mesmo arquivo chamado zeroslib.py
####################################
# Método da Newton-Secante
def newtonsec(f,df,x0,x1,tol, imet):
"""Aplica o método de Newton para encontra o zero da função f(x).
f - função de uma variável real: y=f(x).
df - derivada da função f(x): df/dx
x0 - ponto 'x' inicial.
x1 - ponto 'x' próximo a x0
tol- valor de tolerância.
imet- Seleciona qual método de parada usar:
imet=1 - para quando |f(x)|<e
imet=2 - para quando |x(n)-x(n-1)|<e
"""
for k in range(0,50):
f0 = f(x0)
f1 = f(x1)
df = (f1-f0)/(x1-x0)
x2 = x1-f(x1)/df
#print('x=',x0,'dx=',x1-x0)
if imet==1:
if abs(f(x2))<tol:
return x2
if imet==2:
if abs(x2-x1)<tol:
return x2
x0 = x1
x1 = x2
print('Cheguei no final das 50 iterações...');
return x0
import matplotlib.pyplot as plt
import numpy as np
import zeroslib as zz
###############
# Define a funcao a ser estudada
def f(x):
return x**3-2*x-5
################
# Define a derivada de f para o metodo de newton
def df(x):
return 3*x**2-2
################
# Metodo Newton-Secante
################
# Test na tamanho do passo
print('Newtonsec - teste |dx|<e')
zero = zz.newtonsec(f, df, 3, 3.1, 1e-5, 2)
print('x=',zero,'f(x)=',f(zero))
Salve no arquivo zeroslib.py
##############
# Newton para sistemas não-lineares
##############
def newtonsys(F,J,x0,n,tol):
# Cria vetor e matriz com zeros.
f = np.zeros(n)
jac = np.zeros((n,n))
# Loop de iterações (max 50)
for k in range(0,50):
# Calcula valores de f e j
for i in range(0,n):
f[i]=F[i](x0)
for j in range(0,n):
jac[i,j]=J[i][j](x0)
# Resolve Jv=-F
# Ax=B <-> A=J, B=-F
# Transforma B em triangular (Eliminação Gaussiana)
A,B=eg(jac,-f)
# Resolve o sistema trangular.
v=ts(A,B)
x1 = x0+v
print(x1)
if abs(v).max()<tol:
return x1
x0 = x1
print('Cheguei no final das 50 iterações...');
return x1
import zeroslib as zz
# Define a função f1
def f1(x):
return -x[0]*(x[0]+1)+2*x[1]-18
# Define a função f2
def f2(x):
return (x[0]-1)**2+(x[1]-6)**2 - 25
# Define a derivada df1/dx1
def j11(x):
return -2*x[0]-1
# Define a derivada df1/dx2
def j12(x):
return 2
# Define a derivada df2/dx1
def j21(x):
return 2*x[0]-2
# Define a derivada df2/dx2
def j22(x):
return 2*x[1]-12
# Junta as funções em um "vetor de funções"
F = [f1, f2]
# Junta as derivadas em uma "matriz de funções"
J = [ [j11, j12], [j21, j22]]
# Aplica o método de newton no sistema acima
zero = zz.newtonsys(F,J, (3,12), 2, 1e-6)