[Scipy-svn] r3786 - in branches/testing_cleanup: . scipy/io/matlab scipy/sparse scipy/sparse/sparsetools scipy/sparse/tests

scipy-svn@scip... scipy-svn@scip...
Sat Jan 5 02:16:35 CST 2008


Author: matthew.brett@gmail.com
Date: 2008-01-05 02:16:25 -0600 (Sat, 05 Jan 2008)
New Revision: 3786

Modified:
   branches/testing_cleanup/
   branches/testing_cleanup/scipy/io/matlab/mio5.py
   branches/testing_cleanup/scipy/io/matlab/miobase.py
   branches/testing_cleanup/scipy/sparse/bsr.py
   branches/testing_cleanup/scipy/sparse/compressed.py
   branches/testing_cleanup/scipy/sparse/sparsetools/fixed_size.h
   branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.h
   branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.i
   branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.py
   branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools_wrap.cxx
   branches/testing_cleanup/scipy/sparse/tests/test_base.py
Log:
Merged with trunk up to 3784


Property changes on: branches/testing_cleanup
___________________________________________________________________
Name: svnmerge-integrated
   - /branches/scipy.scons:1-3533 /trunk:1-3661
   + /branches/scipy.scons:1-3533 /trunk:1-3662,3667-3672,3674-3675,3684,3723-3735,3738,3744,3749,3754-3755,3759,3761,3764,3769,3774,3778-3785

Modified: branches/testing_cleanup/scipy/io/matlab/mio5.py
===================================================================
--- branches/testing_cleanup/scipy/io/matlab/mio5.py	2008-01-05 07:04:22 UTC (rev 3785)
+++ branches/testing_cleanup/scipy/io/matlab/mio5.py	2008-01-05 08:16:25 UTC (rev 3786)
@@ -190,23 +190,25 @@
     def read_element(self, copy=True):
         raw_tag = self.mat_stream.read(8)
         tag = N.ndarray(shape=(),
-                      dtype=self.dtypes['tag_full'],
-                      buffer = raw_tag)
+                        dtype=self.dtypes['tag_full'],
+                        buffer=raw_tag)
         mdtype = tag['mdtype'].item()
+
         byte_count = mdtype >> 16
         if byte_count: # small data element format
             if byte_count > 4:
                 raise ValueError, 'Too many bytes for sde format'
             mdtype = mdtype & 0xFFFF
             dt = self.dtypes[mdtype]
-            el_count = byte_count / dt.itemsize
+            el_count = byte_count // dt.itemsize
             return N.ndarray(shape=(el_count,),
-                           dtype=dt,
-                           buffer=raw_tag[4:])
+                             dtype=dt,
+                             buffer=raw_tag[4:])
+
         byte_count = tag['byte_count'].item()
         if mdtype == miMATRIX:
             return self.current_getter(byte_count).get_array()
-        if mdtype in self.codecs: # encoded char data
+        elif mdtype in self.codecs: # encoded char data
             raw_str = self.mat_stream.read(byte_count)
             codec = self.codecs[mdtype]
             if not codec:
@@ -214,15 +216,18 @@
             el = raw_str.decode(codec)
         else: # numeric data
             dt = self.dtypes[mdtype]
-            el_count = byte_count / dt.itemsize
+            el_count = byte_count // dt.itemsize
             el = N.ndarray(shape=(el_count,),
                          dtype=dt,
                          buffer=self.mat_stream.read(byte_count))
             if copy:
                 el = el.copy()
+
+        # Seek to next 64-bit boundary
         mod8 = byte_count % 8
         if mod8:
             self.mat_stream.seek(8 - mod8, 1)
+
         return el
 
     def matrix_getter_factory(self):
@@ -572,14 +577,16 @@
             tag['mdtype'] = np_to_mtypes[arr.dtype.str[1:]]
         else:
             tag['mdtype'] = mdtype
-        tag['byte_count'] =  arr.size*arr.itemsize
+
+        tag['byte_count'] = arr.size*arr.itemsize
+        padding = (8 - tag['byte_count']) % 8
+
         self.write_dtype(tag)
         self.write_bytes(arr)
-        # do 8 byte padding if needed
-        if tag['byte_count']%8 != 0:
-            pad = (1+tag['byte_count']//8)*8 - tag['byte_count']
-            self.write_bytes(N.zeros((pad,),dtype='u1'))
 
+        # pad to next 64-bit boundary
+        self.write_bytes(N.zeros((padding,),'u1'))
+
     def write_header(self, mclass,
                      is_global=False,
                      is_complex=False,
@@ -673,7 +680,6 @@
         A.sort_indices()     # MATLAB expects sorted row indices
         is_complex = (A.dtype.kind == 'c')
         nz = A.nnz
-
         self.write_header(mclass=mxSPARSE_CLASS,
                           is_complex=is_complex,
                           nzmax=nz)

Modified: branches/testing_cleanup/scipy/io/matlab/miobase.py
===================================================================
--- branches/testing_cleanup/scipy/io/matlab/miobase.py	2008-01-05 07:04:22 UTC (rev 3785)
+++ branches/testing_cleanup/scipy/io/matlab/miobase.py	2008-01-05 08:16:25 UTC (rev 3786)
@@ -90,11 +90,9 @@
                           or in ('little', '<')
                           or in ('BIG', '>')
     mat_dtype          - return arrays in same dtype as loaded into matlab
-                          (instead of the dtype with which they are saved)
+                         (instead of the dtype with which they were saved)
     squeeze_me         - whether to squeeze unit dimensions or not
     chars_as_strings   - whether to convert char arrays to string arrays
-    mat_dtype          - return matrices with datatype that matlab would load as
-                          (rather than in the datatype matlab saves as)
     matlab_compatible  - returns matrices as would be loaded by matlab
                          (implies squeeze_me=False, chars_as_strings=False
                          mat_dtype=True)

Modified: branches/testing_cleanup/scipy/sparse/bsr.py
===================================================================
--- branches/testing_cleanup/scipy/sparse/bsr.py	2008-01-05 07:04:22 UTC (rev 3785)
+++ branches/testing_cleanup/scipy/sparse/bsr.py	2008-01-05 08:16:25 UTC (rev 3786)
@@ -1,5 +1,4 @@
-"""Compressed Block Sparse Row matrix format
-"""
+"""Compressed Block Sparse Row matrix format"""
 
 __all__ = ['bsr_matrix', 'isspmatrix_bsr']
 
@@ -12,7 +11,7 @@
 from sparsetools import bsr_matvec, csr_matmat_pass1, bsr_matmat_pass2
 from data import _data_matrix
 from compressed import _cs_matrix
-from base import isspmatrix
+from base import isspmatrix, _formats
 from sputils import isshape, getdtype, to_native, isscalarlike, isdense, \
         upcast
 
@@ -21,44 +20,45 @@
 
     This can be instantiated in several ways:
       - bsr_matrix(D, [blocksize=(R,C)])
-        with a dense matrix or rank-2 ndarray D
+        - with a dense matrix or rank-2 ndarray D
 
       - bsr_matrix(S, [blocksize=(R,C)])
-        with another sparse matrix S (equivalent to S.tocsr())
+        - with another sparse matrix S (equivalent to S.tobsr())
 
       - bsr_matrix((M, N), [blocksize=(R,C), dtype])
-        to construct an empty matrix with shape (M, N)
-        dtype is optional, defaulting to dtype='d'.
+        - to construct an empty matrix with shape (M, N)
+        - dtype is optional, defaulting to dtype='d'.
 
       - bsr_matrix((data, ij), [blocksize=(R,C), shape=(M, N)])
-        where data, ij satisfy:
-            a[ij[0, k], ij[1, k]] = data[k]
+        - where data, ij satisfy:
+          - a[ij[0, k], ij[1, k]] = data[k]
 
       - bsr_matrix((data, indices, indptr), [shape=(M, N)])
-        is the standard BSR representation where:
-            the block column indices for row i are stored in
-                indices[ indptr[i]: indices[i+1] ] 
-            and their corresponding block values are stored in
-                data[ indptr[i]: indptr[i+1] ]
-        If the shape parameter is not supplied, the matrix dimensions
-        are inferred from the index arrays.
+        - is the standard BSR representation where:
+          the block column indices for row i are stored in
+           - indices[ indptr[i]: indices[i+1] ] 
+          and their corresponding block values are stored in
+           - data[ indptr[i]: indptr[i+1] ]
+        - if the shape parameter is not supplied, the matrix dimensions
+          are inferred from the index arrays.
 
 
-    *Notes*
-    -------
-        The blocksize (R,C) must evenly divide the shape of 
-        the matrix (M,N).  That is, R and C must satisfy the
-        relationship M % R = 0 and N % C = 0.
+    Notes
+    =====
+        
+        - The blocksize (R,C) must evenly divide the shape of 
+          the matrix (M,N).  That is, R and C must satisfy the
+          relationship M % R = 0 and N % C = 0.
     
-        The Block Compressed Row (BSR) format is very similar to the
-        Compressed Sparse Row (CSR) format.  BSR is appropriate for
-        sparse matrices with dense sub matrices like the last example
-        below.  Such matrices often arise, for instance, in finite
-        element discretizations.
+        - The Block Compressed Row (BSR) format is very similar to the
+          Compressed Sparse Row (CSR) format.  BSR is appropriate for
+          sparse matrices with dense sub matrices like the last example
+          below.  Such matrices often arise, for instance, in vector-valued
+          finite element discretizations.
 
 
-    *Examples*
-    ----------
+    Examples
+    ========
 
     >>> from scipy.sparse import *
     >>> from scipy import *
@@ -113,11 +113,11 @@
                 self.data   = zeros( (0,) + blocksize, getdtype(dtype, default=float) )
                 self.indices = zeros( 0, dtype=intc )
                 
-                X,Y = blocksize
-                if (M % X) != 0 or (N % Y) != 0:
+                R,C = blocksize
+                if (M % R) != 0 or (N % C) != 0:
                     raise ValueError, 'shape must be multiple of blocksize'
 
-                self.indptr  = zeros(M/X + 1, dtype=intc )
+                self.indptr  = zeros(M/R + 1, dtype=intc )
             
             elif len(arg1) == 2:
                 # (data,(row,col)) format
@@ -279,7 +279,7 @@
         """
         if isdense(other):
             M,N = self.shape
-            X,Y = self.blocksize
+            R,C = self.blocksize
 
             if other.shape != (N,) and other.shape != (N,1):
                 raise ValueError, "dimension mismatch"
@@ -299,7 +299,7 @@
                 y = output
             
             
-            bsr_matvec(M/X, N/Y, X, Y, \
+            bsr_matvec(M/R, N/C, R, C, \
                 self.indptr, self.indices, ravel(self.data), ravel(other), y)
 
             if isinstance(other, matrix):
@@ -389,15 +389,15 @@
         """
         
         M,N = self.shape
-        X,Y = self.blocksize
+        R,C = self.blocksize
 
-        row  = (X * arange(M/X)).repeat(diff(self.indptr))
-        row  = row.repeat(X*Y).reshape(-1,X,Y)
-        row += tile( arange(X).reshape(-1,1), (1,Y) )
+        row  = (R * arange(M/R)).repeat(diff(self.indptr))
+        row  = row.repeat(R*C).reshape(-1,R,C)
+        row += tile( arange(R).reshape(-1,1), (1,C) )
         row  = row.reshape(-1) 
 
-        col  = (Y * self.indices).repeat(X*Y).reshape(-1,X,Y)
-        col += tile( arange(Y), (X,1) )
+        col  = (C * self.indices).repeat(R*C).reshape(-1,R,C)
+        col += tile( arange(C), (R,1) )
         col  = col.reshape(-1)
 
         data = self.data.reshape(-1)
@@ -411,16 +411,16 @@
 
     def transpose(self):
         
-        X,Y = self.blocksize
+        R,C = self.blocksize
         M,N = self.shape
         
         if self.nnz == 0:
-            return bsr_matrix((N,M),blocksize=(Y,X))
+            return bsr_matrix((N,M),blocksize=(C,R))
 
         #use CSR.T to determine a permutation for BSR.T
         from csr import csr_matrix
         data = arange(len(self.indices), dtype=self.indices.dtype)
-        proxy = csr_matrix((data,self.indices,self.indptr),shape=(M/X,N/Y))
+        proxy = csr_matrix((data,self.indices,self.indptr),shape=(M/R,N/C))
         proxy = proxy.tocsc()
 
         data    = self.data.swapaxes(1,2)[proxy.data] #permute data
@@ -434,7 +434,29 @@
     ############################################################## 
     # methods that examine or modify the internal data structure #
     ##############################################################
-   
+    
+    def eliminate_zeros(self):
+        R,C = self.blocksize
+        M,N = self.shape
+
+        mask = (self.data != 0).reshape(-1,R*C).sum(axis=1) #nonzero blocks
+       
+        nonzero_blocks = mask.nonzero()[0]
+
+        if len(nonzero_blocks) == 0:
+            return #nothing to do
+
+        self.data[:len(nonzero_blocks)] = self.data[nonzero_blocks]
+
+        from csr import csr_matrix
+
+        # modifies self.indptr and self.indices *in place*
+        proxy = csr_matrix((mask,self.indices,self.indptr),shape=(M/R,N/C))
+        proxy.eliminate_zeros()
+       
+        self.prune()
+
+
     def sum_duplicates(self):
         raise NotImplementedError
 

Modified: branches/testing_cleanup/scipy/sparse/compressed.py
===================================================================
--- branches/testing_cleanup/scipy/sparse/compressed.py	2008-01-05 07:04:22 UTC (rev 3785)
+++ branches/testing_cleanup/scipy/sparse/compressed.py	2008-01-05 08:16:25 UTC (rev 3786)
@@ -553,6 +553,17 @@
     # methods that examine or modify the internal data structure #
     ##############################################################
 
+    def eliminate_zeros(self):
+        """Remove zero entries from the matrix
+
+        The is an *in place* operation
+        """
+        fn = sparsetools.csr_eliminate_zeros
+        M,N = self._swap(self.shape)
+        fn( M, N, self.indptr, self.indices, self.data)
+
+        self.prune() #nnz may have changed
+
     def sum_duplicates(self):
         """Eliminate duplicate matrix entries by adding them together
 
@@ -570,8 +581,10 @@
     def __get_sorted(self):
         """Determine whether the matrix has sorted indices
 
-            True if the indices of the matrix are in
-            sorted order, False otherwise.
+        Returns
+            - True: if the indices of the matrix are in sorted order
+            - False: otherwise
+        
         """
 
         #first check to see if result was cached

Modified: branches/testing_cleanup/scipy/sparse/sparsetools/fixed_size.h
===================================================================
--- branches/testing_cleanup/scipy/sparse/sparsetools/fixed_size.h	2008-01-05 07:04:22 UTC (rev 3785)
+++ branches/testing_cleanup/scipy/sparse/sparsetools/fixed_size.h	2008-01-05 08:16:25 UTC (rev 3786)
@@ -2,7 +2,7 @@
 #define FIXED_SIZE_H
 
 /*
- * templates for fixed size array and vector arithmetic
+ * templates for fixed size vector and matrix arithmetic
  * 
  */
 
@@ -12,63 +12,139 @@
  *  Dot Product
  * 
  */
-template<int N, class T>
+template<int N, int SX, int SY, class T>
 class _dot
 {
     public:
-        inline T operator()(const T * V1, const T * V2)
+        inline T operator()(const T * X, const T * Y)
         {
-            _dot<N-1,T> d;
-            return (*V1) * (*V2) + d(++V1, ++V2);
+            _dot<N-1,SX,SY,T> d;
+            return (*X) * (*Y) + d(X + SX, Y + SY);
         }
 };
-template<class T>
-class _dot<1,T>
+template<int SX, int SY, class T>
+class _dot<1,SX,SY,T>
 {
     public:
-        inline T operator()(const T * V1, const T * V2)
+        inline T operator()(const T * X, const T * Y)
         {
-            return (*V1) * (*V2);
+            return (*X) * (*Y);
         }
 };
 
-template<int N, class T>
-inline T dot(const T * V1, const T * V2)
+template<int N, int SX, int SY, class T>
+inline T dot(const T * X, const T * Y)
 {
-    _dot<N,T> d;
-    return d(V1, V2);
+    _dot<N,SX,SY,T> d;
+    return d(X, Y);
 }
 
 
 
+/*
+ *  Matrix Vector Product Y = A*X
+ * 
+ */
+template<int M, int N, int SX, int SY, class T>
+class _matvec
+{
+    public:
+        inline void operator()(const T * A, const T * X, T * Y)
+        {
+            *Y += dot<N,1,SX,T>(A,X);
+            _matvec<M-1,N,SX,SY,T> d;
+            d(A + N, X, Y + SY);
+        }
+};
 
+template<int N, int SX, int SY, class T>
+class _matvec<1,N,SX,SY,T>
+{
+    public:
+        inline void operator()(const T * A, const T * X, T * Y)
+        {
+            *Y += dot<N,1,SX,T>(A,X);
+        }
+};
 
+template<int M, int N, int SX, int SY, class T>
+inline void matvec(const T * A, const T * X, T * Y)
+{
+    _matvec<M,N,SX,SY,T> d;
+    d(A,X,Y);
+}
+
+
+/*
+ *  Matrix Matrix Product C = A*B
+ *
+ *  C is L*N
+ *  A is L*M
+ *  B is M*N
+ * 
+ */
+template<int L, int M, int N, int U, class T>
+class _matmat
+{
+    public:
+        inline void operator()(const T * A, const T * B, T * C)
+        {
+            matvec<L,M,N,N>(A,B,C);
+            
+            _matmat<L,M,N,U-1,T> d;
+            d(A, B + 1, C + 1);
+        }
+};
+template<int L, int M, int N, class T>
+class _matmat<L,M,N,0,T>
+{
+    public:
+        inline void operator()(const T * A, const T * B, T * C)
+        {
+            matvec<L,M,N,N>(A,B,C);
+        }
+};
+
+template<int L, int M, int N, class T>
+inline void matmat(const T * A, const T * B, T * C)
+{
+    _matmat<L,M,N,N-1,T> d;
+    d(A,B,C);
+}
+
+
+
+/*
+ * Binary vector operation Z = op(X,Y) 
+ *
+ */
+
 template<int N, class T, class bin_op>
 class _vec_binop_vec
 {
     public:
-        inline void operator()(const T * V1, const T * V2, T * V3, const bin_op& op)
+        inline void operator()(const T * X, const T * Y, T * Z, const bin_op& op)
         {
-            *V3 = op( *V1, *V2 );
+            *Z = op( *X, *Y );
             _vec_binop_vec<N-1,T,bin_op> d;
-            d(V1 + 1, V2 + 1, V3 + 1, op);
+            d(X + 1, Y + 1, Z + 1, op);
         }
 };
 template<class T, class bin_op>
 class _vec_binop_vec<1,T,bin_op>
 {
     public:
-        inline void operator()(const T * V1, const T * V2, T * V3, const bin_op& op)
+        inline void operator()(const T * X, const T * Y, T * Z, const bin_op& op)
         {
-            *V3 = op( *V1, *V2 );
+            *Z = op( *X, *Y );
         }
 };
 
 template<int N, class T, class bin_op>
-inline void vec_binop_vec(const T * V1, const T * V2, T * V3, const bin_op& op)
+inline void vec_binop_vec(const T * X, const T * Y, T * Z, const bin_op& op)
 {
     _vec_binop_vec<N,T,bin_op> d;
-    d(V1,V2,V3,op);
+    d(X,Y,Z,op);
 }
 
 

Modified: branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.h
===================================================================
--- branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.h	2008-01-05 07:04:22 UTC (rev 3785)
+++ branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.h	2008-01-05 08:16:25 UTC (rev 3786)
@@ -330,7 +330,7 @@
                       const I Bj[],
                             I Cp[])
 {
-//    // method that uses O(n) temp storage
+//    // method that uses O(1) temp storage
 //    const I hash_size = 1 << 5;
 //    I vals[hash_size];
 //    I mask[hash_size];
@@ -462,6 +462,74 @@
         Cp[i+1] = nnz;
     }
 }
+
+
+
+template <class I, class T, int R, int C, int N>
+void bsr_matmat_pass2_fixed(const I n_brow,  const I n_bcol, 
+      	                    const I Ap[],    const I Aj[],    const T Ax[],
+      	                    const I Bp[],    const I Bj[],    const T Bx[],
+      	                          I Cp[],          I Cj[],          T Cx[])
+{
+    const I RC = R*C;
+    const I RN = R*N;
+    const I NC = N*C;
+    const I SIZE = RC*Cp[n_brow];
+
+    for(I i = 0; i < SIZE; i++){
+        Cx[i] = 0;
+    }
+ 
+    std::vector<I>  next(n_bcol,-1);
+    std::vector<T*> mats(n_bcol);
+
+    
+    I nnz = 0;
+
+    Cp[0] = 0;
+
+    for(I i = 0; i < n_brow; i++){
+        I head   = -2;
+        I length =  0;
+
+        I jj_start = Ap[i];
+        I jj_end   = Ap[i+1];
+        for(I jj = jj_start; jj < jj_end; jj++){
+            I j = Aj[jj];
+
+            I kk_start = Bp[j];
+            I kk_end   = Bp[j+1];
+            for(I kk = kk_start; kk < kk_end; kk++){
+                I k = Bj[kk];
+
+                if(next[k] == -1){
+                    next[k] = head;                        
+                    head = k;
+                    Cj[nnz] = k;
+                    mats[k] = Cx + RC*nnz;
+                    nnz++;
+                    length++;
+                }
+
+                const T * A = Ax + jj*RN;
+                const T * B = Bx + kk*NC;
+                T * result = mats[k];
+                matmat<R,C,N>(A,B,result);
+            }
+        }         
+
+        for(I jj = 0; jj < length; jj++){
+            I temp = head;                
+            head = next[head];
+            next[temp] = -1; //clear arrays
+        }
+
+    }
+    
+}
+
+#define F(X,Y,Z) bsr_matmat_pass2_fixed<I,T,X,Y,Z>
+
 template <class I, class T>
 void bsr_matmat_pass2(const I n_brow,  const I n_bcol, 
                       const I R,       const I C,       const I N,
@@ -469,22 +537,55 @@
       	              const I Bp[],    const I Bj[],    const T Bx[],
       	                    I Cp[],          I Cj[],          T Cx[])
 {
+    assert(R > 0 && C > 0 && N > 0);
+
+#ifdef TESTING
+    void (*dispatch[4][4][4])(I,I,const I*,const I*,const T*,
+                                  const I*,const I*,const T*,
+                                        I*,      I*,      T*) = \
+    {
+        { { F(1,1,1), F(1,1,2), F(1,1,3), F(1,1,4) },
+          { F(1,2,1), F(1,2,2), F(1,2,3), F(1,2,4) },
+          { F(1,3,1), F(1,3,2), F(1,3,3), F(1,3,4) },
+          { F(1,4,1), F(1,4,2), F(1,4,3), F(1,4,4) },
+        },
+        { { F(2,1,1), F(2,1,2), F(2,1,3), F(2,1,4) },
+          { F(2,2,1), F(2,2,2), F(2,2,3), F(2,2,4) },
+          { F(2,3,1), F(2,3,2), F(2,3,3), F(2,3,4) },
+          { F(2,4,1), F(2,4,2), F(2,4,3), F(2,4,4) },
+        },
+        { { F(3,1,1), F(3,1,2), F(3,1,3), F(3,1,4) },
+          { F(3,2,1), F(3,2,2), F(3,2,3), F(3,2,4) },
+          { F(3,3,1), F(3,3,2), F(3,3,3), F(3,3,4) },
+          { F(3,4,1), F(3,4,2), F(3,4,3), F(3,4,4) },
+        },
+        { { F(4,1,1), F(4,1,2), F(4,1,3), F(4,1,4) },
+          { F(4,2,1), F(4,2,2), F(4,2,3), F(4,2,4) },
+          { F(4,3,1), F(4,3,2), F(4,3,3), F(4,3,4) },
+          { F(4,4,1), F(4,4,2), F(4,4,3), F(4,4,4) },
+        }
+    };
+    
+    if (R <= 4 && C <= 4 && N <= 4){
+        dispatch[R-1][N-1][C-1](n_brow,n_bcol,Ap,Aj,Ax,Bp,Bj,Bx,Cp,Cj,Cx);
+        return;
+    }
+#endif
+
     const I RC = R*C;
     const I RN = R*N;
     const I NC = N*C;
     const I SIZE = RC*Cp[n_brow];
 
+
     for(I i = 0; i < SIZE; i++){
         Cx[i] = 0;
     }
-    //std::cout << "n_brow " << n_brow << " Cp[-1] " << Cp[n_brow] << " R " << R << " C " << C << " N " << N << std::endl;
  
     std::vector<I>  next(n_bcol,-1);
     std::vector<T*> mats(n_bcol);
-
     
     I nnz = 0;
-
     Cp[0] = 0;
 
     for(I i = 0; i < n_brow; i++){
@@ -519,34 +620,24 @@
                             result[C*r + c] += A[N*r + n] * B[C*n + c];
 
                         }
-                        //std::cout << "result[" << r << "," << c << "] = " << result[C*r + c] << std::endl;
                     }
                 }
             }
         }         
 
         for(I jj = 0; jj < length; jj++){
-
-            //if(is_nonzero_block(result,RC)){
-            //    Cj[nnz] = head;
-            //    Cx[nnz] = sums[head];
-            //    nnz++;
-            //}
-
             I temp = head;                
             head = next[head];
-
             next[temp] = -1; //clear arrays
         }
 
-        //Cp[i+1] = nnz;
     }
 }
+#undef F
 
 
 
 
-
 template <class I, class T>
 bool is_nonzero_block(const T block[], const I blocksize){
     for(I i = 0; i < blocksize; i++){
@@ -567,18 +658,9 @@
                          I Cp[],         I Cj[],          T Cx[],
                    const bin_op& op)
 {
-   //Method that works for unsorted indices
-   // assert( csr_has_sorted_indices(n_brow,Ap,Aj) );
-   // assert( csr_has_sorted_indices(n_brow,Bp,Bj) );
+    const I RC = R*C;
+    T * result = Cx;
 
-    //if (R == 3 && C == 3){
-    //    bsr_binop_bsr_fixed<I,T,3,3>(n_brow,n_bcol,Ap,Aj,Ax,Bp,Bj,Bx,Cp,Cj,Cx,op);
-    //    return;
-    //}
-
-    const I RC = R*C;
-    T result[8*8];
-    //T zeros[8*8];
     Cp[0] = 0;
     I nnz = 0;
 
@@ -600,9 +682,7 @@
 
                 if( is_nonzero_block(result,RC) ){
                     Cj[nnz] = A_j;
-                    for(I n = 0; n < RC; n++){
-                        Cx[RC*nnz + n] = result[n];
-                    }
+                    result += RC;
                     nnz++;
                 }
 
@@ -616,9 +696,7 @@
 
                 if(is_nonzero_block(result,RC)){
                     Cj[nnz] = A_j;
-                    for(I n = 0; n < RC; n++){
-                        Cx[RC*nnz + n] = result[n];
-                    }
+                    result += RC;
                     nnz++;
                 }
 
@@ -631,9 +709,7 @@
                 }
                 if(is_nonzero_block(result,RC)){
                     Cj[nnz] = B_j;
-                    for(I n = 0; n < RC; n++){
-                        Cx[RC*nnz + n] = result[n];
-                    }
+                    result += RC;
                     nnz++;
                 }
 
@@ -644,15 +720,14 @@
 
         //tail
         while(A_pos < A_end){
+
             for(I n = 0; n < RC; n++){
                 result[n] = op(Ax[RC*A_pos + n],0);
             }
 
             if(is_nonzero_block(result,RC)){
                 Cj[nnz] = A_j;
-                for(I n = 0; n < RC; n++){
-                    Cx[RC*nnz + n] = result[n];
-                }
+                result += RC;
                 nnz++;
             }
 
@@ -663,11 +738,10 @@
             for(I n = 0; n < RC; n++){
                 result[n] = op(0,Bx[RC*B_pos + n]);
             }
+
             if(is_nonzero_block(result,RC)){
                 Cj[nnz] = B_j;
-                for(I n = 0; n < RC; n++){
-                    Cx[RC*nnz + n] = result[n];
-                }
+                result += RC;
                 nnz++;
             }
 
@@ -887,7 +961,8 @@
  *   T    Ax[nnz(A)]  - nonzeros
  *   
  * Note:
- *   Ap,Aj, and Ax will be modified *inplace*
+ *   The column indicies within each row must be in sorted order.
+ *   Ap, Aj, and Ax will be modified *inplace*
  *
  */
 template <class I, class T>
@@ -916,49 +991,47 @@
         }
         Ap[i+1] = nnz;
     }
+}
 
-
-  //method that works on unsorted indices
-//  std::vector<I>  next(n_col,-1);
-//  std::vector<T>  sums(n_col, 0);
-//
-//  I nnz = 0;
-//
-//  I row_start = 0;
-//  I row_end   = 0;
-//  
-//  for(I i = 0; i < n_row; i++){
-//    I head = -2;
-//    
-//    row_start = row_end; //Ap[i] may have been changed
-//    row_end   = Ap[i+1]; //Ap[i+1] is safe
-//    
-//    for(I jj = row_start; jj < row_end; jj++){
-//      I j = Aj[jj];
-//
-//      sums[j] += Ax[jj];
-//      
-//      if(next[j] == -1){
-//	    next[j] = head;                        
-//	    head    = j;
-//      }
-//    }
-//
-//    while(head != -2){
-//        I curr = head; //current column
-//        head   = next[curr];
-//        
-//        if(sums[curr] != 0){
-//            Aj[nnz] = curr;
-//            Ax[nnz] = sums[curr];
-//            nnz++;
-//        }
-//        
-//        next[curr] = -1;
-//        sums[curr] =  0;
-//    }
-//    Ap[i+1] = nnz;
-//  }
+/*
+ * Eliminate zero entries from CSR matrix A
+ *
+ *   
+ * Input Arguments:
+ *   I    n_row       - number of rows in A (and B)
+ *   I    n_col       - number of columns in A (and B)
+ *   I    Ap[n_row+1] - row pointer
+ *   I    Aj[nnz(A)]  - column indices
+ *   T    Ax[nnz(A)]  - nonzeros
+ *   
+ * Note:
+ *   Ap, Aj, and Ax will be modified *inplace*
+ *
+ */
+template <class I, class T>
+void csr_eliminate_zeros(const I n_row,
+                         const I n_col, 
+                               I Ap[], 
+                               I Aj[], 
+                               T Ax[])
+{
+    I nnz = 0;
+    I row_end = 0;
+    for(I i = 0; i < n_row; i++){
+        I jj = row_end;
+        row_end = Ap[i+1];
+        while( jj < row_end ){
+            I j = Aj[jj];
+            T x = Ax[jj];
+            if(x != 0){
+                Aj[nnz] = j;
+                Ax[nnz] = x;
+                nnz++;
+            }
+            jj++;
+        }
+        Ap[i+1] = nnz;
+    }
 }
 
 
@@ -985,8 +1058,6 @@
  * Note: 
  *   Input:  row and column indices *are not* assumed to be ordered
  *           
- *   Output: CSR column indices *will be* in sorted order
- *
  *   Note: duplicate entries are carried over to the CSR represention
  *
  *   Complexity: Linear.  Specifically O(nnz(A) + max(n_row,n_col))
@@ -1162,38 +1233,15 @@
 	                  const T Xx[],
 	                        T Yx[])
 {
-    //TODO make a matvec template
+    for(I i = 0; i < R*n_brow; i++){
+        Yx[i] = 0;
+    }
+
     for(I i = 0; i < n_brow; i++) {
-        T r0 = 0;
-        T r1 = 0;
-        T r2 = 0;
-        T r3 = 0;
-        T r4 = 0;
-        T r5 = 0;
-        T r6 = 0;
-        T r7 = 0;
-
         for(I jj = Ap[i]; jj < Ap[i+1]; jj++) {
             I j = Aj[jj];
-            const T * base = Ax + jj*(R*C);
-            if (R > 0) r0 += dot<C>(base + 0*C, Xx + j*C);
-            if (R > 1) r1 += dot<C>(base + 1*C, Xx + j*C);
-            if (R > 2) r2 += dot<C>(base + 2*C, Xx + j*C);
-            if (R > 3) r3 += dot<C>(base + 3*C, Xx + j*C);
-            if (R > 4) r4 += dot<C>(base + 4*C, Xx + j*C);
-            if (R > 5) r5 += dot<C>(base + 5*C, Xx + j*C);
-            if (R > 6) r6 += dot<C>(base + 6*C, Xx + j*C);
-            if (R > 7) r7 += dot<C>(base + 7*C, Xx + j*C);
+            matvec<R,C,1,1>(Ax + jj*R*C, Xx + j*C, Yx + i*R);
         }
-
-        if (R > 0) Yx[R*i+0] = r0; 
-        if (R > 1) Yx[R*i+1] = r1;
-        if (R > 2) Yx[R*i+2] = r2;
-        if (R > 3) Yx[R*i+3] = r3;
-        if (R > 4) Yx[R*i+4] = r4;
-        if (R > 5) Yx[R*i+5] = r5;
-        if (R > 6) Yx[R*i+6] = r6;
-        if (R > 7) Yx[R*i+7] = r7;
     }
 }
 
@@ -1244,7 +1292,7 @@
 
 
     //otherwise use general method
-    for(I i = 0; i < n_brow; i++){
+    for(I i = 0; i < R*n_brow; i++){
         Yx[i] = 0;
     }
 

Modified: branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.i
===================================================================
--- branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.i	2008-01-05 07:04:22 UTC (rev 3785)
+++ branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.i	2008-01-05 08:16:25 UTC (rev 3786)
@@ -259,6 +259,11 @@
 
 
 /*
+ * Remove zeros
+ */
+INSTANTIATE_ALL(csr_eliminate_zeros)
+
+/*
  * Sum duplicate entries.
  */
 INSTANTIATE_ALL(csr_sum_duplicates)

Modified: branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.py
===================================================================
--- branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.py	2008-01-05 07:04:22 UTC (rev 3785)
+++ branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools.py	2008-01-05 08:16:25 UTC (rev 3786)
@@ -1055,6 +1055,25 @@
     """
   return _sparsetools.csr_sort_indices(*args)
 
+def csr_eliminate_zeros(*args):
+  """
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, signed char Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, unsigned char Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, short Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, unsigned short Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, int Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, unsigned int Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, long long Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, unsigned long long Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, float Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, double Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, long double Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, npy_cfloat_wrapper Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, npy_cdouble_wrapper Ax)
+    csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, npy_clongdouble_wrapper Ax)
+    """
+  return _sparsetools.csr_eliminate_zeros(*args)
+
 def csr_sum_duplicates(*args):
   """
     csr_sum_duplicates(int n_row, int n_col, int Ap, int Aj, signed char Ax)

Modified: branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools_wrap.cxx
===================================================================
--- branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools_wrap.cxx	2008-01-05 07:04:22 UTC (rev 3785)
+++ branches/testing_cleanup/scipy/sparse/sparsetools/sparsetools_wrap.cxx	2008-01-05 08:16:25 UTC (rev 3786)
@@ -77001,6 +77001,1213 @@
 }
 
 
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  signed char *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_BYTE);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (signed char*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,signed char >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  unsigned char *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_UBYTE);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (unsigned char*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,unsigned char >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  short *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_SHORT);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (short*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,short >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_4(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  unsigned short *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_USHORT);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (unsigned short*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,unsigned short >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_5(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  int *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_INT);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (int*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,int >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_6(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  unsigned int *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_UINT);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (unsigned int*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,unsigned int >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_7(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  long long *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_LONGLONG);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (long long*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,long long >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_8(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  unsigned long long *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_ULONGLONG);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (unsigned long long*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,unsigned long long >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_9(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  float *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_FLOAT);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (float*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,float >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_10(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  double *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_DOUBLE);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (double*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,double >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_11(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  long double *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_LONGDOUBLE);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (long double*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,long double >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_12(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  npy_cfloat_wrapper *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_CFLOAT);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (npy_cfloat_wrapper*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,npy_cfloat_wrapper >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_13(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  npy_cdouble_wrapper *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_CDOUBLE);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (npy_cdouble_wrapper*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,npy_cdouble_wrapper >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros__SWIG_14(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int *arg3 ;
+  int *arg4 ;
+  npy_clongdouble_wrapper *arg5 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyArrayObject *temp3 = NULL ;
+  PyArrayObject *temp4 = NULL ;
+  PyArrayObject *temp5 = NULL ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:csr_eliminate_zeros",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_eliminate_zeros" "', argument " "1"" of type '" "int""'");
+  } 
+  arg1 = static_cast< int >(val1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "csr_eliminate_zeros" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  {
+    temp3 = obj_to_array_no_conversion(obj2,PyArray_INT);
+    if (!temp3  || !require_contiguous(temp3) || !require_native(temp3)) SWIG_fail;
+    arg3 = (int*) array_data(temp3);
+  }
+  {
+    temp4 = obj_to_array_no_conversion(obj3,PyArray_INT);
+    if (!temp4  || !require_contiguous(temp4) || !require_native(temp4)) SWIG_fail;
+    arg4 = (int*) array_data(temp4);
+  }
+  {
+    temp5 = obj_to_array_no_conversion(obj4,PyArray_CLONGDOUBLE);
+    if (!temp5  || !require_contiguous(temp5) || !require_native(temp5)) SWIG_fail;
+    arg5 = (npy_clongdouble_wrapper*) array_data(temp5);
+  }
+  csr_eliminate_zeros<int,npy_clongdouble_wrapper >(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_csr_eliminate_zeros(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[6];
+  int ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = (int)PyObject_Length(args);
+  for (ii = 0; (ii < argc) && (ii < 5); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_BYTE)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_1(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_UBYTE)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_2(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_SHORT)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_3(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_USHORT)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_4(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_INT)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_5(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_UINT)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_6(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_LONGLONG)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_7(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_ULONGLONG)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_8(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_FLOAT)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_9(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_DOUBLE)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_10(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_LONGDOUBLE)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_11(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_CFLOAT)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_12(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_CDOUBLE)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_13(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_int(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          _v = (is_array(argv[2]) && PyArray_CanCastSafely(PyArray_TYPE(argv[2]),PyArray_INT)) ? 1 : 0;
+        }
+        if (_v) {
+          {
+            _v = (is_array(argv[3]) && PyArray_CanCastSafely(PyArray_TYPE(argv[3]),PyArray_INT)) ? 1 : 0;
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_CLONGDOUBLE)) ? 1 : 0;
+            }
+            if (_v) {
+              return _wrap_csr_eliminate_zeros__SWIG_14(self, args);
+            }
+          }
+        }
+      }
+    }
+  }
+  
+fail:
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'csr_eliminate_zeros'.\n  Possible C/C++ prototypes are:\n""    csr_eliminate_zeros<(int,signed char)>(int const,int const,int [],int [],signed char [])\n""    csr_eliminate_zeros<(int,unsigned char)>(int const,int const,int [],int [],unsigned char [])\n""    csr_eliminate_zeros<(int,short)>(int const,int const,int [],int [],short [])\n""    csr_eliminate_zeros<(int,unsigned short)>(int const,int const,int [],int [],unsigned short [])\n""    csr_eliminate_zeros<(int,int)>(int const,int const,int [],int [],int [])\n""    csr_eliminate_zeros<(int,unsigned int)>(int const,int const,int [],int [],unsigned int [])\n""    csr_eliminate_zeros<(int,long long)>(int const,int const,int [],int [],long long [])\n""    csr_eliminate_zeros<(int,unsigned long long)>(int const,int const,int [],int [],unsigned long long [])\n""    csr_eliminate_zeros<(int,float)>(int const,int const,int [],int [],float [])\n""    csr_eliminate_zeros<(int,double)>(int const,int const,int [],int [],double [])\n""    csr_eliminate_zeros<(int,long double)>(int const,int const,int [],int [],long double [])\n""    csr_eliminate_zeros<(int,npy_cfloat_wrapper)>(int const,int const,int [],int [],npy_cfloat_wrapper [])\n""    csr_eliminate_zeros<(int,npy_cdouble_wrapper)>(int const,int const,int [],int [],npy_cdouble_wrapper [])\n""    csr_eliminate_zeros<(int,npy_clongdouble_wrapper)>(int const,int const,int [],int [],npy_clongdouble_wrapper [])\n");
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_csr_sum_duplicates__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   int arg1 ;
@@ -82221,6 +83428,22 @@
 		"csr_sort_indices(int n_row, int Ap, int Aj, npy_cdouble_wrapper Ax)\n"
 		"csr_sort_indices(int n_row, int Ap, int Aj, npy_clongdouble_wrapper Ax)\n"
 		""},
+	 { (char *)"csr_eliminate_zeros", _wrap_csr_eliminate_zeros, METH_VARARGS, (char *)"\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, signed char Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, unsigned char Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, short Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, unsigned short Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, int Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, unsigned int Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, long long Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, unsigned long long Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, float Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, double Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, long double Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, npy_cfloat_wrapper Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, npy_cdouble_wrapper Ax)\n"
+		"csr_eliminate_zeros(int n_row, int n_col, int Ap, int Aj, npy_clongdouble_wrapper Ax)\n"
+		""},
 	 { (char *)"csr_sum_duplicates", _wrap_csr_sum_duplicates, METH_VARARGS, (char *)"\n"
 		"csr_sum_duplicates(int n_row, int n_col, int Ap, int Aj, signed char Ax)\n"
 		"csr_sum_duplicates(int n_row, int n_col, int Ap, int Aj, unsigned char Ax)\n"

Modified: branches/testing_cleanup/scipy/sparse/tests/test_base.py
===================================================================
--- branches/testing_cleanup/scipy/sparse/tests/test_base.py	2008-01-05 07:04:22 UTC (rev 3785)
+++ branches/testing_cleanup/scipy/sparse/tests/test_base.py	2008-01-05 08:16:25 UTC (rev 3786)
@@ -15,7 +15,7 @@
 
 import numpy
 from numpy import arange, zeros, array, dot, ones, matrix, asmatrix, \
-        asarray, vstack, ndarray, kron
+        asarray, vstack, ndarray, kron, transpose
 
 import random
 from scipy.testing import *
@@ -812,6 +812,17 @@
         assert_array_equal(asp.indices,[1, 2, 7, 4, 5])
         assert_array_equal(asp.todense(),bsp.todense())
 
+    def test_eliminate_zeros(self):
+        data    = array( [1, 0, 0, 0, 2, 0, 3, 0] )
+        indices = array( [1, 2, 3, 4, 5, 6, 7, 8] )
+        indptr  = array( [0, 3, 8] )
+        asp = csr_matrix( (data, indices, indptr), shape=(2,10) )
+        bsp = asp.copy()
+        asp.eliminate_zeros( )
+        assert_array_equal(asp.nnz, 3)
+        assert_array_equal(asp.data,[1, 2, 3])
+        assert_array_equal(asp.todense(),bsp.todense())
+
     def test_get_submatrix(self):
         a = csr_matrix( array([[1,2,3,4],[1,2,3,5],[0,2,0,1]]) )
         i0 = slice( 0, 2 )
@@ -875,6 +886,17 @@
         csc = csc_matrix((data, indices, indptr))
         assert_array_equal(csc.shape,(6,3))
     
+    def test_eliminate_zeros(self):
+        data    = array( [1, 0, 0, 0, 2, 0, 3, 0] )
+        indices = array( [1, 2, 3, 4, 5, 6, 7, 8] )
+        indptr  = array( [0, 3, 8] )
+        asp = csc_matrix( (data, indices, indptr), shape=(10,2) )
+        bsp = asp.copy()
+        asp.eliminate_zeros( )
+        assert_array_equal(asp.nnz, 3)
+        assert_array_equal(asp.data,[1, 2, 3])
+        assert_array_equal(asp.todense(),bsp.todense())
+    
     def test_sort_indices(self):
         data = arange( 5 )
         row = array( [7, 2, 1, 5, 4] )
@@ -1260,6 +1282,16 @@
         A = kron( [[1,0,2,0],[0,1,0,0],[0,0,0,0]], [[0,1,2],[3,0,5]] )
         assert_equal(bsr_matrix(A,blocksize=(2,3)).todense(),A)
         
+    def check_eliminate_zeros(self):
+        data = kron([1, 0, 0, 0, 2, 0, 3, 0], [[1,1],[1,1]]).T
+        data = data.reshape(-1,2,2)
+        indices = array( [1, 2, 3, 4, 5, 6, 7, 8] )
+        indptr  = array( [0, 3, 8] )
+        asp = bsr_matrix( (data, indices, indptr), shape=(4,20) )
+        bsp = asp.copy()
+        asp.eliminate_zeros()
+        assert_array_equal(asp.nnz, 3*4)
+        assert_array_equal(asp.todense(),bsp.todense())
 
                 
 if __name__ == "__main__":



More information about the Scipy-svn mailing list