Você está na página 1de 21

UNIVERSIDADE FEDERAL DE SANTA CATARINA

CÁLCULO NUMÉRICO DAS5103 - 04220

TRABALHO PRÁTICO 1:
RELATÓRIO FINAL

Professor:
Eduardo Camponogara
Alunos:
Bruno Forte de Lunardi Pinto - 22102525
Marcus Vinicius Novais Ferrari - 22104098
Paulo Librelotto Ferroli - 22100768
Victória De Carvalho Taveira - 21202235

Florianópolis
2023
SUMÁRIO

1 QUESTÃO 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 MÉTODO DA BISSECÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 MÉTODO DA FALSA POSIÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 MÉTODO DE NEWTON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.4 MÉTODO DAS SECANTES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2 QUESTÃO 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.1 ITEM 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2 ITEM 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3 ITEM 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3 QUESTÃO 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.1 SISTEMA DE EQUAÇÕES LINEARES A SER RESOLVIDO . . . . . . . . . . . . . . 15
3.2 PROGRAMAÇÃO DO MÉTODO DE ELIMINAÇÃO GAUSSIANA . . . . . . . . . 15
3.3 SOLUÇÃO FINAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4 QUESTÃO 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.1 ITEM 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.2 ITEM 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.3 ITEM 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.4 ITEM 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.5 ITEM 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1

1 QUESTÃO 1

1.1 MÉTODO DA BISSECÇÃO

#Importações das bibliotecas necessárias


import math
import numpy as np
import matplotlib.pyplot as plt

#Função que representa a expressão da atenuação


def f(x):
return 10*math.log10(1+math.e**-x)-5*math.sin(2*math.pi*x)+2*math.log(x+1)

#Função que realiza o método da bissescção


def bissec(a, b, e, itm):
it = 0
m = a
er = 1

x_values = []
error_values = []
interval_a_values = []
interval_b_values = []

while (er >= e and it < itm):


if f(a) * f(b) > 0:
print("Não há raiz neste intervalo")
else:
mold = m
m = (a + b)/ 2
er = np.abs((m - mold)/m)

if f(a) * f(m) < 0:


b = m
else:
a = m

#Armazena os valores
x_values.append(m)
error_values.append(er)
interval_a_values.append(a)
interval_b_values.append(b)

it += 1

if m == mold:
break
2

#Plotando os gráficos
plt.figure(figsize=(12, 8))
plt.subplot(2, 2, 1)
plt.plot(range(1, it+1), x_values, marker=’o’)
plt.xlabel(’Iterações’)
plt.ylabel(’x_k’)
plt.title(’Iterações de x_k’)

plt.subplot(2, 2, 2)
plt.plot(range(1, it+1), error_values, marker=’o’)
plt.xlabel(’Iterações’)
plt.ylabel(’|A(x)|’)
plt.title(’Erros |A(x)|’)

plt.subplot(2, 2, (3,4))
plt.plot(range(1, it+1), interval_a_values, marker=’o’, label=’a_k’, color=’blue’)
plt.plot(range(1, it+1), interval_b_values, marker=’o’, label=’b_k’, color=’red’)
plt.xlabel(’Iterações’)
plt.ylabel(’[a_k,b_k]’)
plt.title(’Intervalos [a_k,b_k]’)
plt.legend()

plt.tight_layout()
plt.show()

print(f’O valor aproximado da raiz é: {m}’)

bissec(1.4, 0.5, 10**-6, 100)


3

Através do código e de seus gráficos, pode-se observar que houve convergência no


método implementado para o valor aproximado de 1.0920317649841307. Porém, o mé-
todo da bissecção é um algoritmo de busca de raízes de funções não lineares que divide
iterativamente um intervalo ao meio e seleciona o subintervalo que contém a raiz, tendo
portanto, uma taxa de convergência linear, não sendo o mais eficiente.

1.2 MÉTODO DA FALSA POSIÇÃO

#Importações das bibliotecas necessárias


import math
import numpy as np
import matplotlib.pyplot as plt

#Função que representa a expressão da atenuação


def f(x):
return 10*math.log10(1+math.e**-x)-5*math.sin(2*math.pi*x)+2*math.log(x+1)

#Função que realiza o método da falsa posição


def false_position(a, b, e, itm):
it=0
4

m = a
er = 1

x_values = []
error_values = []
interval_a_values = []
interval_b_values = []

while(er >= e and it < itm):


if f(a)*f(b) > 0:
print("Não há raiz neste intervalo")
else:
mold = m
m = a - f(a)*(b-a)/(f(b)-f(a))
er = np.abs((m-mold)/m)
if f(a)*f(m) < 0:
b = m
else:
a = m
#Armazena os valores
x_values.append(m)
error_values.append(er)
interval_a_values.append(a)
interval_b_values.append(b)

it += 1
if m == mold:
break

#Plotagem dos gráficos


plt.figure(figsize=(12, 8))

plt.subplot(2, 2, 1)
plt.plot(range(1, it+1), x_values, marker=’o’)
plt.xlabel(’Iterações’)
plt.ylabel(’x_k’)
plt.title(’Iterações de x_k’)

plt.subplot(2, 2, 2)
plt.plot(range(1, it+1), error_values, marker=’o’)
plt.xlabel(’Iterações’)
plt.ylabel(’|A(x)|’)
plt.title(’Erros |A(x)|’)

plt.subplot(2, 2, (3,4))
plt.plot(range(1, it+1), interval_a_values, marker=’o’, label=’a_k’, color=’blue’)
plt.plot(range(1, it+1), interval_b_values, marker=’o’, label=’b_k’, color=’red’)
5

plt.xlabel(’Iterações’)
plt.ylabel(’[a_k,b_k]’)
plt.title(’Intervalos [a_k,b_k]’)
plt.legend()

plt.tight_layout()
plt.show()

print(f’O valor aproximado da raiz é: {m}’)

false_position(1.4, 0.5, 10**-6, 100)

Através do código e de seus gráficos, pode-se observar que houve convergência no


método implementado para o valor aproximado de 1.0920323739749607. Porém, o método
da falsa posição é um algoritmo numérico usado para encontrar a raiz de uma função não
6

linear. Ele começa com um intervalo inicial [a, b] que contém a raiz e em cada iteração,
é calculado um novo valor médio m baseado na fórmula da falsa posição, tendo portanto,
uma taxa de convergência linear, não sendo também o mais eficiente.

1.3 MÉTODO DE NEWTON

#Importações das bibliotecas necessárias


import math
import numpy as np
import matplotlib.pyplot as plt

#Função que representa a expressão da atenuação


def f(x):
return 10*math.log10(1+math.e**-x)-5*math.sin(2*math.pi*x)+2*math.log(x+1)

#Função que representa a derivada da expressão da atenuação


def df(x):
return -10/(math.log(10)*(math.e**x+1))-10*math.pi*math.cos(2*math.pi*x)+2/(x+1)

#Função que realiza o método de Newton


def newton(x0, e, itm):
it = 0
er = 1
x = x0
error_values = []
x_values = []

while er >= e and it < itm:


xold = x
x = x - f(x) / df(x)
er = np.abs((x - xold)/x)

#Armazena os valores
error_values.append(er)
x_values.append(x)

it += 1

if x == xold:
break

# Plotagem dos gráficos


plt.figure(figsize=(12, 8))

plt.subplot(2, 2, 1)
plt.plot(range(1, it+1), x_values, marker=’o’)
7

plt.xlabel(’Iterações’)
plt.ylabel(’x_k’)
plt.title(’Iterações de x_k’)

plt.subplot(2, 2, 2)
plt.plot(range(1, it + 1), error_values, marker=’o’)
plt.xlabel(’Iterações’)
plt.ylabel(’|A(x)|’)
plt.title(’Erros |A(x)|’)

plt.tight_layout()
plt.show()

print(f’O valor aproximado da raiz é: {x}’)

newton(1.2, 10 ** -6, 100)

Através do código e de seus gráficos, pode-se observar que houve convergência no


método implementado para o valor aproximado de 1.0920322837847314. O método de
Newton é um algoritmo numérico usado para encontrar as raízes de uma função não
linear. Ele começa com uma suposição inicial para a raiz e, em seguida, usa a derivada da
função para refinar essa suposição em cada iteração, sendo a opção mais eficiente, visto
que, tem uma convergência quadrática.

1.4 MÉTODO DAS SECANTES

#Importações das bibliotecas necessárias


8

import math
import numpy as np
import matplotlib.pyplot as plt

#Função que representa a expressão da atenuação


def f(x):
return 10*math.log10(1+math.e**-x)-5*math.sin(2*math.pi*x)+2*math.log(x+1)

#Função que realiza o método das secantes


def secante(x0, x1, e, itm):
it = 0
er = 1
xa1 = x0
x = x1

x_values = []
error_values = []
interval_a_values = []
interval_b_values = []

while (er >= e and it < itm):


xa2 = xa1
xa1 = x
x = xa1 - f(xa1)*(xa2-xa1)/(f(xa2)-f(xa1))
er = np.abs((x-xa1)/x)

#Armazena os valores
x_values.append(x)
error_values.append(er)
interval_a_values.append(xa1)
interval_b_values.append(xa2)

it += 1
if (x == xa1):
break

#Plotagem dos gráficos


plt.figure(figsize=(12, 8))

plt.subplot(2, 2, 1)
plt.plot(range(1, it + 1), x_values, marker=’o’)
plt.xlabel(’Iterações’)
plt.ylabel(’x_k’)
plt.title(’Valores de x nas iterações’)

plt.subplot(2, 2, 2)
plt.plot(range(1, it + 1), error_values, marker=’o’)
plt.xlabel(’Iterações’)
9

plt.ylabel(’|A(x)|’)
plt.title(’Erros |A(x)|’)

plt.subplot(2, 2, (3, 4))


plt.plot(range(1, it + 1), interval_a_values, marker=’o’, label=’a_k’, color=’b
plt.plot(range(1, it + 1), interval_b_values, marker=’o’, label=’b_k’, color=’r
plt.xlabel(’Iterações’)
plt.ylabel(’[a_k,b_k]’)
plt.title(’Intervalos [a_k,b_k]’)

plt.tight_layout()
plt.show()

print(f’O valor aproximado da raiz é: {x}’)

secante(0.5, 1.3, 10 ** -6, 100)

Através do código e de seus gráficos, pode-se observar que houve convergência no


10

método implementado para o valor aproximado de 1.0920322837847554. O método das


secantes é um algoritmo numérico usado para encontrar a raiz de uma função não linear.
Ele começa com duas suposições iniciais para a raiz e, em cada iteração, calcula um novo
valor baseado na fórmula das secantes. Este método é mais rápido que a iteração linear
ou bissecção, contudo, pode ser mais lento que o método de Newton.
11

2 QUESTÃO 2

2.1 ITEM 1

A raiz aproximada encontrada, com precisão de 10−9 , através do código abaixo foi:
1.5458515577832742e-16.

2.2 ITEM 2

#Importações das bibliotecas necessárias


import numpy as np
import math
from numpy import linalg as LA
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

#Função que representa o sistema não-linear de três equações


def f(x):
N = len(x)
b = [0]*N
b[0] = x[0]**2 + x[1]**2 + x[2]**2 - 1 + x[0]*x[1]-math.e**(x[2])
b[1] = x[0]*2 - x[1] + x[2]**2 - 2 + x[0]*x[2] + math.e**(-x[1])
b[2] = x[0]*3 + x[1] - x[2]**3 + 1 - x[0]*x[1]*x[2] + math.e**(x[0]+x[1])

return b

#Função que representa a Jacobiana do sistema não-linear de três equações


def J(x):
A = [[0,0,0],[0,0,0],[0,0,0]]
A[0][0] = 2*x[0]+x[1]
A[0][1] = 2*x[1]+x[0]
A[0][2] = 2*x[2]-math.e**x[2]
A[1][0] = 2+x[2]
A[1][1] = -1-math.e**(-x[1])
A[1][2] = 2*x[2]+x[1]
A[2][0] = 3-x[1]*x[2]+math.e**(x[0]+x[1])
A[2][1] = 1-x[0]*x[2]+math.e**(x[0]+x[1])
A[2][2] = -3*x[2]**2-x[0]*x[1]

return A

#Realiza o método de Newton para mais de uma variável


x0 = [-2, -2, -2]
iter = 0
eps = 10**-9
print("Iteração ",iter,": ",x0)
12

x_values = []
residual_norms = []
errors = []

while (iter < 100):


A = np.array(J(x0))
b = np.array(f(x0))
s = LA.solve(A,-b)
x1 = np.array(x0) + s
iter = iter + 1
print("Iteração ",iter,": ",x1)

residual_norm = LA.norm(b, np.inf)


error = LA.norm(x1 - x0, np.inf)

#Armazenar os resultados para o gráfico


x_values.append(list(x1))
residual_norms.append(residual_norm)
errors.append(error)

if (LA.norm(s, np.inf) < eps)|(LA.norm(b, np.inf) < eps):


print("Convergiu")
print("Precisao:",LA.norm(s, np.inf))
break

x0 = x1

it = len(x_values)
x_values = np.array(x_values).T

# Plotar os gráficos
plt.figure(figsize=(12, 8))

plt.subplot(2, 2, 1)
plt.plot(range(1, it + 1), residual_norms, marker=’o’)
plt.xlabel(’Iterações’)
plt.ylabel(’||f(x(k))||2’)
plt.title(’Resíduos f(x(k))2’)

plt.subplot(2, 2, 2)
plt.plot(range(1, it + 1), errors, marker=’o’)
plt.xlabel(’Iterações’)
plt.ylabel(’x(k) x2’)
plt.title(’Erro x(k) x2’)
13

plt.tight_layout()
plt.show()

#Plotar em 3D
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection=’3d’)

x = x_values[0]
y = x_values[1]
z = x_values[2]

ax.scatter(x, y, z, c=’r’, marker=’o’)

ax.set_xlabel(’X’)
ax.set_ylabel(’Y’)
ax.set_zlabel(’Z’)
plt.title(’Iterandos x(k) em 3D’)
plt.show()

Jacobiana analítica usada no algoritmo:


 
2x0 + x1 x0 + 2x1 2x2 − ex2
J(x) =  2 + x2 −1 − e−x1 2x2 + x0 
x0 +x1 x0 +x1
3 − x1 x2 + e 1 − x0 x2 + e −3x22 − x0 x1

2.3 ITEM 3
14
15

3 QUESTÃO 3

3.1 SISTEMA DE EQUAÇÕES LINEARES A SER RESOLVIDO

Em forma matricial A x = b:
    
3 1 2 0 1 x1 12
1 4 2 1 0 x2  20
   
 
2 0 3 4 1 x3  = 18
    
4 2 1 2 3 x4  22
0 2 1 3 4 x5 19

Matriz ampliada para aplicar o método de Gauss:


 
3 1 2 0 1 12
 1 4 2 1 0 20 
 
 2 0 3 4 1 18 
 
 4 2 1 2 3 22 
0 2 1 3 4 19

3.2 PROGRAMAÇÃO DO MÉTODO DE ELIMINAÇÃO GAUSSIANA

#Função que realiza a eliminação dos valores em cada linha


def elimination(A,b):
n = len(b)
x = [0]*n

#Cálculo dos pivos


for k in list(range(1,n,1)):
# Calculo dos multiplicadores.
for i in list(range(k+1,n+1,1)):
m = A[i-1][k-1]/A[k-1][k-1]
A[i-1][k-1] = 0
b[i-1] = b[i-1] - m*b[k-1]
#Atualizar demais valores da linha
for j in list(range(k+1,n+1,1)):
A[i-1][j-1] = A[i-1][j-1]-m*A[k-1][j-1]

return A,b

#Resolve o sistema triangular superior


def solveUpperTriangular(U,b):
n = len(b)
x = [0]*n
x[n-1] = b[n-1]/U[n-1][n-1]
16

for i in list(range(n-1,0,-1)):
s = 0
for j in list(range(i+1,n+1,1)):
s = s + U[i-1][j-1]*x[j-1]

x[i-1] = (b[i-1]-s)/(U[i-1][i-1])

return x

#Dados do problema
Ai = [[3, 1, 2, 0, 1],
[1, 4, 2, 1, 0],
[2, 0, 3, 4, 1],
[4, 2, 1, 2, 3],
[0, 2, 1, 3, 4]]

bi = [12, 20, 18, 22, 19]

#Resolve o pivoteamento do sistema acima


U,b = elimination(Ai,bi)
print("U =",U)
print("b =",b)
x = solveUpperTriangular(U,b)
print("x =",x)

Solução:
 
3 1 2 0 1
0 3.6666666666666665 1.3333333333333335
 1.0 −0.3333333333333333 

U=  0 0 1.9090909090909092 4.181818181818182 0.27272727272727276 

0 0 0 5.999999999999999 2.0 
0 0 0 0 3.5238095238095233
 
12

 16.0 

b =  12.90909090909091 


15.999999999999998
3.4761904761904763

3.3 SOLUÇÃO FINAL

 
1.5810810810810805
 3.27027027027027 

 
1.5000000000000007
x = 
2.3378378378378377
0.9864864864864866
17

4 QUESTÃO 4

4.1 ITEM 1

#Importando as bibliotecas necessárias


import math
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt

v0 = sp.Symbol(’v0’)

#Método de Euler para resolvera ODE


def EulerODE( v0 , dt , T ) :
t = 0
x = 0
v = v0
while t <= T:
a = (-0.5*x + 2 )
v = v + a*dt
x = x + v*dt
t+= dt
return x

EulerODE: 1.2000069821834*v0 + 6.12860346757127.

4.2 ITEM 2

def AproximacaoDerivada( v0 , h ) :
fv0 = EulerODE( v0 , 0.01 , 3) - 10
fv0_delta = EulerODE( v0 + h , 0.01 , 3)- 10
derivada = ( fv0_delta - fv0 ) / h
return derivada

AproximacaoDerivada: 1.20000698218981.

4.3 ITEM 3

v = 1
itm = 0
vitm =[]

while itm < 20 :


v = v - ((EulerODE(v, 0.01, 3) - 10) / AproximacaoDerivada(v, 0.001))
18

vitm.append(v)
itm = itm + 1

plt.figure()
plt.plot(vitm)
v0=v

v0: 3.226145005743854.

4.4 ITEM 4

Colocando o resultado de v0 obtido no item anterior na equação discretizada que


achamos no item 1, pode-se concluir que o método converge para uma solução.

Resultado: 1.2000069821834 · 3.226145005743854 + 6.12860346757127 = 10.

4.5 ITEM 5
19

Você também pode gostar