On 31/01/2012 18:23, Chris Barker wrote:
On Tue, Jan 31, 2012 at 6:14 AM, Malcolm Reynolds
<malcolm.reyno...@gmail.com>  wrote:
Not exactly an answer to your question, but I can highly recommend
using Boost.python, PyUblas and Ublas for your C++ vectors and
matrices. It gives you a really good interface on the C++ side to
numpy arrays and matrices, which can be passed in both directions over
the language threshold with no copying.
or use Cython...

If I had to guess I'd say sometimes when transposing numpy simply sets
a flag internally to avoid copying the data, but in some cases (such
as perhaps when multiplication needs to take place) the data has to be
placed in a new object.
good guess:

V = numpy.dot(R, U.transpose()).transpose()
a
array([[1, 2],
        [3, 4],
        [5, 6]])
a.flags
   C_CONTIGUOUS : True
   F_CONTIGUOUS : False
   OWNDATA : True
   WRITEABLE : True
   ALIGNED : True
   UPDATEIFCOPY : False

b = a.transpose()
b.flags
   C_CONTIGUOUS : False
   F_CONTIGUOUS : True
   OWNDATA : False
   WRITEABLE : True
   ALIGNED : True
   UPDATEIFCOPY : False

so the transpose() simple re-arranges the strides to Fortran order,
rather than changing anything in memory.

np.dot() produces a new array, so it is C-contiguous, then you
transpose it, so you get a fortran-ordered array.

Now when I call my C++ function from the Python side, all the data in V is 
printed, but it has been transposed.
as mentioned, if you are working with arrays in C++ (or fortran, orC,
or...) and need to count on the ordering of the data, you need to
check it in your extension code. There are utilities for this.

However, if I do:
V = numpy.array(U.transpose()).transpose()
right:

In [7]: a.flags
Out[7]:
   C_CONTIGUOUS : True
   F_CONTIGUOUS : False
   OWNDATA : True
   WRITEABLE : True
   ALIGNED : True
   UPDATEIFCOPY : False

In [8]: a.transpose().flags
Out[8]:
   C_CONTIGUOUS : False
   F_CONTIGUOUS : True
   OWNDATA : False
   WRITEABLE : True
   ALIGNED : True
   UPDATEIFCOPY : False

In [9]: np.array( a.transpose() ).flags
Out[9]:
   C_CONTIGUOUS : False
   F_CONTIGUOUS : True
   OWNDATA : True
   WRITEABLE : True
   ALIGNED : True
   UPDATEIFCOPY : False


so the np.array call doesn't re-arrange the order if it doesn't need
to. If you want to force it, you can specify the order:

In [10]: np.array( a.transpose(), order='C' ).flags
Out[10]:
   C_CONTIGUOUS : True
   F_CONTIGUOUS : False
   OWNDATA : True
   WRITEABLE : True
   ALIGNED : True
   UPDATEIFCOPY : False


(note: this does surprise me a bit, as it is making a copy, but there
you go -- if order matters, specify it)

In general, numpy does a lot of things for the sake of efficiency --
avoiding copies when it can, for instance -- this give efficiency and
flexibility, but you do need to be careful, particularly when
interfacing with the binary data directly.

-Chris






Thanks for all the answers to my question. Helped a lot.

Mads

--
+-----------------------------------------------------+
| Mads Ipsen                                          |
+----------------------+------------------------------+
| Gåsebæksvej 7, 4. tv |                              |
| DK-2500 Valby        | phone:          +45-29716388 |
| Denmark              | email:  mads.ip...@gmail.com |
+----------------------+------------------------------+


_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion

Reply via email to