File: class/Extras/Code/Misc/matrix-code.py
"""
a numerically-inclined student asked for examples related to
matrix processing (in the core language, not using NumPy which
has better built-in support for vector and matrix processing);
the following is a quick tour through some simple matrix code,
showing equivalents coded in for loops and list comprehensions;
requires Python 2.7 for some tests, one line works in 3.X only;
"""
######################################################################################
# Vectors: 1D lists (added mar-12-11)
######################################################################################
L = [1, 2, 3, 4, 5, 6]
M = [7, 8, 9, 10, 11, 12]
#-------------------------------------------------------------
# [L ** 2]: print squares of all in one vector: 1 4 9 16 25 36
#-------------------------------------------------------------
for i in range(len(L)):
print(L[i] ** 2)
for x in L: # simpler, probably faster
print(x ** 2)
# ---3.X only---
list( map(print, (x ** 2 for x in L)) ) # 3.X print(), map() generator
#------------------------------------------------------------
# [N = L ** 2]: make new result vector: [1, 4, 9, 16, 25, 36]
#------------------------------------------------------------
N = [x ** 2 for x in L]
print(N)
N = []
for x in L:
N.append(x ** 2)
print(N)
N = list(map((lambda x: x ** 2), L)) # list() required in 3.X only
print(N)
# other: generators produce results on demand
G = (x ** 2 for x in L)
print(list(G)) # list() requests results
def gensquares(L):
for x in L:
yield x ** 2
print(list(gensquares(L))) # list() requests results
# other: set and dict comprehensions (3.X, 2.7)
print({x ** 2 for x in L}) # set: {1, 36, 9, 16, 25, 4} in 3.X, set(...) in 2.X
print({x: x ** 2 for x in L}) # dict: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36}
#--------------------------------------------------------------
# [L + M]: print pairwise sums of two vectors: 8 10 12 14 16 18
#--------------------------------------------------------------
for i in range(len(L)):
print(L[i] + M[i])
for (x, y) in zip(L, M):
print(x + y)
#----------------------------------------------------------------------
# [N = L + M]: create new pairwise sums vector: [8, 10, 12, 14, 16, 18]
#----------------------------------------------------------------------
N = [L[i] + M[i] for i in range(len(L))]
print(N)
N = [x + y for (x, y) in zip(L, M)]
print(N)
N = []
for i in range(len(L)): N.append(L[i] + M[i])
print(N)
N = []
for (x, y) in zip(L, M): N.append(x + y)
print(N)
# other ops
print([x * y for (x, y) in zip(L, M)]) # [7, 16, 27, 40, 55, 72]
print([y / x for (x, y) in zip(L, M)]) # [7.0, 4.0, 3.0, 2.5, 2.2, 2.0] (3.X)
print([y // x for (x, y) in zip(L, M)]) # [7, 4, 3, 2, 2, 2]
print(list( map((lambda x, y: x * y), L, M) )) # [7, 16, 27, 40, 55, 72]
######################################################################################
# Matrixes: 2D lists (original code)
######################################################################################
def init():
global M, N # reset state for new tests
M = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
N = [[10, 20, 30],
[40, 50, 60],
[70, 80, 90]]
#---------------------------------------------------------------
# [M ** 2]: print squares of one matrix: 1 4 9 16 25 36 49 64 81
#---------------------------------------------------------------
init()
for row in M:
for col in row:
print(col ** 2)
for i in range(3):
for j in range(3):
print(M[i][j] ** 2)
#-----------------------------------------------------------------------------
# [M **= 2]: matrix squares, in-place: [[1, 4, 9], [16, 25, 36], [49, 64, 81]]
#-----------------------------------------------------------------------------
init()
for i in range(3):
for j in range(3):
M[i][j] **= 2
print(M)
init()
for i in range(len(M)):
for j in range(len(M[i])):
M[i][j] **= 2
print(M)
#
# similar, but make new 1D vector: [1, 4, 9, 16, 25, 36, 49, 64, 81]
#
init()
print( [col ** 2 for row in M for col in row] )
print( [M[i][j] ** 2 for i in range(len(M)) for j in range(len(M[i]))] )
#--------------------------------------------------------------------------------
# [X = M ** 2]: new 2D matrix of squares: [[1, 4, 9], [16, 25, 36], [49, 64, 81]]
#--------------------------------------------------------------------------------
X = []
for i in range(len(M)):
row = []
for j in range(len(M[i])):
row.append(M[i][j] ** 2)
X.append(row)
print(X)
X = []
for row in M:
tmp = []
for col in row:
tmp.append(col ** 2)
X.append(tmp)
print(X)
# nest comprehensions for 2D data
print( [[M[i][j] ** 2 for j in range(len(M[i]))] for i in range(len(M))] )
print( [[col ** 2 for col in row] for row in M] )
#-------------------------------------------------------------------------------------
# [X = M + N]: new matrix of pairwise sums: [[11, 22, 33], [44, 55, 66], [77, 88, 99]]
#-------------------------------------------------------------------------------------
X = []
for i in range(len(M)):
row = []
for j in range(len(M[i])):
row.append(M[i][j] + N[i][j])
X.append(row)
print(X)
X = []
for (row1, row2) in zip(M, N):
tmp = []
for (col1, col2) in zip(row1, row2):
tmp.append(col1 + col2)
X.append(tmp)
print(X)
print( [[M[i][j] + N[i][j] for j in range(3)] for i in range(3)] )
print( [[col1 + col2 for (col1, col2) in zip(row1, row2)] for (row1, row2) in zip(M, N)] )