3

Why can't nested list be packed?

In[252]:= ftest = {1., {3.}};
ftest = Developer`ToPackedArray[ftest];
Developer`PackedArrayQ[ftest]

Out[254]= False

Al Guy
  • 1,610
  • 1
  • 10
  • 15
  • 5
    Only tensors (passes ArrayQ[]) can be packed. {{1.}, {3.}}, {{1., 3.}}, and {1., 3.} can all be packed, but yours can't. – J. M.'s missing motivation Mar 30 '16 at 05:07
  • Thanks! I guess it has something to do how memory can be allocated. – Al Guy Mar 30 '16 at 05:12
  • (P.S. could anyone who can link to the appropriate place in the docs answer this question for me? I promise to upvote. ;)) – J. M.'s missing motivation Mar 30 '16 at 05:14
  • 5
    @J.M. _"Packed arrays are a representation for rectangular tensors of machine integers, machine reals, and complex numbers with real and imaginary parts that are machine reals." http://reference.wolfram.com/mathematica/tutorial/LinearAlgebraPerformance.html – Dr. belisarius Mar 30 '16 at 05:18
  • 3
    Just think about how you would implement such a data structure in a low-level language like C. It's much more complicated than dealing with a rectangular array. For a rectangular array you only need to store its data and its dimensions, and indexing into it is trivial. That's what "packed" means here: use one flat block of memory, which is very fast. For a ragged 2D array you'd likely have multiple 1D sub-arrays allocated separately and a pointer vector with references to each. Each sub-array needs to store its length separately. This is exactly what a non-packed list is. – Szabolcs Mar 30 '16 at 07:31

1 Answers1

4

Per J.M.'s and Dr. Belisarius's comment:

Only tensors passing ArrayQ can be packed. Any of {{1.}, {3.}}, {{1., 3.}}, and {1., 3.} can be packed, but ragged, non-rectangular lists (e.g. {{1, 2}, {3, 4, 5}} or {1, {2}, 3}) cannot.

"Packed arrays are a representation for rectangular tensors of machine integers, machine reals, and complex numbers with real and imaginary parts that are machine reals"

lists = N@{
    {{1}, {3}},
    {{1, 3}},
    {1, 3},
    {1},
    {1, 2},
    {1, {2}, 3},
    {{1, 2}, {3, 4, 5}}
    };
ArrayQ /@ lists
packed = Developer`ToPackedArray /@ lists;
Developer`PackedArrayQ /@ packed
{True, True, True, True, True, False, False} (* ArrayQ *)

{True, True, True, True, True, False, False} (* PackedArrayQ *)

from the documentation.

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
István Zachar
  • 47,032
  • 20
  • 143
  • 291