Skip to content

Commit ec4cfb1

Browse files
committed
add sparseMatrix code in chapter4
1 parent 2bfe07f commit ec4cfb1

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed

sparseMatrix.py

+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Implementation of the Sparse Matrix ADT using a list.
2+
3+
class SparseMatrix:
4+
# Create a sparse matrix of size numRows * numCols initialized to 0.
5+
def __init__( self, numRows, numCols ):
6+
self._numRows = numRows
7+
self._numCols = numCols
8+
self._elementList = list()
9+
10+
# Return the number of rows in the matrix
11+
def numRows( self ):
12+
return self._numRows
13+
14+
# Return the number of colums in the matrix.
15+
def numCols( self ):
16+
return self._numCols
17+
18+
# Return the value of element (i, j): x[i, j]
19+
def __getitem__( self, ndxTuple ):
20+
row = ndxTuple[0]
21+
col = ndxTuple[1]
22+
assert row >=0 and row < self.numRows() and col >=0 and col < self.numCols(), \
23+
"subscript out of range"
24+
ndx = self._findPosition( row, col )
25+
if ndx is not None:
26+
return self._elementList[ndx].value
27+
else:
28+
return 0
29+
30+
# Set the value of element (i,j) to the value s: x[i,j] = s
31+
def __setitem__( self, ndxTuple, scalar ):
32+
ndx = self._findPosition( ndxTuple[0], ndxTuple[1] )
33+
if ndx is not None:
34+
if scalar != 0.0:
35+
self._elementList[ndx].value = scalar
36+
else:
37+
self._elementList.pop( ndx )
38+
else:
39+
if scalar != 0.0:
40+
element = _MatrixElement( ndxTuple[0], ndxTuple[1], scalar )
41+
self._elementList.append( element )
42+
43+
# Scalar the matrix by the given scalar.
44+
def scaleBy( self, scalar ):
45+
for element in self._elementList:
46+
element.value *= scalar
47+
48+
# add
49+
def __add__( self, rhsMatrix ):
50+
assert rhsMatrix.numRows() == self.numRows() and \
51+
rhsMatrix.numCols() == self.numCols(), \
52+
"Matrix sizes not compatible for the add operation."
53+
54+
# Create the new matrix
55+
newMatrix = SparseMatrix( self.numRows(), self.numCols() )
56+
57+
# Duplicate the lhsmatrix. The elements are mutable, thus we must
58+
# create new objects and not simply copy the reference.
59+
for element in self._elementList:
60+
dupElement = _MatrixElement( element.row, element.col, element.value)
61+
newMatrix._elementList.append( dupElement )
62+
63+
# Iterate through each non-zero element of the rhsMatrix.
64+
for element in rhsMatrix._elementList:
65+
value = newMatrix[ element.row, element.col ]
66+
value += element.value
67+
newMatrix[ element.row, element.col ] = value
68+
69+
# Return the new matrix
70+
return newMatrix
71+
72+
73+
# sub
74+
def __sub__( self, rhsMatrix ):
75+
assert rhsMatrix.numRows() == self.numRows() and \
76+
rhsMatrix.numCols() == self.numCols(), \
77+
"Matrix sizes not compatible for the sub operation."
78+
79+
# Create the new matrix
80+
newMatrix = SparseMatrix( self.numRows(), self.numCols() )
81+
82+
# Duplicate the lhsMatrix.
83+
for element in self._elementList:
84+
dupElement = _MatrixElement( element.row, element.col, element.value )
85+
newMatrix._elementList.append( dupElement )
86+
87+
# Iterator through each non-zero element of the rhsMatrix.
88+
for element in rhsMatrix._elementList:
89+
value = newMatrix[ element.row, element.col ]
90+
value -= element.value
91+
newMatrix[ element.row, element.col ] = value
92+
93+
# Return the new matrix
94+
return newMatrix
95+
96+
# multiply
97+
def __mul__( self, rhsMatrix ):
98+
assert rhsMatrix.numRows() == self.numCols(), \
99+
"Marix sizes not compatible for the multiply operation."
100+
101+
# Create the new matrix
102+
newMatrix = SparseMatrix( self.numRows(), rhsMatrix.numCols() )
103+
104+
for row in range( self.numRows() ):
105+
for col in range( rhsMatrix.numCols() ):
106+
tmp_sum = 0
107+
for kk in range( self.numCols() ):
108+
if self[ row, kk ] != 0 and rhsMatrix[ kk, col ] != 0:
109+
tmp_sum += self[ row, kk ] * rhsMatrix[ kk, col ]
110+
newMatrix[ row, col ] = tmp_sum
111+
112+
return newMatrix
113+
114+
# Helper method used to find a specific matrix element (row, col) in the
115+
# list of non-zero entries. None is returned if the element is not found.
116+
def _findPosition( self, row, col ):
117+
n = len( self._elementList )
118+
for i in range( n ):
119+
if row == self._elementList[i].row and \
120+
col == self._elementList[i].col:
121+
return i
122+
return None
123+
124+
# Storage class for holding the non-zero matrix elements.
125+
class _MatrixElement:
126+
def __init__( self, row, col, value ):
127+
self.row = row
128+
self.col = col
129+
self.value = value
130+
131+
132+
if __name__ == '__main__':
133+
sparse_mat_A = SparseMatrix( 3, 4 )
134+
sparse_mat_B = SparseMatrix( 3, 4 )
135+
sparse_mat_C = SparseMatrix( 4, 2 )
136+
137+
sparse_mat_A[0, 0] = 1
138+
sparse_mat_A[2, 3] = 3
139+
140+
sparse_mat_B[1, 2] = 4
141+
sparse_mat_B[2, 3] = -3
142+
sparse_mat_B[2, 2] = 1
143+
144+
sparse_mat_C[0, 0] = 5
145+
sparse_mat_C[2, 1] = 2
146+
sparse_mat_C[3, 1] = 11
147+
148+
print 'mat A: '
149+
for i in range(3):
150+
for j in range(4):
151+
print sparse_mat_A[i, j],
152+
print ''
153+
154+
print 'mat B: '
155+
for i in range(3):
156+
for j in range(4):
157+
print sparse_mat_B[i, j],
158+
print ''
159+
160+
print 'mat C: '
161+
for i in range(4):
162+
for j in range(2):
163+
print sparse_mat_C[i, j],
164+
print ''
165+
166+
add_mat_01 = sparse_mat_A + sparse_mat_B
167+
print 'A + B: '
168+
for i in range( add_mat_01.numRows() ):
169+
for j in range( add_mat_01.numCols() ):
170+
print add_mat_01[i, j],
171+
print ''
172+
173+
sub_mat_02 = sparse_mat_A - sparse_mat_B
174+
print 'A - B: '
175+
for i in range( sub_mat_02.numRows() ):
176+
for j in range( sub_mat_02.numCols() ):
177+
print sub_mat_02[i, j],
178+
print ''
179+
180+
mul_mat_03 = sparse_mat_A * sparse_mat_C
181+
print ' A * C: '
182+
for i in range( mul_mat_03.numRows() ):
183+
for j in range( mul_mat_03.numCols() ):
184+
print mul_mat_03[i, j],
185+
print ''

0 commit comments

Comments
 (0)