[Scipy-svn] r3697 - in trunk/scipy: sandbox/multigrid sparse sparse/sparsetools sparse/tests

scipy-svn@scip... scipy-svn@scip...
Sun Dec 23 11:43:22 CST 2007


Author: wnbell
Date: 2007-12-23 11:42:51 -0600 (Sun, 23 Dec 2007)
New Revision: 3697

Modified:
   trunk/scipy/sandbox/multigrid/utils.py
   trunk/scipy/sparse/block.py
   trunk/scipy/sparse/compressed.py
   trunk/scipy/sparse/construct.py
   trunk/scipy/sparse/coo.py
   trunk/scipy/sparse/sparsetools/fixed_size.h
   trunk/scipy/sparse/sparsetools/sparsetools.h
   trunk/scipy/sparse/sparsetools/sparsetools.i
   trunk/scipy/sparse/sparsetools/sparsetools.py
   trunk/scipy/sparse/sparsetools/sparsetools_wrap.cxx
   trunk/scipy/sparse/spfuncs.py
   trunk/scipy/sparse/tests/test_sparse.py
Log:
added bsr arithmetic
added simple block size determination


Modified: trunk/scipy/sandbox/multigrid/utils.py
===================================================================
--- trunk/scipy/sandbox/multigrid/utils.py	2007-12-22 17:20:01 UTC (rev 3696)
+++ trunk/scipy/sandbox/multigrid/utils.py	2007-12-23 17:42:51 UTC (rev 3697)
@@ -98,8 +98,6 @@
                     H[1,0] = H[0,1]
                     beta = H[2,1]
        
-        #estimates.append( max( [norm(x) for x in eigvals(H[:j+1,:j+1])] ) )
-
     return norm(H[:j+1,:j+1],2)
 
 

Modified: trunk/scipy/sparse/block.py
===================================================================
--- trunk/scipy/sparse/block.py	2007-12-22 17:20:01 UTC (rev 3696)
+++ trunk/scipy/sparse/block.py	2007-12-23 17:42:51 UTC (rev 3697)
@@ -1,12 +1,15 @@
 """base class for block sparse formats"""
 
 from numpy import zeros, intc, array, asarray, arange, diff, tile, rank, \
-        prod
+        prod, ravel
 
 from data import _data_matrix
 from base import isspmatrix, _formats
-from sputils import isshape, getdtype, to_native
+from sputils import isshape, getdtype, to_native, isscalarlike, isdense
+import sparsetools
 
+#TODO refactor w/ compressed.py
+
 class _block_matrix(_data_matrix):
     def __init__(self, arg1, shape=None, dtype=None, copy=False, blocksize=None):
         _data_matrix.__init__(self)
@@ -109,9 +112,11 @@
                     % self.indices.dtype.name )
 
         # only support 32-bit ints for now
-        self.indptr  = self.indptr.astype(intc)
-        self.indices = self.indices.astype(intc)
-        self.data    = to_native(self.data)
+        if self.indptr.dtype != intc:
+            self.indptr  = self.indptr.astype(intc)
+        if self.indices.dtype != intc:
+            self.indices = self.indices.astype(intc)
+        self.data = to_native(self.data)
 
         # check array shapes
         if (rank(self.indices) != 1) or (rank(self.indptr) != 1):
@@ -168,6 +173,109 @@
                ( self.shape + (self.dtype.type, nnz) + self.blocksize + \
                  (_formats[format][1],) )
 
+
+    def __add__(self,other):
+        # First check if argument is a scalar
+        if isscalarlike(other):
+            # Now we would add this scalar to every element.
+            raise NotImplementedError, 'adding a scalar to a CSC or CSR ' \
+                  'matrix is not supported'
+        elif isspmatrix(other):
+            if (other.shape != self.shape):
+                raise ValueError, "inconsistent shapes"
+            
+            return self._binopt(other,'_plus_')
+        elif isdense(other):
+            # Convert this matrix to a dense matrix and add them
+            return self.todense() + other
+        else:
+            raise NotImplementedError
+
+    def __radd__(self,other):
+        return self.__add__(other)
+
+    def __sub__(self,other):
+        # First check if argument is a scalar
+        if isscalarlike(other):
+            # Now we would add this scalar to every element.
+            raise NotImplementedError, 'adding a scalar to a sparse ' \
+                  'matrix is not supported'
+        elif isspmatrix(other):
+            if (other.shape != self.shape):
+                raise ValueError, "inconsistent shapes"
+
+            return self._binopt(other,'_minus_')
+        elif isdense(other):
+            # Convert this matrix to a dense matrix and subtract them
+            return self.todense() - other
+        else:
+            raise NotImplementedError
+
+    def __rsub__(self,other):  # other - self
+        #note: this can't be replaced by other + (-self) for unsigned types
+        if isscalarlike(other):
+            # Now we would add this scalar to every element.
+            raise NotImplementedError, 'adding a scalar to a sparse ' \
+                  'matrix is not supported'
+        elif isdense(other):
+            # Convert this matrix to a dense matrix and subtract them
+            return other - self.todense()
+        else:
+            raise NotImplementedError
+
+
+    def __mul__(self, other): # self * other
+        """ Scalar, vector, or matrix multiplication
+        """
+        if isscalarlike(other):
+            return self._with_data(self.data * other)
+        else:
+            return self.dot(other)
+
+
+    def __rmul__(self, other): # other * self
+        if isscalarlike(other):
+            return self.__mul__(other)
+        else:
+            # Don't use asarray unless we have to
+            try:
+                tr = other.transpose()
+            except AttributeError:
+                tr = asarray(other).transpose()
+            return self.transpose().dot(tr).transpose()
+
+
+    def __truediv__(self,other):
+        if isscalarlike(other):
+            return self * (1./other)
+        elif isspmatrix(other):
+            if (other.shape != self.shape):
+                raise ValueError, "inconsistent shapes"
+            
+            return self._binopt(other,'_eldiv_')
+        else:
+            raise NotImplementedError
+
+    
+    def multiply(self, other):
+        """Point-wise multiplication by another matrix
+        """
+        if (other.shape != self.shape):
+            raise ValueError, "inconsistent shapes"
+
+        if isdense(other):
+            return multiply(self.todense(),other)
+        else:
+            other = self.__class__(other)
+            return self._binopt(other,'_elmul_')
+
+
+
+
+
+
+
+
     def _set_self(self, other, copy=False):
         """take the member variables of other and assign them to self"""
 
@@ -219,6 +327,8 @@
     def sort_indices(self):
         """Sort the indices of this matrix *in place*
         """
+        from csr import csr_matrix
+
         X,Y = self.blocksize
         M,N = self.shape
 
@@ -248,7 +358,26 @@
         self.data    = self.data[:self.nnz]
         self.indices = self.indices[:self.nnz]
 
+    # utility functions
+    def _binopt(self, other, op, in_shape=None, out_shape=None):
+        """apply the binary operation fn to two sparse matrices"""
+        other = self.__class__(other,blocksize=self.blocksize)
 
+        if in_shape is None:
+            in_shape = self.shape
+        if out_shape is None:
+            out_shape = self.shape
+
+        # e.g. csr_plus_csr, cscmucsc, etc.
+        fn = getattr(sparsetools, self.format + op + self.format)
+
+        R,C = self.blocksize 
+        indptr, ind, data = fn(in_shape[0]/R, in_shape[1]/C, R, C, \
+                               self.indptr, self.indices, ravel(self.data),
+                               other.indptr, other.indices, ravel(other.data))
+        data = data.reshape(-1,R,C)
+        return self.__class__((data, ind, indptr), shape=out_shape)
+
     # needed by _data_matrix
     def _with_data(self,data,copy=True):
         """Returns a matrix with the same sparsity structure as self,

Modified: trunk/scipy/sparse/compressed.py
===================================================================
--- trunk/scipy/sparse/compressed.py	2007-12-22 17:20:01 UTC (rev 3696)
+++ trunk/scipy/sparse/compressed.py	2007-12-23 17:42:51 UTC (rev 3697)
@@ -94,7 +94,8 @@
                 else:
                     self.shape = self._swap((major_dim,minor_dim))
 
-        self.check_format(full_check=False)
+        #self.check_format(full_check=False)
+        self.check_format(full_check=True)
 
     def getnnz(self):
         return self.indptr[-1]
@@ -137,9 +138,11 @@
                     % self.indices.dtype.name )
 
         # only support 32-bit ints for now
-        self.indptr  = self.indptr.astype(intc)
-        self.indices = self.indices.astype(intc)
-        self.data    = to_native(self.data)
+        if self.indptr.dtype != intc:
+            self.indptr  = self.indptr.astype(intc)
+        if self.indices.dtype != intc:
+            self.indices = self.indices.astype(intc)
+        self.data = to_native(self.data)
 
         # check array shapes
         if (rank(self.data) != 1) or (rank(self.indices) != 1) or \
@@ -203,7 +206,7 @@
         # First check if argument is a scalar
         if isscalarlike(other):
             # Now we would add this scalar to every element.
-            raise NotImplementedError, 'adding a scalar to a CSC or CSR ' \
+            raise NotImplementedError, 'adding a scalar to a sparse ' \
                   'matrix is not supported'
         elif isspmatrix(other):
             if (other.shape != self.shape):
@@ -220,7 +223,7 @@
         #note: this can't be replaced by other + (-self) for unsigned types
         if isscalarlike(other):
             # Now we would add this scalar to every element.
-            raise NotImplementedError, 'adding a scalar to a CSC or CSR ' \
+            raise NotImplementedError, 'adding a scalar to a sparse ' \
                   'matrix is not supported'
         elif isdense(other):
             # Convert this matrix to a dense matrix and subtract them
@@ -446,7 +449,7 @@
         return M
 
     
-    # methods that modify the internal data structure
+    # methods that examine or modify the internal data structure
     def sum_duplicates(self):
         """Eliminate duplicate matrix entries by adding them together
 
@@ -459,6 +462,13 @@
 
         self.prune() #nnz may have changed
 
+    def has_sorted_indices(self):
+        """Determine whether the matrix has sorted indices
+        """
+        fn = sparsetools.has_sorted_indices
+        M,N = self._swap(self.shape)
+        return fn( M, N, self.indptr, self.indices)
+
     def sorted_indices(self):
         """Return a copy of this matrix with sorted indices
         """
@@ -473,6 +483,10 @@
     def sort_indices(self):
         """Sort the indices of this matrix *in place*
         """
+        if self.has_sorted_indices(): 
+            #see if sorting can be avoided
+            return
+
         fn = getattr(sparsetools,self.format + '_sort_indices')
 
         M,N = self.shape
@@ -529,6 +543,10 @@
         if out_shape is None:
             out_shape = self.shape
 
+        #only necessary for sorted binopt method
+        #self.sort_indices()
+        #other.sort_indices()
+
         # e.g. csr_plus_csr, cscmucsc, etc.
         fn = getattr(sparsetools, self.format + op + self.format)
 

Modified: trunk/scipy/sparse/construct.py
===================================================================
--- trunk/scipy/sparse/construct.py	2007-12-22 17:20:01 UTC (rev 3696)
+++ trunk/scipy/sparse/construct.py	2007-12-23 17:42:51 UTC (rev 3697)
@@ -95,10 +95,8 @@
             [ 15.,  20.,   0.,   0.]])
 
     """
-    if not isspmatrix(A) and isspmatrix(B):
-        raise ValueError,'expected sparse matrix'
-
-    A,B = A.tocoo(),B.tocoo()
+    #TODO optimize for small dense B and CSR A
+    A,B = coo_matrix(A),coo_matrix(B)
     output_shape = (A.shape[0]*B.shape[0],A.shape[1]*B.shape[1])
 
     if A.nnz == 0 or B.nnz == 0:

Modified: trunk/scipy/sparse/coo.py
===================================================================
--- trunk/scipy/sparse/coo.py	2007-12-22 17:20:01 UTC (rev 3696)
+++ trunk/scipy/sparse/coo.py	2007-12-23 17:42:51 UTC (rev 3697)
@@ -13,6 +13,7 @@
 from base import isspmatrix
 from data import _data_matrix
 from sputils import upcast, to_native, isshape, getdtype
+from spfuncs import estimate_blocksize
 
 class coo_matrix(_data_matrix):
     """A sparse matrix in COOrdinate format.
@@ -175,8 +176,10 @@
                     % self.col.dtype.name )
        
         # only support 32-bit ints for now
-        self.row  = self.row.astype(intc)
-        self.col  = self.col.astype(intc)
+        if self.row.dtype != intc:
+            self.row  = self.row.astype(intc)
+        if self.col.dtype != intc:
+            self.col  = self.col.astype(intc)
         self.data = to_native(self.data)
 
         if nnz > 0:
@@ -305,7 +308,9 @@
         if self.nnz == 0:
             return bsr_matrix(self.shape,blocksize=blocksize,dtype=self.dtype)
 
-        if blocksize in [None, (1,1)]:
+        if blocksize is None:
+            blocksize = estimate_blocksize(self)
+        elif blocksize in (1,1):
             return self.tocsr().tobsr(blocksize)
 
         M,N = self.shape

Modified: trunk/scipy/sparse/sparsetools/fixed_size.h
===================================================================
--- trunk/scipy/sparse/sparsetools/fixed_size.h	2007-12-22 17:20:01 UTC (rev 3696)
+++ trunk/scipy/sparse/sparsetools/fixed_size.h	2007-12-23 17:42:51 UTC (rev 3697)
@@ -6,33 +6,72 @@
  * 
  */
 
+
+
+/*
+ *  Dot Product
+ * 
+ */
 template<int N, class T>
-class Dot
+class _dot
 {
     public:
-        inline T operator()(const T * lhs, const T * rhs)
+        inline T operator()(const T * V1, const T * V2)
         {
-            Dot<N-1,T> d;
-            return (*lhs * *rhs) + d(++lhs, ++rhs);
+            _dot<N-1,T> d;
+            return (*V1) * (*V2) + d(++V1, ++V2);
         }
 };
-
 template<class T>
-class Dot<1,T>
+class _dot<1,T>
 {
     public:
-        inline T operator()(const T * lhs, const T * rhs)
+        inline T operator()(const T * V1, const T * V2)
         {
-            return *lhs * *rhs;
+            return (*V1) * (*V2);
         }
 };
 
 template<int N, class T>
-inline T dot(const T * lhs, const T * rhs)
+inline T dot(const T * V1, const T * V2)
 {
-    Dot<N,T> d;
-    return d(lhs, rhs);
+    _dot<N,T> d;
+    return d(V1, V2);
 }
 
 
+
+
+
+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)
+        {
+            *V3 = op( *V1, *V2 );
+            _vec_binop_vec<N-1,T,bin_op> d;
+            d(V1 + 1, V2 + 1, V3 + 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)
+        {
+            *V3 = op( *V1, *V2 );
+        }
+};
+
+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)
+{
+    _vec_binop_vec<N,T,bin_op> d;
+    d(V1,V2,V3,op);
+}
+
+
+
+
 #endif

Modified: trunk/scipy/sparse/sparsetools/sparsetools.h
===================================================================
--- trunk/scipy/sparse/sparsetools/sparsetools.h	2007-12-22 17:20:01 UTC (rev 3696)
+++ trunk/scipy/sparse/sparsetools/sparsetools.h	2007-12-23 17:42:51 UTC (rev 3697)
@@ -4,17 +4,10 @@
 
 /*
  * sparsetools.h 
- *   A collection of CSR/CSC/COO matrix conversion and arithmetic functions.
+ *   A collection of CSR/CSC/COO/BSR matrix conversion and arithmetic functions.
  *  
- * Authors:  
- *    Nathan Bell
+ * Original code by Nathan Bell
  *
- * Revisions:
- *    07/14/2007 - added csr_sum_duplicates
- *    07/12/2007 - added templated function for binary arithmetic ops
- *    01/09/2007 - index type is now templated
- *    01/06/2007 - initial inclusion into SciPy
- *
  */
 
 
@@ -23,11 +16,8 @@
 #include <vector>
 #include <algorithm>
 #include <functional>
-
-
 #include "fixed_size.h"
 
-
 /*
  * Extract main diagonal of CSR matrix A
  *
@@ -96,14 +86,114 @@
                const I Ap[], 
                      I Bi[])
 {
+    for(I i = 0; i < n_row; i++){
+        for(I jj = Ap[i]; jj < Ap[i+1]; jj++){
+            Bi[jj] = i;
+        }
+    }
+}
+
+/*
+ * Compute the number of occupied RxC blocks in a matrix
+ *
+ * Input Arguments:
+ *   I  n_row         - number of rows in A
+ *   I  R             - row blocksize
+ *   I  C             - column blocksize
+ *   I  Ap[n_row+1]   - row pointer
+ *   I  Aj[nnz(A)]    - column indices
+ *
+ * Output Arguments:
+ *   I  num_blocks    - number of blocks
+ *
+ * Note: 
+ *   Complexity: Linear.
+ * 
+ */
+template <class I>
+I csr_count_blocks(const I n_row,
+                   const I n_col,
+                   const I R,
+                   const I C,
+                   const I Ap[], 
+                   const I Aj[])
+{
+    std::vector<I> mask(n_col/C + 1,-1);
+    I n_blks = 0;
+    for(I i = 0; i < n_row; i++){
+        I bi = i/R;
+        for(I jj = Ap[i]; jj < Ap[i+1]; jj++){
+            I bj = Aj[jj]/C;
+            if(mask[bj] != bi){
+                mask[bj] = bi;
+                n_blks++;
+            }
+        }
+    }
+    return n_blks;
+}
+
+
+
+/*
+ * Sort CSR column indices inplace
+ *
+ * Input Arguments:
+ *   I  n_row           - number of rows in A
+ *   I  n_col           - number of columns in A
+ *   I  Ap[n_row+1]     - row pointer
+ *   I  Aj[nnz(A)]      - column indices
+ *   T  Ax[nnz(A)]      - nonzeros 
+ *
+ */
+template <class I>
+bool has_sorted_indices(const I n_row, 
+                        const I n_col,
+                        const I Ap[],
+                        const I Aj[])
+{
   for(I i = 0; i < n_row; i++){
-    for(I jj = Ap[i]; jj < Ap[i+1]; jj++){
-      Bi[jj] = i;
-    }
+      for(I jj = Ap[i]; jj < Ap[i+1] - 1; jj++){
+          if(Aj[jj] > Aj[jj+1]){
+              return false;
+          }
+      }
   }
+  return true;
 }
+template< class T1, class T2 >
+bool kv_pair_less(const std::pair<T1,T2>& x, const std::pair<T1,T2>& y){
+    return x.first < y.first;
+}
 
+template<class I, class T>
+void csr_sort_indices(const I n_row,
+                      const I n_col,
+                      const I Ap[], 
+                            I Aj[], 
+                            T Ax[])
+{
+    std::vector< std::pair<I,T> > temp;
 
+    for(I i = 0; i < n_row; i++){
+        I row_start = Ap[i];
+        I row_end   = Ap[i+1];
+
+        temp.clear();
+
+        for(I jj = row_start; jj < row_end; jj++){
+            temp.push_back(std::make_pair(Aj[jj],Ax[jj]));
+        }
+
+        std::sort(temp.begin(),temp.end(),kv_pair_less<I,T>);
+
+        for(I jj = row_start, n = 0; jj < row_end; jj++, n++){
+            Aj[jj] = temp[n].first;
+            Ax[jj] = temp[n].second;
+        }
+    }    
+}
+
 /*
  * Compute B = A for CSR matrix A, CSC matrix B
  *
@@ -144,40 +234,40 @@
 	                 I Bi[],
 	                 T Bx[])
 {  
-  const I nnz = Ap[n_row];
- 
-  //compute number of non-zero entries per column of A 
-  std::fill(Bp, Bp + n_col, 0);
+    const I nnz = Ap[n_row];
 
-  for (I n = 0; n < nnz; n++){            
-    Bp[Aj[n]]++;
-  }
-        
-  //cumsum the nnz per column to get Bp[]
-  for(I col = 0, cumsum = 0; col < n_col; col++){     
-    I temp  = Bp[col];
-    Bp[col] = cumsum;
-    cumsum += temp;
-  }
-  Bp[n_col] = nnz; 
-  
-  for(I row = 0; row < n_row; row++){
-    for(I jj = Ap[row]; jj < Ap[row+1]; jj++){
-      I col  = Aj[jj];
-      I dest = Bp[col];
+    //compute number of non-zero entries per column of A 
+    std::fill(Bp, Bp + n_col, 0);
 
-      Bi[dest] = row;
-      Bx[dest] = Ax[jj];
+    for (I n = 0; n < nnz; n++){            
+        Bp[Aj[n]]++;
+    }
 
-      Bp[col]++;
+    //cumsum the nnz per column to get Bp[]
+    for(I col = 0, cumsum = 0; col < n_col; col++){     
+        I temp  = Bp[col];
+        Bp[col] = cumsum;
+        cumsum += temp;
     }
-  }  
+    Bp[n_col] = nnz; 
 
-  for(I col = 0, last = 0; col <= n_col; col++){
-      I temp  = Bp[col];
-      Bp[col] = last;
-      last    = temp;
-  }
+    for(I row = 0; row < n_row; row++){
+        for(I jj = Ap[row]; jj < Ap[row+1]; jj++){
+            I col  = Aj[jj];
+            I dest = Bp[col];
+
+            Bi[dest] = row;
+            Bx[dest] = Ax[jj];
+
+            Bp[col]++;
+        }
+    }  
+
+    for(I col = 0, last = 0; col <= n_col; col++){
+        I temp  = Bp[col];
+        Bp[col] = last;
+        last    = temp;
+    }
 }   
 
 
@@ -240,37 +330,22 @@
                       const I Bj[],
                             I Cp[])
 {
-    std::vector<I> next(n_col,-1);
-
+    std::vector<I> mask(n_col,-1);
     Cp[0] = 0;
 
+    I nnz = 0;
     for(I i = 0; i < n_row; 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++){
+        for(I jj = Ap[i]; jj < Ap[i+1]; 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++){
+            for(I kk = Bp[j]; kk < Bp[j+1]; kk++){
                 I k = Bj[kk];
-                if(next[k] == -1){
-                    next[k] = head;                        
-                    head = k;
-                    length++;
+                if(mask[k] != i){
+                    mask[k] = i;                        
+                    nnz++;
                 }
             }
         }         
-
-        for(I jj = 0; jj < length; jj++){
-            I temp = head;                
-            head = next[head];      
-            next[temp] = -1;
-        }
-        
-        Cp[i+1] = Cp[i] + length;
+        Cp[i+1] = nnz;
     }
 }
 
@@ -299,7 +374,7 @@
     Cp[0] = 0;
 
     for(I i = 0; i < n_row; i++){
-        I head = -2;
+        I head   = -2;
         I length =  0;
 
         I jj_start = Ap[i];
@@ -349,6 +424,129 @@
 
 
 
+template <class I, class T, class bin_op>
+void bsr_binop_bsr(const I n_brow, const I n_bcol, 
+                   const I R,      const I C, 
+                   const I Ap[],   const I Aj[],    const T Ax[],
+                   const I Bp[],   const I Bj[],    const T Bx[],
+                   std::vector<I>* Cp,
+                   std::vector<I>* Cj,
+                   std::vector<T>* Cx,
+                   const bin_op& op)
+{
+    Cp->resize(n_brow + 1, 0);
+
+    const I RC = R*C;
+
+    std::vector<I>  next(n_bcol,-1);
+    std::vector<T> A_row(n_bcol*RC, 0);
+    std::vector<T> B_row(n_bcol*RC, 0);
+
+    for(I i = 0; i < n_brow; i++){
+        I head   = -2;
+        I length =  0;
+
+        //add a row of A to A_row
+        for(I jj = Ap[i]; jj < Ap[i+1]; jj++){
+            I j = Aj[jj];
+
+            for(I n = 0; n < RC; n++)
+                A_row[RC*j + n] += Ax[RC*jj + n];
+
+            if(next[j] == -1){
+                next[j] = head;                        
+                head = j;
+                length++;
+            }
+        }
+
+        //add a row of B to B_row
+        for(I jj = Bp[i]; jj < Bp[i+1]; jj++){
+            I j = Bj[jj];
+
+            for(I n = 0; n < RC; n++)
+                B_row[RC*j + n] += Bx[RC*jj + n];
+
+            if(next[j] == -1){
+                next[j] = head;                        
+                head = j;
+                length++;
+            }
+        }
+
+
+        for(I jj = 0; jj < length; jj++){
+            bool nonzero_block = false;
+            for(I n = 0; n < RC; n++){
+                T result = op(A_row[RC*head + n],B_row[RC*head + n]);
+                A_row[RC*head + n] = result;
+                if(result != 0)
+                    nonzero_block = true;
+            }
+
+
+            if(nonzero_block){
+                Cj->push_back(head);
+                for(I n = 0; n < RC; n++){
+                    Cx->push_back(A_row[RC*head + n]);
+                }
+            }
+
+            for(I n = 0; n < RC; n++){
+                A_row[RC*head + n] = 0;
+                B_row[RC*head + n] = 0;
+            }
+
+            I temp = head;                
+            head = next[head];
+            next[temp] = -1;
+        }
+
+        (*Cp)[i+1] = Cj->size();
+    }
+}
+
+/* element-wise binary operations*/
+template <class I, class T>
+void bsr_elmul_bsr(const I n_row, const I n_col, const I R, const I C, 
+                   const I Ap [], const I Aj [], const T Ax [],
+                   const I Bp [], const I Bj [], const T Bx [],
+                   std::vector<I>* Cp, std::vector<I>* Cj, std::vector<T>* Cx)
+{
+    bsr_binop_bsr(n_row,n_col,R,C,Ap,Aj,Ax,Bp,Bj,Bx,Cp,Cj,Cx,std::multiplies<T>());
+}
+
+template <class I, class T>
+void bsr_eldiv_bsr(const I n_row, const I n_col, const I R, const I C,
+                   const I Ap [], const I Aj [], const T Ax [],
+                   const I Bp [], const I Bj [], const T Bx [],
+                   std::vector<I>* Cp, std::vector<I>* Cj, std::vector<T>* Cx)
+{
+    bsr_binop_bsr(n_row,n_col,R,C,Ap,Aj,Ax,Bp,Bj,Bx,Cp,Cj,Cx,std::divides<T>());
+}
+
+
+template <class I, class T>
+void bsr_plus_bsr(const I n_row, const I n_col, const I R, const I C, 
+                  const I Ap [], const I Aj [], const T Ax [],
+                  const I Bp [], const I Bj [], const T Bx [],
+                  std::vector<I>* Cp, std::vector<I>* Cj, std::vector<T>* Cx)
+{
+    bsr_binop_bsr(n_row,n_col,R,C,Ap,Aj,Ax,Bp,Bj,Bx,Cp,Cj,Cx,std::plus<T>());
+}
+
+template <class I, class T>
+void bsr_minus_bsr(const I n_row, const I n_col, const I R, const I C, 
+                   const I Ap [], const I Aj [], const T Ax [],
+                   const I Bp [], const I Bj [], const T Bx [],
+                   std::vector<I>* Cp, std::vector<I>* Cj, std::vector<T>* Cx)
+{
+    bsr_binop_bsr(n_row,n_col,R,C,Ap,Aj,Ax,Bp,Bj,Bx,Cp,Cj,Cx,std::minus<T>());
+}
+
+
+
+
 /*
  * Compute C = A (bin_op) B for CSR matrices A,B
  *
@@ -392,65 +590,129 @@
                    std::vector<T>* Cx,
                    const bin_op& op)
 {
-  Cp->resize(n_row + 1, 0);
-  
-  std::vector<I>  next(n_col,-1);
-  std::vector<T> A_row(n_col, 0);
-  std::vector<T> B_row(n_col, 0);
+//   //Method that works for unsorted indices
+//    Cp->resize(n_row + 1, 0);
+//    (*Cp)[0] = 0;
+//
+//    for(I i = 0; i < n_row; i++){
+//        I A_pos = Ap[i];
+//        I B_pos = Bp[i];
+//        I A_end = Ap[i+1];
+//        I B_end = Bp[i+1];
+//
+//        I A_j = Aj[A_pos];
+//        I B_j = Bj[B_pos];
+//            
+//        //while not finished with either row
+//        while(A_pos < A_end && B_pos < B_end){
+//            if(A_j == B_j){
+//                T result = op(Ax[A_pos],Bx[B_pos]);
+//                if(result != 0){
+//                    Cj->push_back(A_j);
+//                    Cx->push_back(result);
+//                }
+//                A_j = Aj[++A_pos]; 
+//                B_j = Bj[++B_pos];
+//            } else if (A_j < B_j) {
+//                T result = op(Ax[A_pos],0);
+//                if (result != 0){
+//                    Cj->push_back(A_j);
+//                    Cx->push_back(result);
+//                }
+//                A_j = Aj[++A_pos]; 
+//            } else {
+//                //B_j < A_j
+//                T result = op(0,Bx[B_pos]);
+//                if (result != 0){
+//                    Cj->push_back(B_j);
+//                    Cx->push_back(result);
+//                }
+//                B_j = Bj[++B_pos];
+//            }
+//        }
+//
+//        //tail
+//        while(A_pos < A_end){
+//            T result = op(Ax[A_pos],0);
+//            if (result != 0){
+//                Cj->push_back(A_j);
+//                Cx->push_back(result);
+//            }
+//            A_j = Aj[++A_pos]; 
+//        }
+//        while(B_pos < B_end){
+//            T result = op(0,Bx[B_pos]);
+//            if (result != 0){
+//                Cj->push_back(B_j);
+//                Cx->push_back(result);
+//            }
+//            B_j = Bj[++B_pos];
+//        }
+//        (*Cp)[i+1] = Cx->size();
+//    }
 
-  for(I i = 0; i < n_row; i++){
-    I head   = -2;
-    I length =  0;
-    
-    //add a row of A to A_row
-    I i_start = Ap[i];
-    I i_end   = Ap[i+1];
-    for(I jj = i_start; jj < i_end; jj++){
-      I j = Aj[jj];
 
-      A_row[j] += Ax[jj];
-      
-      if(next[j] == -1){
-	    next[j] = head;                        
-	    head = j;
-	    length++;
-      }
-    }
-    
-    //add a row of B to B_row
-    i_start = Bp[i];
-    i_end   = Bp[i+1];
-    for(I jj = i_start; jj < i_end; jj++){
-      I j = Bj[jj];
+   //Method that works for unsorted indices
 
-      B_row[j] += Bx[jj];
+    Cp->resize(n_row + 1, 0);
 
-      if(next[j] == -1){
-          next[j] = head;                        
-	      head = j;
-	      length++;
-      }
-    }
+    std::vector<I>  next(n_col,-1);
+    std::vector<T> A_row(n_col, 0);
+    std::vector<T> B_row(n_col, 0);
 
+    for(I i = 0; i < n_row; i++){
+        I head   = -2;
+        I length =  0;
 
-    for(I jj = 0; jj < length; jj++){
-      T result = op(A_row[head],B_row[head]);
-      
-      if(result != 0){
-	    Cj->push_back(head);
-	    Cx->push_back(result);
-      }
-      
-      I temp = head;                
-      head = next[head];
-      
-      next[temp] = -1;
-      A_row[temp] =  0;                              
-      B_row[temp] =  0;
+        //add a row of A to A_row
+        I i_start = Ap[i];
+        I i_end   = Ap[i+1];
+        for(I jj = i_start; jj < i_end; jj++){
+            I j = Aj[jj];
+
+            A_row[j] += Ax[jj];
+
+            if(next[j] == -1){
+                next[j] = head;                        
+                head = j;
+                length++;
+            }
+        }
+
+        //add a row of B to B_row
+        i_start = Bp[i];
+        i_end   = Bp[i+1];
+        for(I jj = i_start; jj < i_end; jj++){
+            I j = Bj[jj];
+
+            B_row[j] += Bx[jj];
+
+            if(next[j] == -1){
+                next[j] = head;                        
+                head = j;
+                length++;
+            }
+        }
+
+
+        for(I jj = 0; jj < length; jj++){
+            T result = op(A_row[head],B_row[head]);
+
+            if(result != 0){
+                Cj->push_back(head);
+                Cx->push_back(result);
+            }
+
+            I temp = head;                
+            head = next[head];
+
+            next[temp] = -1;
+            A_row[temp] =  0;                              
+            B_row[temp] =  0;
+        }
+
+        (*Cp)[i+1] = Cj->size();
     }
-    
-    (*Cp)[i+1] = Cx->size();
-  }
 }
 
 /* element-wise binary operations*/
@@ -872,52 +1134,7 @@
 
 
 
-/*
- * Sort CSR column indices inplace
- *
- * Input Arguments:
- *   I  n_row           - number of rows in A
- *   I  n_col           - number of columns in A
- *   I  Ap[n_row+1]     - row pointer
- *   I  Aj[nnz(A)]      - column indices
- *   T  Ax[nnz(A)]      - nonzeros 
- *
- */
-template< class T1, class T2 >
-bool kv_pair_less(const std::pair<T1,T2>& x, const std::pair<T1,T2>& y){
-    return x.first < y.first;
-}
-
 template<class I, class T>
-void csr_sort_indices(const I n_row,
-                      const I n_col,
-                      const I Ap[], 
-                            I Aj[], 
-                            T Ax[])
-{
-  std::vector< std::pair<I,T> > temp;
-
-  for(I i = 0; i < n_row; i++){
-      I row_start = Ap[i];
-      I row_end   = Ap[i+1];
-
-      temp.clear();
-
-      for(I jj = row_start; jj < row_end; jj++){
-          temp.push_back(std::make_pair(Aj[jj],Ax[jj]));
-      }
-
-      std::sort(temp.begin(),temp.end(),kv_pair_less<I,T>);
-
-      for(I jj = row_start, n = 0; jj < row_end; jj++, n++){
-          Aj[jj] = temp[n].first;
-          Ax[jj] = temp[n].second;
-      }
-    }    
-}
-
-
-template<class I, class T>
 void get_csr_submatrix(const I n_row,
 		               const I n_col,
 		               const I Ap[], 

Modified: trunk/scipy/sparse/sparsetools/sparsetools.i
===================================================================
--- trunk/scipy/sparse/sparsetools/sparsetools.i	2007-12-22 17:20:01 UTC (rev 3696)
+++ trunk/scipy/sparse/sparsetools/sparsetools.i	2007-12-23 17:42:51 UTC (rev 3697)
@@ -200,7 +200,12 @@
 INSTANTIATE_ALL(coo_tocsr)
 INSTANTIATE_ALL(coo_tocsc)
 
+/*
+ * CSR<->BSR
+ */
+%template(csr_count_blocks)   csr_count_blocks<int>;
 
+
 /*
  * CSR*CSR and CSC*CSC
  */
@@ -229,10 +234,15 @@
 INSTANTIATE_ALL(csc_plus_csc)
 INSTANTIATE_ALL(csc_minus_csc)
 
+INSTANTIATE_ALL(bsr_elmul_bsr)
+INSTANTIATE_ALL(bsr_eldiv_bsr)
+INSTANTIATE_ALL(bsr_plus_bsr)
+INSTANTIATE_ALL(bsr_minus_bsr)
 
 /*
  * Sort CSR/CSC indices.
  */
+%template(has_sorted_indices)   has_sorted_indices<int>;
 INSTANTIATE_ALL(csr_sort_indices)
 INSTANTIATE_ALL(csc_sort_indices)
 

Modified: trunk/scipy/sparse/sparsetools/sparsetools.py
===================================================================
--- trunk/scipy/sparse/sparsetools/sparsetools.py	2007-12-22 17:20:01 UTC (rev 3696)
+++ trunk/scipy/sparse/sparsetools/sparsetools.py	2007-12-23 17:42:51 UTC (rev 3697)
@@ -53,6 +53,10 @@
   """expandptr(int n_row, int Ap, int Bi)"""
   return _sparsetools.expandptr(*args)
 
+def csr_count_blocks(*args):
+  """csr_count_blocks(int n_row, int n_col, int R, int C, int Ap, int Aj) -> int"""
+  return _sparsetools.csr_count_blocks(*args)
+
 def csr_matmat_pass1(*args):
   """
     csr_matmat_pass1(int n_row, int n_col, int Ap, int Aj, int Bp, int Bj, 
@@ -67,7 +71,11 @@
     """
   return _sparsetools.csc_matmat_pass1(*args)
 
+def has_sorted_indices(*args):
+  """has_sorted_indices(int n_row, int n_col, int Ap, int Aj) -> bool"""
+  return _sparsetools.has_sorted_indices(*args)
 
+
 def csr_diagonal(*args):
   """
     csr_diagonal(int n_row, int n_col, int Ap, int Aj, signed char Ax, 
@@ -597,6 +605,154 @@
     """
   return _sparsetools.csc_minus_csc(*args)
 
+def bsr_elmul_bsr(*args):
+  """
+    bsr_elmul_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        signed char Ax, int Bp, int Bj, signed char Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(signed char)> Cx)
+    bsr_elmul_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        unsigned char Ax, int Bp, int Bj, unsigned char Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(unsigned char)> Cx)
+    bsr_elmul_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        short Ax, int Bp, int Bj, short Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(short)> Cx)
+    bsr_elmul_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        int Ax, int Bp, int Bj, int Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(int)> Cx)
+    bsr_elmul_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        long long Ax, int Bp, int Bj, long long Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(long long)> Cx)
+    bsr_elmul_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        float Ax, int Bp, int Bj, float Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(float)> Cx)
+    bsr_elmul_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        double Ax, int Bp, int Bj, double Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(double)> Cx)
+    bsr_elmul_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        npy_cfloat_wrapper Ax, int Bp, int Bj, npy_cfloat_wrapper Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(npy_cfloat_wrapper)> Cx)
+    bsr_elmul_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        npy_cdouble_wrapper Ax, int Bp, int Bj, npy_cdouble_wrapper Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(npy_cdouble_wrapper)> Cx)
+    """
+  return _sparsetools.bsr_elmul_bsr(*args)
+
+def bsr_eldiv_bsr(*args):
+  """
+    bsr_eldiv_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        signed char Ax, int Bp, int Bj, signed char Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(signed char)> Cx)
+    bsr_eldiv_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        unsigned char Ax, int Bp, int Bj, unsigned char Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(unsigned char)> Cx)
+    bsr_eldiv_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        short Ax, int Bp, int Bj, short Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(short)> Cx)
+    bsr_eldiv_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        int Ax, int Bp, int Bj, int Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(int)> Cx)
+    bsr_eldiv_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        long long Ax, int Bp, int Bj, long long Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(long long)> Cx)
+    bsr_eldiv_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        float Ax, int Bp, int Bj, float Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(float)> Cx)
+    bsr_eldiv_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        double Ax, int Bp, int Bj, double Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(double)> Cx)
+    bsr_eldiv_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        npy_cfloat_wrapper Ax, int Bp, int Bj, npy_cfloat_wrapper Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(npy_cfloat_wrapper)> Cx)
+    bsr_eldiv_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        npy_cdouble_wrapper Ax, int Bp, int Bj, npy_cdouble_wrapper Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(npy_cdouble_wrapper)> Cx)
+    """
+  return _sparsetools.bsr_eldiv_bsr(*args)
+
+def bsr_plus_bsr(*args):
+  """
+    bsr_plus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        signed char Ax, int Bp, int Bj, signed char Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(signed char)> Cx)
+    bsr_plus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        unsigned char Ax, int Bp, int Bj, unsigned char Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(unsigned char)> Cx)
+    bsr_plus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        short Ax, int Bp, int Bj, short Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(short)> Cx)
+    bsr_plus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        int Ax, int Bp, int Bj, int Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(int)> Cx)
+    bsr_plus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        long long Ax, int Bp, int Bj, long long Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(long long)> Cx)
+    bsr_plus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        float Ax, int Bp, int Bj, float Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(float)> Cx)
+    bsr_plus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        double Ax, int Bp, int Bj, double Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(double)> Cx)
+    bsr_plus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        npy_cfloat_wrapper Ax, int Bp, int Bj, npy_cfloat_wrapper Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(npy_cfloat_wrapper)> Cx)
+    bsr_plus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        npy_cdouble_wrapper Ax, int Bp, int Bj, npy_cdouble_wrapper Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(npy_cdouble_wrapper)> Cx)
+    """
+  return _sparsetools.bsr_plus_bsr(*args)
+
+def bsr_minus_bsr(*args):
+  """
+    bsr_minus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        signed char Ax, int Bp, int Bj, signed char Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(signed char)> Cx)
+    bsr_minus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        unsigned char Ax, int Bp, int Bj, unsigned char Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(unsigned char)> Cx)
+    bsr_minus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        short Ax, int Bp, int Bj, short Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(short)> Cx)
+    bsr_minus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        int Ax, int Bp, int Bj, int Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(int)> Cx)
+    bsr_minus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        long long Ax, int Bp, int Bj, long long Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(long long)> Cx)
+    bsr_minus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        float Ax, int Bp, int Bj, float Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(float)> Cx)
+    bsr_minus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        double Ax, int Bp, int Bj, double Bx, std::vector<(int)> Cp, 
+        std::vector<(int)> Cj, std::vector<(double)> Cx)
+    bsr_minus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        npy_cfloat_wrapper Ax, int Bp, int Bj, npy_cfloat_wrapper Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(npy_cfloat_wrapper)> Cx)
+    bsr_minus_bsr(int n_row, int n_col, int R, int C, int Ap, int Aj, 
+        npy_cdouble_wrapper Ax, int Bp, int Bj, npy_cdouble_wrapper Bx, 
+        std::vector<(int)> Cp, std::vector<(int)> Cj, 
+        std::vector<(npy_cdouble_wrapper)> Cx)
+    """
+  return _sparsetools.bsr_minus_bsr(*args)
+
 def csr_sort_indices(*args):
   """
     csr_sort_indices(int n_row, int n_col, int Ap, int Aj, signed char Ax)

Modified: trunk/scipy/sparse/sparsetools/sparsetools_wrap.cxx
===================================================================
--- trunk/scipy/sparse/sparsetools/sparsetools_wrap.cxx	2007-12-22 17:20:01 UTC (rev 3696)
+++ trunk/scipy/sparse/sparsetools/sparsetools_wrap.cxx	2007-12-23 17:42:51 UTC (rev 3697)
@@ -3077,6 +3077,23 @@
   return res;
 }
 
+
+  #define SWIG_From_long   PyInt_FromLong 
+
+
+SWIGINTERNINLINE PyObject *
+SWIG_From_int  (int value)
+{    
+  return SWIG_From_long  (value);
+}
+
+
+SWIGINTERNINLINE PyObject*
+  SWIG_From_bool  (bool value)
+{
+  return PyBool_FromLong(value ? 1 : 0);
+}
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -11673,6 +11690,95 @@
 }
 
 
+SWIGINTERN PyObject *_wrap_csr_count_blocks(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int *arg5 ;
+  int *arg6 ;
+  int result;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  int val3 ;
+  int ecode3 = 0 ;
+  int val4 ;
+  int ecode4 = 0 ;
+  PyArrayObject *array5 = NULL ;
+  int is_new_object5 ;
+  PyArrayObject *array6 = NULL ;
+  int is_new_object6 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:csr_count_blocks",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "csr_count_blocks" "', 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_count_blocks" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "csr_count_blocks" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "csr_count_blocks" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array5 = obj_to_array_contiguous_allow_conversion(obj4, PyArray_INT, &is_new_object5);
+    if (!array5 || !require_dimensions(array5,1) || !require_size(array5,size,1)
+      || !require_contiguous(array5)   || !require_native(array5)) SWIG_fail;
+    
+    arg5 = (int*) array5->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array6 = obj_to_array_contiguous_allow_conversion(obj5, PyArray_INT, &is_new_object6);
+    if (!array6 || !require_dimensions(array6,1) || !require_size(array6,size,1)
+      || !require_contiguous(array6)   || !require_native(array6)) SWIG_fail;
+    
+    arg6 = (int*) array6->data;
+  }
+  result = (int)csr_count_blocks<int >(arg1,arg2,arg3,arg4,(int const (*))arg5,(int const (*))arg6);
+  resultobj = SWIG_From_int(static_cast< int >(result));
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  return resultobj;
+fail:
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_csr_matmat_pass1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   int arg1 ;
@@ -37843,6 +37949,9685 @@
 }
 
 
+SWIGINTERN PyObject *_wrap_bsr_elmul_bsr__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int *arg5 ;
+  int *arg6 ;
+  signed char *arg7 ;
+  int *arg8 ;
+  int *arg9 ;
+  signed char *arg10 ;
+  std::vector<int > *arg11 = (std::vector<int > *) 0 ;
+  std::vector<int > *arg12 = (std::vector<int > *) 0 ;
+  std::vector<signed char > *arg13 = (std::vector<signed char > *) 0 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  int val3 ;
+  int ecode3 = 0 ;
+  int val4 ;
+  int ecode4 = 0 ;
+  PyArrayObject *array5 = NULL ;
+  int is_new_object5 ;
+  PyArrayObject *array6 = NULL ;
+  int is_new_object6 ;
+  PyArrayObject *array7 = NULL ;
+  int is_new_object7 ;
+  PyArrayObject *array8 = NULL ;
+  int is_new_object8 ;
+  PyArrayObject *array9 = NULL ;
+  int is_new_object9 ;
+  PyArrayObject *array10 = NULL ;
+  int is_new_object10 ;
+  std::vector<int > *tmp11 ;
+  std::vector<int > *tmp12 ;
+  std::vector<signed char > *tmp13 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  PyObject * obj6 = 0 ;
+  PyObject * obj7 = 0 ;
+  PyObject * obj8 = 0 ;
+  PyObject * obj9 = 0 ;
+  
+  {
+    tmp11 = new std::vector<int>(); 
+    arg11 = tmp11; 
+  }
+  {
+    tmp12 = new std::vector<int>(); 
+    arg12 = tmp12; 
+  }
+  {
+    tmp13 = new std::vector<signed char>(); 
+    arg13 = tmp13; 
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:bsr_elmul_bsr",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bsr_elmul_bsr" "', 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 '" "bsr_elmul_bsr" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bsr_elmul_bsr" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "bsr_elmul_bsr" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array5 = obj_to_array_contiguous_allow_conversion(obj4, PyArray_INT, &is_new_object5);
+    if (!array5 || !require_dimensions(array5,1) || !require_size(array5,size,1)
+      || !require_contiguous(array5)   || !require_native(array5)) SWIG_fail;
+    
+    arg5 = (int*) array5->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array6 = obj_to_array_contiguous_allow_conversion(obj5, PyArray_INT, &is_new_object6);
+    if (!array6 || !require_dimensions(array6,1) || !require_size(array6,size,1)
+      || !require_contiguous(array6)   || !require_native(array6)) SWIG_fail;
+    
+    arg6 = (int*) array6->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array7 = obj_to_array_contiguous_allow_conversion(obj6, PyArray_BYTE, &is_new_object7);
+    if (!array7 || !require_dimensions(array7,1) || !require_size(array7,size,1)
+      || !require_contiguous(array7)   || !require_native(array7)) SWIG_fail;
+    
+    arg7 = (signed char*) array7->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array8 = obj_to_array_contiguous_allow_conversion(obj7, PyArray_INT, &is_new_object8);
+    if (!array8 || !require_dimensions(array8,1) || !require_size(array8,size,1)
+      || !require_contiguous(array8)   || !require_native(array8)) SWIG_fail;
+    
+    arg8 = (int*) array8->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array9 = obj_to_array_contiguous_allow_conversion(obj8, PyArray_INT, &is_new_object9);
+    if (!array9 || !require_dimensions(array9,1) || !require_size(array9,size,1)
+      || !require_contiguous(array9)   || !require_native(array9)) SWIG_fail;
+    
+    arg9 = (int*) array9->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array10 = obj_to_array_contiguous_allow_conversion(obj9, PyArray_BYTE, &is_new_object10);
+    if (!array10 || !require_dimensions(array10,1) || !require_size(array10,size,1)
+      || !require_contiguous(array10)   || !require_native(array10)) SWIG_fail;
+    
+    arg10 = (signed char*) array10->data;
+  }
+  bsr_elmul_bsr<int,signed char >(arg1,arg2,arg3,arg4,(int const (*))arg5,(int const (*))arg6,(signed char const (*))arg7,(int const (*))arg8,(int const (*))arg9,(signed char const (*))arg10,arg11,arg12,arg13);
+  resultobj = SWIG_Py_Void();
+  {
+    int length = (arg11)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg11))[0]),sizeof(int)*length);	 
+    delete arg11; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg12)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg12))[0]),sizeof(int)*length);	 
+    delete arg12; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg13)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_BYTE); 
+    memcpy(PyArray_DATA(obj),&((*(arg13))[0]),sizeof(signed char)*length);	 
+    delete arg13; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return resultobj;
+fail:
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bsr_elmul_bsr__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int *arg5 ;
+  int *arg6 ;
+  unsigned char *arg7 ;
+  int *arg8 ;
+  int *arg9 ;
+  unsigned char *arg10 ;
+  std::vector<int > *arg11 = (std::vector<int > *) 0 ;
+  std::vector<int > *arg12 = (std::vector<int > *) 0 ;
+  std::vector<unsigned char > *arg13 = (std::vector<unsigned char > *) 0 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  int val3 ;
+  int ecode3 = 0 ;
+  int val4 ;
+  int ecode4 = 0 ;
+  PyArrayObject *array5 = NULL ;
+  int is_new_object5 ;
+  PyArrayObject *array6 = NULL ;
+  int is_new_object6 ;
+  PyArrayObject *array7 = NULL ;
+  int is_new_object7 ;
+  PyArrayObject *array8 = NULL ;
+  int is_new_object8 ;
+  PyArrayObject *array9 = NULL ;
+  int is_new_object9 ;
+  PyArrayObject *array10 = NULL ;
+  int is_new_object10 ;
+  std::vector<int > *tmp11 ;
+  std::vector<int > *tmp12 ;
+  std::vector<unsigned char > *tmp13 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  PyObject * obj6 = 0 ;
+  PyObject * obj7 = 0 ;
+  PyObject * obj8 = 0 ;
+  PyObject * obj9 = 0 ;
+  
+  {
+    tmp11 = new std::vector<int>(); 
+    arg11 = tmp11; 
+  }
+  {
+    tmp12 = new std::vector<int>(); 
+    arg12 = tmp12; 
+  }
+  {
+    tmp13 = new std::vector<unsigned char>(); 
+    arg13 = tmp13; 
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:bsr_elmul_bsr",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bsr_elmul_bsr" "', 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 '" "bsr_elmul_bsr" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bsr_elmul_bsr" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "bsr_elmul_bsr" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array5 = obj_to_array_contiguous_allow_conversion(obj4, PyArray_INT, &is_new_object5);
+    if (!array5 || !require_dimensions(array5,1) || !require_size(array5,size,1)
+      || !require_contiguous(array5)   || !require_native(array5)) SWIG_fail;
+    
+    arg5 = (int*) array5->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array6 = obj_to_array_contiguous_allow_conversion(obj5, PyArray_INT, &is_new_object6);
+    if (!array6 || !require_dimensions(array6,1) || !require_size(array6,size,1)
+      || !require_contiguous(array6)   || !require_native(array6)) SWIG_fail;
+    
+    arg6 = (int*) array6->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array7 = obj_to_array_contiguous_allow_conversion(obj6, PyArray_UBYTE, &is_new_object7);
+    if (!array7 || !require_dimensions(array7,1) || !require_size(array7,size,1)
+      || !require_contiguous(array7)   || !require_native(array7)) SWIG_fail;
+    
+    arg7 = (unsigned char*) array7->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array8 = obj_to_array_contiguous_allow_conversion(obj7, PyArray_INT, &is_new_object8);
+    if (!array8 || !require_dimensions(array8,1) || !require_size(array8,size,1)
+      || !require_contiguous(array8)   || !require_native(array8)) SWIG_fail;
+    
+    arg8 = (int*) array8->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array9 = obj_to_array_contiguous_allow_conversion(obj8, PyArray_INT, &is_new_object9);
+    if (!array9 || !require_dimensions(array9,1) || !require_size(array9,size,1)
+      || !require_contiguous(array9)   || !require_native(array9)) SWIG_fail;
+    
+    arg9 = (int*) array9->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array10 = obj_to_array_contiguous_allow_conversion(obj9, PyArray_UBYTE, &is_new_object10);
+    if (!array10 || !require_dimensions(array10,1) || !require_size(array10,size,1)
+      || !require_contiguous(array10)   || !require_native(array10)) SWIG_fail;
+    
+    arg10 = (unsigned char*) array10->data;
+  }
+  bsr_elmul_bsr<int,unsigned char >(arg1,arg2,arg3,arg4,(int const (*))arg5,(int const (*))arg6,(unsigned char const (*))arg7,(int const (*))arg8,(int const (*))arg9,(unsigned char const (*))arg10,arg11,arg12,arg13);
+  resultobj = SWIG_Py_Void();
+  {
+    int length = (arg11)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg11))[0]),sizeof(int)*length);	 
+    delete arg11; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg12)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg12))[0]),sizeof(int)*length);	 
+    delete arg12; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg13)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_UBYTE); 
+    memcpy(PyArray_DATA(obj),&((*(arg13))[0]),sizeof(unsigned char)*length);	 
+    delete arg13; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return resultobj;
+fail:
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bsr_elmul_bsr__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int *arg5 ;
+  int *arg6 ;
+  short *arg7 ;
+  int *arg8 ;
+  int *arg9 ;
+  short *arg10 ;
+  std::vector<int > *arg11 = (std::vector<int > *) 0 ;
+  std::vector<int > *arg12 = (std::vector<int > *) 0 ;
+  std::vector<short > *arg13 = (std::vector<short > *) 0 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  int val3 ;
+  int ecode3 = 0 ;
+  int val4 ;
+  int ecode4 = 0 ;
+  PyArrayObject *array5 = NULL ;
+  int is_new_object5 ;
+  PyArrayObject *array6 = NULL ;
+  int is_new_object6 ;
+  PyArrayObject *array7 = NULL ;
+  int is_new_object7 ;
+  PyArrayObject *array8 = NULL ;
+  int is_new_object8 ;
+  PyArrayObject *array9 = NULL ;
+  int is_new_object9 ;
+  PyArrayObject *array10 = NULL ;
+  int is_new_object10 ;
+  std::vector<int > *tmp11 ;
+  std::vector<int > *tmp12 ;
+  std::vector<short > *tmp13 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  PyObject * obj6 = 0 ;
+  PyObject * obj7 = 0 ;
+  PyObject * obj8 = 0 ;
+  PyObject * obj9 = 0 ;
+  
+  {
+    tmp11 = new std::vector<int>(); 
+    arg11 = tmp11; 
+  }
+  {
+    tmp12 = new std::vector<int>(); 
+    arg12 = tmp12; 
+  }
+  {
+    tmp13 = new std::vector<short>(); 
+    arg13 = tmp13; 
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:bsr_elmul_bsr",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bsr_elmul_bsr" "', 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 '" "bsr_elmul_bsr" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bsr_elmul_bsr" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "bsr_elmul_bsr" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array5 = obj_to_array_contiguous_allow_conversion(obj4, PyArray_INT, &is_new_object5);
+    if (!array5 || !require_dimensions(array5,1) || !require_size(array5,size,1)
+      || !require_contiguous(array5)   || !require_native(array5)) SWIG_fail;
+    
+    arg5 = (int*) array5->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array6 = obj_to_array_contiguous_allow_conversion(obj5, PyArray_INT, &is_new_object6);
+    if (!array6 || !require_dimensions(array6,1) || !require_size(array6,size,1)
+      || !require_contiguous(array6)   || !require_native(array6)) SWIG_fail;
+    
+    arg6 = (int*) array6->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array7 = obj_to_array_contiguous_allow_conversion(obj6, PyArray_SHORT, &is_new_object7);
+    if (!array7 || !require_dimensions(array7,1) || !require_size(array7,size,1)
+      || !require_contiguous(array7)   || !require_native(array7)) SWIG_fail;
+    
+    arg7 = (short*) array7->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array8 = obj_to_array_contiguous_allow_conversion(obj7, PyArray_INT, &is_new_object8);
+    if (!array8 || !require_dimensions(array8,1) || !require_size(array8,size,1)
+      || !require_contiguous(array8)   || !require_native(array8)) SWIG_fail;
+    
+    arg8 = (int*) array8->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array9 = obj_to_array_contiguous_allow_conversion(obj8, PyArray_INT, &is_new_object9);
+    if (!array9 || !require_dimensions(array9,1) || !require_size(array9,size,1)
+      || !require_contiguous(array9)   || !require_native(array9)) SWIG_fail;
+    
+    arg9 = (int*) array9->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array10 = obj_to_array_contiguous_allow_conversion(obj9, PyArray_SHORT, &is_new_object10);
+    if (!array10 || !require_dimensions(array10,1) || !require_size(array10,size,1)
+      || !require_contiguous(array10)   || !require_native(array10)) SWIG_fail;
+    
+    arg10 = (short*) array10->data;
+  }
+  bsr_elmul_bsr<int,short >(arg1,arg2,arg3,arg4,(int const (*))arg5,(int const (*))arg6,(short const (*))arg7,(int const (*))arg8,(int const (*))arg9,(short const (*))arg10,arg11,arg12,arg13);
+  resultobj = SWIG_Py_Void();
+  {
+    int length = (arg11)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg11))[0]),sizeof(int)*length);	 
+    delete arg11; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg12)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg12))[0]),sizeof(int)*length);	 
+    delete arg12; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg13)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_SHORT); 
+    memcpy(PyArray_DATA(obj),&((*(arg13))[0]),sizeof(short)*length);	 
+    delete arg13; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return resultobj;
+fail:
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bsr_elmul_bsr__SWIG_4(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int *arg5 ;
+  int *arg6 ;
+  int *arg7 ;
+  int *arg8 ;
+  int *arg9 ;
+  int *arg10 ;
+  std::vector<int > *arg11 = (std::vector<int > *) 0 ;
+  std::vector<int > *arg12 = (std::vector<int > *) 0 ;
+  std::vector<int > *arg13 = (std::vector<int > *) 0 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  int val3 ;
+  int ecode3 = 0 ;
+  int val4 ;
+  int ecode4 = 0 ;
+  PyArrayObject *array5 = NULL ;
+  int is_new_object5 ;
+  PyArrayObject *array6 = NULL ;
+  int is_new_object6 ;
+  PyArrayObject *array7 = NULL ;
+  int is_new_object7 ;
+  PyArrayObject *array8 = NULL ;
+  int is_new_object8 ;
+  PyArrayObject *array9 = NULL ;
+  int is_new_object9 ;
+  PyArrayObject *array10 = NULL ;
+  int is_new_object10 ;
+  std::vector<int > *tmp11 ;
+  std::vector<int > *tmp12 ;
+  std::vector<int > *tmp13 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  PyObject * obj6 = 0 ;
+  PyObject * obj7 = 0 ;
+  PyObject * obj8 = 0 ;
+  PyObject * obj9 = 0 ;
+  
+  {
+    tmp11 = new std::vector<int>(); 
+    arg11 = tmp11; 
+  }
+  {
+    tmp12 = new std::vector<int>(); 
+    arg12 = tmp12; 
+  }
+  {
+    tmp13 = new std::vector<int>(); 
+    arg13 = tmp13; 
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:bsr_elmul_bsr",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bsr_elmul_bsr" "', 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 '" "bsr_elmul_bsr" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bsr_elmul_bsr" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "bsr_elmul_bsr" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array5 = obj_to_array_contiguous_allow_conversion(obj4, PyArray_INT, &is_new_object5);
+    if (!array5 || !require_dimensions(array5,1) || !require_size(array5,size,1)
+      || !require_contiguous(array5)   || !require_native(array5)) SWIG_fail;
+    
+    arg5 = (int*) array5->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array6 = obj_to_array_contiguous_allow_conversion(obj5, PyArray_INT, &is_new_object6);
+    if (!array6 || !require_dimensions(array6,1) || !require_size(array6,size,1)
+      || !require_contiguous(array6)   || !require_native(array6)) SWIG_fail;
+    
+    arg6 = (int*) array6->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array7 = obj_to_array_contiguous_allow_conversion(obj6, PyArray_INT, &is_new_object7);
+    if (!array7 || !require_dimensions(array7,1) || !require_size(array7,size,1)
+      || !require_contiguous(array7)   || !require_native(array7)) SWIG_fail;
+    
+    arg7 = (int*) array7->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array8 = obj_to_array_contiguous_allow_conversion(obj7, PyArray_INT, &is_new_object8);
+    if (!array8 || !require_dimensions(array8,1) || !require_size(array8,size,1)
+      || !require_contiguous(array8)   || !require_native(array8)) SWIG_fail;
+    
+    arg8 = (int*) array8->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array9 = obj_to_array_contiguous_allow_conversion(obj8, PyArray_INT, &is_new_object9);
+    if (!array9 || !require_dimensions(array9,1) || !require_size(array9,size,1)
+      || !require_contiguous(array9)   || !require_native(array9)) SWIG_fail;
+    
+    arg9 = (int*) array9->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array10 = obj_to_array_contiguous_allow_conversion(obj9, PyArray_INT, &is_new_object10);
+    if (!array10 || !require_dimensions(array10,1) || !require_size(array10,size,1)
+      || !require_contiguous(array10)   || !require_native(array10)) SWIG_fail;
+    
+    arg10 = (int*) array10->data;
+  }
+  bsr_elmul_bsr<int,int >(arg1,arg2,arg3,arg4,(int const (*))arg5,(int const (*))arg6,(int const (*))arg7,(int const (*))arg8,(int const (*))arg9,(int const (*))arg10,arg11,arg12,arg13);
+  resultobj = SWIG_Py_Void();
+  {
+    int length = (arg11)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg11))[0]),sizeof(int)*length);	 
+    delete arg11; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg12)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg12))[0]),sizeof(int)*length);	 
+    delete arg12; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg13)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg13))[0]),sizeof(int)*length);	 
+    delete arg13; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return resultobj;
+fail:
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bsr_elmul_bsr__SWIG_5(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int *arg5 ;
+  int *arg6 ;
+  long long *arg7 ;
+  int *arg8 ;
+  int *arg9 ;
+  long long *arg10 ;
+  std::vector<int > *arg11 = (std::vector<int > *) 0 ;
+  std::vector<int > *arg12 = (std::vector<int > *) 0 ;
+  std::vector<long long > *arg13 = (std::vector<long long > *) 0 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  int val3 ;
+  int ecode3 = 0 ;
+  int val4 ;
+  int ecode4 = 0 ;
+  PyArrayObject *array5 = NULL ;
+  int is_new_object5 ;
+  PyArrayObject *array6 = NULL ;
+  int is_new_object6 ;
+  PyArrayObject *array7 = NULL ;
+  int is_new_object7 ;
+  PyArrayObject *array8 = NULL ;
+  int is_new_object8 ;
+  PyArrayObject *array9 = NULL ;
+  int is_new_object9 ;
+  PyArrayObject *array10 = NULL ;
+  int is_new_object10 ;
+  std::vector<int > *tmp11 ;
+  std::vector<int > *tmp12 ;
+  std::vector<long long > *tmp13 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  PyObject * obj6 = 0 ;
+  PyObject * obj7 = 0 ;
+  PyObject * obj8 = 0 ;
+  PyObject * obj9 = 0 ;
+  
+  {
+    tmp11 = new std::vector<int>(); 
+    arg11 = tmp11; 
+  }
+  {
+    tmp12 = new std::vector<int>(); 
+    arg12 = tmp12; 
+  }
+  {
+    tmp13 = new std::vector<long long>(); 
+    arg13 = tmp13; 
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:bsr_elmul_bsr",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bsr_elmul_bsr" "', 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 '" "bsr_elmul_bsr" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bsr_elmul_bsr" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "bsr_elmul_bsr" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array5 = obj_to_array_contiguous_allow_conversion(obj4, PyArray_INT, &is_new_object5);
+    if (!array5 || !require_dimensions(array5,1) || !require_size(array5,size,1)
+      || !require_contiguous(array5)   || !require_native(array5)) SWIG_fail;
+    
+    arg5 = (int*) array5->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array6 = obj_to_array_contiguous_allow_conversion(obj5, PyArray_INT, &is_new_object6);
+    if (!array6 || !require_dimensions(array6,1) || !require_size(array6,size,1)
+      || !require_contiguous(array6)   || !require_native(array6)) SWIG_fail;
+    
+    arg6 = (int*) array6->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array7 = obj_to_array_contiguous_allow_conversion(obj6, PyArray_LONGLONG, &is_new_object7);
+    if (!array7 || !require_dimensions(array7,1) || !require_size(array7,size,1)
+      || !require_contiguous(array7)   || !require_native(array7)) SWIG_fail;
+    
+    arg7 = (long long*) array7->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array8 = obj_to_array_contiguous_allow_conversion(obj7, PyArray_INT, &is_new_object8);
+    if (!array8 || !require_dimensions(array8,1) || !require_size(array8,size,1)
+      || !require_contiguous(array8)   || !require_native(array8)) SWIG_fail;
+    
+    arg8 = (int*) array8->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array9 = obj_to_array_contiguous_allow_conversion(obj8, PyArray_INT, &is_new_object9);
+    if (!array9 || !require_dimensions(array9,1) || !require_size(array9,size,1)
+      || !require_contiguous(array9)   || !require_native(array9)) SWIG_fail;
+    
+    arg9 = (int*) array9->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array10 = obj_to_array_contiguous_allow_conversion(obj9, PyArray_LONGLONG, &is_new_object10);
+    if (!array10 || !require_dimensions(array10,1) || !require_size(array10,size,1)
+      || !require_contiguous(array10)   || !require_native(array10)) SWIG_fail;
+    
+    arg10 = (long long*) array10->data;
+  }
+  bsr_elmul_bsr<int,long long >(arg1,arg2,arg3,arg4,(int const (*))arg5,(int const (*))arg6,(long long const (*))arg7,(int const (*))arg8,(int const (*))arg9,(long long const (*))arg10,arg11,arg12,arg13);
+  resultobj = SWIG_Py_Void();
+  {
+    int length = (arg11)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg11))[0]),sizeof(int)*length);	 
+    delete arg11; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg12)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg12))[0]),sizeof(int)*length);	 
+    delete arg12; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg13)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_LONGLONG); 
+    memcpy(PyArray_DATA(obj),&((*(arg13))[0]),sizeof(long long)*length);	 
+    delete arg13; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return resultobj;
+fail:
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bsr_elmul_bsr__SWIG_6(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int *arg5 ;
+  int *arg6 ;
+  float *arg7 ;
+  int *arg8 ;
+  int *arg9 ;
+  float *arg10 ;
+  std::vector<int > *arg11 = (std::vector<int > *) 0 ;
+  std::vector<int > *arg12 = (std::vector<int > *) 0 ;
+  std::vector<float > *arg13 = (std::vector<float > *) 0 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  int val3 ;
+  int ecode3 = 0 ;
+  int val4 ;
+  int ecode4 = 0 ;
+  PyArrayObject *array5 = NULL ;
+  int is_new_object5 ;
+  PyArrayObject *array6 = NULL ;
+  int is_new_object6 ;
+  PyArrayObject *array7 = NULL ;
+  int is_new_object7 ;
+  PyArrayObject *array8 = NULL ;
+  int is_new_object8 ;
+  PyArrayObject *array9 = NULL ;
+  int is_new_object9 ;
+  PyArrayObject *array10 = NULL ;
+  int is_new_object10 ;
+  std::vector<int > *tmp11 ;
+  std::vector<int > *tmp12 ;
+  std::vector<float > *tmp13 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  PyObject * obj6 = 0 ;
+  PyObject * obj7 = 0 ;
+  PyObject * obj8 = 0 ;
+  PyObject * obj9 = 0 ;
+  
+  {
+    tmp11 = new std::vector<int>(); 
+    arg11 = tmp11; 
+  }
+  {
+    tmp12 = new std::vector<int>(); 
+    arg12 = tmp12; 
+  }
+  {
+    tmp13 = new std::vector<float>(); 
+    arg13 = tmp13; 
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:bsr_elmul_bsr",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bsr_elmul_bsr" "', 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 '" "bsr_elmul_bsr" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bsr_elmul_bsr" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "bsr_elmul_bsr" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array5 = obj_to_array_contiguous_allow_conversion(obj4, PyArray_INT, &is_new_object5);
+    if (!array5 || !require_dimensions(array5,1) || !require_size(array5,size,1)
+      || !require_contiguous(array5)   || !require_native(array5)) SWIG_fail;
+    
+    arg5 = (int*) array5->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array6 = obj_to_array_contiguous_allow_conversion(obj5, PyArray_INT, &is_new_object6);
+    if (!array6 || !require_dimensions(array6,1) || !require_size(array6,size,1)
+      || !require_contiguous(array6)   || !require_native(array6)) SWIG_fail;
+    
+    arg6 = (int*) array6->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array7 = obj_to_array_contiguous_allow_conversion(obj6, PyArray_FLOAT, &is_new_object7);
+    if (!array7 || !require_dimensions(array7,1) || !require_size(array7,size,1)
+      || !require_contiguous(array7)   || !require_native(array7)) SWIG_fail;
+    
+    arg7 = (float*) array7->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array8 = obj_to_array_contiguous_allow_conversion(obj7, PyArray_INT, &is_new_object8);
+    if (!array8 || !require_dimensions(array8,1) || !require_size(array8,size,1)
+      || !require_contiguous(array8)   || !require_native(array8)) SWIG_fail;
+    
+    arg8 = (int*) array8->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array9 = obj_to_array_contiguous_allow_conversion(obj8, PyArray_INT, &is_new_object9);
+    if (!array9 || !require_dimensions(array9,1) || !require_size(array9,size,1)
+      || !require_contiguous(array9)   || !require_native(array9)) SWIG_fail;
+    
+    arg9 = (int*) array9->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array10 = obj_to_array_contiguous_allow_conversion(obj9, PyArray_FLOAT, &is_new_object10);
+    if (!array10 || !require_dimensions(array10,1) || !require_size(array10,size,1)
+      || !require_contiguous(array10)   || !require_native(array10)) SWIG_fail;
+    
+    arg10 = (float*) array10->data;
+  }
+  bsr_elmul_bsr<int,float >(arg1,arg2,arg3,arg4,(int const (*))arg5,(int const (*))arg6,(float const (*))arg7,(int const (*))arg8,(int const (*))arg9,(float const (*))arg10,arg11,arg12,arg13);
+  resultobj = SWIG_Py_Void();
+  {
+    int length = (arg11)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg11))[0]),sizeof(int)*length);	 
+    delete arg11; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg12)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg12))[0]),sizeof(int)*length);	 
+    delete arg12; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg13)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_FLOAT); 
+    memcpy(PyArray_DATA(obj),&((*(arg13))[0]),sizeof(float)*length);	 
+    delete arg13; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return resultobj;
+fail:
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bsr_elmul_bsr__SWIG_7(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int *arg5 ;
+  int *arg6 ;
+  double *arg7 ;
+  int *arg8 ;
+  int *arg9 ;
+  double *arg10 ;
+  std::vector<int > *arg11 = (std::vector<int > *) 0 ;
+  std::vector<int > *arg12 = (std::vector<int > *) 0 ;
+  std::vector<double > *arg13 = (std::vector<double > *) 0 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  int val3 ;
+  int ecode3 = 0 ;
+  int val4 ;
+  int ecode4 = 0 ;
+  PyArrayObject *array5 = NULL ;
+  int is_new_object5 ;
+  PyArrayObject *array6 = NULL ;
+  int is_new_object6 ;
+  PyArrayObject *array7 = NULL ;
+  int is_new_object7 ;
+  PyArrayObject *array8 = NULL ;
+  int is_new_object8 ;
+  PyArrayObject *array9 = NULL ;
+  int is_new_object9 ;
+  PyArrayObject *array10 = NULL ;
+  int is_new_object10 ;
+  std::vector<int > *tmp11 ;
+  std::vector<int > *tmp12 ;
+  std::vector<double > *tmp13 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  PyObject * obj6 = 0 ;
+  PyObject * obj7 = 0 ;
+  PyObject * obj8 = 0 ;
+  PyObject * obj9 = 0 ;
+  
+  {
+    tmp11 = new std::vector<int>(); 
+    arg11 = tmp11; 
+  }
+  {
+    tmp12 = new std::vector<int>(); 
+    arg12 = tmp12; 
+  }
+  {
+    tmp13 = new std::vector<double>(); 
+    arg13 = tmp13; 
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:bsr_elmul_bsr",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bsr_elmul_bsr" "', 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 '" "bsr_elmul_bsr" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bsr_elmul_bsr" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "bsr_elmul_bsr" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array5 = obj_to_array_contiguous_allow_conversion(obj4, PyArray_INT, &is_new_object5);
+    if (!array5 || !require_dimensions(array5,1) || !require_size(array5,size,1)
+      || !require_contiguous(array5)   || !require_native(array5)) SWIG_fail;
+    
+    arg5 = (int*) array5->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array6 = obj_to_array_contiguous_allow_conversion(obj5, PyArray_INT, &is_new_object6);
+    if (!array6 || !require_dimensions(array6,1) || !require_size(array6,size,1)
+      || !require_contiguous(array6)   || !require_native(array6)) SWIG_fail;
+    
+    arg6 = (int*) array6->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array7 = obj_to_array_contiguous_allow_conversion(obj6, PyArray_DOUBLE, &is_new_object7);
+    if (!array7 || !require_dimensions(array7,1) || !require_size(array7,size,1)
+      || !require_contiguous(array7)   || !require_native(array7)) SWIG_fail;
+    
+    arg7 = (double*) array7->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array8 = obj_to_array_contiguous_allow_conversion(obj7, PyArray_INT, &is_new_object8);
+    if (!array8 || !require_dimensions(array8,1) || !require_size(array8,size,1)
+      || !require_contiguous(array8)   || !require_native(array8)) SWIG_fail;
+    
+    arg8 = (int*) array8->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array9 = obj_to_array_contiguous_allow_conversion(obj8, PyArray_INT, &is_new_object9);
+    if (!array9 || !require_dimensions(array9,1) || !require_size(array9,size,1)
+      || !require_contiguous(array9)   || !require_native(array9)) SWIG_fail;
+    
+    arg9 = (int*) array9->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array10 = obj_to_array_contiguous_allow_conversion(obj9, PyArray_DOUBLE, &is_new_object10);
+    if (!array10 || !require_dimensions(array10,1) || !require_size(array10,size,1)
+      || !require_contiguous(array10)   || !require_native(array10)) SWIG_fail;
+    
+    arg10 = (double*) array10->data;
+  }
+  bsr_elmul_bsr<int,double >(arg1,arg2,arg3,arg4,(int const (*))arg5,(int const (*))arg6,(double const (*))arg7,(int const (*))arg8,(int const (*))arg9,(double const (*))arg10,arg11,arg12,arg13);
+  resultobj = SWIG_Py_Void();
+  {
+    int length = (arg11)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg11))[0]),sizeof(int)*length);	 
+    delete arg11; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg12)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg12))[0]),sizeof(int)*length);	 
+    delete arg12; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg13)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_DOUBLE); 
+    memcpy(PyArray_DATA(obj),&((*(arg13))[0]),sizeof(double)*length);	 
+    delete arg13; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return resultobj;
+fail:
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bsr_elmul_bsr__SWIG_8(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int *arg5 ;
+  int *arg6 ;
+  npy_cfloat_wrapper *arg7 ;
+  int *arg8 ;
+  int *arg9 ;
+  npy_cfloat_wrapper *arg10 ;
+  std::vector<int > *arg11 = (std::vector<int > *) 0 ;
+  std::vector<int > *arg12 = (std::vector<int > *) 0 ;
+  std::vector<npy_cfloat_wrapper > *arg13 = (std::vector<npy_cfloat_wrapper > *) 0 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  int val3 ;
+  int ecode3 = 0 ;
+  int val4 ;
+  int ecode4 = 0 ;
+  PyArrayObject *array5 = NULL ;
+  int is_new_object5 ;
+  PyArrayObject *array6 = NULL ;
+  int is_new_object6 ;
+  PyArrayObject *array7 = NULL ;
+  int is_new_object7 ;
+  PyArrayObject *array8 = NULL ;
+  int is_new_object8 ;
+  PyArrayObject *array9 = NULL ;
+  int is_new_object9 ;
+  PyArrayObject *array10 = NULL ;
+  int is_new_object10 ;
+  std::vector<int > *tmp11 ;
+  std::vector<int > *tmp12 ;
+  std::vector<npy_cfloat_wrapper > *tmp13 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  PyObject * obj6 = 0 ;
+  PyObject * obj7 = 0 ;
+  PyObject * obj8 = 0 ;
+  PyObject * obj9 = 0 ;
+  
+  {
+    tmp11 = new std::vector<int>(); 
+    arg11 = tmp11; 
+  }
+  {
+    tmp12 = new std::vector<int>(); 
+    arg12 = tmp12; 
+  }
+  {
+    tmp13 = new std::vector<npy_cfloat_wrapper>(); 
+    arg13 = tmp13; 
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:bsr_elmul_bsr",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bsr_elmul_bsr" "', 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 '" "bsr_elmul_bsr" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bsr_elmul_bsr" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "bsr_elmul_bsr" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array5 = obj_to_array_contiguous_allow_conversion(obj4, PyArray_INT, &is_new_object5);
+    if (!array5 || !require_dimensions(array5,1) || !require_size(array5,size,1)
+      || !require_contiguous(array5)   || !require_native(array5)) SWIG_fail;
+    
+    arg5 = (int*) array5->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array6 = obj_to_array_contiguous_allow_conversion(obj5, PyArray_INT, &is_new_object6);
+    if (!array6 || !require_dimensions(array6,1) || !require_size(array6,size,1)
+      || !require_contiguous(array6)   || !require_native(array6)) SWIG_fail;
+    
+    arg6 = (int*) array6->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array7 = obj_to_array_contiguous_allow_conversion(obj6, PyArray_CFLOAT, &is_new_object7);
+    if (!array7 || !require_dimensions(array7,1) || !require_size(array7,size,1)
+      || !require_contiguous(array7)   || !require_native(array7)) SWIG_fail;
+    
+    arg7 = (npy_cfloat_wrapper*) array7->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array8 = obj_to_array_contiguous_allow_conversion(obj7, PyArray_INT, &is_new_object8);
+    if (!array8 || !require_dimensions(array8,1) || !require_size(array8,size,1)
+      || !require_contiguous(array8)   || !require_native(array8)) SWIG_fail;
+    
+    arg8 = (int*) array8->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array9 = obj_to_array_contiguous_allow_conversion(obj8, PyArray_INT, &is_new_object9);
+    if (!array9 || !require_dimensions(array9,1) || !require_size(array9,size,1)
+      || !require_contiguous(array9)   || !require_native(array9)) SWIG_fail;
+    
+    arg9 = (int*) array9->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array10 = obj_to_array_contiguous_allow_conversion(obj9, PyArray_CFLOAT, &is_new_object10);
+    if (!array10 || !require_dimensions(array10,1) || !require_size(array10,size,1)
+      || !require_contiguous(array10)   || !require_native(array10)) SWIG_fail;
+    
+    arg10 = (npy_cfloat_wrapper*) array10->data;
+  }
+  bsr_elmul_bsr<int,npy_cfloat_wrapper >(arg1,arg2,arg3,arg4,(int const (*))arg5,(int const (*))arg6,(npy_cfloat_wrapper const (*))arg7,(int const (*))arg8,(int const (*))arg9,(npy_cfloat_wrapper const (*))arg10,arg11,arg12,arg13);
+  resultobj = SWIG_Py_Void();
+  {
+    int length = (arg11)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg11))[0]),sizeof(int)*length);	 
+    delete arg11; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg12)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg12))[0]),sizeof(int)*length);	 
+    delete arg12; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg13)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_CFLOAT); 
+    memcpy(PyArray_DATA(obj),&((*(arg13))[0]),sizeof(npy_cfloat_wrapper)*length);	 
+    delete arg13; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return resultobj;
+fail:
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bsr_elmul_bsr__SWIG_9(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  int arg1 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int *arg5 ;
+  int *arg6 ;
+  npy_cdouble_wrapper *arg7 ;
+  int *arg8 ;
+  int *arg9 ;
+  npy_cdouble_wrapper *arg10 ;
+  std::vector<int > *arg11 = (std::vector<int > *) 0 ;
+  std::vector<int > *arg12 = (std::vector<int > *) 0 ;
+  std::vector<npy_cdouble_wrapper > *arg13 = (std::vector<npy_cdouble_wrapper > *) 0 ;
+  int val1 ;
+  int ecode1 = 0 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  int val3 ;
+  int ecode3 = 0 ;
+  int val4 ;
+  int ecode4 = 0 ;
+  PyArrayObject *array5 = NULL ;
+  int is_new_object5 ;
+  PyArrayObject *array6 = NULL ;
+  int is_new_object6 ;
+  PyArrayObject *array7 = NULL ;
+  int is_new_object7 ;
+  PyArrayObject *array8 = NULL ;
+  int is_new_object8 ;
+  PyArrayObject *array9 = NULL ;
+  int is_new_object9 ;
+  PyArrayObject *array10 = NULL ;
+  int is_new_object10 ;
+  std::vector<int > *tmp11 ;
+  std::vector<int > *tmp12 ;
+  std::vector<npy_cdouble_wrapper > *tmp13 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  PyObject * obj6 = 0 ;
+  PyObject * obj7 = 0 ;
+  PyObject * obj8 = 0 ;
+  PyObject * obj9 = 0 ;
+  
+  {
+    tmp11 = new std::vector<int>(); 
+    arg11 = tmp11; 
+  }
+  {
+    tmp12 = new std::vector<int>(); 
+    arg12 = tmp12; 
+  }
+  {
+    tmp13 = new std::vector<npy_cdouble_wrapper>(); 
+    arg13 = tmp13; 
+  }
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:bsr_elmul_bsr",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
+  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "bsr_elmul_bsr" "', 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 '" "bsr_elmul_bsr" "', argument " "2"" of type '" "int""'");
+  } 
+  arg2 = static_cast< int >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "bsr_elmul_bsr" "', argument " "3"" of type '" "int""'");
+  } 
+  arg3 = static_cast< int >(val3);
+  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "bsr_elmul_bsr" "', argument " "4"" of type '" "int""'");
+  } 
+  arg4 = static_cast< int >(val4);
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array5 = obj_to_array_contiguous_allow_conversion(obj4, PyArray_INT, &is_new_object5);
+    if (!array5 || !require_dimensions(array5,1) || !require_size(array5,size,1)
+      || !require_contiguous(array5)   || !require_native(array5)) SWIG_fail;
+    
+    arg5 = (int*) array5->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array6 = obj_to_array_contiguous_allow_conversion(obj5, PyArray_INT, &is_new_object6);
+    if (!array6 || !require_dimensions(array6,1) || !require_size(array6,size,1)
+      || !require_contiguous(array6)   || !require_native(array6)) SWIG_fail;
+    
+    arg6 = (int*) array6->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array7 = obj_to_array_contiguous_allow_conversion(obj6, PyArray_CDOUBLE, &is_new_object7);
+    if (!array7 || !require_dimensions(array7,1) || !require_size(array7,size,1)
+      || !require_contiguous(array7)   || !require_native(array7)) SWIG_fail;
+    
+    arg7 = (npy_cdouble_wrapper*) array7->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array8 = obj_to_array_contiguous_allow_conversion(obj7, PyArray_INT, &is_new_object8);
+    if (!array8 || !require_dimensions(array8,1) || !require_size(array8,size,1)
+      || !require_contiguous(array8)   || !require_native(array8)) SWIG_fail;
+    
+    arg8 = (int*) array8->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array9 = obj_to_array_contiguous_allow_conversion(obj8, PyArray_INT, &is_new_object9);
+    if (!array9 || !require_dimensions(array9,1) || !require_size(array9,size,1)
+      || !require_contiguous(array9)   || !require_native(array9)) SWIG_fail;
+    
+    arg9 = (int*) array9->data;
+  }
+  {
+    npy_intp size[1] = {
+      -1
+    };
+    array10 = obj_to_array_contiguous_allow_conversion(obj9, PyArray_CDOUBLE, &is_new_object10);
+    if (!array10 || !require_dimensions(array10,1) || !require_size(array10,size,1)
+      || !require_contiguous(array10)   || !require_native(array10)) SWIG_fail;
+    
+    arg10 = (npy_cdouble_wrapper*) array10->data;
+  }
+  bsr_elmul_bsr<int,npy_cdouble_wrapper >(arg1,arg2,arg3,arg4,(int const (*))arg5,(int const (*))arg6,(npy_cdouble_wrapper const (*))arg7,(int const (*))arg8,(int const (*))arg9,(npy_cdouble_wrapper const (*))arg10,arg11,arg12,arg13);
+  resultobj = SWIG_Py_Void();
+  {
+    int length = (arg11)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg11))[0]),sizeof(int)*length);	 
+    delete arg11; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg12)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_INT); 
+    memcpy(PyArray_DATA(obj),&((*(arg12))[0]),sizeof(int)*length);	 
+    delete arg12; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    int length = (arg13)->size(); 
+    PyObject *obj = PyArray_FromDims(1, &length,PyArray_CDOUBLE); 
+    memcpy(PyArray_DATA(obj),&((*(arg13))[0]),sizeof(npy_cdouble_wrapper)*length);	 
+    delete arg13; 
+    resultobj = helper_appendToTuple( resultobj, (PyObject *)obj ); 
+  }
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return resultobj;
+fail:
+  {
+    if (is_new_object5 && array5) Py_DECREF(array5);
+  }
+  {
+    if (is_new_object6 && array6) Py_DECREF(array6);
+  }
+  {
+    if (is_new_object7 && array7) Py_DECREF(array7);
+  }
+  {
+    if (is_new_object8 && array8) Py_DECREF(array8);
+  }
+  {
+    if (is_new_object9 && array9) Py_DECREF(array9);
+  }
+  {
+    if (is_new_object10 && array10) Py_DECREF(array10);
+  }
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_bsr_elmul_bsr(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[11];
+  int ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = (int)PyObject_Length(args);
+  for (ii = 0; (ii < argc) && (ii < 10); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 10) {
+    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) {
+        {
+          int res = SWIG_AsVal_int(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_int(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_INT)) ? 1 : 0;
+            }
+            if (_v) {
+              {
+                _v = (is_array(argv[5]) && PyArray_CanCastSafely(PyArray_TYPE(argv[5]),PyArray_INT)) ? 1 : 0;
+              }
+              if (_v) {
+                {
+                  _v = (is_array(argv[6]) && PyArray_CanCastSafely(PyArray_TYPE(argv[6]),PyArray_BYTE)) ? 1 : 0;
+                }
+                if (_v) {
+                  {
+                    _v = (is_array(argv[7]) && PyArray_CanCastSafely(PyArray_TYPE(argv[7]),PyArray_INT)) ? 1 : 0;
+                  }
+                  if (_v) {
+                    {
+                      _v = (is_array(argv[8]) && PyArray_CanCastSafely(PyArray_TYPE(argv[8]),PyArray_INT)) ? 1 : 0;
+                    }
+                    if (_v) {
+                      {
+                        _v = (is_array(argv[9]) && PyArray_CanCastSafely(PyArray_TYPE(argv[9]),PyArray_BYTE)) ? 1 : 0;
+                      }
+                      if (_v) {
+                        return _wrap_bsr_elmul_bsr__SWIG_1(self, args);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 10) {
+    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) {
+        {
+          int res = SWIG_AsVal_int(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_int(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_INT)) ? 1 : 0;
+            }
+            if (_v) {
+              {
+                _v = (is_array(argv[5]) && PyArray_CanCastSafely(PyArray_TYPE(argv[5]),PyArray_INT)) ? 1 : 0;
+              }
+              if (_v) {
+                {
+                  _v = (is_array(argv[6]) && PyArray_CanCastSafely(PyArray_TYPE(argv[6]),PyArray_UBYTE)) ? 1 : 0;
+                }
+                if (_v) {
+                  {
+                    _v = (is_array(argv[7]) && PyArray_CanCastSafely(PyArray_TYPE(argv[7]),PyArray_INT)) ? 1 : 0;
+                  }
+                  if (_v) {
+                    {
+                      _v = (is_array(argv[8]) && PyArray_CanCastSafely(PyArray_TYPE(argv[8]),PyArray_INT)) ? 1 : 0;
+                    }
+                    if (_v) {
+                      {
+                        _v = (is_array(argv[9]) && PyArray_CanCastSafely(PyArray_TYPE(argv[9]),PyArray_UBYTE)) ? 1 : 0;
+                      }
+                      if (_v) {
+                        return _wrap_bsr_elmul_bsr__SWIG_2(self, args);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 10) {
+    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) {
+        {
+          int res = SWIG_AsVal_int(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_int(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_INT)) ? 1 : 0;
+            }
+            if (_v) {
+              {
+                _v = (is_array(argv[5]) && PyArray_CanCastSafely(PyArray_TYPE(argv[5]),PyArray_INT)) ? 1 : 0;
+              }
+              if (_v) {
+                {
+                  _v = (is_array(argv[6]) && PyArray_CanCastSafely(PyArray_TYPE(argv[6]),PyArray_SHORT)) ? 1 : 0;
+                }
+                if (_v) {
+                  {
+                    _v = (is_array(argv[7]) && PyArray_CanCastSafely(PyArray_TYPE(argv[7]),PyArray_INT)) ? 1 : 0;
+                  }
+                  if (_v) {
+                    {
+                      _v = (is_array(argv[8]) && PyArray_CanCastSafely(PyArray_TYPE(argv[8]),PyArray_INT)) ? 1 : 0;
+                    }
+                    if (_v) {
+                      {
+                        _v = (is_array(argv[9]) && PyArray_CanCastSafely(PyArray_TYPE(argv[9]),PyArray_SHORT)) ? 1 : 0;
+                      }
+                      if (_v) {
+                        return _wrap_bsr_elmul_bsr__SWIG_3(self, args);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 10) {
+    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) {
+        {
+          int res = SWIG_AsVal_int(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_int(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_INT)) ? 1 : 0;
+            }
+            if (_v) {
+              {
+                _v = (is_array(argv[5]) && PyArray_CanCastSafely(PyArray_TYPE(argv[5]),PyArray_INT)) ? 1 : 0;
+              }
+              if (_v) {
+                {
+                  _v = (is_array(argv[6]) && PyArray_CanCastSafely(PyArray_TYPE(argv[6]),PyArray_INT)) ? 1 : 0;
+                }
+                if (_v) {
+                  {
+                    _v = (is_array(argv[7]) && PyArray_CanCastSafely(PyArray_TYPE(argv[7]),PyArray_INT)) ? 1 : 0;
+                  }
+                  if (_v) {
+                    {
+                      _v = (is_array(argv[8]) && PyArray_CanCastSafely(PyArray_TYPE(argv[8]),PyArray_INT)) ? 1 : 0;
+                    }
+                    if (_v) {
+                      {
+                        _v = (is_array(argv[9]) && PyArray_CanCastSafely(PyArray_TYPE(argv[9]),PyArray_INT)) ? 1 : 0;
+                      }
+                      if (_v) {
+                        return _wrap_bsr_elmul_bsr__SWIG_4(self, args);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 10) {
+    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) {
+        {
+          int res = SWIG_AsVal_int(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_int(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_INT)) ? 1 : 0;
+            }
+            if (_v) {
+              {
+                _v = (is_array(argv[5]) && PyArray_CanCastSafely(PyArray_TYPE(argv[5]),PyArray_INT)) ? 1 : 0;
+              }
+              if (_v) {
+                {
+                  _v = (is_array(argv[6]) && PyArray_CanCastSafely(PyArray_TYPE(argv[6]),PyArray_LONGLONG)) ? 1 : 0;
+                }
+                if (_v) {
+                  {
+                    _v = (is_array(argv[7]) && PyArray_CanCastSafely(PyArray_TYPE(argv[7]),PyArray_INT)) ? 1 : 0;
+                  }
+                  if (_v) {
+                    {
+                      _v = (is_array(argv[8]) && PyArray_CanCastSafely(PyArray_TYPE(argv[8]),PyArray_INT)) ? 1 : 0;
+                    }
+                    if (_v) {
+                      {
+                        _v = (is_array(argv[9]) && PyArray_CanCastSafely(PyArray_TYPE(argv[9]),PyArray_LONGLONG)) ? 1 : 0;
+                      }
+                      if (_v) {
+                        return _wrap_bsr_elmul_bsr__SWIG_5(self, args);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 10) {
+    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) {
+        {
+          int res = SWIG_AsVal_int(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_int(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_INT)) ? 1 : 0;
+            }
+            if (_v) {
+              {
+                _v = (is_array(argv[5]) && PyArray_CanCastSafely(PyArray_TYPE(argv[5]),PyArray_INT)) ? 1 : 0;
+              }
+              if (_v) {
+                {
+                  _v = (is_array(argv[6]) && PyArray_CanCastSafely(PyArray_TYPE(argv[6]),PyArray_FLOAT)) ? 1 : 0;
+                }
+                if (_v) {
+                  {
+                    _v = (is_array(argv[7]) && PyArray_CanCastSafely(PyArray_TYPE(argv[7]),PyArray_INT)) ? 1 : 0;
+                  }
+                  if (_v) {
+                    {
+                      _v = (is_array(argv[8]) && PyArray_CanCastSafely(PyArray_TYPE(argv[8]),PyArray_INT)) ? 1 : 0;
+                    }
+                    if (_v) {
+                      {
+                        _v = (is_array(argv[9]) && PyArray_CanCastSafely(PyArray_TYPE(argv[9]),PyArray_FLOAT)) ? 1 : 0;
+                      }
+                      if (_v) {
+                        return _wrap_bsr_elmul_bsr__SWIG_6(self, args);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 10) {
+    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) {
+        {
+          int res = SWIG_AsVal_int(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_int(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_INT)) ? 1 : 0;
+            }
+            if (_v) {
+              {
+                _v = (is_array(argv[5]) && PyArray_CanCastSafely(PyArray_TYPE(argv[5]),PyArray_INT)) ? 1 : 0;
+              }
+              if (_v) {
+                {
+                  _v = (is_array(argv[6]) && PyArray_CanCastSafely(PyArray_TYPE(argv[6]),PyArray_DOUBLE)) ? 1 : 0;
+                }
+                if (_v) {
+                  {
+                    _v = (is_array(argv[7]) && PyArray_CanCastSafely(PyArray_TYPE(argv[7]),PyArray_INT)) ? 1 : 0;
+                  }
+                  if (_v) {
+                    {
+                      _v = (is_array(argv[8]) && PyArray_CanCastSafely(PyArray_TYPE(argv[8]),PyArray_INT)) ? 1 : 0;
+                    }
+                    if (_v) {
+                      {
+                        _v = (is_array(argv[9]) && PyArray_CanCastSafely(PyArray_TYPE(argv[9]),PyArray_DOUBLE)) ? 1 : 0;
+                      }
+                      if (_v) {
+                        return _wrap_bsr_elmul_bsr__SWIG_7(self, args);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 10) {
+    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) {
+        {
+          int res = SWIG_AsVal_int(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_int(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            {
+              _v = (is_array(argv[4]) && PyArray_CanCastSafely(PyArray_TYPE(argv[4]),PyArray_INT)) ? 1 : 0;
+            }
+            if (_v) {
+              {
+                _v = (is_array(argv[5]) && PyArray_CanCastSafely(PyArray_TYPE(argv[5]),PyArray_INT)) ? 1 : 0;
+              }
+              if (_v) {
+                {
+                  _v = (is_array(argv[6]) && PyArray_CanCastSafely(PyArray_TYPE(argv[6]),PyArray_CFLOAT)) ? 1 : 0;
+                }
+                if (_v) {
+                  {
+                    _v = (is_array(argv[7]) && PyArray_CanCastSafely(PyArray_TYPE(argv[7]),PyArray_INT)) ? 1 : 0;
+                  }
+                  if (_v) {
+                    {
+                      _v = (is_array(argv[8]) && PyArray_CanCastSafely(PyArray_TYPE(argv[8]),PyArray_INT)) ? 1 : 0;
+                    }
+                    if (_v) {
+                      {
+                        _v = (is_array(argv[9]) && PyArray_CanCastSafely(PyArray_TYPE(argv[9]),PyArray_CFLOAT)) ? 1 : 0;
+                      }
+                      if (_v) {
+                        return _wrap_bsr_elmul_bsr__SWIG_8(self, args);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  if (argc == 10) {
+    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) {
+        {
+