In [80]:
class Array:
"Una clase minima para algebra lineal"
def __init__(self, list_of_rows):
"Constructor y validador"
# obtener dimensiones
self.data = list_of_rows
nrow = len(list_of_rows)
# ___caso vector: redimensionar correctamente
if not isinstance(list_of_rows[0], list):
nrow = 1
self.data = [[x] for x in list_of_rows]
# ahora las columnas deben estar bien aunque sea un vector
ncol = len(self.data[0])
self.shape = (nrow, ncol)
# validar tamano correcto de filas
if any([len(r) != ncol for r in self.data]):
raise Exception("Las filas deben ser del mismo tamano")
for a in range(nrow):
for b in range(len(list_of_rows[a])):
if not type(list_of_rows[a][b]) == int and not type(list_of_rows[a][b]) == float:
raise Exception("Hay datos no numericos")
def __repr__(self): #Ejercicio1
"Funcion que se manda llamar cuando solo pones el dato en terminal >> dato"
return self.printdata(self.data)
def printdata(self, data): #Ejercicio1
"Funcion que da formato a la impresion de matrices y vectores"
rows = len(data)
cadena = "["
for a in range(rows):
if a>0:
cadena+=str("\n ")
cadena+=str(data[a])
cadena+="]"
return cadena
def __str__(self): #Ejercicio1
"Funcion que se manda llamar cuando solo pones llamas a imprimir el dato en terminal >>print(dato)"
return self.printdata(self.data)
def __getitem__(self, idx): #Ejercicio2
"Metodo para poder obtener datos del objeto mediante un indice"
return self.data[idx[0]][idx[1]]
def __setitem__(self, idx, new_value): #Ejercicio2
"Metodo por el cual podemos asignar valores al objeto mediante indices"
self.data[idx[0]][idx[1]] = new_value
def transpose(self): #Ejercicio4
"Metodo para obtener la matriz transpuesta del objeto Array"
rows = self.shape[0]
cols = self.shape[1]
transpuesta = [[self.data[x][y] for x in range(rows)] for y in range(cols)]
return Array(transpuesta)
#return self.printdata(transpuesta)
def __add__(self, other): #Ejercicio5
"Hora de sumar"
if isinstance(other, Array):
if self.shape != other.shape:
raise Exception("Las dimensiones son distintas!")
rows, cols = self.shape
newArray = Array([[0. for c in range(cols)] for r in range(rows)])
for r in range(rows):
for c in range(cols):
newArray.data[r][c] = self.data[r][c] + other.data[r][c]
return newArray
elif isinstance(other, (int, float, complex)): # en caso de que el lado derecho sea solo un numero
rows, cols = self.shape
newArray = Array([[0. for c in range(cols)] for r in range(rows)])
for r in range(rows):
for c in range(cols):
newArray.data[r][c] = self.data[r][c] + other
return newArray
else:
raise Exception("Data must be either Array class or scalar") # es un tipo de error particular usado en estos metodos
__radd__ = __add__ #Ejercicio5
def __sub__(self, other): #Ejercicio5
"Hora de restar"
"Hora de sumar"
if isinstance(other, Array):
if self.shape != other.shape:
raise Exception("Las dimensiones son distintas!")
rows, cols = self.shape
newArray = Array([[0. for c in range(cols)] for r in range(rows)])
for r in range(rows):
for c in range(cols):
newArray.data[r][c] = self.data[r][c] - other.data[r][c]
return newArray
elif isinstance(other, (int, float, complex)): # en caso de que el lado derecho sea solo un numero
rows, cols = self.shape
newArray = Array([[0. for c in range(cols)] for r in range(rows)])
for r in range(rows):
for c in range(cols):
newArray.data[r][c] = self.data[r][c] - other
return newArray
else:
raise Exception("Data must be either Array class or scalar") # es un tipo de error particular usado en estos metodos
__rsub__ = __sub__ #Ejercicio5
def __mul__(self,other): #Ejercicio6
"Metodo para multiplicar una matriz ya sea con un escalar, u otra matriz(vectores tambien ya que son matrices de 1xn o nx1"
#if len(other[0])
if isinstance(other, Array):
compatible = False #
if self.shape[1] == other.shape[0]:
compatible = True
else:
print("Incompatible matrices")
if compatible:
rows, cols = self.shape
matmult = []
for a in range(rows):
vec = []
for b in range(other.shape[1]):
vec.append(self.multAdd(self.data[a],[other.data[i][b] for i in range(other.shape[0])]))
matmult.append(vec)
return self.printdata(matmult)
elif isinstance(other, (int, float)):
rows, cols = self.shape
newArray = Array([[0. for c in range(cols)] for r in range(rows)])
newArray.data = [[self.data[y][x]*other for x in range(cols)] for y in range(rows)]
return newArray
def multAdd(self,parama, paramb): #Ejercicio6 (auxiliar)
"Metodo para calcular producto punto"
sum = 0
for x in range(len(parama)):
sum+=(parama[x]*paramb[x])
return sum
__rmul__ = __mul__ #Ejercicio6
In [81]:
dato = Array([[1,2,3],[4,5,6],[8,9,10]])
In [82]:
print(dato)
In [83]:
dato
Out[83]:
In [84]:
dato = Array([[1,2,3],[4,5,6],[8,9,10]])
print("Original: ")
print(dato)
print("Acceder a elemento por indices dato[1,2]")
print(dato[1,2])
dato[0,0] = 10
print("Asignamos elemento por indices dato[0,0] = 10")
print(dato)
In [85]:
def zeros(filas, columnas):
"Clase que crea un objeto de clase Array inicializado con valores en ceros sintaxis matriz_ceros(2,3)"
return Array([[0 for x in range(columnas)] for y in range(filas)])
In [101]:
zeros(5,5)
Out[101]:
In [87]:
def evaluate(a,b):
"Evalua si son iguales y regresa 1, si no 0"
if a == b:
return 1
else:
return 0
def eye(n):
"Crea matriz diagonal de dim = n x n"
return Array([[evaluate(x,y) for x in range(n)] for y in range(n)])
In [88]:
eye(5)
Out[88]:
In [89]:
dato = Array([[1,2,3,6],[4,5,6,11],[8,9,10,49],[9,12,67,1]])
print("Original: ")
print(dato)
print("Transpuesta")
print(dato.transpose())
dato1 = Array([[1,2,3,6],[4,5,6,11],[8,9,10,49],[9,12,67,1]]).transpose()
print("Transpuesta: ")
print(dato1)
In [90]:
dato = Array([[1,2,3],[4,5,6],[8,9,10]])
dato1 = Array([[1,2,71],[14,15,16],[28,29,20]])
print("elemento1" )
print(dato)
print("elemento2" )
print(dato1)
print("suma de ambos")
print(dato+dato1)
print("suma de Array y escalar")
print(dato+1)
print("suma de escalar y Array")
print(1+dato)
In [91]:
print("Resta de ambos")
print(dato-dato1)
print("Resta de Array y escalar")
print(dato-1)
print("Resta de escalar y Array")
print(1-dato)
In [92]:
dato = Array([[1,2,3],[4,5,6],[1,2,3],[4,5,6]])
dato1 = Array([[1,2,8,78],[14,15,12,21],[28,29,78,90]])
print("primer elemento")
print(dato)
print("Segundo elemento")
print(dato1)
print ("multiplicacion")
print(dato*dato1)
print("multiplicacion de primer elemento por escalar 5")
print(dato * 5)
print("multiplicacion de escalar 5 por primer elemento")
print(5*dato)
In [93]:
def forward_subs(matrix,vector):
"Resuelve matrices de la forma Lx = b"
""" Codigo de validacion, tamanios, matriz L"""
flag = False
y = None
if type(matrix) == Array and type(vector) == Array:
if matrix.shape[0] == vector.shape[0]:
if matrix.shape[0] == matrix.shape[1]:
for y in range(matrix.shape[0]):
for x in range(matrix.shape[1]):
if x>y:
if not matrix[y,x] == 0:
raise Exception("No es matriz L")
else:
flag = True
else:
print("No es matriz cuadrada")
else:
print("No concuerdan las dimensiones de la matriz y del vector")
if flag:
print("Es matriz L")
y = []
for a in range(vector.shape[0]):
y.append(vector[a,0])
for b in range(a):
y[a]-=matrix[a,b]*y[b]
y[a] /= matrix[a,a]
return y
In [94]:
dato = Array([[1,0,0,0],[4,2,0,0],[1,2,1,0],[3,4,5,2]])
print("Matriz: ")
print(dato)
print("vector")
vector = Array([[1],[2],[3],[6]])
print(vector)
print("solucion de resolucion de Lx = b")
print(forward_subs(dato,vector))
In [95]:
def backward_subs(matrix, vector):
"Resuelve matrices de la forma Lx = b"
""" Codigo de validacion, tamanios, matriz L"""
flag = False
y = None
if type(matrix) == Array and type(vector) == Array:
if matrix.shape[0] == vector.shape[0]:
if matrix.shape[0] == matrix.shape[1]:
for y in range(matrix.shape[0]):
for x in range(matrix.shape[1]):
if x<y:
if not matrix[y,x] == 0:
raise Exception("No es matriz U")
else:
flag = True
else:
print("No es matriz cuadrada")
else:
print("No concuerdan las dimensiones de la matriz y del vector")
if flag:
print("Es matriz U")
y = [0] * vector.shape[0]
for a in range(vector.shape[0]-1,-1,-1):
y[a] = vector[a,0]
for b in range(a+1,vector.shape[0]):
y[a]-=matrix[a,b]*y[b]
y[a] /= matrix[a,a]
return y
In [96]:
dato = Array([[1,1],[0,2]])
print("Matriz: ")
print(dato)
print("vector")
vector = Array([[12],[20]])
print(vector)
print("solucion de resolucion de Ux = b")
print(backward_subs(dato,vector))
In [97]:
def LU(A):
"Funcion para realizar descomposicion de matriz en PA = LU"
if type(A == Array):
L = [[0 for x in range(A.shape[1])] for y in range(A.shape[0])]
for a in range(A.shape[0]):
L[a][a] = 1
L = Array(L)
"""Matriz de permutacion"""
list_tuples = [(0,0) for x in range(A.shape[0])]
for a in range(A.shape[0]):
list_tuples[a] = (a,A.data[a])
data = []
data.append((0,A.data[0]))
del list_tuples[0]
if len(list_tuples) == 1:
starting = 0
else:
starting = 1
for row in range(starting,len(list_tuples)):
temp = sorted(list_tuples, key=lambda value: value[1][row], reverse=True)
data += temp
U = []
for row in data:
U.append(row[1])
U = Array(U)
permutation_matrix = [[0 for x in range(A.shape[0])] for y in range(A.shape[0])]
permutation_matrix = Array(permutation_matrix)
for row in range(len(data)):
permutation_matrix[row, data[row][0]] = 1
n = A.shape[0]
for a in range(n):
for b in range(a+1,n):
multiplicador = float((U[b,a]/U[a,a]))
L[b,a] = multiplicador
multiplicador= multiplicador*(-1)
for c in range(n):
U[b,c] += U[a,c]*multiplicador
return [L,U,permutation_matrix]
In [98]:
A = Array([[1,1,-1],[1,-2,3],[2,3,1]])
#A = Array([[1,7,-1],[1,6,8],[2,3,7]])
print("Matriz original")
print(A)
L,U,P = LU(A)
print("Matrices de Lower, Upper y Permutacion son: ")
print("L")
print(L)
print("U")
print(U)
print("P")
print(P)
In [99]:
def lu_linsolve(A,y):
"Funcion para resolver sistemas de ecuaciones basado en la descomposicion LU"
solucion = None
if type(A) == Array and type(y) == Array:
if A.shape[0] == y.shape[0]:
L,U,P = LU(A)
new_vector = []
for x in range(P.shape[0]):
for z in range(P.shape[1]):
if(P[x,z] == 1):
new_vector.append([y[z,0]])
new_vector = Array(new_vector)
x = Array([forward_subs(L,new_vector)])
solucion = backward_subs(U, x.transpose())
else:
print("No son compatibles Array y vector")
print("Forma de matriz ")
print(A.shape)
print("Forma de vector")
print(y.shape)
else:
print("No son estructuras de datos Array")
return solucion
In [100]:
matriz = Array([[1,1,3],[2,4,4],[2,2,2]])
print("La matriz es: ")
print(matriz)
vector = Array([[30],[68],[36]])
print("El vector es: ")
print(vector)
solucion = lu_linsolve(matriz,vector)
print("La solucion al sistema de ecuaciones es")
print(solucion)
In [ ]:
In [ ]: