In [1]:
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")
            
    def __repr__(self):
        "Ejercicio"
        return repr(self.data)
            
    def __str__(self):
        "Ejercicio"
        return str(self.data)
            
    def __getitem__(self, idx):
        "Ejercicio"
        return self.data[idx[0]][idx[1]]
            
    def __setitem__(self, idx, new_value):
        "Ejercicio"
        self.data[idx[0]][idx[1]] = new_value
        
        
    def transpuesta(self):
        "Matriz transpuesta"
        rows, cols = self.shape
        newArray = Array([[0. for c in range(rows)] for r in range(cols)])
        for c in range(rows):
            for r in range(cols):
                newArray.data[r][c] = self.data[c][r]
        return newArray

    
    def identidad(rows,cols): 
        "Matriz Identidad"
        newArray = Array([[0. for c in range(cols)] for r in range(rows)])
        for r in range(rows):
            for c in range(cols):
                if(r==c):
                    newArray.data[r][c] = 1.
                else:
                    newArray.data[r][c] = 0.
        return newArray
            
    def zeros(rows,cols):
        "Zeros"
        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] = 0.
                return newArray

    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 self__radd__.other
    
    __radd__ = __add__   
    
    
    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 self__radd__.other
    
    __rsub__ = __sub__   
    

    def __mul__(self, other):
        "Hora de multiplicar"
        if isinstance(other, Array):
            if self.shape[1] != other.shape[0]:
                raise Exception("Las matrices no se pueden multiplicar!")
            
            rows, cols = self.shape[0],other.shape[1]
            newArray = Array([[0. for c in range(cols)] for r in range(rows)])
            
            for r in range(rows):
                for c in range(cols):
                    for k in range(len(other.data)):
                        newArray.data[r][c] += self.data[r][k] * other.data[k][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 self__rmul__.other
    
    __rmul__ = __mul__
    

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 [2]:
A = Array([[5,2],[4,5]])
A.data


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

In [4]:
B = Array([[67,2],[4,5]])
B.data


Out[4]:
[[67, 2], [4, 5]]

repr


In [5]:
A


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

str


In [6]:
print(A)


[[5, 2], [4, 5]]

getitem


In [7]:
A[0,0]


Out[7]:
5

setitem


In [8]:
A[0,0] = 4
A.data


Out[8]:
[[4, 2], [4, 5]]

shape


In [9]:
A.shape


Out[9]:
(2, 2)

Matriz de ceros


In [10]:
D = Array.zeros(4,2)
D.data


Out[10]:
[[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]

In [11]:
J = Array.zeros(3,2)
J.data


Out[11]:
[[0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]

Matriz identidad


In [12]:
E = Array.identidad(4,4)
E.data


Out[12]:
[[1.0, 0.0, 0.0, 0.0],
 [0.0, 1.0, 0.0, 0.0],
 [0.0, 0.0, 1.0, 0.0],
 [0.0, 0.0, 0.0, 1.0]]

Matriz transpuesta


In [15]:
A.data


Out[15]:
[[4, 2], [4, 5]]

In [16]:
F = A.transpuesta()
F.data


Out[16]:
[[4, 4], [2, 5]]

In [17]:
J = Array ([[17,18,19], [20,21,22]])
J.data


Out[17]:
[[17, 18, 19], [20, 21, 22]]

In [19]:
Z= J.transpuesta()
Z.data


Out[19]:
[[17, 20], [18, 21], [19, 22]]

Suma y resta de matrices


In [20]:
C = A + B
C.data


Out[20]:
[[71, 4], [8, 10]]

In [21]:
H = 1 + A
H.data


Out[21]:
[[5, 3], [5, 6]]

In [22]:
G = 1 + Array([[1,2], [3,4]])
G.data


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

In [23]:
I = A - 1
I.data


Out[23]:
[[3, 1], [3, 4]]

In [24]:
K = 20 - A
K.data


Out[24]:
[[-16, -18], [-16, -15]]

Multiplicación de matrices


In [25]:
L = A * Array([[1],[2]])
L.data


Out[25]:
[[8.0], [14.0]]

In [26]:
M = Array([[1,2,3],[4,5,6],[7,8,9]]) * Array([[10,11,12],[13,14,15],[16,17,18]])
M.data


Out[26]:
[[84.0, 90.0, 96.0], [201.0, 216.0, 231.0], [318.0, 342.0, 366.0]]

In [27]:
N = Array([[1,2,3],[4,5,6],[7,8,9]]) * Array([[10,11],[13,14],[16,17]])
N.data


Out[27]:
[[84.0, 90.0], [201.0, 216.0], [318.0, 342.0]]

In [28]:
O = 2 * Array([[1,2,3],[4,5,6],[7,8,9]])
O.data


Out[28]:
[[3, 4, 5], [6, 7, 8], [9, 10, 11]]

Multiplicación de matriz Array y Vector (clase)


In [29]:
P = Array([[1,2,3],[4,5,6],[7,8,9]]) *  Vector([2,3,4])
P.data


Out[29]:
[[20.0], [47.0], [74.0]]

In [41]:
X =  Vector([17, 59, 26]) *  Array ([[2,3,5]])
X.data


Out[41]:
[[34.0, 51.0, 85.0], [118.0, 177.0, 295.0], [52.0, 78.0, 130.0]]

In [ ]: