[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