[Scipy-svn] r3665 - in trunk/scipy/sparse: . tests

scipy-svn at scipy.org scipy-svn at scipy.org
Sat Dec 15 01:54:49 EST 2007


Author: wnbell
Date: 2007-12-15 00:54:42 -0600 (Sat, 15 Dec 2007)
New Revision: 3665

Modified:
   trunk/scipy/sparse/csc.py
   trunk/scipy/sparse/csr.py
   trunk/scipy/sparse/tests/test_base.py
Log:
beginning unification of CSR/CSC get/set method
sped up sparse unittests


Modified: trunk/scipy/sparse/csc.py
===================================================================
--- trunk/scipy/sparse/csc.py	2007-12-15 05:59:12 UTC (rev 3664)
+++ trunk/scipy/sparse/csc.py	2007-12-15 06:54:42 UTC (rev 3665)
@@ -7,7 +7,7 @@
 
 import numpy
 from numpy import array, matrix, asarray, asmatrix, zeros, rank, intc, \
-        empty, hstack, isscalar, ndarray, shape, searchsorted
+        empty, hstack, isscalar, ndarray, shape, searchsorted, where
 
 from base import spmatrix,isspmatrix
 from sparsetools import csc_tocsr
@@ -56,15 +56,17 @@
         return _cs_matrix._transpose(self, csr_matrix, copy)
 
     def __getitem__(self, key):
+        #TODO unify these in _cs_matrix
         if isinstance(key, tuple):
-            #TODO use _swap() to unify this in _cs_matrix
             row = key[0]
             col = key[1]
+            
             if isinstance(col, slice):
                 # Returns a new matrix!
                 return self.get_submatrix( row, col )
             elif isinstance(row, slice):
                 return self._getslice(row, col)
+            
             M, N = self.shape
             if (row < 0):
                 row = M + row
@@ -72,12 +74,23 @@
                 col = N + col
             if not (0<=row<M) or not (0<=col<N):
                 raise IndexError, "index out of bounds"
-            #this was implemented in fortran before - is there a noticable performance advantage?
-            indxs = numpy.where(row == self.indices[self.indptr[col]:self.indptr[col+1]])
-            if len(indxs[0]) == 0:
+            
+            major_index, minor_index = self._swap((row,col))
+
+            start = self.indptr[major_index]
+            end   = self.indptr[major_index+1]
+            indxs = where(minor_index == self.indices[start:end])[0]
+
+            num_matches = len(indxs)
+
+            if num_matches == 0:
+                # entry does not appear in the matrix
                 return 0
+            elif num_matches == 1:
+                return self.data[start:end][indxs[0]]
             else:
-                return self.data[self.indptr[col]:self.indptr[col+1]][indxs[0]]
+                raise ValueError,'nonzero entry (%d,%d) occurs more than once' % (row,col)
+        
         elif isintlike(key):
             # Was: return self.data[key]
             # If this is allowed, it should return the relevant row, as for
@@ -85,8 +98,18 @@
             raise IndexError, "integer index not supported for csc_matrix"
         else:
             raise IndexError, "invalid index"
+    
+    def _getslice(self, i, myslice):
+        return self._getcolslice(i, myslice)
 
+    def _getcolslice(self, myslice, j):
+        """Returns a view of the elements [myslice.start:myslice.stop, j].
+        """
+        start, stop, stride = myslice.indices(self.shape[0])
+        return _cs_matrix._get_slice(self, j, start, stop, stride, (stop - start, 1))
 
+
+
     def __setitem__(self, key, val):
         if isinstance(key, tuple):
             row = key[0]
@@ -136,15 +159,6 @@
             # We should allow slices here!
             raise IndexError, "invalid index"
 
-    def _getslice(self, i, myslice):
-        return self._getcolslice(i, myslice)
-
-    def _getcolslice(self, myslice, j):
-        """Returns a view of the elements [myslice.start:myslice.stop, j].
-        """
-        start, stop, stride = myslice.indices(self.shape[0])
-        return _cs_matrix._get_slice(self, j, start, stop, stride, (stop - start, 1))
-
     def rowcol(self, ind):
         row = self.indices[ind]
         col = searchsorted(self.indptr, ind+1)-1

Modified: trunk/scipy/sparse/csr.py
===================================================================
--- trunk/scipy/sparse/csr.py	2007-12-15 05:59:12 UTC (rev 3664)
+++ trunk/scipy/sparse/csr.py	2007-12-15 06:54:42 UTC (rev 3665)
@@ -8,7 +8,7 @@
 
 import numpy
 from numpy import array, matrix, asarray, asmatrix, zeros, rank, intc, \
-        empty, hstack, isscalar, ndarray, shape, searchsorted
+        empty, hstack, isscalar, ndarray, shape, searchsorted, where
 
 from base import spmatrix,isspmatrix
 from sparsetools import csr_tocsc
@@ -52,14 +52,15 @@
 
     def __getitem__(self, key):
         if isinstance(key, tuple):
-            #TODO use _swap() to unify this in _cs_matrix
             row = key[0]
             col = key[1]
+            
             if isinstance(row, slice):
                 # Returns a new matrix!
                 return self.get_submatrix( row, col )
             elif isinstance(col, slice):
                 return self._getslice(row, col)
+            
             M, N = self.shape
             if (row < 0):
                 row = M + row
@@ -67,12 +68,23 @@
                 col = N + col
             if not (0<=row<M) or not (0<=col<N):
                 raise IndexError, "index out of bounds"
-            #this was implemented in fortran before - is there a noticable performance advantage?
-            indxs = numpy.where(col == self.indices[self.indptr[row]:self.indptr[row+1]])
-            if len(indxs[0]) == 0:
+            
+            major_index, minor_index = self._swap((row,col))
+
+            start = self.indptr[major_index]
+            end   = self.indptr[major_index+1]
+            indxs = where(minor_index == self.indices[start:end])[0]
+
+            num_matches = len(indxs)
+
+            if num_matches == 0:
+                # entry does not appear in the matrix
                 return 0
+            elif num_matches == 1:
+                return self.data[start:end][indxs[0]]
             else:
-                return self.data[self.indptr[row]:self.indptr[row+1]][indxs[0]]
+                raise ValueError,'nonzero entry (%d,%d) occurs more than once' % (row,col)
+
         elif isintlike(key):
             return self[key, :]
         else:

Modified: trunk/scipy/sparse/tests/test_base.py
===================================================================
--- trunk/scipy/sparse/tests/test_base.py	2007-12-15 05:59:12 UTC (rev 3664)
+++ trunk/scipy/sparse/tests/test_base.py	2007-12-15 06:54:42 UTC (rev 3665)
@@ -580,26 +580,20 @@
         self.A = matrix([[   -1.5,      0,       0,    2.25],
                          [  3.125,      0,  -0.125,       0],
                          [      0, -5.375,       0,       0]],'float64')
-        self.B = matrix([[      0,  3.375,       0,  -7.875],
-                         [  6.625,   4.75,       0,       0],
-                         [    3.5, 6.0625,       0,       1]],'float64')
-
-        self.C = matrix([[  0.375,       0,      -5,     2.5],
+        self.B = matrix([[  0.375,       0,      -5,     2.5],
                          [      0,    7.25,       0,  -4.875],
                          [      0, -0.0625,       0,       0]],'complex128')
-        self.C.imag = matrix([[    1.25,     0,  0, -3.875],
+        self.B.imag = matrix([[    1.25,     0,  0, -3.875],
                               [       0, 4.125,  0,   2.75],
                               [ -0.0625,     0,  0,      1]],'float64')
 
         #fractions are all x/16ths
         assert_array_equal((self.A*16).astype('int32'),16*self.A)
-        assert_array_equal((self.B*16).astype('int32'),16*self.B)
-        assert_array_equal((self.C.real*16).astype('int32'),16*self.C.real)
-        assert_array_equal((self.C.imag*16).astype('int32'),16*self.C.imag)
+        assert_array_equal((self.B.real*16).astype('int32'),16*self.B.real)
+        assert_array_equal((self.B.imag*16).astype('int32'),16*self.B.imag)
 
         self.Asp = self.spmatrix(self.A)
         self.Bsp = self.spmatrix(self.B)
-        self.Csp = self.spmatrix(self.C)
 
         #supported types
         self.dtypes =  ['int8','uint8','int16','int32','int64',
@@ -612,77 +606,46 @@
         for x in self.dtypes:
             A = self.A.astype(x)
             B = self.B.astype(x)
-            C = self.C.astype(x)
 
             Asp = self.spmatrix(A)
             Bsp = self.spmatrix(B)
-            Csp = self.spmatrix(C)
             assert_equal(A.dtype,Asp.dtype)
             assert_equal(B.dtype,Bsp.dtype)
-            assert_equal(C.dtype,Csp.dtype)
             assert_array_equal(A,Asp.todense())
             assert_array_equal(B,Bsp.todense())
-            assert_array_equal(C,Csp.todense())
 
     def check_add_sub(self):
         self.arith_init()
 
         #basic tests
         assert_array_equal(self.A+self.B,(self.Asp+self.Bsp).todense())
-        assert_array_equal(self.A+self.C,(self.Asp+self.Csp).todense())
 
         #check conversions
         for x in self.dtypes:
             for y in self.dtypes:
                 A = self.A.astype(x)
                 B = self.B.astype(y)
-                C = self.C.astype(y)
 
                 Asp = self.spmatrix(A)
                 Bsp = self.spmatrix(B)
-                Csp = self.spmatrix(C)
 
                 #addition
                 D1 = A + B
-                D2 = A + C
-                D3 = B + C
                 S1 = Asp + Bsp
-                S2 = Asp + Csp
-                S3 = Bsp + Csp
 
                 assert_equal(D1.dtype,S1.dtype)
-                assert_equal(D2.dtype,S2.dtype)
-                assert_equal(D3.dtype,S3.dtype)
                 assert_array_equal(D1,S1.todense())
-                assert_array_equal(D2,S2.todense())
-                assert_array_equal(D3,S3.todense())
                 assert_array_equal(D1,Asp + B)          #check sparse + dense
-                assert_array_equal(D2,Asp + C)
-                assert_array_equal(D3,Bsp + C)
                 assert_array_equal(D1,A + Bsp)          #check dense + sparse
-                assert_array_equal(D2,A + Csp)
-                assert_array_equal(D3,B + Csp)
 
                 #subtraction
                 D1 = A - B
-                D2 = A - C
-                D3 = B - C
                 S1 = Asp - Bsp
-                S2 = Asp - Csp
-                S3 = Bsp - Csp
 
                 assert_equal(D1.dtype,S1.dtype)
-                assert_equal(D2.dtype,S2.dtype)
-                assert_equal(D3.dtype,S3.dtype)
                 assert_array_equal(D1,S1.todense())
-                assert_array_equal(D2,S2.todense())
-                assert_array_equal(D3,S3.todense())
                 assert_array_equal(D1,Asp - B)          #check sparse - dense
-                assert_array_equal(D2,Asp - C)
-                assert_array_equal(D3,Bsp - C)
                 assert_array_equal(D1,A - Bsp)          #check dense - sparse
-                assert_array_equal(D2,A - Csp)
-                assert_array_equal(D3,B - Csp)
 
 
     def check_mu(self):
@@ -690,32 +653,20 @@
 
         #basic tests
         assert_array_equal(self.A*self.B.T,(self.Asp*self.Bsp.T).todense())
-        assert_array_equal(self.A*self.C.T,(self.Asp*self.Csp.T).todense())
 
         for x in self.dtypes:
             for y in self.dtypes:
                 A = self.A.astype(x)
                 B = self.B.astype(y)
-                C = self.C.astype(y)
 
                 Asp = self.spmatrix(A)
                 Bsp = self.spmatrix(B)
-                Csp = self.spmatrix(C)
 
                 D1 = A * B.T
-                D2 = A * C.T
-                D3 = B * C.T
-
                 S1 = Asp * Bsp.T
-                S2 = Asp * Csp.T
-                S3 = Bsp * Csp.T
 
                 assert_array_equal(D1,S1.todense())
-                assert_array_equal(D2,S2.todense())
-                assert_array_equal(D3,S3.todense())
                 assert_equal(D1.dtype,S1.dtype)
-                assert_equal(D2.dtype,S2.dtype)
-                assert_equal(D3.dtype,S3.dtype)
 
 
 




More information about the Scipy-svn mailing list