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):
self.repr = ""
for i in range((self.shape[0]-1)):
self.repr += str(self.data[i]) + ',' + '\n'
self.repr = self.repr + str(self.data[self.shape[0]-1])
return "([" + self.repr + "])"
def __str__(self):
self.stru = ""
self.str = ""
for j in range(self.shape[0]-1):
self.str = ""
for i in range(self.shape[1]):
self.str += str(self.data[j][i]) + ' '
self.stru += self.str + '\n'
self.str = ""
for i in range(self.shape[1]):
self.str += str(self.data[self.shape[0]-1][i]) + ' '
self.stru = self.stru + self.str
return "[ " + str(self.stru) +"]"
In [2]:
A = Array([[1,2,3,4],[4,5,6,7]])
In [3]:
A
Out[3]:
In [4]:
print(A)
In [5]:
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 __getitem__(self, idx):
return self.data[idx[0]][idx[1]]
def __setitem__(self,idx,new_value):
self.data[idx[0]][idx[1]] = new_value
In [6]:
A = Array([[1,2,3],[4,5,6]])
In [7]:
A[0,1]
Out[7]:
In [8]:
A[0,1] = 3
In [9]:
A[0,1]
Out[9]:
def zeros(shape):
"Implementame por favor"
[0. for x in range(5)]
crea una lista de 5 ceros.eye(n)
que crea la matriz identidad de $n\times n$ (es decir, la matriz que tiene puros ceros y unos en la diagonal). El nombre eye
es tradicional en software de algebra lineal, aunque no es muy intuitivo.
In [10]:
class Array:
def __init__(self, list_of_rows):
"Constructor y validador"
# obtener dimensiones
self.data = list_of_rows
self.shape = (len(list_of_rows), len(list_of_rows[0]))
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 zeros(self,r,c):
self.columnas = c
self.filas = r
self.zeros = [[0 for col in range(c)] for row in range(r)]
return self.zeros
def eye(self,n):
self.zeros = [[0 for col in range(n)] for row in range(n)]
for i in range(n):
self.zeros[i][i] = 1
return self.zeros
In [11]:
A = Array([[1,2,3],[4,5,6]])
In [12]:
A.zeros(2,3)
Out[12]:
In [13]:
A.eye(2)
Out[13]:
In [14]:
class Zeros:
def __init__(self,r,c):
self.columnas = c
self.filas = r
self.data = [[0 for col in range(c)] for row in range(r)]
def __repr__(self):
self.repr = ""
for i in range((self.filas-1)):
self.repr += str(self.data[i]) + ',' + '\n'
self.repr = self.repr + str(self.data[self.filas-1])
return "([" + self.repr + "])"
def __str__(self):
self.stru = ""
self.str = ""
for j in range(self.filas-1):
self.str = ""
for i in range(self.columnas):
self.str += str(self.data[j][i]) + ' '
self.stru += self.str + '\n'
self.str = ""
for i in range(self.columnas):
self.str += str(self.data[self.filas-1][i]) + ' '
self.stru = self.stru + self.str
return "[ " + str(self.stru) +"]"
In [15]:
x = Zeros(5,6)
In [16]:
x
Out[16]:
In [17]:
print(x)
In [18]:
class eye:
def __init__(self,n):
self.dim = n
self.data = [[0 for col in range(n)] for row in range(n)]
for i in range(n):
self.data[i][i] = 1
def __repr__(self):
self.repr = ""
for i in range((self.dim-1)):
self.repr += str(self.data[i]) + ',' + '\n'
self.repr = self.repr + str(self.data[self.dim-1])
return "([" + self.repr + "])"
def __str__(self):
self.stru = ""
self.str = ""
for j in range(self.dim-1):
self.str = ""
for i in range(self.dim):
self.str += str(self.data[j][i]) + ' '
self.stru += self.str + '\n'
self.str = ""
for i in range(self.dim):
self.str += str(self.data[self.dim-1][i]) + ' '
self.stru = self.stru + self.str
return "[ " + str(self.stru) +"]"
In [19]:
y = eye(2)
In [20]:
y
Out[20]:
In [21]:
print(y)
In [22]:
class Array:
"Una clase minima para algebra lineal"
def __init__(self, list_of_rows):
"Constructor y validador"
# obtener dimensiones
self.data = list_of_rows
self.shape = (len(list_of_rows), len(list_of_rows[0]))
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 transpose(self):
self.fila = self.shape[0]
self.columna = self.shape[1]
self.row = [[0 for col in range(self.fila)] for row in range(self.columna)]
for j in range(self.columna):
for i in range(self.fila):
self.row[j][i] = self.data[i][j]
return self.row
In [23]:
A = Array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
In [24]:
A.transpose()
Out[24]:
A + 1
tiene sentido para un Array A
, sin embargo la expresion inversa falla, por ejemplo 1 + Array([[1,2], [3,4]])
__radd__
para resolver este problema.__sub__
similar a la suma para poder calcular expresiones como A - B para A y B arrays o numeros.
In [25]:
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 __add__(self, other):
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
"Parte 1"
__radd__ = __add__
"Parte 2"
def __sub__(self, other):
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 __rsub__(self, other):
if 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] = other - self.data[r][c]
return newArray
else:
return NotImplemented # es un tipo de error particular usado en estos metodos
In [26]:
A = Array([[1,2,3],[4,5,6]])
In [27]:
B = Array([[4,5,6],[7,8,9]])
In [28]:
C = A + B
In [29]:
C.data
Out[29]:
In [30]:
D = A + 2
In [31]:
D.data
Out[31]:
In [32]:
E = 3 + B
In [33]:
E.data
Out[33]:
In [34]:
F = A - B
In [35]:
F.data
Out[35]:
In [36]:
G = B - 3
In [37]:
G.data
Out[37]:
In [38]:
H = 10 - A
In [39]:
H.data
Out[39]:
In [40]:
class Array:
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 __mul__(self, other):
if isinstance(other, Array):
if self.shape[1] != other.shape[0]:
raise Exception("Las dimensiones no coinciden!")
rowsarr = self.shape[0]
coincidir = self.shape[1]
colsoth = other.shape[1]
val = 0
newArray = Array([[0. for c in range(colsoth)] for r in range(rowsarr)])
for r in range(rowsarr):
for c in range(colsoth):
val = 0
for i in range(coincidir):
val += self.data[r][i] * other.data[i][c]
newArray.data[r][c] = val
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 __rmul__(self, other):
if isinstance(other, Array):
if self.shape[1] != other.shape[0]:
raise Exception("Las dimensiones no coinciden!")
rowsarr = self.shape[0]
coincidir = self.shape[1]
colsoth = other.shape[1]
val = 0
newArray = Array([[0. for c in range(colsoth)] for r in range(rowsarr)])
for r in range(rowsarr):
for c in range(colsoth):
val = 0
for i in range(coincidir):
val += other.data[i][c] * self.data[r][i]
newArray.data[r][c] = val
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
In [41]:
A = Array([[1,2],[4,5],[7,8]])
In [42]:
B = Array([[4,5,6],[7,8,9]])
In [43]:
C = B * A
In [44]:
C.data
Out[44]:
In [45]:
D = 2 * A
In [46]:
D.data
Out[46]:
In [47]:
E = B * (-1)
In [48]:
E.data
Out[48]:
In [ ]: