[Numpy-discussion] Re: linalg.svd returns fortran arrays, causes problems
Travis Oliphant
oliphant.travis at ieee.org
Mon Mar 20 20:12:02 CST 2006
Zachary Pincus wrote:
>> Can you give us some small, self-contained code that demonstrates the
>> problem?
>
> u, s, vt = numpy.linalg.svd([[1,2],[3,4]])
> u.flags.fortran
> True
>
> The problem, as per my original email, is that linalg.svd seems to be
> now returning fortran-style arrays. I believe that it did not do this
> in the past, but I am not certain.
I think it's always done this. It is really very easy to generate
fortran-order arrays (always has been --- the transpose operation has
always returned a fortran-order array).
a = numpy.rand(10,20).transpose()
a.flags.fortran
I think the issue that has raised this discussion is that the reshape
function is now not running asarray if it doesn't have to --- this was
done to preserve matrices...
Notice that currently the asarray function will convert Fortran-order
arrays to C-order arrays (and thus make a copy). Now that I'm aware
it's doing this, I actually think that's a bug. This is because
Fortran order is really just a special case of striding, and other
non-uniformly strided arrays are not automatically converted just
because asarray is called.
So, I think as a side-issue that bug should be fixed. Now, the real
issue that brought this to the fore-front is what is meant by the
"reshape" function.
It has been the case for several months that a fortran-order array has a
different scan order for it's reshape *method* than any-other strided
array. The reshape method is one of those functions that you can't
avoid thinking about layout of the array (so my previous statement about
not concerning yourself with striding was too far-reaching).
We are supporting more than one view about how layout should be done.
But, we should be doing it in a backward-compatible fashion so that the
standard is C-contiguous unless otherwise specified. Thus, I think the
bug is in the design of the reshape method in that it uses a different
layout standard depending on whether or not the array is Fortran or
not. This bug has been there for awhile, I think, but only exposed by
the re-working of the reshape function.
I propose to change the reshape method to always expect a C-contiguous
perspective unless a fortran flag is set (defaults to False), in which
case the perspective is Fortran-contiguous. This is true regardless of
the layout of the current array.
This will fix the reshape function as well but also make it possible for
someone to use reshape who has a Fortran-order array-view.
>
>
> In any case, there are two issues at play:
> (1) Should any numpy functions be allowed to return fortran arrays
> unless specifically requested?
> (2) Should all structural operations like reshape (etc.) behave the
> same for fortran and c-style arrays?
>
The issue is that there are only a few shape-changing functions (ravel,
reshape, etc.), that the Python user needs to have any perspective at
all on how the data is layed out in memory. Other routines should not
depend on the striding (or if they do they need to ensure it's
contiguous first).
For those routines that do require memory-layout knowledge the default
must continue to be C-contiguous, but we need to add a fortran keyword
to allow that perspective as well should the user choose it.
This is already done for the ravel method. And it should be available
for reshape (and resize---though that one will take more effort and I
will not do tonight---as well).
Thanks for the bug-reports.
-Travis
More information about the Numpy-discussion
mailing list