title: Cython: Transpose a memoryview
body: <p><strong>Some background for the question:</strong></p>
  
  <p>I'm trying to optimise a custom neural network code.
  It relies heavily on loops and I decided to use cython to speed up the calculation.</p>
  
  <p>I followed the usual online tips: Declare all local variables with appropriate cdefs and switch off boundscheck and nonecheck. This barely gave me 10% performance.</p>
  
  <p>Well, my code relies on lots of class members. Therefore I decided to convert the entire class into a cdef class. Turns out that cython doesn't allow numpy ndarrays as types for class members. Instead one has to use memoryviews.
  Unfortunately the two types seem to be vastly incompatible.</p>
  
  <p>I already ran into this problem: <a href="https://stackoverflow.com/questions/37174074/cython-memoryview-transpose-typeerror">Cython memoryview transpose: Typeerror</a></p>
  
  <p>To sum it up: You can store an np.ndarray in a memoryview. You can transpose it and store the returned array in a memview. But not if that memview is a class member. Then you have to create an intermediate memview, store the result in that and assign the intermediate memview to the class member.</p>
  
  <p>Here's the code ( many thanks to DavidW)</p>
  
  <pre><code>def double[:,:,:,:] temporary_view_of_transpose
  
  # temporary_view_of_transpose now "looks at" the memory allocated by transpose
  # no square brackets!
  temporary_view_of_transpose = out_image.transpose(1, 0, 2, 3)
  
  # data is copied from temporary_view_of_transpose to self.y
  self.y[...] = temporary_view_of_transpose # (remembering that self.y must be the correct shape before this assignment).
  </code></pre>
  
  <p>Now I've got a new problem.
  The code above is from the so-called "forward-pass". There is also a corresponding backward-pass, which does all the calculations backward (for analytical gradients).</p>
  
  <p>This means that for the backward pass, I have to transpose the memoryview and store it in a numpy array:</p>
  
  <pre><code>cdef np.ndarray[DTYPE_t, ndim=4] d_out_image = self.d_y.transpose(1, 0, 2,3)
  </code></pre>
  
  <p>d_y has to be a class member, therefore it has to be a memoryview. Memoryviews don't allow transposing. They have a .T method, but that doesn't help me.</p>
  
  <p><strong>Actual Question:</strong></p>
  
  <ul>
  <li>How do I correctly store a numpy array as a class member of a cdef class?</li>
  <li>If the answer is :"as a memoryview", how do I transpose a memoryview ?</li>
  </ul>