
Re: Packed Arrays in version 4
Posted:
Aug 5, 1999 2:28 AM


In article <7o5h0k$rjs@smc.vnet.net>, Bruno Daniel <bruno.daniel@hadiko.de> writes >Hi John > >You could use contexts: Define a new context "Efficient`" and put it >in front of "System`" in the context search path. Then you can >define your own "Transpose" etc inside this context and use the >builtin "Transpose" by fully qualifying it (System`Transpose) in >the implementation of your "Transpose". > >Here's an example how this can be done in the context "Global`": > >In[1]:= Global`Transpose[x_]:= System`Transpose[x] + a >In[2]:= Transpose[{{c,d,e}}] >Out[2]:= {{a+c},{a+d},{a+e}} > >Yours sincerely > Bruno >
Thank you: that is really neat, and I really appreciate not having to Unprotect and modify the System definition.
This works well for Transpose, and for other functions which "sometimes" unpack PackedArrays. My list so far of "higher level" functions with this behaviour is:
(1) Transpose: a multidimensional Transpose always unpacks
(2) Outer: always unpacks
(3) Map: usually OK but can surprise you (see below)
What I intend to do at present is to modify Transpose and Outer (and possibly also Map) as suggested above and/or by Ted Ersek (MG18963)  thank you both.
I give some illustrations here of 3 different ways of doing exactly the same thing, with 3 wholly different results (i.e. "Packed", "Unpacked" and "List of Packed" for Dot, Outer and Map). Yes I know that Dot is the best to use in this case, but the choice is not so simple for functions other than Times!
In[1]:= avbytesize[arr_] := ByteCount[arr]/Length[Flatten[{arr}]] // N
In[2]:= arr1 = Range[1., 10.]; arr2 = Range[1., 100.];
In[3]]:= arr1dot2 = Transpose[{arr1}].{arr2}; arr1outer2 = Outer[Times, arr1, arr2]; arr2map1 = arr2*# & /@ arr1;
In[4]:= Dimensions[#] & /@ {arr1, arr2, arr1dot2, arr1outer2, arr2map1}
Out[4]= {{10}, {100}, {10, 100}, {10, 100}, {10, 100}}
In[5]:= avbytesize[#] & /@ {arr1, arr2, arr1dot2, arr1outer2, arr2map1}
Out[5]= {13.6, 8.56, 8.06, 20.296, 8.616}
In[6]:= Developer`PackedArrayQ[#] & /@ {arr1, arr2, arr1dot2, arr1outer2, arr2map1}
Out[6]= {True, True, True, False, False}
A much more risky redefinition to get around the problem of Times[I*realarray] is also possible, since redefinition of Times seems to be very problematic (see my reply to Ted Ersek(MG18963)):
Global`I := N[System`I]
I am still struggling with the full implications of this  I suspect it would seriously mess up symbolic simplifications.
Thank you,
John.  from  John Tanner home  john@janacek.demon.co.uk mantra  curse Microsoft, curse... work  john.tanner@gecm.com I hate this 'orrible computer, I really ought to sell it: It never does what I want, but only what I tell it.

