TAREA 1

Federico Riveroll Gonzalez 105898

Clase Array


In [1]:
import numpy as np
class Array:
    "Una clase minima de 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")
    
    def __repr__(self):
        respuesta = "["
        for i in range(0,len(self.data)):
            respuesta = respuesta + "["
            for j in range (0,len(self.data[0])):
                respuesta = respuesta + str(self.data[i][j])
                if j < len(self.data[0]) - 1:
                    respuesta = respuesta + ","
            respuesta = respuesta + "]"
            if i < len(self.data) - 1:
                respuesta = respuesta + ","
        return respuesta + "]"
    
    def __str__(self):
        respuesta = "Array["
        for i in range(0,len(self.data)):
            respuesta = respuesta + "["
            for j in range (0,len(self.data[0])):
                respuesta = respuesta + str(self.data[i][j])
                if j < len(self.data[0]) - 1:
                    respuesta = respuesta + ","
            respuesta = respuesta + "]"
            if i < len(self.data) - 1:
                respuesta = respuesta + ","
        return respuesta + "]"
    
    def __getitem__(self, idx):
        return self.data[idx[0]][idx[1]]
    
    def __setitem__(self, idx, new_value):
        self.data[idx[0]][idx[1]] = new_value
    
    def zeros(self, shape):
        respuesta = [[0. for i in range(0, shape[0,0])] for j in range (0, shape[1,0])]
        return respuesta
    
    def eye(self, n):
        respuesta = list()
        for i in range (0, n):
            subrespuesta = list()
            for j in range(0, n):
                if j == i:
                    subrespuesta.append(1,)
                else:
                    subrespuesta.append(0,)
            respuesta.append(subrespuesta)
        return respuesta
    
    def transpose(self):
        respuesta = list()
        for i in range(0, len(self.data[0])):
            subrespuesta = list()
            for j in range (0, len(self.data)):
                subrespuesta.append(self.data[j][i])
            respuesta.append(subrespuesta)
        return Array(respuesta)
    
    def __add__(self, other):
        "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(2, (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:
            return NotImplemented # es un tipo de error particular usado en estos metodos
        
    def __sub__(self, other):
        "Hora de restar"
        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(2, (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:
            return NotImplemented # es un tipo de error particular usado en estos metodos
        
    def __radd__(self, other):
        return self + other
        
    def __mul__(self, other):
        if isinstance(other, Array):
            if self.shape[0] != other.shape[1] | self.shape[1] != other.shape[0] :
                raise Exception("Las dimensiones son incorrectas!")
            
            rows, cols = self.shape
            respuestaArr = Array([[0. for c in range(rows)] for r in range(rows)])
            for iN in range(rows):
                for jN in range (rows):
                    sumatoria = 0
                    for m in range (cols):
                        sumatoria = sumatoria + self.data[iN][m] * other.data[m][jN]
                    respuestaArr.data[iN][jN] = sumatoria
            return respuestaArr
        elif isinstance(2, (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:
            return NotImplemented # es un tipo de error particular usado en estos metodos
        
         
        
    def __rmul__(self,other):
        "hacer rmul"

Prueba ejercicio 1


In [2]:
A = Array([[1,2,3], [4,5,6]])
A


Out[2]:
[[1,2,3],[4,5,6]]

Prueba ejercicio 2


In [3]:
A[0,1] = 8
print(A)


Array[[1,8,3],[4,5,6]]

Prueba ejercicio 3


In [4]:
A.zeros(Array([4,5]))


Out[4]:
[[0.0, 0.0, 0.0, 0.0],
 [0.0, 0.0, 0.0, 0.0],
 [0.0, 0.0, 0.0, 0.0],
 [0.0, 0.0, 0.0, 0.0],
 [0.0, 0.0, 0.0, 0.0]]

In [5]:
A.eye(5)


Out[5]:
[[1, 0, 0, 0, 0],
 [0, 1, 0, 0, 0],
 [0, 0, 1, 0, 0],
 [0, 0, 0, 1, 0],
 [0, 0, 0, 0, 1]]

Prueba ejercicio 4


In [6]:
A.transpose()


Out[6]:
[[1,4],[8,5],[3,6]]

In [7]:
print(A)


Array[[1,8,3],[4,5,6]]

Prueba ejercicio 5


In [8]:
B = Array([[2,3,4], [1,1,1]])
A + B


Out[8]:
[[3,11,7],[5,6,7]]

In [9]:
B + 10


Out[9]:
[[12,13,14],[11,11,11]]

In [10]:
B - 1


Out[10]:
[[1,2,3],[0,0,0]]

In [11]:
1 + B


Out[11]:
[[3,4,5],[2,2,2]]

Prueba ejercicio 6


In [12]:
A


Out[12]:
[[1,8,3],[4,5,6]]

In [13]:
C = Array([[2,3], [1,1], [4,6]])

In [14]:
#[[14,31,24],[5,13,9],[28,62,48]]
C * A


Out[14]:
[[14,31,24],[5,13,9],[28,62,48]]

In [15]:
C * 3


Out[15]:
[[6,9],[3,3],[12,18]]

In [16]:
C.transpose()*C


Out[16]:
[[21,31],[31,46]]

Clase Vector


In [17]:
class Vector(Array): # declara que Vector es un tipo de Array
    def __init__(self, list_of_numbers):
        self.vdata = list_of_numbers
        list_of_rows = [[x] for x in list_of_numbers]
        return Array.__init__(self, list_of_rows)
    def __repr__(self):
        return "Vector(" + str(self.vdata) + ")"
    def __str__(self):
        return str(self.vdata)
    def __add__(self, other):
        new_arr = Array.__add__(self, other)
        return Vector([x[0] for x in new_arr.data])

In [18]:
Vector([1,2,3]).__dict__


Out[18]:
{'data': [[1], [2], [3]], 'shape': (3, 1), 'vdata': [1, 2, 3]}

Ejercicio 7: A = L*U

Funcion DameVectorUyValorL


In [19]:
def dameVectorUyValorL(arr_semilla, arr_objetivo, columna):
    valor_L = arr_objetivo.data[0][columna] / arr_semilla.data[0][columna]
    fila_U = arr_objetivo - (arr_semilla * valor_L)
    return valor_L, fila_U

In [20]:
#A = Array([[25, 5, 1],[64, 8, 1],[144, 12, 1]])
A = Array([[1, 1, -1],[0, 1, 3],[-1, 0, -2]])
L = Array(A.eye(A.shape[0]))
U = A
fila_L, columna_obj = 0, 0

In [21]:
for ij in range(0, A.shape[1] - 1):
    for i in range(1, A.shape[1] - ij):
        valor_L, fila_U = dameVectorUyValorL(Array([A[fila_L,:]]),Array([A[fila_L + i,:]]), columna_obj)
        L[fila_L + i, columna_obj] = valor_L
        for j in range(fila_U.shape[1]):
            U[fila_L + i, j] = fila_U[0,j]
    fila_L = fila_L + 1
    columna_obj = columna_obj + 1

In [22]:
print(L)


Array[[1,0,0],[0.0,1,0],[-1.0,1.0,1]]

In [23]:
U.data[0][1]


Out[23]:
1

In [24]:
U


Out[24]:
[[1,1,-1],[0.0,1.0,3.0],[0.0,0.0,-6.0]]

In [25]:
L*U


Out[25]:
[[1.0,1.0,-1.0],[0.0,1.0,3.0],[-1.0,0.0,-2.0]]

Ejercicio 8: Resolver sistemas con Lower

Funcion modifica fila


In [26]:
def convierteAuno(A, pos_fila, pos_col):
    fila = Array([A[pos_fila,:]])
    if fila[0, pos_col] != 0:
        fila = Array([[fila[0, j] / fila[0, pos_col] for j in range(fila.shape[1])]])
    for j in range(fila.shape[1]):
        A[pos_fila, j] = fila[0,j]
    
def convierteAcero(A, pos_fila_semilla, pos_fila_objetivo, pos_col):
    fila_semilla = Array([A[pos_fila_semilla,:]])
    if fila_semilla[0, pos_col] != 0:
        fila_objetivo = Array([A[pos_fila_objetivo,:]])
        multiplicador = fila_objetivo[0, pos_col] / fila_semilla[0, pos_col]
        fila_objetivo = fila_objetivo - Array([[fila_semilla[0, j] * multiplicador for j in range(fila_semilla.shape[1])]])
        for j in range(fila_objetivo.shape[1]):
            A[pos_fila_objetivo, j] = fila_objetivo[0,j]
    
def cerosHaciaAbajo(A, pos_fila_semilla, pos_col):
    for i in range(pos_fila_semilla + 1, A.shape[0]):
        convierteAcero(A, pos_fila_semilla, i, pos_col)
    
def cerosHaciaArriba(A, pos_fila_semilla, pos_col):
    for i in range(0, pos_fila_semilla):
        convierteAcero(A, pos_fila_semilla, i, pos_col)
    
def resuelveSistemaLower(A):
    for i in range(A.shape[0]):
        convierteAuno(A, i, i)
        cerosHaciaAbajo(A, i, i)
    
def resuelveSistemaUpper(A):
    for i in range(A.shape[0]):
        convierteAuno(A, i, i)
        cerosHaciaArriba(A, i, i)

def resuelveSistemaDeEcuaciones(A):
    resuelveSistemaLower(A)
    resuelveSistemaUpper(A)
    return [A[i,A.shape[1] - 1] for i in range(A.shape[0])]

In [27]:
# Aj = X, Y, Z, R
A = Array([[1, 1, -1, 9],[0, 1, 3, 3],[-1, 0, -2, 2]])
resuelveSistemaDeEcuaciones(A)


Out[27]:
[0.666666666666667, 7.0, -1.3333333333333333]

In [28]:
B = Array([[2, 1, 2],[4, 6, 1]])
resuelveSistemaDeEcuaciones(B)


Out[28]:
[1.375, -0.75]

In [ ]:


In [ ]: