-
Notifications
You must be signed in to change notification settings - Fork 0
/
matrixOps.py
177 lines (150 loc) · 5.77 KB
/
matrixOps.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# MatrixOps Module
# Matrix Assignment - Computer Graphics
# Misha (Mikhail Kotlik)
from pprint import pprint
"""
Matrices look like:
matrixA[col (index of sublist), row (index within sublist)]
in terms of the edge matrix: matrixA[position][point]
We are not modifying in place; we are returning a new matrix
"""
# Returns string representation of matrix
# Table will be padded and columns separated by pipes
def toString(matrix):
"""
Returns string representation of matrix
Table will be padded and columns separated by pipes
"""
if len(matrix) == 0 or len(matrix[0]) == 0:
return str(matrix)
else:
obj_str = ""
rowList = ["|"] * len(matrix[0])
for col in matrix:
# Calculate maxLen for padding
maxLen = 0
for rowEl in col:
curLen = len(str(rowEl))
if curLen > maxLen:
maxLen = curLen
# Create padding formatting string
padStr = "{:>" + str(maxLen) + "}"
# Add each rowEl to respective rowStr, w/ padding
for rowN in range(len(matrix[0])):
rowList[rowN] += padStr.format(col[rowN]) + " | "
for row in rowList:
obj_str += row[:-1] + "\n"
return obj_str[:-1]
# Prints the matrix
def printM(matrix):
"""Prints the matrix"""
print toString(matrix)
# Converts matrix to an int matrix, rounds all floats
def toIntMatrix(matrix):
"""Converts matrix to an int matrix, rounds all floats"""
intMatrix = []
for col in matrix:
intCol = []
for rowCell in col:
intCol.append(int(round(rowCell)))
intMatrix.append(intCol)
return intMatrix
# ++++++++++++++++++++++++ #
# MULTIPLICATION FUNCTIONS #
# ++++++++++++++++++++++++ #
# General matrix multiplication (determines operands)
def multiply(operandA, matrix):
"""General matrix multiplication (determines operands)
Args: int/float/long/list operandA, list matrix
Returns: multiplication result
Throws: error if operandA isn't an accepted type
"""
if type(operandA) is int:
return scalarMult(operandA, matrix)
elif type(operandA) is float:
return scalarMult(operandA, matrix)
elif type(operandA) is list:
return matrixMult(operandA, matrix)
elif type(operandA) is long:
return scalarMult(operandA, matrix)
else:
raise TypeError("matrixOps.multiply() takes a matrix or number, "
"followed by a matrix")
# Scalar Multiplication
def scalarMult(scalar, matrix):
"""Matrix multiplication by a scalar"""
# Check that matrix isn't empty
if (len(matrix) == 0 or len(matrix[0]) == 0):
raise ValueError(
"matrixOps.multiply() cannot multiply an empty matrix")
modMatrix = []
for colEl in matrix:
newCol = []
for rowEl in colEl:
newCol.append(rowEl * scalar)
modMatrix.append(newCol)
return modMatrix
# Matrix Multiplication
def matrixMult(matrixA, matrixB):
"""Matrix by matrix multiplication"""
# Check that both matrices are not empty
if (len(matrixA) == 0 or len(matrixA[0]) == 0 or
len(matrixB) == 0 or len(matrixB[0]) == 0):
raise ValueError(
"matrixOps.multiply() cannot multiply an empty matrix")
# Check that numbers of cols in A matches number of rows in B
if (len(matrixA) != len(matrixB[0])):
raise ValueError("matrixOps.multiply() matrix multiplication "
"requires that num cols in 1 matrix matches num "
"rows in 2nd matrix")
# Create new matrix, and fill it with multiplication product
product = []
# Iterate over dimensions of product matrix (thru each col, thru each cell)
# Dimensions: num cols in B * num rows in A
for colN in range(len(matrixB)):
col = [] # Create new column to fill
for rowN in range(len(matrixA[0])):
cellProd = 0
# Iterate over els to be multiplied, equal to num cols in A
for elNum in range(len(matrixA)):
cellProd += matrixA[elNum][rowN] * matrixB[colN][elNum]
col.append(cellProd)
product.append(col)
return product
# ++++++++++++++++++ #
# IDENTITY FUNCTIONS #
# ++++++++++++++++++ #
# By default, gets left identity matrix
def getIdentity(matrix):
"""Creates and returns the left identity matrix for given matrix"""
try:
return getLeftIdentity(matrix)
except ValueError:
raise ValueError("matrixOps.getIdentity() cannot create identity "
"for an empty matrix")
# Create the left identity matrix for a given matrix
# Aka the identity matrix that would be the left operand
def getLeftIdentity(matrix):
"""Creates and returns the left identity matrix for given matrix"""
if (len(matrix) == 0 or len(matrix[0]) == 0):
raise ValueError("matrixOps.getLeftIdentity() cannot create identity "
"for an empty matrix")
# Left identity needs to match num rows in matrix
return createIdentity(len(matrix[0]))
# Create the right identity matrix for a given matrix
# Aka the identity matrix that would be the right operand
def getRightIdentity(matrix):
"""Creates and returns the right identity matrix for given matrix"""
if (len(matrix) == 0 or len(matrix[0]) == 0):
raise ValueError("matrixOps.getRightIdentity() cannot create identity "
"for an empty matrix")
# Right identity needs to match num cols in matrix
return createIdentity(len(matrix))
# Creates identity matrix with given dimension
def createIdentity(numEls):
identity = []
for colN in range(numEls):
col = [0] * numEls
col[colN] = 1
identity.append(col)
return identity