[Scipy-svn] r2539 - in trunk/Lib: linsolve linsolve/umfpack sparse sparse/tests
scipy-svn at scipy.org
scipy-svn at scipy.org
Thu Jan 11 20:16:34 EST 2007
Author: timl
Date: 2007-01-11 19:16:24 -0600 (Thu, 11 Jan 2007)
New Revision: 2539
Modified:
trunk/Lib/linsolve/linsolve.py
trunk/Lib/linsolve/umfpack/umfpack.py
trunk/Lib/sparse/sparse.py
trunk/Lib/sparse/tests/test_sparse.py
Log:
further refactoring to sparse matrices
Modified: trunk/Lib/linsolve/linsolve.py
===================================================================
--- trunk/Lib/linsolve/linsolve.py 2007-01-11 18:44:52 UTC (rev 2538)
+++ trunk/Lib/linsolve/linsolve.py 2007-01-12 01:16:24 UTC (rev 2539)
@@ -87,10 +87,7 @@
else:
mat, csc = _toCS_superLU( A )
- if csc:
- index0 = mat.rowind
- else:
- index0 = mat.colind
+ index0 = mat.index
ftype, lastel, data, index1 = mat.ftype, mat.nnz, mat.data, mat.indptr
gssv = eval('_superlu.' + ftype + 'gssv')
b = asarray(b, dtype=data.dtype)
@@ -115,7 +112,7 @@
csc = A.tocsc()
gstrf = eval('_superlu.' + csc.ftype + 'gstrf')
- return gstrf(N, csc.nnz, csc.data, csc.rowind, csc.indptr, permc_spec,
+ return gstrf(N, csc.nnz, csc.data, csc.index, csc.indptr, permc_spec,
diag_pivot_thresh, drop_tol, relax, panel_size)
def _testme():
Modified: trunk/Lib/linsolve/umfpack/umfpack.py
===================================================================
--- trunk/Lib/linsolve/umfpack/umfpack.py 2007-01-11 18:44:52 UTC (rev 2538)
+++ trunk/Lib/linsolve/umfpack/umfpack.py 2007-01-12 01:16:24 UTC (rev 2539)
@@ -317,10 +317,10 @@
def _getIndx( self, mtx ):
if sp.isspmatrix_csc( mtx ):
- indx = mtx.rowind
+ indx = mtx.index
self.isCSR = 0
elif sp.isspmatrix_csr( mtx ):
- indx = mtx.colind
+ indx = mtx.index
self.isCSR = 1
else:
raise TypeError, 'must be a CSC/CSR matrix (is %s)' % mtx.__class__
Modified: trunk/Lib/sparse/sparse.py
===================================================================
--- trunk/Lib/sparse/sparse.py 2007-01-11 18:44:52 UTC (rev 2538)
+++ trunk/Lib/sparse/sparse.py 2007-01-12 01:16:24 UTC (rev 2539)
@@ -5,6 +5,8 @@
Revision of sparsetools by Nathan Bell
"""
+import warnings
+
from numpy import zeros, isscalar, real, imag, asarray, asmatrix, matrix, \
ndarray, amax, amin, rank, conj, searchsorted, ndarray, \
less, where, greater, array, transpose, empty, ones, \
@@ -484,7 +486,7 @@
- def __add__(self, other, self_ind, other_ind, fn, cls):
+ def __add__(self, other, fn):
# First check if argument is a scalar
if isscalarlike(other):
# Now we would add this scalar to every element.
@@ -494,17 +496,12 @@
other = other.tocsc()
if (other.shape != self.shape):
raise ValueError, "inconsistent shapes"
- if other_ind:
- other = other.tocsc()
- other_ind = other.rowind
- else:
- other = other.tocsr()
- other_ind = other.colind
+ other = self._tothis(other)
indptr, ind, data = fn(self.shape[0], self.shape[1], \
- self.indptr, self_ind, \
+ self.indptr, self.index, \
self.data, other.indptr, \
- other_ind, other.data)
- return cls((data, ind, indptr), self.shape)
+ other.index, other.data)
+ return self.__class__((data, ind, indptr), self.shape)
elif isdense(other):
# Convert this matrix to a dense matrix and add them
return other + self.todense()
@@ -546,7 +543,7 @@
new.data *= -1
return new
- def __pow__(self, other, self_ind, other_ind, fn, cls):
+ def __pow__(self, other, fn):
""" Element-by-element power (unless other is a scalar, in which
case return the matrix power.)
"""
@@ -557,40 +554,29 @@
new.ftype = _transtabl[new.dtype.char]
return new
elif isspmatrix(other):
- if other_ind:
- other = other.tocsc()
- other_ind = other.rowind
- else:
- other = other.tocsr()
- other_ind = other.colind
-
+ other = self._tothis(other)
if (other.shape != self.shape):
raise ValueError, "inconsistent shapes"
indptr, ind, data = fn(self.shape[0], self.shape[1], \
- self.indptr, self_ind, \
+ self.indptr, self.index, \
self.data, other.indptr, \
- other_ind, other.data)
- return cls((data, ind, indptr), (self.shape[0], other.shape[1]))
+ other.index, other.data)
+ return self.__class__((data, ind, indptr), (self.shape[0], other.shape[1]))
else:
raise TypeError, "unsupported type for sparse matrix power"
- def _matmat(self, other, self_ind, other_ind, fn, cls):
+ def _matmat(self, other, fn):
if isspmatrix(other):
M, K1 = self.shape
K2, N = other.shape
if (K1 != K2):
raise ValueError, "shape mismatch error"
- if other_ind:
- other = other.tocsc()
- other_ind = other.rowind
- else:
- other = other.tocsr()
- other_ind = other.colind
- indptr, ind, data = fn(M, N, self.indptr, self_ind, \
+ other = self._tothis(other)
+ indptr, ind, data = fn(M, N, self.indptr, self.index, \
self.data, other.indptr, \
- other_ind, other.data)
- return cls((data, ind, indptr), (M, N))
+ other.index, other.data)
+ return self.__class__((data, ind, indptr), (M, N))
elif isdense(other):
# This is SLOW! We need a more efficient implementation
# of sparse * dense matrix multiplication!
@@ -598,7 +584,7 @@
else:
raise TypeError, "need a dense or sparse matrix"
- def _matvec(self, other, self_ind, fn):
+ def _matvec(self, other, fn):
if isdense(other):
# This check is too harsh -- it prevents a column vector from
# being created on-the-fly like dense matrix objects can.
@@ -606,7 +592,7 @@
# raise ValueError, "dimension mismatch"
oth = numpy.ravel(other)
y = fn(self.shape[0], self.shape[1], \
- self.indptr, self_ind, self.data, oth)
+ self.indptr, self.index, self.data, oth)
if isinstance(other, matrix):
y = asmatrix(y)
# If 'other' was an (nx1) column vector, transpose the result
@@ -630,7 +616,7 @@
else:
cd = self.data
oth = numpy.ravel(other)
- y = fn(shape0, shape1, self.indptr, self.rowind, cd, oth)
+ y = fn(shape0, shape1, self.indptr, self.index, cd, oth)
if isinstance(other, matrix):
y = asmatrix(y)
# In the (unlikely) event that this matrix is 1x1 and 'other'
@@ -646,13 +632,80 @@
def getdata(self, ind):
return self.data[ind]
- def _tocoo(self, fn, self_ind):
+ def _tocoo(self, fn):
rows, cols, data = fn(self.shape[0], self.shape[1], \
- self.indptr, self_ind, self.data)
+ self.indptr, self.index, self.data)
return coo_matrix((data, (rows, cols)), self.shape)
+ def copy(self):
+ new = self.__class__(self.shape, nzmax=self.nzmax, dtype=self.dtype)
+ new.data = self.data.copy()
+ new.index = self.index.copy()
+ new.indptr = self.indptr.copy()
+ new._check()
+ return new
+
+ def _get_slice(self, i, start, stop, stride, dims):
+ """Returns a view of the elements [i, myslice.start:myslice.stop].
+ """
+ if stride != 1:
+ raise ValueError, "slicing with step != 1 not supported"
+ if stop <= start:
+ raise ValueError, "slice width must be >= 1"
+
+ indices = []
+
+ for ind in xrange(self.indptr[i], self.indptr[i+1]):
+ if self.index[ind] >= start and self.index[ind] < stop:
+ indices.append(ind)
+
+ index = self.index[indices] - start
+ data = self.data[indices]
+ indptr = numpy.array([0, len(indices)])
+ return self.__class__((data, index, indptr), dims=dims, \
+ dtype=self.dtype)
+
+
+ def _transpose(self, cls, copy=False):
+ M, N = self.shape
+ if copy:
+ data = self.data.copy()
+ index = self.index.copy()
+ indptr = self.indptr.copy()
+ else:
+ data = self.data
+ index = self.index
+ indptr = self.indptr
+ return cls((data,index,indptr),(N,M))
+
+
+ def conj(self, copy=False):
+ new = self.__class__(self.shape, nzmax=self.nzmax, dtype=self.dtype)
+ if copy:
+ new.data = self.data.conj().copy()
+ new.index = self.index.conj().copy()
+ new.indptr = self.indptr.conj().copy()
+ else:
+ new.data = self.data.conj()
+ new.index = self.index.conj()
+ new.indptr = self.indptr.conj()
+ new._check()
+ return new
+
+ def _ensure_sorted_indices(self, shape0, shape1, inplace=False):
+ """Return a copy of this matrix where the row indices are sorted
+ """
+ if inplace:
+ sparsetools.ensure_sorted_indices(shape0, shape1,
+ self.indptr, self.index,
+ self.data )
+ else:
+ return self._toother()._toother()
+
+
+
class csc_matrix(_cs_matrix):
""" Compressed sparse column matrix
This can be instantiated in several ways:
@@ -690,7 +743,7 @@
s = s*1.0
if (rank(s) == 2):
self.shape = s.shape
- self.indptr, self.rowind, self.data = densetocsr(s.shape[1], \
+ self.indptr, self.index, self.data = densetocsr(s.shape[1], \
s.shape[0], \
s.T)
else:
@@ -703,23 +756,23 @@
self.shape = s.shape
if copy:
self.data = s.data.copy()
- self.rowind = s.rowind.copy()
+ self.index = s.index.copy()
self.indptr = s.indptr.copy()
else:
self.data = s.data
- self.rowind = s.rowind
+ self.index = s.index
self.indptr = s.indptr
elif isinstance(s, csr_matrix):
self.shape = s.shape
- self.indptr, self.rowind, self.data = csrtocsc(s.shape[0],
+ self.indptr, self.index, self.data = csrtocsc(s.shape[0],
s.shape[1],
s.indptr,
- s.colind,
+ s.index,
s.data)
else:
temp = s.tocsc()
self.data = temp.data
- self.rowind = temp.rowind
+ self.index = temp.index
self.indptr = temp.indptr
self.shape = temp.shape
elif type(arg1) == tuple:
@@ -728,7 +781,7 @@
# It's a tuple of matrix dimensions (M, N)
M, N = arg1
self.data = zeros((nzmax,), self.dtype)
- self.rowind = zeros((nzmax,), intc)
+ self.index = zeros((nzmax,), intc)
self.indptr = zeros((N+1,), intc)
self.shape = (M, N)
else:
@@ -744,11 +797,11 @@
self.dtype = getdtype(dtype, s)
if copy:
self.data = array(s)
- self.rowind = array(rowind)
+ self.index = array(rowind)
self.indptr = array(indptr, dtype=intc)
else:
self.data = asarray(s)
- self.rowind = asarray(rowind)
+ self.index = asarray(rowind)
self.indptr = asarray(indptr, dtype=intc)
except:
raise ValueError, "unrecognized form for csc_matrix constructor"
@@ -760,7 +813,7 @@
dtype=self.dtype).tocsc()
self.shape = temp.shape
self.data = temp.data
- self.rowind = temp.rowind
+ self.index = temp.index
self.indptr = temp.indptr
else:
raise ValueError, "unrecognized form for csc_matrix constructor"
@@ -778,8 +831,8 @@
raise TypeError, "dimensions not understood"
else:
M = N = None
- if len(self.rowind) > 0:
- M = max(oldM, M, int(amax(self.rowind)) + 1)
+ if len(self.index) > 0:
+ M = max(oldM, M, int(amax(self.index)) + 1)
else:
# Matrix is completely empty
M = max(oldM, M)
@@ -793,8 +846,8 @@
M, N = self.shape
nnz = self.indptr[-1]
- nzmax = len(self.rowind)
- if (rank(self.data) != 1) or (rank(self.rowind) != 1) or \
+ nzmax = len(self.index)
+ if (rank(self.data) != 1) or (rank(self.index) != 1) or \
(rank(self.indptr) != 1):
raise ValueError, "data, rowind, and indptr arrays "\
"should be rank 1"
@@ -804,14 +857,14 @@
raise ValueError, "index pointer should be of of size N+1"
if (nzmax < nnz):
raise ValueError, "nzmax must not be less than nnz"
- if (nnz>0) and (amax(self.rowind[:nnz]) >= M):
+ if (nnz>0) and (amax(self.index[:nnz]) >= M):
raise ValueError, "row values must be < M"
- if (self.indptr[-1] > len(self.rowind)):
+ if (self.indptr[-1] > len(self.index)):
raise ValueError, \
"Last value of index list should be less than "\
"the size of data list"
- if (self.rowind.dtype != numpy.intc):
- self.rowind = self.rowind.astype(numpy.intc)
+ if (self.index.dtype != numpy.intc):
+ self.index = self.index.astype(numpy.intc)
if (self.indptr.dtype != numpy.intc):
self.indptr = self.indptr.astype(numpy.intc)
@@ -824,6 +877,15 @@
self.ftype = _transtabl[self.dtype.char]
+
+ def __getattr__(self, attr):
+ if attr == 'rowind':
+ warnings.warn("rowind attribute no longer in use. Use .indices instead",
+ DeprecationWarning)
+ return self.index
+ else:
+ return _cs_matrix.__getattr__(self, attr)
+
def __radd__(self, other):
""" Function supporting the operation: self + other.
@@ -836,9 +898,9 @@
if (ocs.shape != self.shape):
raise ValueError, "inconsistent shapes"
indptr, rowind, data = cscplcsc(self.shape[0], self.shape[1], \
- self.indptr, self.rowind, \
+ self.indptr, self.index, \
self.data, ocs.indptr, \
- ocs.rowind, ocs.data)
+ ocs.index, ocs.data)
return csc_matrix((data, rowind, indptr), self.shape)
elif isdense(other):
# Convert this matrix to a dense matrix and add them.
@@ -847,37 +909,17 @@
raise TypeError, "unsupported type for sparse matrix addition"
def __add__(self, other):
- return _cs_matrix.__add__(self, other, self.rowind, True, cscplcsc, csc_matrix)
+ return _cs_matrix.__add__(self, other, cscplcsc)
def __pow__(self, other):
- return _cs_matrix.__pow__(self, other, self.rowind, True, cscelmulcsc, csc_matrix)
+ return _cs_matrix.__pow__(self, other, cscelmulcsc)
def transpose(self, copy=False):
- M, N = self.shape
+ return _cs_matrix._transpose(self, csr_matrix, copy)
- if copy:
- data = self.data.copy()
- colind = self.rowind.copy()
- indptr = self.indptr.copy()
- else:
- data = self.data
- colind = self.rowind
- indptr = self.indptr
- return csr_matrix((data,colind,indptr),(N,M))
-
def conj(self, copy=False):
- new = csc_matrix(self.shape, nzmax=self.nzmax, dtype=self.dtype)
- if copy:
- new.data = self.data.conj().copy()
- new.rowind = self.rowind.conj().copy()
- new.indptr = self.indptr.conj().copy()
- else:
- new.data = self.data.conj()
- new.rowind = self.rowind.conj()
- new.indptr = self.indptr.conj()
- new._check()
- return new
+ return _cs_matrix.conj(self, copy)
def sum(self, axis=None):
# Override the base class sum method for efficiency in the cases
@@ -889,30 +931,30 @@
# The first element in column j has index indptr[j], the last
# indptr[j+1]
indptr = self.indptr
- for j in xrange(n):
- out[j] = data[indptr[j] : indptr[j+1]].sum()
+ for i in xrange(n):
+ out[i] = data[indptr[i] : indptr[i+1]].sum()
if axis == 0:
# Output is a (1 x n) dense matrix
return asmatrix(out)
else:
return out.sum()
else:
- rowind = self.rowind
+ index = self.index
out = zeros(m, dtype=self.dtype)
# Loop over non-zeros
for k in xrange(self.nnz):
- out[rowind[k]] += data[k]
+ out[index[k]] += data[k]
# Output is a (m x 1) dense matrix
return asmatrix(out).T
def matvec(self, other):
- return _cs_matrix._matvec(self, other, self.rowind, cscmux)
+ return _cs_matrix._matvec(self, other, cscmux)
def rmatvec(self, other, conjugate=True):
return _cs_matrix._rmatvec(self, other, shape[1], shape[0], cscmux, conjugate=conjugate)
def matmat(self, other):
- return _cs_matrix._matmat(self, other, self.rowind, True, cscmucsc, csc_matrix)
+ return _cs_matrix._matmat(self, other, cscmucsc)
def __getitem__(self, key):
@@ -932,7 +974,7 @@
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 advangate?
- indxs = numpy.where(row == self.rowind[self.indptr[col]:self.indptr[col+1]])
+ indxs = numpy.where(row == self.index[self.indptr[col]:self.indptr[col+1]])
if len(indxs[0]) == 0:
return 0
else:
@@ -965,21 +1007,21 @@
M = row+1
self.shape = (M, N)
- indxs = numpy.where(row == self.rowind[self.indptr[col]:self.indptr[col+1]])
+ indxs = numpy.where(row == self.index[self.indptr[col]:self.indptr[col+1]])
if len(indxs[0]) == 0:
#value not present
nzmax = self.nzmax
if (nzmax < self.nnz+1): # need more room
alloc = max(1, self.allocsize)
self.data = resize1d(self.data, nzmax + alloc)
- self.rowind = resize1d(self.rowind, nzmax + alloc)
+ self.index = resize1d(self.index, nzmax + alloc)
newindex = self.indptr[col]
self.data[newindex+1:] = self.data[newindex:-1]
- self.rowind[newindex+1:] = self.rowind[newindex:-1]
+ self.index[newindex+1:] = self.index[newindex:-1]
self.data[newindex] = val
- self.rowind[newindex] = row
+ self.index[newindex] = row
self.indptr[col+1:] += 1
elif len(indxs[0]) == 1:
@@ -997,25 +1039,10 @@
"""Returns a view of the elements [myslice.start:myslice.stop, j].
"""
start, stop, stride = myslice.indices(self.shape[0])
- if stride != 1:
- raise ValueError, "slicing with step != 1 not supported"
- if stop <= start:
- raise ValueError, "slice width must be >= 1"
-
- indices = []
-
- for ind in xrange(self.indptr[j], self.indptr[j+1]):
- if self.rowind[ind] >= start and self.rowind[ind] < stop:
- indices.append(ind)
-
- rowind = self.rowind[indices] - start
- data = self.data[indices]
- indptr = numpy.array([0, len(indices)])
- return csc_matrix((data, rowind, indptr), dims=(stop-start, 1), \
- dtype=self.dtype)
+ return _cs_matrix._get_slice(self, j, start, stop, stride, (stop - start, 1))
def rowcol(self, ind):
- row = self.rowind[ind]
+ row = self.index[ind]
col = searchsorted(self.indptr, ind+1)-1
return (row, col)
@@ -1023,12 +1050,18 @@
return self.toself(copy)
def tocoo(self):
- return _cs_matrix._tocoo(self, csctocoo, self.rowind)
+ return _cs_matrix._tocoo(self, csctocoo)
def tocsr(self):
indptr, colind, data = csctocsr(self.shape[0], self.shape[1], \
- self.indptr, self.rowind, self.data)
+ self.indptr, self.index, self.data)
return csr_matrix((data, colind, indptr), self.shape)
+
+ def _toother(self):
+ return self.tocsr()
+
+ def _tothis(self, other):
+ return other.tocsc()
def toarray(self):
return self.tocsr().toarray()
@@ -1043,30 +1076,16 @@
return
self.nnz = nnz
self.data = self.data[:nnz]
- self.rowind = self.rowind[:nnz]
+ self.index = self.index[:nnz]
self.nzmax = nnz
self._check()
def ensure_sorted_indices(self, inplace=False):
"""Return a copy of this matrix where the row indices are sorted
"""
- if inplace:
- sparsetools.ensure_sorted_indices(self.shape[1], self.shape[0],
- self.indptr, self.rowind,
- self.data )
- else:
- return self.tocsr().tocsc()
+ return _cs_matrix._ensure_sorted_indices(self, self.shape[1], self.shape[0], inplace)
- def copy(self):
- new = csc_matrix(self.shape, nzmax=self.nzmax, dtype=self.dtype)
- new.data = self.data.copy()
- new.rowind = self.rowind.copy()
- new.indptr = self.indptr.copy()
- new._check()
- return new
-
-
class csr_matrix(_cs_matrix):
""" Compressed sparse row matrix
This can be instantiated in several ways:
@@ -1099,7 +1118,7 @@
if rank(arg1) == 2:
s = arg1
ocsc = csc_matrix(transpose(s))
- self.colind = ocsc.rowind
+ self.index = ocsc.index
self.indptr = ocsc.indptr
self.data = ocsc.data
self.shape = (ocsc.shape[1], ocsc.shape[0])
@@ -1113,11 +1132,11 @@
self.shape = s.shape
if copy:
self.data = s.data.copy()
- self.colind = s.colind.copy()
+ self.index = s.index.copy()
self.indptr = s.indptr.copy()
else:
self.data = s.data
- self.colind = s.colind
+ self.index = s.index
self.indptr = s.indptr
else:
try:
@@ -1125,7 +1144,7 @@
except AttributeError:
temp = csr_matrix(s.tocsc())
self.data = temp.data
- self.colind = temp.colind
+ self.index = temp.index
self.indptr = temp.indptr
self.shape = temp.shape
elif type(arg1) == tuple:
@@ -1134,7 +1153,7 @@
M, N = arg1
self.dtype = getdtype(dtype, default=float)
self.data = zeros((nzmax,), self.dtype)
- self.colind = zeros((nzmax,), intc)
+ self.index = zeros((nzmax,), intc)
self.indptr = zeros((M+1,), intc)
self.shape = (M, N)
else:
@@ -1153,11 +1172,11 @@
self.dtype = getdtype(dtype, s)
if copy:
self.data = array(s, dtype=self.dtype)
- self.colind = array(colind)
+ self.index = array(colind)
self.indptr = array(indptr, dtype=intc)
else:
self.data = asarray(s, dtype=self.dtype)
- self.colind = asarray(colind)
+ self.index = asarray(colind)
self.indptr = asarray(indptr, dtype=intc)
else:
# (data, ij) format
@@ -1167,7 +1186,7 @@
dtype=self.dtype).tocsr()
self.shape = temp.shape
self.data = temp.data
- self.colind = temp.colind
+ self.index = temp.index
self.indptr = temp.indptr
else:
raise ValueError, "unrecognized form for csr_matrix constructor"
@@ -1186,8 +1205,8 @@
else:
M = N = None
M = max(0, oldM, M, len(self.indptr) - 1)
- if len(self.colind) > 0:
- N = max(oldN, N, int(amax(self.colind)) + 1)
+ if len(self.index) > 0:
+ N = max(oldN, N, int(amax(self.index)) + 1)
else:
# Matrix is completely empty
N = max(oldN, N)
@@ -1200,8 +1219,8 @@
M, N = self.shape
nnz = self.indptr[-1]
- nzmax = len(self.colind)
- if (rank(self.data) != 1) or (rank(self.colind) != 1) or \
+ nzmax = len(self.index)
+ if (rank(self.data) != 1) or (rank(self.index) != 1) or \
(rank(self.indptr) != 1):
raise ValueError, "data, colind, and indptr arrays "\
"should be rank 1"
@@ -1209,14 +1228,14 @@
raise ValueError, "data and row list should have same length"
if (len(self.indptr) != M+1):
raise ValueError, "index pointer should be of length #rows + 1"
- if (nnz>0) and (amax(self.colind[:nnz]) >= N):
+ if (nnz>0) and (amax(self.index[:nnz]) >= N):
raise ValueError, "column-values must be < N"
if (nnz > nzmax):
raise ValueError, \
"last value of index list should be less than "\
"the size of data list"
- if (self.colind.dtype != numpy.intc):
- self.colind = self.colind.astype(numpy.intc)
+ if (self.index.dtype != numpy.intc):
+ self.index = self.index.astype(numpy.intc)
if (self.indptr.dtype != numpy.intc):
self.indptr = self.indptr.astype(numpy.intc)
@@ -1229,28 +1248,26 @@
self.ftype = _transtabl[self.dtype.char]
+ def __getattr__(self, attr):
+ if attr == 'colind':
+ warnings.warn("colind attribute no longer in use. Use .indices instead",
+ DeprecationWarning)
+ return self.index
+ else:
+ return _cs_matrix.__getattr__(self, attr)
def __add__(self, other):
- return _cs_matrix.__add__(self, other, self.colind, False, csrplcsr, csr_matrix)
+ return _cs_matrix.__add__(self, other, csrplcsr)
-
def __pow__(self, other):
- return _cs_matrix.__pow__(self, other, self.colind, False, csrelmulcsr, csr_matrix)
+ return _cs_matrix.__pow__(self, other, csrelmulcsr)
def transpose(self, copy=False):
- M, N = self.shape
+ return _cs_matrix._transpose(self, csc_matrix, copy)
- if copy:
- data = self.data.copy()
- rowind = self.colind.copy()
- indptr = self.indptr.copy()
- else:
- data = self.data
- rowind = self.colind
- indptr = self.indptr
+ def conj(self, copy=False):
+ return _cs_matrix.conj(self, copy)
- return csc_matrix((data,rowind,indptr),(N,M))
-
def sum(self, axis=None):
# Override the base class sum method for efficiency in the cases
# axis=1 and axis=None.
@@ -1269,22 +1286,22 @@
else:
return out.sum()
else:
- colind = self.colind
+ index = self.index
out = zeros(n, dtype=self.dtype)
# Loop over non-zeros
for k in xrange(self.nnz):
- out[colind[k]] += data[k]
+ out[index[k]] += data[k]
# Output is a (1 x n) dense matrix
return asmatrix(out)
def matvec(self, other):
- return _cs_matrix._matvec(self, other, self.colind, csrmux)
+ return _cs_matrix._matvec(self, other, csrmux)
def rmatvec(self, other, conjugate=True):
return _cs_matrix._rmatvec(self, other, shape[0], shape[1], csrmux, conjugate=conjugate)
def matmat(self, other):
- return _cs_matrix._matmat(self, other, self.colind, False, csrmucsr, csr_matrix)
+ return _cs_matrix._matmat(self, other, csrmucsr)
def __getitem__(self, key):
@@ -1304,7 +1321,7 @@
if not (0<=row<M) or not (0<=col<N):
raise IndexError, "index out of bounds"
- indxs = numpy.where(col == self.colind[self.indptr[row]:self.indptr[row+1]])
+ indxs = numpy.where(col == self.index[self.indptr[row]:self.indptr[row+1]])
if len(indxs[0]) == 0:
return 0
else:
@@ -1319,22 +1336,7 @@
"""Returns a view of the elements [i, myslice.start:myslice.stop].
"""
start, stop, stride = myslice.indices(self.shape[1])
- if stride != 1:
- raise ValueError, "slicing with step != 1 not supported"
- if stop <= start:
- raise ValueError, "slice width must be >= 1"
-
- indices = []
-
- for ind in xrange(self.indptr[i], self.indptr[i+1]):
- if self.colind[ind] >= start and self.colind[ind] < stop:
- indices.append(ind)
-
- colind = self.colind[indices] - start
- data = self.data[indices]
- indptr = numpy.array([0, len(indices)])
- return csr_matrix((data, colind, indptr), dims=(1, stop-start), \
- dtype=self.dtype)
+ return _cs_matrix._get_slice(self, i, start, stop, stride, (1, stop-start))
def __setitem__(self, key, val):
if isinstance(key, tuple):
@@ -1355,21 +1357,21 @@
N = col+1
self.shape = (M, N)
- indxs = numpy.where(col == self.colind[self.indptr[row]:self.indptr[row+1]])
+ indxs = numpy.where(col == self.index[self.indptr[row]:self.indptr[row+1]])
if len(indxs[0]) == 0:
#value not present
nzmax = self.nzmax
if (nzmax < self.nnz+1): # need more room
alloc = max(1, self.allocsize)
self.data = resize1d(self.data, nzmax + alloc)
- self.colind = resize1d(self.colind, nzmax + alloc)
+ self.index = resize1d(self.index, nzmax + alloc)
newindex = self.indptr[row]
self.data[newindex+1:] = self.data[newindex:-1]
- self.colind[newindex+1:] = self.colind[newindex:-1]
+ self.index[newindex+1:] = self.index[newindex:-1]
self.data[newindex] = val
- self.colind[newindex] = col
+ self.index[newindex] = col
self.indptr[row+1:] += 1
elif len(indxs[0]) == 1:
@@ -1384,7 +1386,7 @@
raise IndexError, "invalid index"
def rowcol(self, ind):
- col = self.colind[ind]
+ col = self.index[ind]
row = searchsorted(self.indptr, ind+1)-1
return (row, col)
@@ -1392,17 +1394,22 @@
return self.toself(copy)
def tocoo(self):
- return _cs_matrix._tocoo(self, csrtocoo, self.colind)
+ return _cs_matrix._tocoo(self, csrtocoo)
def tocsc(self):
indptr, rowind, data = csrtocsc(self.shape[0], self.shape[1], \
- self.indptr, self.colind, self.data)
+ self.indptr, self.index, self.data)
return csc_matrix((data, rowind, indptr), self.shape)
+ def _toother(self):
+ return self.tocsc()
+
+ def _tothis(self, other):
+ return other.tocsr()
def toarray(self):
data = numpy.zeros(self.shape, self.data.dtype)
- csrtodense(self.shape[0], self.shape[1], self.indptr, self.colind,
+ csrtodense(self.shape[0], self.shape[1], self.indptr, self.index,
self.data, data)
return data
@@ -1416,29 +1423,16 @@
raise RuntimeError, "should never have nnz > nzmax"
return
self.data = self.data[:nnz]
- self.colind = self.colind[:nnz]
+ self.index = self.index[:nnz]
self.nzmax = nnz
self._check()
def ensure_sorted_indices(self, inplace=False):
"""Return a copy of this matrix where the column indices are sorted
"""
- if inplace:
- sparsetools.ensure_sorted_indices(self.shape[0], self.shape[1],
- self.indptr, self.colind,
- self.data )
- else:
- return self.tocsc().tocsr()
+ return _cs_matrix._ensure_sorted_indices(self, self.shape[0], self.shape[1], inplace)
- def copy(self):
- new = csr_matrix(self.shape, nzmax=self.nzmax, dtype=self.dtype)
- new.data = self.data.copy()
- new.colind = self.colind.copy()
- new.indptr = self.indptr.copy()
- new._check()
- return new
-
# This function was for sorting dictionary keys by the second tuple element.
# (We now use the Schwartzian transform instead for efficiency.)
# def csc_cmp(x, y):
@@ -2441,7 +2435,7 @@
if x.shape != (1, self.shape[1]):
raise ValueError, "sparse matrix source must be (1 x n)"
- self.rows[i] = x.colind.tolist()
+ self.rows[i] = x.index.tolist()
self.data[i] = x.data.tolist()
# This should be generalized to other shapes than an entire
# row.
Modified: trunk/Lib/sparse/tests/test_sparse.py
===================================================================
--- trunk/Lib/sparse/tests/test_sparse.py 2007-01-11 18:44:52 UTC (rev 2538)
+++ trunk/Lib/sparse/tests/test_sparse.py 2007-01-12 01:16:24 UTC (rev 2539)
@@ -470,7 +470,7 @@
[0,2,0]],'d')
bsp = csr_matrix(b)
assert_array_almost_equal(bsp.data,[4,3,1,2])
- assert_array_equal(bsp.colind,[1,0,2,1])
+ assert_array_equal(bsp.index,[1,0,2,1])
assert_array_equal(bsp.indptr,[0,1,3,4])
assert_equal(bsp.getnnz(),4)
assert_equal(bsp.getformat(),'csr')
@@ -481,7 +481,7 @@
b[3,4] = 5
bsp = csr_matrix(b)
assert_array_almost_equal(bsp.data,[5])
- assert_array_equal(bsp.colind,[4])
+ assert_array_equal(bsp.index,[4])
assert_array_equal(bsp.indptr,[0,0,0,0,1,1,1])
assert_array_almost_equal(bsp.todense(),b)
@@ -491,7 +491,7 @@
[3,0]],'d')
bsp = csr_matrix(b)
assert_array_almost_equal(bsp.data,[1,2,3])
- assert_array_equal(bsp.colind,[0,1,0])
+ assert_array_equal(bsp.index,[0,1,0])
assert_array_equal(bsp.indptr,[0,1,2,3])
assert_array_almost_equal(bsp.todense(),b)
@@ -523,7 +523,7 @@
print 'in\n', asp
asp.ensure_sorted_indices( inplace = True )
print 'out\n', asp
- assert_array_equal(asp.colind,[1, 2, 7, 4, 5])
+ assert_array_equal(asp.index,[1, 2, 7, 4, 5])
for ir in range( asp.shape[0] ):
for ic in range( asp.shape[1] ):
assert_equal( asp[ir, ic], bsp[ir, ic] )
@@ -535,7 +535,7 @@
b = matrix([[1,0,0],[3,0,1],[0,2,0]],'d')
bsp = csc_matrix(b)
assert_array_almost_equal(bsp.data,[1,3,2,1])
- assert_array_equal(bsp.rowind,[0,1,2,1])
+ assert_array_equal(bsp.index,[0,1,2,1])
assert_array_equal(bsp.indptr,[0,2,3,4])
assert_equal(bsp.getnnz(),4)
assert_equal(bsp.getformat(),'csc')
@@ -545,14 +545,14 @@
b[2,4] = 5
bsp = csc_matrix(b)
assert_array_almost_equal(bsp.data,[5])
- assert_array_equal(bsp.rowind,[2])
+ assert_array_equal(bsp.index,[2])
assert_array_equal(bsp.indptr,[0,0,0,0,0,1,1])
def check_constructor3(self):
b = matrix([[1,0],[0,2],[3,0]],'d')
bsp = csc_matrix(b)
assert_array_almost_equal(bsp.data,[1,3,2])
- assert_array_equal(bsp.rowind,[0,2,1])
+ assert_array_equal(bsp.index,[0,2,1])
assert_array_equal(bsp.indptr,[0,2,3])
def check_empty(self):
@@ -582,7 +582,7 @@
print 'in\n', asp
asp.ensure_sorted_indices( inplace = True )
print 'out\n', asp
- assert_array_equal(asp.rowind,[1, 2, 7, 4, 5])
+ assert_array_equal(asp.index,[1, 2, 7, 4, 5])
for ir in range( asp.shape[0] ):
for ic in range( asp.shape[1] ):
assert_equal( asp[ir, ic], bsp[ir, ic] )
More information about the Scipy-svn
mailing list