[Numpy-discussion] Proposed X.flat solution

David M. Cooke cookedm at physics.mcmaster.ca
Fri Feb 18 13:12:10 CST 2005


Travis Oliphant <oliphant at ee.byu.edu> writes:

>>Hmm.  It seems to me that if it is not a live view you can run into
>>serious problems.  What happens if you do this:
>>
>>a = zeros((10,10))
>>b = a[::2,::2].flat
>>b[4] = 1
>>a[0,8] = 2
>>del b
>>
>>Doesn't your behavior lead to a[0,8] being overwritten to 1 by the copy
>>back from b?
>>
>>
> Well in this particular case since a is contiguous to begin with, b is
> not a copy so the copy-back would not occur.
>
> But, you bring up a valid point that if "a" were discontiguous which
> forced a copy, then any later modifications to "a" would be ignored.
> Now, this could be fixed by making "a" read-only for the duration of
> existence of the flattened reference.

> In fact, it probably stands to reason that whenever, UPDATEIFCOPY is
> used on the C-level, the to-be-copied-to array is flagged readonly for
> the duration of existence of the "reference."

Ugh. I realize I'm going to have to sit down and think on this first,
and look at code. My gut feeling is UPDATEIFCOPY and read-write-locks
(which is essentially what you're proposing) will make for some odd,
hard-to-track down, errors.

> Besides that point, to clarify what we are talking about here:
>
> 1)  The PEP has been modified so that X[K] is interpreted as X[K,]
> for integer arrays, and the previously-discussed distinction
> disappears.
>
> 2)  It is desired that X.flat[K]  provide the flattened behavior.
> How should this be done?
>
>      a) having X.flat return an indexable iterator (with an __array__
> method that will automatically return an update-if-copy array on
>          request from asarray() or C-level equivalent)

I'm +1. This feels to be the simplest (in sense of use, not necessarily
implementation :-), and the obvious use. Here, X.flat is *always* a
valid view of X.

>      b) having X.flat return an update-if-copy array (with X flagged
> as readonly while a reference to X.flat exists)

-0, for the locking reasons I mention above. For this usage, I'd make
it a method instead.

>      c) it shouldn't be done and X.flat should just raise an error if
> X is not contiguous.

If this one, then I'd say that X.flat is useless and should be
removed. ravel() (or X.ravel()) should return a view or copy depending
on whether X is contiguous or not. A copy could be forced by a keyword
argument: ravel(X, copy=True)

While we're at it, I'd argue that "ravel" is a bad word for this
usage -- it's not obvious what it does. "flatten" might be a better word.

-- 
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke                      http://arbutus.physics.mcmaster.ca/dmc/
|cookedm at physics.mcmaster.ca




More information about the Numpy-discussion mailing list