ToNDArray¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
ToNDArray[list]
returns list stored as a dense machine-precision buffer. The result is still a List -- same Head, same printed form, same elements -- but NDArrayQ gives True for it. ToNDArray[list, DataType -> "float64"] forces the element type. A mix of Integer and Real machine values is widened to a Real buffer (the integers become doubles); an all-Integer list stays Integer. Returns list unchanged when it is not rectangular, is empty, or holds any non-machine value. Unlike automatic packing it ignores the size threshold.
Examples (12)¶
Every input below was run against the current Mathilda build and its output recorded.
Basic examples (2)¶
In[1]:= a = ToPackedArray[{1, 2, 3.}]
Out[1]= {1.0, 2.0, 3.0}
In[2]:= {PackedArrayQ[a], DataType[a]}
Out[2]= {True, "float64"}
Scope (3)¶
A numeric buffer -> a bool one
Not numeric: delists to symbolic
Options (2)¶
In[6]:= DataType[ToNDArray[{1, 2, 3}, DataType -> "float64"]]
Out[6]= "float64"
In[7]:= NDArrayQ[ToNDArray[{1., 2.5}, DataType -> "int64"]]
Out[7]= False
Applications (5)¶
A real list stored as a dense buffer, still printed as a List
Only NDArrayQ reveals that it is packed
An all-integer list packs to an int64 buffer
A mixed integer/real list widens to a float buffer on request
An int64 request that would round reals is refused; the list is returned unchanged
Implementation notes¶
Algorithm. builtin_tondarray first strips an optional trailing DataType -> "..." rule
with pack_take_dtype (rightmost wins); after that there must be exactly one positional
argument. An argument that is already a packed List with no conflicting DataType is
returned by expr_copy (a no-op); a visible NDArray[...] is turned back into a nested
List first (ndarray_to_nested_list), so ToNDArray is also a way to say "same values, as
a List". The list is then packed by pack_force_coerce → pack_build with min_elems = 0
(no size threshold, unlike automatic packing) and coerce = true:
pack_sniffwalks the nested list once, checking rectangularity and folding every leaf's class (PK_INT/PK_REAL/PK_BOOL) into one; withcoerce = truea mix of machineIntegerandRealfolds toPK_REAL(the integers will widen todouble), whereas the automatic path (coerce = false) declines that mix to keep1 === 1.observable.- The dtype is
int64(all-integer),float64(real, or coerced mixed), orbool(all-True/False). An explicitDataTypemay widen an exact list to a float buffer but is refused when it would round aRealinto anint64slot (want == NDT_INT64 && cls != PK_INT), request a complex buffer, or mismatch bool-vs-number — in which case the original list is returned unchanged. pack_flattenwrites the leaves row-major into a freshlymalloc'd buffer.
A list that is ragged, empty, or holds any Rational/BigInt/arbitrary-precision/Complex/
symbolic element simply comes back unchanged (never an error).
Data structures. The result is an EXPR_NDARRAY with present_as = NDA_HEAD_LIST — the
packed-list surface, so Head is still List and only NDArrayQ/PackedArrayQ reveal the
buffer. Storage is a dense row-major buffer of ndt_elem_size(dt) * n bytes carrying rank and
int64 dims (up to NDARRAY_MAX_RANK).
Complexity / limits. O(n) in two passes (sniff then flatten) and one allocation. Ignores
the automatic-packing size threshold. Complex dtypes are rejected (no faithful round trip
yet); the packing contract is representation-only, so every downstream operation either
answers exactly as the ordinary list does or falls back to it.
Attributes: Protected.
References¶
See also: Rational, Complex, Real, ToPackedArray, DataType, List
- Source:
src/pack.c - Specification:
docs/spec/builtins/packed-arrays.md - Tests:
tests/test_compiledfunction.c - Tests:
tests/test_erf.c - Tests:
tests/test_erfc.c - Tests:
tests/test_erfi.c
Notes & additional examples¶
Notes¶
ToNDArray[list] returns list stored as a dense machine-precision buffer. The result is
still a List — same Head, same printed form, same elements — so the packing is invisible
except to NDArrayQ / PackedArrayQ. Unlike automatic packing it ignores the size threshold,
so even a tiny list packs.
The element type is inferred: all-Integer → "int64", all-Real → "float64",
all-True/False → "bool". A list that mixes machine Integer and Real widens to a
"float64" buffer (the integers become doubles) — the one point where the explicit request
diverges from automatic packing, which leaves {1, 2, 3.} an ordinary list because turning
1 into 1. would be an observable head change. ToNDArray[list, DataType -> "..."] forces
the type, and may widen an exact list to a float buffer, but never rounds a Real into an
int64 slot (that request returns the list unchanged).
It returns list unchanged — not an error — whenever it cannot pack: a ragged (non-
rectangular) list, an empty list, or any Rational/BigInt/arbitrary-precision/Complex/
symbolic element. On an already-packed list it is a no-op; on a visible NDArray[...] it
restates the same values as a List.