Changeset 8127
- Timestamp:
- Mar 7, 2011, 5:32:19 PM (14 years ago)
- Location:
- trunk/anuga_core/source/anuga
- Files:
-
- 5 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/anuga_core/source/anuga/utilities/sparse.py
r8124 r8127 1 """Proof of concept sparse matrix code 1 """ 2 Proof of concept sparse matrix code 2 3 """ 3 4 … … 12 13 Usage: 13 14 14 Sparse(A) #Creates sparse matrix from dense matrix A 15 Sparse(A) #Creates sparse matrix from dense matrix A 15 16 Sparse(M, N) #Creates empty MxN sparse matrix 16 17 """ 17 18 18 19 self.Data = {} 19 20 20 21 if len(args) == 1: 21 22 try: … … 25 26 26 27 assert len(A.shape) == 2, 'Input must be a 2d matrix' 27 28 28 29 self.M, self.N = A.shape 29 30 for i in range(self.M): … … 31 32 if A[i, j] != 0.0: 32 33 self.Data[i, j] = A[i, j] 33 34 34 35 35 36 elif len(args) == 2: 36 37 self.M = args[0] … … 38 39 else: 39 40 raise Exception('Invalid construction') 40 41 self.shape = (self.M, self.N) 41 42 self.shape = (self.M, self.N) 42 43 43 44 … … 52 53 def nonzeros(self): 53 54 """Return number of nonzeros of A 54 """ 55 """ 55 56 return len(self) 56 57 57 58 def __setitem__(self, key, x): 58 59 … … 60 61 # removing these asserts will not speed things up 61 62 assert 0 <= i < self.M 62 assert 0 <= j < self.N 63 assert 0 <= j < self.N 63 64 64 65 if x != 0: 65 66 self.Data[key] = float(x) 66 67 else: 67 if self.Data.has_key( key ): 68 if self.Data.has_key( key ): 68 69 del self.Data[key] 69 70 70 71 def __getitem__(self, key): 71 72 72 73 i,j = key 73 74 # removing these asserts will not speed things up 74 75 assert 0 <= i < self.M 75 assert 0 <= j < self.N 76 assert 0 <= j < self.N 76 77 77 78 if self.Data.has_key( key ): … … 94 95 def todense(self): 95 96 D = num.zeros( (self.M, self.N), num.float) 96 97 97 98 for i in range(self.M): 98 99 for j in range(self.N): 99 if self.Data.has_key( (i,j) ): 100 if self.Data.has_key( (i,j) ): 100 101 D[i, j] = self.Data[ (i,j) ] 101 102 return D 102 103 103 104 104 105 105 106 def __mul__(self, other): 106 107 """Multiply this matrix onto 'other' which can either be … … 113 114 msg = 'FIXME: Only numeric types implemented so far' 114 115 raise Exception(msg) 115 116 116 117 117 118 # Assume numeric types from now on 118 119 119 120 if len(B.shape) == 0: 120 121 # Scalar - use __rmul__ method 121 122 R = B*self 122 123 123 124 elif len(B.shape) == 1: 124 125 # Vector … … 128 129 129 130 R = num.zeros(self.M, num.float) #Result 130 131 131 132 # Multiply nonzero elements 132 133 for key in self.Data.keys(): … … 135 136 R[i] += self.Data[key]*B[j] 136 137 elif len(B.shape) == 2: 137 138 138 139 139 140 R = num.zeros((self.M, B.shape[1]), num.float) #Result matrix 140 141 … … 142 143 for col in range(R.shape[1]): 143 144 # For each column 144 145 145 146 for key in self.Data.keys(): 146 147 i, j = key 147 148 148 149 R[i, col] += self.Data[key]*B[j, col] 149 150 150 151 151 152 else: 152 153 raise ValueError('Dimension too high: d=%d' %len(B.shape)) 153 154 154 155 return R 155 156 156 157 157 158 def __add__(self, other): 158 """Add this matrix onto 'other' 159 """Add this matrix onto 'other' 159 160 """ 160 161 … … 220 221 class Sparse_CSR: 221 222 222 def __init__(self, A ):223 def __init__(self, A=None, data=None, Colind=None, rowptr=None, m=None, n=None): 223 224 """Create sparse matrix in csr format. 224 225 … … 239 240 Regard it as a pointer into the colind array, for the ith row. 240 241 241 242 242 243 """ 243 244 … … 264 265 row_ptr[row] = nnz 265 266 #row_ptr[-1] = nnz 266 267 267 268 self.data = data 268 269 self.colind = colind … … 270 271 self.M = A.M 271 272 self.N = A.N 272 else: 273 raise ValueError("Sparse_CSR(A) expects A == Sparse Matrix") 274 273 elif isinstance(data,num.ndarray) and isinstance(Colind,num.ndarray) and isinstance(rowptr,num.ndarray) and isinstance(m,int) and isinstance(n,int): 274 msg = "Sparse_CSR: data is array of wrong dimensions" 275 #assert len(data.shape) == 1, msg 276 nnz = data.size 277 278 msg = "Sparse_CSR: Colind is array of wrong dimensions" 279 assert Colind.shape == (nnz,), msg 280 281 msg = "Sparse_CSR: rowptr is array of wrong dimensions" 282 assert rowptr.shape == (m+1,), msg 283 284 self.data = data 285 self.colind = Colind 286 self.row_ptr = rowptr 287 self.M = m 288 self.N = n 289 else: 290 raise ValueError('Sparse_CSR(A) expects A == Sparse Matrix *or* data==array,colind==array,rowptr==array,m==int,n==int') 291 275 292 def __repr__(self): 276 293 return '%d X %d sparse matrix:\n' %(self.M, self.N) + `self.data` … … 283 300 def nonzeros(self): 284 301 """Return number of nonzeros of A 285 """ 302 """ 286 303 return len(self) 287 304 288 305 def todense(self): 289 306 D = num.zeros( (self.M, self.N), num.float) 290 307 291 308 for i in range(self.M): 292 309 for ckey in range(self.row_ptr[i],self.row_ptr[i+1]): … … 305 322 print 'FIXME: Only numeric types implemented so far' 306 323 307 return csr_mv(self,B) 324 return csr_mv(self,B) 308 325 309 326 … … 317 334 if __name__ == '__main__': 318 335 # A little selftest 319 336 320 337 A = Sparse(3,3) 321 338 … … 329 346 330 347 print A 331 print A.todense() 348 print A.todense() 332 349 333 350 A[1,2] = 0 -
trunk/anuga_core/source/anuga/utilities/test_sparse.py
r8124 r8127 199 199 assert num.allclose(B*C2, [[15.0, 30.0],[10.0, 20.0],[8.0, 16.0],[0.0, 0.0]]) 200 200 201 def test_sparse_csr_init(self): 202 A = num.array([[1.0,0.0,-1.0,0.0],[0.0,2.0,0.0,0.0],[0.0,0.0,0.0,-3.0],[0.0,0.0,4.0,0.0]]) 203 data = num.array([1.0,-1.0,2.0,-3.0,4.0]) 204 Colind = num.array([0,2,1,3,2]) 205 rowptr = num.array([0,2,3,4,5]) #the 5 does not correspond to any row, it is just there so we know how many nonzero entries there are! 206 A_CSR = Sparse_CSR(None,data,Colind,rowptr,4,4) 207 A_dense = A_CSR.todense() 208 assert num.allclose(A, A_dense) 209 201 210 ################################################################################ 202 211
Note: See TracChangeset
for help on using the changeset viewer.