Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions band_lu_factorization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import numpy as np
from copy import deepcopy
from band_matrix import BandMatrix

def mult(m1: BandMatrix, m2: BandMatrix):
matRes = []

for i in range(0, m1.dimension_x):
matRes.append([])

for j in range(0, m2.dimension_y):
# multiplica cada linha de mat1 por cada coluna de mat2;
listMult = [x*y for x, y in zip(m1.get_line(i), m2.get_col(j))]

# e em seguida adiciona a matRes a soma das multiplicações
matRes[i].append(sum(listMult))

return matRes

def print_matrix(matrix):
for line in matrix:
print("|{}|".format("\t".join(list(map(lambda item: "{:7.2f}".format(item), line)))))
print('\n\n')

def set_diagonal(m, n = 1):
for i in range(m.dimension_x):
m.set(i, i, n)

def find_pivo(matrix, col):
maior = matrix.get(col, col)
index = col
for i in range(col, matrix.dimension_x):
if(abs(matrix.get(i, col)) > abs(maior)):
maior = matrix.get(i, col)
index = i
return index, maior

def lu_factor(matrix):
u = deepcopy(matrix)
l = BandMatrix(12, 12, matrix.lower_bandwidth, 0)
for k in range(matrix.dimension_x - 1):
# pivoteamento #
"""index, maior = find_pivo(u, k)
print("Swap line {} with line {}".format(k, index))
u.swap_lines(k, index)
l.swap_lines(k, index)"""
##
for j in range(k + 1, matrix.dimension_x):
l.set(j, k, u.get(j, k)/u.get(k, k))
for i in range(k, matrix.dimension_x):
u.set(j, i, u.get(j, i) - l.get(j, k)*u.get(k, i))
set_diagonal(l)
return l, u


def solvingl(l, b):
n = l.dimension_x
for i in np.arange(n):
pivo = b[i]

for j in np.arange(n):
if(j > i):
b[j] = b[j] + round((l.get(j,i)*-1),2) * pivo # Multiplica l *multiplicadores* com o pivo e soma com b

return(np.copy(b))

def solvingu(A, b):
n = A.dimension_x
x = np.zeros(n)
x[n-1] = b[n-1]/A.get(n-1, n-1)

for k in range(n-1, -1, -1): # linha
soma = 0
for j in range(0,n): # coluna
soma = soma + A.get(k,j) * x[j]
x[k]=(b[k] - soma)/A.get(k,k)

return(x)

if __name__ == "__main__":

normal_matrix = [
[ 1, 0, 0, 0, 1],
[-1, 1, 0, 0, 1],
[-1, -1, 1, 0, 1],
[-1, -1, -1, 1, 1],
[-1, -1, -1, -1, 1]
]

normal_matrix = [
[ 10, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0],
[ 20, 20, 21, 14, 4, 0, 0, 0, 0, 0, 0, 0],
[ 90, 65, 82, 64, 10, 3, 0, 0, 0, 0, 0, 0],
[ 0, 90, 101, 12, 49, 14, 7, 0, 0, 0, 0, 0],
[ 0, 0, 90, 29, 46, 48, 20, 7, 0, 0, 0, 0],
[ 0, 0, 0, 90, 101, 92, 83, 20, 4, 0, 0, 0],
[ 0, 0, 0, 0, 90, 65, 80, 84, 15, 5, 0, 0],
[ 0, 0, 0, 0, 0, 90, 92, 82, 53, 11, 2, 0],
[ 0, 0, 0, 0, 0, 0, 90, 101, 79, 47, 5, 9],
[ 0, 0, 0, 0, 0, 0, 0, 90, 47, 19, 28, 20],
[ 0, 0, 0, 0, 0, 0, 0, 0, 90, 20, 35, 86],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 92, 30]
]

b = [28, 79, 314, 273, 240, 390, 339, 330, 331, 204, 231, 212]

m = BandMatrix(12, 12, 2, 3)
m.convert(normal_matrix)

l, u = lu_factor(m)

print("l (banda):")
l.print() # printa a matriz de banda
print('\n\nu (banda):')
u.print() # printa a matriz de banda


print("\n\nl (completo):")
l.print_complete_matrix() # printa a matriz completa
print('\n\nu (completo):')
u.print_complete_matrix() # printa a matriz completa

print_matrix(mult(l, u))

# i) ly = b
y = solvingl(l, b)
# ii) ux = y
x = solvingu(u,y)

print("\n\nResolvendo ly = b..")
print("y: ")
print(list(y))
print("\n\nResolvendo ux = y..")
print("x: ")
print(list(x))
62 changes: 41 additions & 21 deletions band_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@

class BandMatrix:

def __init__(self, dimension_x, dimension_y, lower_bandwidth, superior_bandwidth):
def __init__(self, dimension_x, dimension_y, lower_bandwidth, superior_bandwidth, matrix=None):
self.dimension_x = dimension_x
self.dimension_y = dimension_y
self.lower_bandwidth = lower_bandwidth
self.superior_bandwidth = superior_bandwidth
self.width = lower_bandwidth + superior_bandwidth + 1
self._matrix = [[0]*self.width for i in range(self.dimension_y)]
if not matrix:
self._matrix = [[0]*self.width for i in range(self.dimension_y)]
else:
self._matrix = matrix

def print(self):
for line in self._matrix:
print("|{}|".format("\t".join(list(map(lambda item: "{:6.2f}".format(item), line)))))

def print_complete_matrix(self):
for i in range(0, self.dimension_x):
line = self.get_line(i)
print("|{}|".format("\t".join(list(map(lambda item: "{:6.2f}".format(item), line)))))

def convert(self, normal_matrix):
for i in range(len(normal_matrix)):
Expand All @@ -39,26 +47,38 @@ def get(self, i, j):
return self._matrix[i][self.lower_bandwidth + j - i]

def set(self, i, j, new_val):
print(i, j)
if not self._valid_position(i, j):
raise ValueError('Position ({}, {}) is not a valid position'.format(i, j))
if(self.lower_bandwidth + j - i) < 0 or (self.lower_bandwidth + j - i) >= len(self._matrix[0]) or i >= len(self._matrix):
if new_val != 0:
raise ValueError()
else:
self._matrix[i][self.lower_bandwidth + j - i] = new_val
return
self._matrix[i][self.lower_bandwidth + j - i] = new_val

def get_line(self, n, aux=None):
if aux is None:
aux = self.dimension_y-1
self.get_line(n, aux)

if aux == -1:
return []

return self.get_line(n, aux-1) + [self.get(n, aux)]

def get_col(self, n, aux=None):
if aux is None:
aux = self.dimension_y-1
self.get_col(n, aux)

if aux == -1:
return []

return self.get_col(n, aux-1) + [self.get(aux, n)]

def swap_lines(self, l1, l2):
if(l1 != l2 and l1 < len(self._matrix) and l1 >=0 and l2 < len(self._matrix) and l2 >=0):
aux = self._matrix[l1]
self._matrix[l1] = self._matrix[l2]
self._matrix[l2] = aux
temp = []
for i in range(0, self.dimension_y):
temp.append(self.get(l1, i))

for i in range(0, self.dimension_y):
self.set(l1, i, self.get(l2, i))

for i in range(0, self.dimension_y):
self.set(l2, i, temp[i])

def to_normal(self):
m = []
for i in range(self.dimension_x):
m.append([0]*self.dimension_x)
for i in range(self.dimension_x):
for j in range(self.dimension_y):
m[i][j] = self.get(i, j)
return m
25 changes: 19 additions & 6 deletions lu_factorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,29 @@ def lu_factor(matrix):
u = clone_matrix(matrix)
l = build_zero_matrix(len(matrix))
for k in range(len(matrix) - 1):
# pivoteamento #
print('L:')
print_matrix(l)
print('U:')
print_matrix(u)
index, maior = find_pivo(u, k)
print("Swap line {} with line {}".format(k, index))
u = swap_lines(matrix, k, index)
l = swap_lines(l, k, index)
print('L:')
print_matrix(l)
print('U:')
print_matrix(u)
##
print(f"Pivo - {u[k][k]}")
for j in range(k + 1, len(matrix)):
l[j][k] = u[j][k]/u[k][k]
for i in range(k, len(matrix)):
u[j][i] = u[j][i] - l[j][k]*u[k][i]
print('L:')
print_matrix(l)
print('U:')
print_matrix(u)
set_diagonal(l)
return l, u

Expand All @@ -68,12 +87,6 @@ def lu_factor(matrix):
[-1, -1, -1, -1, 1]
]

m = [
[1, 1, 1],
[2, 2, 5],
[4, 6, 8]
]

m = [
[ 10, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0],
[ 20, 20, 21, 14, 4, 0, 0, 0, 0, 0, 0, 0],
Expand Down
4 changes: 3 additions & 1 deletion test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@
m = BandMatrix(12, 12, 2, 3)
m.convert(normal_matrix)
m.print()
print(m.get(1, 5))#49
print(m.get(3, 4))#49
print(m.get(1, 1))#20
print(m.get(3, 4))#29