title: Optimize NumPy sum of matrices iterated through every element
body: <p>I'm working using <strong>numpy 1.9</strong>, <strong>python 2.7</strong> with opencv, dealing with big matrices and I have to make the following operation many times</p>
  
  <pre><code>def sumShifted(A):  # A: numpy array 1000*1000*10
      return A[:, 0:-1] + A[:, 1:]    
  </code></pre>
  
  <p>I'd like to optimize this operation, if possible; I tried with <a href="http://cython.org/" rel="nofollow">Cython</a> but I don't get any significant improvement but I do not exclude that it is because of my bad implementation.<br></p>
  
  <p>Is there a way to make it faster?</p>
  
  <p><strong>EDIT</strong>:
  <code>sumShifted</code> is getting called in a for loop like this:</p>
  
  <pre><code>for i in xrange(0, 400):
      # ... Various operations on B
      A = sumShifted(B)
      # ... Other operations on B
  
  
  #More detailed
  for i in xrange(0, 400):
      A = sumShifted(a11)
      B = sumShifted(a12)
      C = sumShifted(b12)
      D = sumShifted(b22)
  
      v = -upQ12/upQ11
  
      W, X, Z = self.function1( input_matrix, v, A, C[:,:,4], D[:,:,4] )
      S, D, F = self.function2( input_matrix, v, A, C[:,:,5], D[:,:,5] )
      AA      = self.function3( input_matrix, v, A, C[:,:,6], D[:,:,6] )
      BB      = self.function4( input_matrix, v, A, C[:,:,7], D[:,:,7] )
  </code></pre>
  
  <p><strong>EDIT2</strong>: Following your advice I created this two runnable benchmarks (with Cython) about merging the 4 <code>sumShifted</code> methods in one.</p>
  
  <pre><code>A, B, C, D= improvedSumShifted(E, F, G, H)
  #E,F: 1000x1000 matrices
  #G,H: 1000x1000x8 matrices
  
  #first implementation
  def improvedSumShifted(np.ndarray[dtype_t, ndim=2] a, np.ndarray[dtype_t, ndim=2] b, np.ndarray[dtype_t, ndim=3] c, np.ndarray[dtype_t, ndim=3] d):
    cdef unsigned int i,j,k;
    cdef unsigned int w = a.shape[0], h = a.shape[1]-1, z = c.shape[2]
    cdef np.ndarray[dtype_t, ndim=2] aa = np.empty((w, h))
    cdef np.ndarray[dtype_t, ndim=2] bb = np.empty((w, h))
    cdef np.ndarray[dtype_t, ndim=3] cc = np.empty((w, h, z))
    cdef np.ndarray[dtype_t, ndim=3] dd = np.empty((w, h, z))
    with cython.boundscheck(False), cython.wraparound(False), cython.overflowcheck(False), cython.nonecheck(False):
      for i in range(w):
        for j in range(h):
          aa[i,j] = a[i,j] + a[i,j+1]
          bb[i,j] = b[i,j] + b[i,j+1]
          for k in range(z):
            cc[i,j,k] = c[i,j,k] + c[i,j+1,k]
            dd[i,j,k] = d[i,j,k] + d[i,j+1,k]
  return aa, bb, cc, dd
  
  #second implementation
  def improvedSumShifted(np.ndarray[dtype_t, ndim=2] a, np.ndarray[dtype_t, ndim=2] b, np.ndarray[dtype_t, ndim=3] c, np.ndarray[dtype_t, ndim=3] d):
    cdef unsigned int i,j,k;
    cdef unsigned int w = a.shape[0], h = a.shape[1]-1, z = c.shape[2]
    cdef np.ndarray[dtype_t, ndim=2] aa = np.copy(a[:, 0:h])
    cdef np.ndarray[dtype_t, ndim=2] bb = np.copy(b[:, 0:h])
    cdef np.ndarray[dtype_t, ndim=3] cc = np.copy(c[:, 0:h])
    cdef np.ndarray[dtype_t, ndim=3] dd = np.copy(d[:, 0:h])
    with cython.boundscheck(False), cython.wraparound(False), cython.overflowcheck(False), cython.nonecheck(False):
    for i in range(w):
      for j in range(h):
        aa[i,j] += a[i,j+1]
        bb[i,j] += b[i,j+1]
        for k in range(z):
          cc[i,j,k] += c[i,j+1,k]
          dd[i,j,k] += d[i,j+1,k]
  
  return aa, bb, cc, dd
  </code></pre>