[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