Multiple assignment confusion
I am trying to interchange two pieces of an array. Here is my demo code:
from Numeric import * a=array([.7,.1,.1,.1]) a=multiply.outer(a,a) a=multiply.outer(a,a) sum(sum(sum(sum(a)))) 1.0000000000000002 a[1,0],a[1,1]=a[1,1],a[1,0] sum(sum(sum(sum(a)))) 0.93999999999999972
So a is a four-dimensional array that sums to 1, but when I attempt to switch two 2-d sub-arrays of it I just end up duplicating one of them, shown by a change in the value of the sum (to .94). Is this behavior deliberate? It certainly seems to break Python's tuple-assignment model. What I would ideally like to do is perform this swap without more than two-elements'-worth of temporary storage. I.e. perform it as a pure reference swap or switch each pair of elements one by one, reusing temporary space. Is this possible with Numeric (or Numarray?)? Curious, Ben
Benjamin Schwartz wrote:
I am trying to interchange two pieces of an array. Here is my demo code:
from Numeric import * a=array([.7,.1,.1,.1]) a=multiply.outer(a,a) a=multiply.outer(a,a) sum(sum(sum(sum(a)))) 1.0000000000000002 a[1,0],a[1,1]=a[1,1],a[1,0] sum(sum(sum(sum(a)))) 0.93999999999999972
So a is a four-dimensional array that sums to 1, but when I attempt to switch two 2-d sub-arrays of it I just end up duplicating one of them, shown by a change in the value of the sum (to .94). Is this behavior deliberate? It certainly seems to break Python's tuple-assignment model.
What I would ideally like to do is perform this swap without more than two-elements'-worth of temporary storage. I.e. perform it as a pure reference swap or switch each pair of elements one by one, reusing temporary space. Is this possible with Numeric (or Numarray?)?
Curious, Ben
I believe that this is simply a reflection of the fact that subarrays (for Numeric and numarray) are views into the original array rather than copies. A simpler example illustrates the same problem:
a = reshape(arange(4), (2,2)) a array([[0, 1], [2, 3]]) a[0],a[1]=a[1],a[0] a array([[2, 3], [2, 3]])
Even though the right side of the assignment is stored effectively in temporary variables, what is stored are views into the original array, not copies of the subarrays. When the first assignment is made to a[0] (=a[1]), the data in the reference a[0] on the right hand side has changed as well since it views exactly the same data. When it comes time to set a[1] it will be copying from the updated a[0] and thus the duplication. This doesn't happen for a list since one is essentially rebinding the element in a list to another object. In other words, for this case:
b = [[0,1],[2,3]] b[0],b[1]=b[1],b[0] b [[2, 3], [0, 1]]
assigning to b[0] is rebinding that list element away from the list [0,1] to the list [2,3]; changing what the elements b refer to in no way changes the contents of either of the lists that b contained. Numeric arrays have a coupling across dimensions that doesn't exist for lists since nested lists are analogous to arrays of pointers to pointers whereas Numeric arrays are just multidimensional arrays with no indirection involved. The above behavior could be avoided if subarrays always produced copies. This issue was given a great deal of discussion and thought for numarray and for various reasons it was decided not to change the behavior of slices and subarray references. As to whether it is possible to switch subarray contents with only using one or two temporary storage elements efficiently, offhand I don't believe so, but I haven't given it much thought (and don't have the time to) but perhaps someone else knows of an existing mechanism to do so. Nothing prevents writing an extension to provide such capability. Perry Greenfield
participants (2)
-
Benjamin Schwartz
-
Perry Greenfield