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

scipy-svn at scipy.org scipy-svn at scipy.org
Fri Dec 14 17:44:48 EST 2007


Author: wnbell
Date: 2007-12-14 16:44:43 -0600 (Fri, 14 Dec 2007)
New Revision: 3657

Modified:
   trunk/scipy/sparse/base.py
   trunk/scipy/sparse/coo.py
   trunk/scipy/sparse/csc.py
   trunk/scipy/sparse/csr.py
   trunk/scipy/sparse/dia.py
   trunk/scipy/sparse/tests/test_base.py
   trunk/scipy/sparse/tests/test_sparse.py
Log:
test .copy() methods and copy contructor
fixed dia_matrix handling of offsets


Modified: trunk/scipy/sparse/base.py
===================================================================
--- trunk/scipy/sparse/base.py	2007-12-14 22:17:45 UTC (rev 3656)
+++ trunk/scipy/sparse/base.py	2007-12-14 22:44:43 UTC (rev 3657)
@@ -379,15 +379,15 @@
     def todia(self):
         return self.tocoo().todia()
 
-    def toself(self, copy=False):
-        if copy:
-            new = self.copy()
-        else:
-            new = self
-        return new
+#    def toself(self, copy=False):
+#        if copy:
+#            new = self.copy()
+#        else:
+#            new = self
+#        return new
 
     def copy(self):
-        return self.tocsr().copy()
+        return self.__class__(self,copy=True)
 
     def sum(self, axis=None):
         """Sum the matrix over the given axis.  If the axis is None, sum

Modified: trunk/scipy/sparse/coo.py
===================================================================
--- trunk/scipy/sparse/coo.py	2007-12-14 22:17:45 UTC (rev 3656)
+++ trunk/scipy/sparse/coo.py	2007-12-14 22:44:43 UTC (rev 3657)
@@ -93,15 +93,17 @@
             self.col = array([],dtype=intc)
         else:
             if isspmatrix(arg1):
-                if isspmatrix_coo and copy:
-                    A = arg1.copy()
+                if isspmatrix_coo(arg1) and copy:
+                    self.row   = arg1.row.copy()
+                    self.col   = arg1.col.copy()
+                    self.data  = arg1.data.copy()
+                    self.shape = arg1.shape
                 else:
-                    A = arg1.tocoo()
-
-                self.row  = A.row
-                self.col  = A.col
-                self.data = A.data
-                self.shape = A.shape
+                    coo = arg1.tocoo()
+                    self.row   = coo.row
+                    self.col   = coo.col
+                    self.data  = coo.data
+                    self.shape = coo.shape
             else:
                 #dense argument
                 try:
@@ -199,9 +201,13 @@
                      indptr, indices, data)
 
             return csr_matrix((data, indices, indptr), self.shape)
+    
 
     def tocoo(self, copy=False):
-        return self.toself(copy)
+        if copy:
+            return self.copy()
+        else:
+            return self
 
     def todok(self):
         from dok import dok_matrix

Modified: trunk/scipy/sparse/csc.py
===================================================================
--- trunk/scipy/sparse/csc.py	2007-12-14 22:17:45 UTC (rev 3656)
+++ trunk/scipy/sparse/csc.py	2007-12-14 22:44:43 UTC (rev 3657)
@@ -150,9 +150,11 @@
         col = searchsorted(self.indptr, ind+1)-1
         return (row, col)
 
-
     def tocsc(self, copy=False):
-        return self.toself(copy)
+        if copy:
+            return self.copy()
+        else:
+            return self
     
     def tocsr(self):
         indptr  = empty(self.shape[0] + 1, dtype=intc)

Modified: trunk/scipy/sparse/csr.py
===================================================================
--- trunk/scipy/sparse/csr.py	2007-12-14 22:17:45 UTC (rev 3656)
+++ trunk/scipy/sparse/csr.py	2007-12-14 22:44:43 UTC (rev 3657)
@@ -158,7 +158,10 @@
         return lil
 
     def tocsr(self, copy=False):
-        return self.toself(copy)
+        if copy:
+            return self.copy()
+        else:
+            return self
 
     def tocsc(self):
         indptr  = empty(self.shape[1] + 1, dtype=intc)

Modified: trunk/scipy/sparse/dia.py
===================================================================
--- trunk/scipy/sparse/dia.py	2007-12-14 22:17:45 UTC (rev 3656)
+++ trunk/scipy/sparse/dia.py	2007-12-14 22:44:43 UTC (rev 3657)
@@ -56,19 +56,21 @@
                     if shape is None:
                         raise ValueError,'expected a shape argument'
                     self.diags   = asarray(arg1[0],dtype=dtype)
-                    self.offsets = asarray(arg1[1],dtype='i').squeeze()
+                    self.offsets = asarray(arg1[1],dtype='i')
                     self.shape   = shape
 
         #check format
+        if self.offsets.ndim != 1:
+            raise ValueError,'offsets array must have rank 1'
+
         if self.diags.ndim != 2:
-            raise ValueError,'expected rank 2 array for argument diags'
+            raise ValueError,'diags array must have rank 2'
 
         if self.diags.shape[0] != len(self.offsets):
             raise ValueError,'number of diagonals (%d) ' \
                     'does not match the number of offsets (%d)' \
                     % (self.diags.shape[0], len(self.offsets))
         
-
         if len(Set(self.offsets)) != len(self.offsets):
             raise ValueError,'offset array contains duplicate values'
 
@@ -157,12 +159,18 @@
 
         return y
 
+    def todia(self,copy=False):
+        if copy:
+            return self.copy()
+        else:
+            return self
+
     def tocsr(self):
-        #could be optimized
+        #TODO optimize COO->CSR
         return self.tocoo().tocsr()
 
     def tocsc(self):
-        #could be optimized
+        #TODO optimize COO->CSC
         return self.tocoo().tocsc()
 
     def tocoo(self):

Modified: trunk/scipy/sparse/tests/test_base.py
===================================================================
--- trunk/scipy/sparse/tests/test_base.py	2007-12-14 22:17:45 UTC (rev 3656)
+++ trunk/scipy/sparse/tests/test_base.py	2007-12-14 22:44:43 UTC (rev 3657)
@@ -29,6 +29,7 @@
 
 #TODO test spmatrix(DENSE) and spmatrix(SPARSE) for all combos
 #TODO check that invalid shape in constructor raises exception
+#TODO check that spmatrix( ... , copy=X ) is respected
 class _TestCommon:
     """test common functionality shared by all sparse formats"""
 
@@ -110,41 +111,23 @@
     def check_mul_scalar(self):
         assert_array_equal(self.dat*2,(self.datsp*2).todense())
         assert_array_equal(self.dat*17.3,(self.datsp*17.3).todense())
-
-    def check_imul_scalar(self):
-        a = self.datsp.copy()
-        a *= 2
-        assert_array_equal(self.dat*2,a.todense())
-
-        a = self.datsp.copy()
-        a *= 17.3
-        assert_array_equal(self.dat*17.3,a.todense())
-
-    def check_idiv_scalar(self):
-        a = self.datsp.copy()
-        a /= 2
-        assert_array_equal(self.dat/2,a.todense())
-
-        a = self.datsp.copy()
-        a /= 17.3
-        assert_array_equal(self.dat/17.3,a.todense())
-
+    
     def check_rmul_scalar(self):
         assert_array_equal(2*self.dat,(2*self.datsp).todense())
         assert_array_equal(17.3*self.dat,(17.3*self.datsp).todense())
 
     def check_add(self):
-        a = self.datsp
-        b = self.datsp.copy()
-        b[0,2] = 2.0
-        c = a + b
-        assert_array_equal(c.todense(),[[2,0,2,4],[6,0,2,0],[0,4,0,0]])
+        a = self.dat.copy()
+        a[0,2] = 2.0
+        b = self.datsp
+        c = b + a
+        assert_array_equal(c,[[2,0,2,4],[6,0,2,0],[0,4,0,0]])
 
     def check_radd(self):
-        a = self.datsp
-        b = self.datsp.copy()
-        b[0,2] = 2.0
-        c = a.todense() + b
+        a = self.dat.copy()
+        a[0,2] = 2.0
+        b = self.datsp
+        c = a + b
         assert_array_equal(c,[[2,0,2,4],[6,0,2,0],[0,4,0,0]])
 
     def check_sub(self):
@@ -165,10 +148,10 @@
         assert_array_equal(self.datsp - A.todense(),self.dat - A.todense())
 
     def check_elmul(self):
-        a = self.datsp
-        b = self.datsp.copy()
-        b[0,2] = 2.0
-        c = a ** b
+        temp = self.dat.copy()
+        temp[0,2] = 2.0
+        temp = self.spmatrix(temp)
+        c = temp ** self.datsp 
         assert_array_equal(c.todense(),[[1,0,0,4],[9,0,1,0],[0,4,0,0]])
 
     def check_eldiv(self):
@@ -368,6 +351,29 @@
     def check_copy(self):
         """ Check whether the copy=True and copy=False keywords work
         """
+        A = self.datsp
+
+        #check that copy preserves format
+        assert_equal(A.copy().format, A.format)
+        assert_equal(A.__class__(A,copy=True).format,  A.format)
+        assert_equal(A.__class__(A,copy=False).format, A.format)
+        
+        assert_equal(A.copy().todense(), A.todense())
+        assert_equal(A.__class__(A,copy=True).todense(),  A.todense())
+        assert_equal(A.__class__(A,copy=False).todense(), A.todense())
+
+        #check that XXX_matrix.toXXX() works
+        toself = getattr(A,'to' + A.format)
+        assert_equal(toself().format, A.format)
+        assert_equal(toself(copy=True).format, A.format)
+        assert_equal(toself(copy=False).format, A.format)
+        
+        assert_equal(toself().todense(), A.todense())
+        assert_equal(toself(copy=True).todense(), A.todense())
+        assert_equal(toself(copy=False).todense(), A.todense())
+        
+
+        #TODO how can we check whether the data is copied?
         pass
 
     # Eventually we'd like to allow matrix products between dense
@@ -399,6 +405,27 @@
             assert_array_equal(numpy.diag(A),extract_diagonal(self.spmatrix(A)))
 
 
+class _TestInplaceArithmetic:
+    def check_imul_scalar(self):
+        a = self.datsp.copy()
+        a *= 2
+        assert_array_equal(self.dat*2,a.todense())
+
+        a = self.datsp.copy()
+        a *= 17.3
+        assert_array_equal(self.dat*17.3,a.todense())
+
+    def check_idiv_scalar(self):
+        a = self.datsp.copy()
+        a /= 2
+        assert_array_equal(self.dat/2,a.todense())
+
+        a = self.datsp.copy()
+        a /= 17.3
+        assert_array_equal(self.dat/17.3,a.todense())
+
+
+
 class _TestGetSet:
     def check_setelement(self):
         a = self.datsp - self.datsp
@@ -692,7 +719,8 @@
 
 
 
-class TestCSR(_TestCommon, _TestGetSet, _TestSolve, _TestArithmetic,  
+class TestCSR(_TestCommon, _TestGetSet, _TestSolve,
+        _TestInplaceArithmetic, _TestArithmetic,  
         _TestHorizSlicing, _TestVertSlicing, _TestBothSlicing,
         NumpyTestCase):
     spmatrix = csr_matrix
@@ -788,7 +816,8 @@
         assert b.shape == (2,2)
         assert_equal( ab, aa[i0,i1[0]:i1[1]] )
 
-class TestCSC(_TestCommon, _TestGetSet, _TestSolve, _TestArithmetic,  
+class TestCSC(_TestCommon, _TestGetSet, _TestSolve,
+        _TestInplaceArithmetic, _TestArithmetic,  
         _TestHorizSlicing, _TestVertSlicing, _TestBothSlicing,
         NumpyTestCase):
     spmatrix = csc_matrix
@@ -968,7 +997,8 @@
 
 
 class TestLIL( _TestCommon, _TestHorizSlicing, _TestVertSlicing, 
-        _TestBothSlicing, _TestGetSet, _TestSolve, _TestArithmetic, 
+        _TestBothSlicing, _TestGetSet, _TestSolve,
+        _TestArithmetic, _TestInplaceArithmetic,
         NumpyTestCase):
     spmatrix = lil_matrix
 

Modified: trunk/scipy/sparse/tests/test_sparse.py
===================================================================
--- trunk/scipy/sparse/tests/test_sparse.py	2007-12-14 22:17:45 UTC (rev 3656)
+++ trunk/scipy/sparse/tests/test_sparse.py	2007-12-14 22:44:43 UTC (rev 3657)
@@ -1,7 +1,7 @@
 """general tests and simple benchmarks for the sparse module"""
 
 import numpy
-from numpy import ones
+from numpy import ones, array, asarray, empty
 
 import random
 from numpy.testing import *
@@ -11,21 +11,29 @@
 from scipy.linsolve import splu
 restore_path()
 
-
-def poisson2d(N,epsilon=1.0):
+#TODO move this to a matrix gallery and add unittests
+def poisson2d(N,dtype='d',format=None):
     """
-    Return a sparse CSR matrix for the 2d poisson problem
+    Return a sparse matrix for the 2d poisson problem
     with standard 5-point finite difference stencil on a
     square N-by-N grid.
     """
+    if N == 1:
+        diags   = asarray( [[4]],dtype=dtype)
+        return dia_matrix((diags,[0]), shape=(1,1)).asformat(format)
 
-    D = (2 + 2*epsilon)*ones(N*N)
-    T =  -epsilon * ones(N*N)
-    O =  -ones(N*N)
-    T[N-1::N] = 0
-    return spdiags([D,O,T,T,O],[0,-N,-1,1,N],N*N,N*N).tocoo().tocsr() #eliminate explicit zeros
+    offsets = array([0,-N,N,-1,1])
 
+    diags = empty((5,N**2),dtype=dtype)
 
+    diags[0]  =  4 #main diagonal
+    diags[1:] = -1 #all offdiagonals
+
+    diags[3,N-1::N] = 0  #first lower diagonal
+    diags[4,N::N] = 0  #first upper diagonal
+
+    return dia_matrix((diags,offsets),shape=(N**2,N**2)).asformat(format)
+
 import time
 class TestSparseTools(NumpyTestCase):
     """Simple benchmarks for sparse matrix module"""
@@ -33,8 +41,8 @@
     def test_matvec(self,level=5):
         matrices = []
         matrices.append(('Identity', spidentity(10**5,format='csr')))
-        matrices.append(('Poisson5pt', poisson2d(1000)))
-        matrices.append(('Poisson5pt', dia_matrix(poisson2d(1000))))
+        matrices.append(('Poisson5pt', poisson2d(1000,format='csr')))
+        matrices.append(('Poisson5pt', poisson2d(1000,format='dia')))
 
         print
         print '                 Sparse Matrix Vector Product'




More information about the Scipy-svn mailing list