[Scipy-svn] r4858 - in branches/refactor_fft: . scipy/sparse scipy/sparse/benchmarks scipy/sparse/tests
scipy-svn at scipy.org
scipy-svn at scipy.org
Tue Oct 28 01:11:21 EDT 2008
Author: cdavid
Date: 2008-10-28 00:11:07 -0500 (Tue, 28 Oct 2008)
New Revision: 4858
Modified:
branches/refactor_fft/
branches/refactor_fft/scipy/sparse/base.py
branches/refactor_fft/scipy/sparse/benchmarks/bench_sparse.py
branches/refactor_fft/scipy/sparse/bsr.py
branches/refactor_fft/scipy/sparse/compressed.py
branches/refactor_fft/scipy/sparse/coo.py
branches/refactor_fft/scipy/sparse/dia.py
branches/refactor_fft/scipy/sparse/dok.py
branches/refactor_fft/scipy/sparse/extract.py
branches/refactor_fft/scipy/sparse/lil.py
branches/refactor_fft/scipy/sparse/tests/test_base.py
branches/refactor_fft/scipy/sparse/tests/test_extract.py
Log:
Merged revisions 4846-4857 via svnmerge from
http://svn.scipy.org/svn/scipy/trunk
........
r4853 | wnbell | 2008-10-27 11:39:52 +0900 (Mon, 27 Oct 2008) | 2 lines
minor edits
........
r4854 | wnbell | 2008-10-27 12:08:05 +0900 (Mon, 27 Oct 2008) | 4 lines
cleaned up dok_matrix imports
use native matrix * vector product in dok_matrix
renamed _mul_densematrix to _mul_multivector
........
r4855 | wnbell | 2008-10-27 12:56:22 +0900 (Mon, 27 Oct 2008) | 3 lines
added scipy.sparse.find()
fixed handling of dtype= constructor argument in dense case
........
r4856 | wnbell | 2008-10-27 13:14:53 +0900 (Mon, 27 Oct 2008) | 3 lines
fixed handling of dtype= constructor argument in sparse case
ensure that .astype(dtype) maintains sparse format
........
r4857 | wnbell | 2008-10-27 13:22:59 +0900 (Mon, 27 Oct 2008) | 2 lines
test that .astype(dtype) preserves sparse format
........
Property changes on: branches/refactor_fft
___________________________________________________________________
Name: svnmerge-integrated
- /branches/build_with_scons:1-3868 /branches/scipy.scons:1-3533 /branches/sparse_build_reduce_mem:1-4005 /branches/testing_cleanup:1-3662 /trunk:1-4845
+ /branches/build_with_scons:1-3868 /branches/scipy.scons:1-3533 /branches/sparse_build_reduce_mem:1-4005 /branches/testing_cleanup:1-3662 /trunk:1-4857
Modified: branches/refactor_fft/scipy/sparse/base.py
===================================================================
--- branches/refactor_fft/scipy/sparse/base.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/base.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -87,7 +87,7 @@
raise NotImplementedError
def astype(self, t):
- return self.tocsr().astype(t)
+ return self.tocsr().astype(t).asformat(self.format)
def asfptype(self):
"""Upcast matrix to a floating point format (if necessary)"""
@@ -272,8 +272,8 @@
self._mul_scalar()
self._mul_vector()
+ self._mul_multivector()
self._mul_sparse_matrix()
- self._mul_dense_matrix()
"""
M,N = self.shape
@@ -310,12 +310,12 @@
elif len(other.shape) == 2:
##
- # dense 2D array or matrix
+ # dense 2D array or matrix ("multivector")
if other.shape[0] != self.shape[1]:
raise ValueError('dimension mismatch')
- result = self._mul_dense_matrix(np.asarray(other))
+ result = self._mul_multivector(np.asarray(other))
if isinstance(other, np.matrix):
result = np.asmatrix(result)
@@ -331,8 +331,8 @@
def _mul_vector(self, other):
return self.tocsr()._mul_vector(other)
- def _mul_dense_matrix(self, other):
- return self.tocsr()._mul_dense_matrix(other)
+ def _mul_multivector(self, other):
+ return self.tocsr()._mul_multivector(other)
def _mul_sparse_matrix(self, other):
return self.tocsr()._mul_sparse_matrix(other)
@@ -514,7 +514,7 @@
def todia(self):
return self.tocoo().todia()
- def tobsr(self,blocksize=None):
+ def tobsr(self, blocksize=None):
return self.tocsr().tobsr(blocksize=blocksize)
def copy(self):
Modified: branches/refactor_fft/scipy/sparse/benchmarks/bench_sparse.py
===================================================================
--- branches/refactor_fft/scipy/sparse/benchmarks/bench_sparse.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/benchmarks/bench_sparse.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -130,6 +130,8 @@
matrices = []
matrices.append(('Identity', sparse.identity(10**4,format='dia')))
matrices.append(('Identity', sparse.identity(10**4,format='csr')))
+ matrices.append(('Poisson5pt', poisson2d(300,format='lil')))
+ matrices.append(('Poisson5pt', poisson2d(300,format='dok')))
matrices.append(('Poisson5pt', poisson2d(300,format='dia')))
matrices.append(('Poisson5pt', poisson2d(300,format='coo')))
matrices.append(('Poisson5pt', poisson2d(300,format='csr')))
Modified: branches/refactor_fft/scipy/sparse/bsr.py
===================================================================
--- branches/refactor_fft/scipy/sparse/bsr.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/bsr.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -126,7 +126,7 @@
elif len(arg1) == 2:
# (data,(row,col)) format
from coo import coo_matrix
- self._set_self( coo_matrix(arg1).tobsr(blocksize=blocksize) )
+ self._set_self( coo_matrix(arg1, dtype=dtype).tobsr(blocksize=blocksize) )
elif len(arg1) == 3:
# (data,indices,indptr) format
@@ -144,7 +144,7 @@
raise ValueError("unrecognized form for" \
" %s_matrix constructor" % self.format)
from coo import coo_matrix
- arg1 = coo_matrix(arg1).tobsr(blocksize=blocksize)
+ arg1 = coo_matrix(arg1, dtype=dtype).tobsr(blocksize=blocksize)
self._set_self( arg1 )
if shape is not None:
@@ -156,17 +156,20 @@
M = len(self.indptr) - 1
N = self.indices.max() + 1
except:
- raise ValueError,'unable to infer matrix dimensions'
+ raise ValueError('unable to infer matrix dimensions')
else:
R,C = self.blocksize
self.shape = (M*R,N*C)
if self.shape is None:
if shape is None:
- #infer shape here
- raise ValueError,'need to infer shape'
+ #TODO infer shape here
+ raise ValueError('need to infer shape')
else:
self.shape = shape
+
+ if dtype is not None:
+ self.data = self.data.astype(dtype)
self.check_format(full_check=False)
@@ -298,7 +301,7 @@
return result
- def _mul_dense_matrix(self,other):
+ def _mul_multivector(self,other):
R,C = self.blocksize
M,N = self.shape
n_vecs = other.shape[1] #number of column vectors
Modified: branches/refactor_fft/scipy/sparse/compressed.py
===================================================================
--- branches/refactor_fft/scipy/sparse/compressed.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/compressed.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -68,7 +68,7 @@
raise ValueError, "unrecognized %s_matrix constructor usage" % \
self.format
from coo import coo_matrix
- self._set_self( self.__class__(coo_matrix(arg1)) )
+ self._set_self( self.__class__(coo_matrix(arg1, dtype=dtype)) )
# Read matrix dimensions given, if any
if shape is not None:
@@ -83,6 +83,9 @@
raise ValueError,'unable to infer matrix dimensions'
else:
self.shape = self._swap((major_dim,minor_dim))
+
+ if dtype is not None:
+ self.data = self.data.astype(dtype)
self.check_format(full_check=False)
@@ -266,7 +269,7 @@
return result
- def _mul_dense_matrix(self,other):
+ def _mul_multivector(self, other):
M,N = self.shape
n_vecs = other.shape[1] #number of column vectors
Modified: branches/refactor_fft/scipy/sparse/coo.py
===================================================================
--- branches/refactor_fft/scipy/sparse/coo.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/coo.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -172,6 +172,10 @@
self.row,self.col = (M != 0).nonzero()
self.data = M[self.row,self.col]
+ if dtype is not None:
+ self.data = self.data.astype(dtype)
+
+
self._check()
def getnnz(self):
@@ -364,7 +368,7 @@
coo_matvec(self.nnz, self.row, self.col, self.data, other, result)
return result
- def _mul_dense_matrix(self, other):
+ def _mul_multivector(self, other):
return np.hstack( [ self._mul_vector(col).reshape(-1,1) for col in other.T ] )
from sputils import _isinstance
Modified: branches/refactor_fft/scipy/sparse/dia.py
===================================================================
--- branches/refactor_fft/scipy/sparse/dia.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/dia.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -94,12 +94,15 @@
raise ValueError("unrecognized form for" \
" %s_matrix constructor" % self.format)
from coo import coo_matrix
- A = coo_matrix(arg1).todia()
+ A = coo_matrix(arg1, dtype=dtype).todia()
self.data = A.data
self.offsets = A.offsets
self.shape = A.shape
+ if dtype is not None:
+ self.data = self.data.astype(dtype)
+
#check format
if self.offsets.ndim != 1:
raise ValueError('offsets array must have rank 1')
@@ -152,7 +155,7 @@
return y
- def _mul_dense_matrix(self, other):
+ def _mul_multimatrix(self, other):
return np.hstack( [ self._mul_vector(col).reshape(-1,1) for col in other.T ] )
def todia(self,copy=False):
Modified: branches/refactor_fft/scipy/sparse/dok.py
===================================================================
--- branches/refactor_fft/scipy/sparse/dok.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/dok.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -7,10 +7,10 @@
import operator
from itertools import izip
-from numpy import asarray, intc, isscalar
+import numpy as np
-from base import spmatrix,isspmatrix
-from sputils import isdense, getdtype, isshape, isintlike, isscalarlike
+from base import spmatrix, isspmatrix
+from sputils import isdense, getdtype, isshape, isintlike, isscalarlike, upcast
class dok_matrix(spmatrix, dict):
"""Dictionary Of Keys based sparse matrix.
@@ -59,12 +59,16 @@
arg1 = arg1.copy()
else:
arg1 = arg1.todok()
+
+ if dtype is not None:
+ arg1 = arg1.astype(dtype)
+
self.update(arg1)
self.shape = arg1.shape
self.dtype = arg1.dtype
else: # Dense ctor
try:
- arg1 = asarray(arg1)
+ arg1 = np.asarray(arg1)
except:
raise TypeError('invalid input format')
@@ -72,7 +76,7 @@
raise TypeError('expected rank <=2 dense array or matrix')
from coo import coo_matrix
- self.update( coo_matrix(arg1).todok() )
+ self.update( coo_matrix(arg1, dtype=dtype).todok() )
self.shape = arg1.shape
self.dtype = arg1.dtype
@@ -213,7 +217,7 @@
if i < 0 or i >= self.shape[0] or j < 0 or j >= self.shape[1]:
raise IndexError, "index out of bounds"
- if isscalar(value):
+ if np.isscalar(value):
if value==0:
del self[(i,j)]
else:
@@ -243,7 +247,7 @@
else:
raise NotImplementedError, "setting a 2-d slice of" \
" a dok_matrix is not yet supported"
- elif isscalar(value):
+ elif np.isscalar(value):
for element in seq:
self[element, j] = value
else:
@@ -282,7 +286,7 @@
else:
raise NotImplementedError, "setting a 2-d slice of" \
" a dok_matrix is not yet supported"
- elif isscalar(value):
+ elif np.isscalar(value):
for element in seq:
self[i, element] = value
else:
@@ -363,13 +367,28 @@
return new
def _mul_scalar(self, other):
- new = dok_matrix(self.shape, dtype=self.dtype)
# Multiply this scalar by every element.
+ new = dok_matrix(self.shape, dtype=self.dtype)
for (key, val) in self.iteritems():
new[key] = val * other
- #new.dtype.char = self.dtype.char
return new
+ def _mul_vector(self, other):
+ #matrix * vector
+ result = np.zeros( self.shape[0], dtype=upcast(self.dtype,other.dtype) )
+ for (i,j),v in self.iteritems():
+ result[i] += v * other[j]
+ return result
+
+ def _mul_multivector(self, other):
+ #matrix * multivector
+ M,N = self.shape
+ n_vecs = other.shape[1] #number of column vectors
+ result = np.zeros( (M,n_vecs), dtype=upcast(self.dtype,other.dtype) )
+ for (i,j),v in self.iteritems():
+ result[i,:] += v * other[j,:]
+ return result
+
def __imul__(self, other):
if isscalarlike(other):
# Multiply this scalar by every element.
@@ -427,7 +446,6 @@
def copy(self):
new = dok_matrix(self.shape, dtype=self.dtype)
new.update(self)
- new.shape = self.shape
return new
def take(self, cols_or_rows, columns=1):
@@ -475,51 +493,16 @@
newkey = (key[0]-num, key[1])
base[newkey] = self[key]
return base, ext
-
-# TODO update these w/ new multiplication handlers
-# def matvec(self, other):
-# if isdense(other):
-# if other.shape[0] != self.shape[1]:
-# raise ValueError, "dimensions do not match"
-# new = [0] * self.shape[0]
-# for key in self.keys():
-# new[int(key[0])] += self[key] * other[int(key[1])]
-# new = array(new)
-# if isinstance(other, matrix):
-# new = asmatrix(new)
-# # Do we need to return the transpose?
-# if other.shape[1] == 1:
-# new = new.T
-# return new
-# else:
-# raise TypeError, "need a dense vector"
-#
-# def rmatvec(self, other, conjugate=True):
-# if isdense(other):
-# if other.shape[-1] != self.shape[0]:
-# raise ValueError, "dimensions do not match"
-# new = [0] * self.shape[1]
-# for key in self.keys():
-# new[int(key[1])] += other[int(key[0])] * conj(self[key])
-# new = array(new)
-# if isinstance(other, matrix):
-# new = asmatrix(new)
-# # Do we need to return the transpose?
-# if other.shape[1] == 1:
-# new = new.T
-# return new
-# else:
-# raise TypeError, "need a dense vector"
-
+
def tocoo(self):
""" Return a copy of this matrix in COOrdinate format"""
from coo import coo_matrix
if self.nnz == 0:
return coo_matrix(self.shape, dtype=self.dtype)
else:
- data = asarray(self.values(), dtype=self.dtype)
- indices = asarray(self.keys(), dtype=intc).T
- return coo_matrix((data,indices),shape=self.shape,dtype=self.dtype)
+ data = np.asarray(self.values(), dtype=self.dtype)
+ indices = np.asarray(self.keys(), dtype=np.intc).T
+ return coo_matrix((data,indices), shape=self.shape, dtype=self.dtype)
def todok(self,copy=False):
if copy:
Modified: branches/refactor_fft/scipy/sparse/extract.py
===================================================================
--- branches/refactor_fft/scipy/sparse/extract.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/extract.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -3,11 +3,43 @@
__docformat__ = "restructuredtext en"
-__all__ = ['tril', 'triu']
+__all__ = ['find', 'tril', 'triu']
from coo import coo_matrix
+def find(A):
+ """Return the indices and values of the nonzero elements of a matrix
+
+ Parameters
+ ----------
+ A : dense or sparse matrix
+ Matrix whose nonzero elements are desired.
+
+ Returns
+ -------
+ (I,J,V) : tuple of arrays
+ I,J, and V contain the row indices, column indices, and values
+ of the nonzero matrix entries.
+
+
+ Example
+ -------
+ >>> from scipy.sparse import csr_matrix
+ >>> A = csr_matrix([[7.0, 8.0, 0],[0, 0, 9.0]])
+ >>> find(A)
+ (array([0, 0, 1], dtype=int32), array([0, 1, 2], dtype=int32), array([ 7., 8., 9.]))
+
+ """
+
+ A = coo_matrix(A).tocsr() #sums duplicates
+ A.eliminate_zeros() #removes explicit zeros
+ A = A.tocoo(copy=False) #(cheaply) convert to COO
+
+ return A.row,A.col,A.data
+
+
+
def tril(A, k=0, format=None):
"""Return the lower triangular portion of a matrix in sparse format
@@ -37,7 +69,7 @@
Examples
--------
>>> from scipy.sparse import csr_matrix
- >>> A = csr_matrix( [[1,2,0,0,3],[4,5,0,6,7],[0,0,8,9,0]] )
+ >>> A = csr_matrix( [[1,2,0,0,3],[4,5,0,6,7],[0,0,8,9,0]], dtype='int32' )
>>> A.todense()
matrix([[1, 2, 0, 0, 3],
[4, 5, 0, 6, 7],
@@ -103,7 +135,7 @@
Examples
--------
>>> from scipy.sparse import csr_matrix
- >>> A = csr_matrix( [[1,2,0,0,3],[4,5,0,6,7],[0,0,8,9,0]] )
+ >>> A = csr_matrix( [[1,2,0,0,3],[4,5,0,6,7],[0,0,8,9,0]], dtype='int32' )
>>> A.todense()
matrix([[1, 2, 0, 0, 3],
[4, 5, 0, 6, 7],
Modified: branches/refactor_fft/scipy/sparse/lil.py
===================================================================
--- branches/refactor_fft/scipy/sparse/lil.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/lil.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -66,6 +66,10 @@
A = arg1.copy()
else:
A = arg1.tolil()
+
+ if dtype is not None:
+ A = A.astype(dtype)
+
self.shape = A.shape
self.dtype = A.dtype
self.rows = A.rows
@@ -91,7 +95,7 @@
raise TypeError('unsupported matrix type')
else:
from csr import csr_matrix
- A = csr_matrix(A).tolil()
+ A = csr_matrix(A, dtype=dtype).tolil()
self.shape = A.shape
self.dtype = A.dtype
Modified: branches/refactor_fft/scipy/sparse/tests/test_base.py
===================================================================
--- branches/refactor_fft/scipy/sparse/tests/test_base.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/tests/test_base.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -150,16 +150,52 @@
def test_from_array(self):
A = array([[1,0,0],[2,3,4],[0,5,0],[0,0,0]])
- assert_array_equal(self.spmatrix(A).todense(), A)
+ assert_array_equal(self.spmatrix(A).toarray(), A)
+
+ A = array([[1.0 + 3j, 0, 0],
+ [ 0, 2.0 + 5, 0],
+ [ 0, 0, 0]])
+ assert_array_equal(self.spmatrix(A).toarray(), A)
+ assert_array_equal(self.spmatrix(A, dtype='int16').toarray(), A.astype('int16'))
def test_from_matrix(self):
A = matrix([[1,0,0],[2,3,4],[0,5,0],[0,0,0]])
assert_array_equal(self.spmatrix(A).todense(), A)
+
+ A = matrix([[1.0 + 3j, 0, 0],
+ [ 0, 2.0 + 5, 0],
+ [ 0, 0, 0]])
+ assert_array_equal(self.spmatrix(A).toarray(), A)
+ assert_array_equal(self.spmatrix(A, dtype='int16').toarray(), A.astype('int16'))
def test_from_list(self):
A = [[1,0,0],[2,3,4],[0,5,0],[0,0,0]]
assert_array_equal(self.spmatrix(A).todense(), A)
+
+ A = [[1.0 + 3j, 0, 0],
+ [ 0, 2.0 + 5, 0],
+ [ 0, 0, 0]]
+ assert_array_equal(self.spmatrix(A).toarray(), array(A))
+ assert_array_equal(self.spmatrix(A, dtype='int16').todense(), array(A).astype('int16'))
+ def test_from_sparse(self):
+ D = array([[1,0,0],[2,3,4],[0,5,0],[0,0,0]])
+ S = csr_matrix(D)
+ assert_array_equal(self.spmatrix(S).toarray(), D)
+ S = self.spmatrix(D)
+ assert_array_equal(self.spmatrix(S).toarray(), D)
+
+
+ D = array([[1.0 + 3j, 0, 0],
+ [ 0, 2.0 + 5, 0],
+ [ 0, 0, 0]])
+ S = csr_matrix(D)
+ assert_array_equal(self.spmatrix(S).toarray(), D)
+ assert_array_equal(self.spmatrix(S, dtype='int16').toarray(), D.astype('int16'))
+ S = self.spmatrix(D)
+ assert_array_equal(self.spmatrix(S).toarray(), D)
+ assert_array_equal(self.spmatrix(S, dtype='int16').toarray(), D.astype('int16'))
+
#def test_array(self):
# """test array(A) where A is in sparse format"""
# assert_equal( array(self.datsp), self.dat )
@@ -188,12 +224,24 @@
dense_dot_dense = dot(dat, b)
check2 = dot(self.datsp.toarray(), b)
assert_array_equal(dense_dot_dense, check2)
+
+ def test_astype(self):
+ D = array([[1.0 + 3j, 0, 0],
+ [ 0, 2.0 + 5, 0],
+ [ 0, 0, 0]])
+ S = self.spmatrix(D)
+ for x in supported_dtypes:
+ assert_equal(S.astype(x).dtype, D.astype(x).dtype) # correct type
+ assert_equal(S.astype(x).toarray(), D.astype(x)) # correct values
+ assert_equal(S.astype(x).format, S.format) # format preserved
+
def test_asfptype(self):
A = self.spmatrix( arange(6,dtype='int32').reshape(2,3) )
assert_equal( A.dtype , 'int32' )
assert_equal( A.asfptype().dtype, 'float64' )
+ assert_equal( A.asfptype().format, A.format )
assert_equal( A.astype('int16').asfptype().dtype , 'float32' )
assert_equal( A.astype('complex128').asfptype().dtype , 'complex128' )
@@ -779,21 +827,6 @@
self.Asp = self.spmatrix(self.A)
self.Bsp = self.spmatrix(self.B)
- def test_astype(self):
- self.arith_init()
-
- #check whether dtype and value is preserved in conversion
- for x in supported_dtypes:
- A = self.A.astype(x)
- B = self.B.astype(x)
-
- Asp = self.spmatrix(A)
- Bsp = self.spmatrix(B)
- assert_equal(Asp.dtype,A.dtype)
- assert_equal(Bsp.dtype,B.dtype)
- assert_array_equal(Asp.todense(),A)
- assert_array_equal(Bsp.todense(),B)
-
def test_add_sub(self):
self.arith_init()
Modified: branches/refactor_fft/scipy/sparse/tests/test_extract.py
===================================================================
--- branches/refactor_fft/scipy/sparse/tests/test_extract.py 2008-10-27 04:22:59 UTC (rev 4857)
+++ branches/refactor_fft/scipy/sparse/tests/test_extract.py 2008-10-28 05:11:07 UTC (rev 4858)
@@ -26,6 +26,11 @@
self.cases = cases
+ def find(self):
+ for A in self.cases:
+ I,J,V = find(A)
+ assert_equal( A.toarray(), csr_matrix(((I,J),V), shape=A.shape) )
+
def test_tril(self):
for A in self.cases:
B = A.toarray()
More information about the Scipy-svn
mailing list