Você está na página 1de 13

Universidade de Brasília

Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

UNIVERSIDADE DE BRASILIA PROGRAMA DE PÓS-GRADUAÇÃO


FACULDADE DE TECNOLOGIA EM CIÊNCIAS MECÂNICAS
DEPARTAMENTO DE ENG. MECÂNICA
Aluno: Thiago da Silva Gonzales Numerical Methods for Mechanical
Matrícula: 210032651 Sciences (DPG1119/ENM364525
Orientador: Edgar Amaral Silveira Métodos Numéricos em Ciências
Professor: Taygoara F. de Oliveira Mecânicas) - 2021/2

Assignment 3 – Direct methods for linear systens

1) Using a suitable programming language, write computational codes to solve systems of


linear algebraic equations by Gaussian Elimination methods. Your code (or codes) must
read data from a plain (ASCII) text file in the format

given that N is the system dimension, 𝐀𝐢𝐣 , 𝒊, 𝒋 = 𝟏, . . . , 𝑵, are the A-matrix components, and 𝐛𝐢
are the b-vector components.
Select a ill-conditioned system of N ≥ 8 and do the following:

Data Extraction:
Python language:
#Impotar Biblioteca
import numpy as np

with open('teste.txt', 'r') as f:


atv3 = f.readlines()

#print(atv3)

#função para dividir corretamente as informações


def dividir(lista, t):
for i in range(0, len(atv3), t):
yield lista[i:i + t]

listas = list(dividir(atv3,1))
n = listas[0:1]
n = float(content[0])
n = np.array(n)
print("Núm de linhas e colunas:")
print(n)
print ("-x-" *5)
np.loadtxt('teste.txt',delimiter=',')

# skiprows=1 e max_rows= valor de n


a = np.loadtxt('teste.txt',delimiter=',', skiprows=1, max_rows=5)
print("Matriz a:")
print (a)
print ("-*-" *5)
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

# skiprows=valor de n+1 e max_rows= 1


b = np.loadtxt('teste.txt',delimiter=',', skiprows=6, max_rows=1)
print("Vetor b:")
print (b)
Answer:
Núm de linhas e colunas:
5.0
-x--x--x--x--x-
Matriz a:
[[ 5. 5. 5. -6. 1.]
[-2. 2. 4. 4. 5.]
[-2. 5. -4. 0. 0.]
[ 1. -4. 0. 4. -4.]
[-2. -2. 1. -2. -2.]]
-*--*--*--*--*-
Vetor b:
[ 7. -8. 46. -49. 4.]

Data:
Python language:
#Impotar Biblioteca
import numpy as np
import pandas as pd

a = np.array([[ 5., 5., 5., -6., 1.],


[-2., 2., 4., 4., 5.],
[-2., 5., -4., 0., 0.],
[ 1., -4., 0., 4., -4.],
[-2., -2., 1., -2., -2.]])

b = np.array([ 7., -8., 46., -49., 4.])

a) Use the “direct” Gaussian Elimination (GE) to find the solution of the system
Python language:
# ax=b ... x=INVER(a)*b
#Encontra a inversa de a

a_inversa = np.linalg.inv(a)

#print(a)
#print(a_inversa)
#print('')

#calcular eliminação de gauss de forma direta

n = np.size(b) # Tamanho da mariz


x = np.zeros(n)

#Encontra x

x = np.dot(a_inversa,b)
print('residual: ' ,np.linalg.norm(np.dot(a,x) - b))
print ("A solução de gauss direto é:" ,x)
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

# outra resolução

x_2 = np.linalg.solve (a,b)


print('residual: ' ,np.linalg.norm(np.dot(a,x_2) - b))
print ("A solução de gauss direto (outra resolução) é:" ,x_2)
Answer:
residual: 5.329070518200751e-15
A solução de gauss direto é: [-5. 4. -4. -5. 2.]
residual: 9.057678187205881e-15
A solução de gauss direto (outra resolução) é: [-5. 4. -4. -5. 2.]

b) Use the Gaussian Elimination in the LU decomposition form to find the solution of the
system.
Python language:
def lu(a):

n = a.shape[0]
U = a.copy()
L = np.eye(n, dtype=np.double)

for i in range(n):

factor = U[i+1:, i] / U[i, i]


L[i+1:, i] = factor
U[i+1:] -= factor[:, np.newaxis] * U[i]

return L, U

def forward_substitution(L, b):

n = L.shape[0] #Núm de linhas

y = np.zeros_like(b, dtype=np.double); #Alocando espaço para o vet


or da solução

#Forward-substitution.

y[0] = b[0] / L[0, 0]

for i in range(1, n):


y[i] = (b[i] - np.dot(L[i,:i], y[:i])) / L[i,i]

return y

def back_substitution(U, y):

n = U.shape[0] #Núm de linhas

x = np.zeros_like(y, dtype=np.double); #Alocando espaço para o v


etor da solução

#Back-substitution.

x[-1] = y[-1] / U[-1, -1]


Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

for i in range(n-2, -1, -1):


x[i] = (y[i] - np.dot(U[i,i:], x[i:])) / U[i,i]

return x

def lu_solve(a, b):

L, U = lu(a)

y = forward_substitution(L, b)

return back_substitution(U, y)

x = (lu_solve(a, b))
print ("Resolução da Eliminação de Gauss \n")
print (lu_solve(a, b))
print ("-*-" *5)

delta_b = np.linalg.norm(np.dot(a,x) - b)
print ("Residual: \n")
print(delta_b)
print ("-x-" *5)
Answer:
Resolução da Eliminação de Gauss

[-5. 4. -4. -5. 2.]


-*--*--*--*--*-
Residual:

8.140289677804162e-15
-x--x--x--x--x-

Calculations behind the LU factorization is not very complicated. This technique is a fast
decomposition which is used for solving linear equations and finding inverses of matrices.

c) Implement scaled pivoting for GE and LU. Dot not really change the rows, but use the
order vector o(N), instead.
Python language:
#triangular_up(a,b)
def triangular_up(a,b):
n = np.size(b) # Tamanho da mariz
x = np.zeros(n)
vector_o=list(range(n)) #vetor ordenamento
for i in range(0,n):

#Calculo do pivo
for k in range(n-1): #no python começa no zero
#Calculo dos multiplicadores
for i in range(k+1,n):
m = a[i,vector_o[k]]/a[vector_o[k],vector_o[k]] # Multiplicador
a[i,:] = a[i,:] - m*a[k,:] # o : pega todos os elementos da linha #
Atenção, ao menos 1 valor da matriz não pode ser inteiro (receber o ponto)
b[i] = b[i] - m*b[k] # b não tem linhas
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

#print ("A solução do a é: " ,a)


#print ("-*-" *5)
#print ("A solução do b é: " ,b)
#print ("-x-" *5)
return a, b

#print(triangular_up(a,b))

#solução de triangular_up(a,b)

def triangular_solver(a,b):
n = np.size(b)
x = np.zeros(n)
x[n-1]= b[n-1]/a[n-1,n-1]

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

return x

#print ("A resposta da eliminação de gauss é: " ,triangular_solver(a,b))

def eliminacao_de_gauss(a,b):
triangular_up(a,b)
triangular_solver(a,b)
return triangular_solver(a,b)

x = eliminacao_de_gauss(a,b)

print ("Resolução de Eliminação de Gauss \n")


print (x)
print ("-*-" *5)

delta_b = np.linalg.norm(np.dot(a,x) - b)
print ("Residual: \n")
print(delta_b)
print ("-x-" *5)

#print ("A solução de gauss é:" ,x)


#print('residual: ' ,np.linalg.norm(np.dot(a,x) - b))
Answer:
Resolução de Eliminação de Gauss

[-5. 4. -4. -5. 2.]


-*--*--*--*--*-
Residual:

7.32410687763558e-15
-x--x--x--x--x-
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

d) Apply iterative improvement of the solution using the LU decomposition.


Python language:
#triangular_up(a,b)
def triangular_up(a,b):
n = np.size(b) # Tamanho da mariz
x = np.zeros(n)
#Calculo do pivo
for k in range(n-1): #no python começa no zero
#Calculo dos multiplicadores
for i in range(k+1,n):
m = a[i,k]/a[k,k] # Multiplicador
a[i,:] = a[i,:] - m*a[k,:] # o : pega todos os elementos da linha #At
enção, ao menos 1 valor da matriz não pode ser inteiro (receber o ponto)
b[i] = b[i] - m*b[k] # b não tem linhas

#print ("A solução do a é: " ,a)


#print ("-*-" *5)
#print ("A solução do b é: " ,b)
#print ("-x-" *5)
return a, b

#print(triangular_up(a,b))

#solução de triangular_up(a,b)

def triangular_solver(a,b):
n = np.size(b)
x = np.zeros(n)
x[n-1]= b[n-1]/a[n-1,n-1]

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

return x

#print ("A resposta da eliminação de gauss é: " ,triangular_solver(a,b))

def eliminacao_de_gauss(a,b):
triangular_up(a,b)
triangular_solver(a,b)
return triangular_solver(a,b)

x = eliminacao_de_gauss(a,b)
delta_b = np.linalg.norm(np.dot(a,x) - b)

#print ("A solução de gauss é:" ,x)


#print('residual: ' , delta_b)
#print ("-*-" *5)
#print("")
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

#Apply iterative improvement

tol = 1.e-5

while delta_b > tol:

b = x

#triangular_up(a,b)
def triangular_up(a,b):
n = np.size(b) # Tamanho da mariz
x = np.zeros(n)
vector_o=list(range(n)) #vetor ordenamento
for i in range(0,n):

#Calculo do pivo
for k in range(n-1): #no python começa no zero
#Calculo dos multiplicadores
for i in range(k+1,n):
m = a[i,vector_o[k]]/a[vector_o[k],vector_o[k]] # Multiplicador
a[i,:] = a[i,:] - m*a[k,:] # o : pega todos os elementos da linha #
Atenção, ao menos 1 valor da matriz não pode ser inteiro (receber o ponto)
b[i] = b[i] - m*b[k] # b não tem linhas

#print ("A solução do a é: " ,a)


#print ("-*-" *5)
#print ("A solução do b é: " ,b)
#print ("-x-" *5)
return a, b

#print(triangular_up(a,b))

#solução de triangular_up(a,b)

def triangular_solver(a,b):
n = np.size(b)
x = np.zeros(n)
x[n-1]= b[n-1]/a[n-1,n-1]

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

return x

#print ("A resposta da eliminação de gauss é: " ,triangular_solver(a,b))

def eliminacao_de_gauss(a,b):
triangular_up(a,b)
triangular_solver(a,b)
return triangular_solver(a,b)
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

x = eliminacao_de_gauss(a,b)
delta_b = np.linalg.norm(np.dot(a,x) - b)

print ("A solução de gauss é:" ,x)


print('residual: ' , delta_b)
print ("-*-" *5)
print("")
Answer:
A solução de gauss é: [-5. 4. -4. -5. 2.]
residual: 7.32410687763558e-15
-*--*--*--*--*-

e) Use the LU method to find 𝑨−𝟏 , performing the matrix decomposition only once!
Python language:
#Deomposição LU
def lu(a):

n = a.shape[0]
U = a.copy()
L = np.eye(n, dtype=np.double)

for i in range(n):

factor = U[i+1:, i] / U[i, i]


L[i+1:, i] = factor
U[i+1:] -= factor[:, np.newaxis] * U[i]

return L, U

#Decomposição PLU
def plu(A):

n = A.shape[0] #Núm de linhas

#Alocação de P,L e U
U = A.copy()
L = np.eye(n, dtype=np.double)
P = np.eye(n, dtype=np.double)

for i in range(n):

#Linhas de permutação (se necessário)


for k in range(i, n):
if ~np.isclose(U[i, i], 0.0):
break
U[[k, k+1]] = U[[k+1, k]]
P[[k, k+1]] = P[[k+1, k]]

factor = U[i+1:, i] / U[i, i]


L[i+1:, i] = factor
U[i+1:] -= factor[:, np.newaxis] * U[i]

return P, L, U
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

#Forward-substitution
def forward_substitution(L, b):

n = L.shape[0] #Núm de linhas

y = np.zeros_like(b, dtype=np.double); #Alocando espaço para o vet


or da solução

#Forward-substitution.

y[0] = b[0] / L[0, 0]

for i in range(1, n):


y[i] = (b[i] - np.dot(L[i,:i], y[:i])) / L[i,i]

return y

#Back-substitution
def back_substitution(U, y):

n = U.shape[0] #Núm de linhas

x = np.zeros_like(y, dtype=np.double); #Alocando espaço para o v


etor da solução

#Back-substitution.

x[-1] = y[-1] / U[-1, -1]

for i in range(n-2, -1, -1):


x[i] = (y[i] - np.dot(U[i,i:], x[i:])) / U[i,i]

return x

#Solução da Eliminação de Gauss


def lu_solve(a, b):

L, U = lu(a)

y = forward_substitution(L, b)

return back_substitution(U, y)

print ("Resolução de Eliminação de Gauss \n")


print (lu_solve(a, b))
print ("-x-" *5)

#Matrix inversa de a
def plu_inverse(a):

n = a.shape[0]
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

b = np.eye(n)
Ainv = np.zeros((n, n))

P, L, U = plu(a)

for i in range(n):

y = forward_substitution(L, np.dot(P, b[i, :]))

Ainv[:, i] = back_substitution(U, y)

return Ainv

print ("Matrix inversa de a: \n")


print(plu_inverse(a))
print ("-*-" *5)
print("")
#Comparação
print ("Verificação da Matrix inversa de a: \n")
print(np.linalg.inv(a))
print ("-x-" *5)
Answer:
Resolução de Eliminação de Gauss

[-5. 4. -4. -5. 2.]


-x--x--x--x--x-
Matrix inversa de a:

[[ 0.04228446 -0.07633169 -0.07962658 0.02745744 -0.22460187]


[ 0.08347062 0.05711148 0.16749039 0.08017573 0.02416255]
[ 0.08319605 0.10955519 -0.00082372 0.08649094 0.14250412]
[-0.00562878 0.0750961 0.04956068 0.12946183 -0.0739978 ]
[-0.07852828 -0.0010983 -0.13783635 -0.19384953 -0.15431082]]
-*--*--*--*--*-

Verificação da Matrix inversa de a:

[[ 0.04228446 -0.07633169 -0.07962658 0.02745744 -0.22460187]


[ 0.08347062 0.05711148 0.16749039 0.08017573 0.02416255]
[ 0.08319605 0.10955519 -0.00082372 0.08649094 0.14250412]
[-0.00562878 0.0750961 0.04956068 0.12946183 -0.0739978 ]
[-0.07852828 -0.0010983 -0.13783635 -0.19384953 -0.15431082]]
-x--x--x--x--x-

2) Test for the accuracy of the methods.

a) For LS solution methods, compute the residual vector 𝒓 = 𝒃 − 𝑨 ∗ 𝒙 and its norm ∥ 𝒓 ∥ 𝟐 =
𝒓 ∗ 𝒓. Then, for an ill-conditioned system, compare ∥ 𝒓 ∥𝟐 for GE, LU, and LU with iterative
improvement, with and without pivoting.

R- Evaluating the residues of each code presented in exercises 1 for all situations such as GE, LU, and
LU with iterative improvement, with and without pivoting, it is evident that they were close to zero, which
should be considered the computational cost as the determining factor for choosing the best method.

b) For matrix inversion, compute 𝑻 = (𝑨−𝟏 · 𝑨) − 𝑰 and study the influence of the pivoting
and iterative improvement in the norm of 𝑻. For matrices norms, use ∥ 𝑻 ∥ = ∑𝒏𝒊,𝒋 ∥ 𝑻𝒊𝒋 ∥ .
R- The propagation of rounding errors end up happening in the Gaussian elimination method especially
when the value of pivots are numbers close to zero. This problem can be mitigated with a partial pivot
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

with scale or an iterative improvement. Reducing the errors derived from the "residues" that in the case
studied was calculated through the “residual” equation nominated with “delta_b”.

3) Implement Gaussian Elimination for tridiagonal matrices (Thomas TDMA algorithm) for a
system given in the form

𝑎𝑖 𝑥𝑖−1 + 𝑏𝑖 𝑥𝑖 + 𝑐𝑖 𝑥𝑖+1 = 𝑑𝑖 .

Select a tridiagonal system with know solution and test your implementation. Observe that
only the vectors a, b, c, d, and e need to be stored.

Data:
a = np.array([[ 2., 1., 0., 0., 0.],
[ 1., 2., 1., 0., 0.],
[ 0., 1., 2., 1., 0.],
[ 0., 0., 1., 2., 1.],
[ 0., 0., 0., 1., 2.]])

b = np.array([ 4., 4., 0., 0., 2.])

Python language:
import numpy as np

def TDMA(a):
#preliminares
aa = (1.,1.,1.,1.,1.)
bb = (2.,2.,2.,2.,2.)
cc = (1.,1.,1.,1.,1.)
dd = (4.,4.,0.,0.,2.)

a = np.array(aa)
b = np.array(bb)
c = np.array(cc)
d = np.array(dd)

#Tamanho do sistema
n=np.shape(a)[0]

#Vetor auxiliar
cl=np.zeros(n)
dl=np.zeros(n)
x=np.zeros(n)

#execução dos vetores cl e dl


cl[0]=c[0]/b[0]
for i in np.arange(1,n-1,1):
cl[i]=c[i]/(b[i]-a[i]*cl[i-1])

dl[0]=d[0]/b[0]
for i in np.arange(1,n,1):
dl[i]=(d[i]-a[i]*dl[i-1])/(b[i]-a[i]*cl[i-1])

#substituicao reversa -> solucao x


x[n-1]=dl[n-1]
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

for i in np.arange(n-2,-1,-1):
x[i]=dl[i]-cl[i]*x[i+1]

return x

print ("Resolução do TDMA: \n")


print(TDMA(a))
Answer:
Resolução do TDMA:

[ 1.00000000e+00 2.00000000e+00 -1.00000000e+00 -3.33066907e-16


1.00000000e+00]

Or

Python language:
import numpy as np

def TDMA(a):
#preliminares
aa = (1.,1.,1.,1.,1.)
bb = (2.,2.,2.,2.,2.)
cc = (1.,1.,1.,1.,1.)
dd = (4.,4.,0.,0.,2.)

a = np.array(aa)
b = np.array(bb)
c = np.array(cc)
d = np.array(dd)

#Tamanho do sistema
n=np.shape(a)[0]

#inicializa vetor x
x=np.zeros(n)

#calcula cl e dl (vetores auxiliares)


#Economia de custo computacional se não for necessário preservar os valor
es iniciais de c e d
c[0]=c[0]/b[0]
for i in np.arange(1,n-1,1):
c[i]=c[i]/(b[i]-a[i]*c[i-1])

d[0]=d[0]/b[0]
for i in np.arange(1,n,1):
d[i]=(d[i]-a[i]*d[i-1])/(b[i]-a[i]*c[i-1])

#substituicao reversa -> solucao x


x[n-1]=d[n-1]
for i in np.arange(n-2,-1,-1):
x[i]=d[i]-c[i]*x[i+1]

return x
Universidade de Brasília
Faculdade de Tecnologia
Programa de Pós-Graduação em Ciências Mecânicas

print ("Resolução do TDMA: \n")


print(TDMA(a))
Answer:
Resolução do TDMA:

[ 1.00000000e+00 2.00000000e+00 -1.00000000e+00 -3.33066907e-16


1.00000000e+00]

Você também pode gostar