How to interpret the FullForm of a SparseArray?
Reposting my answer from here (its relevant part about SparseArray)
The anatomy of sparse arrays
We start with a generally useful API for construction and deconstruction of SparseArray
objects:
ClearAll[spart, getIC, getJR, getSparseData, getDefaultElement, makeSparseArray];
HoldPattern[spart[SparseArray[s___], p_]] := {s}[[p]];
getIC[s_SparseArray] := spart[s, 4][[2, 1]];
getJR[s_SparseArray] := Flatten@spart[s, 4][[2, 2]];
getSparseData[s_SparseArray] := spart[s, 4][[3]];
getDefaultElement[s_SparseArray] := spart[s, 3];
makeSparseArray[dims : {_, _}, jc : {__Integer}, ir : {__Integer},
data_List, defElem_: 0] :=
SparseArray @@ {Automatic, dims, defElem, {1, {jc, List /@ ir}, data}};
Some brief comments are in order. Here is a sample sparse array:
In[15]:=
ToHeldExpression@ToString@FullForm[
sp = SparseArray[{{0,0,1,0,2},{3,0,0,0,4},{0,5,0,6,7}}]
]
Out[15]=
Hold[
SparseArray[
Automatic,
{3,5}, (* Dimensions *)
0, (* Default element *)
{
1,
{{0,2,4,7},{{3},{5},{1},{5},{2},{4},{5}}}, (* {ic, jr} *)
{1,2,3,4,5,6,7} (* sparseData*)
}
]
]
(I used ToString
- ToHeldExpression
cycle to convert List[...]
etc in the FullForm
back to {...}
for the ease of reading). Here are the meanings of the parts:
{3,5}
are obviously dimensions.- Next is
0
, the default element. Next is a nested list, which we can denote as
{1,{ic,jr}, sparseData}
. Here:ic
gives a total number of nonzero (non-default) elements as we add rows - so it is first 0, then 2 after first row, the second adds 2 more, and the last adds 3 more.- The next list,
jr
, gives positions of non-zero elements in all rows, so they are3
and5
for the first row,1
and5
for the second, and2
,4
and5
for the last one.
There is no confusion as to where which row starts and ends here, since this can be determined by the
ic
list.- Finally, we have the
sparseData
, which is a list of the non-zero elements as read row by row from left to right (the ordering is the same as for thejr
list).
Supplement:
(The following interpretation is a guess based on Silvia's observation.)
Suppose we have an array $A$ with dimension $N_1 \times N_2 \times \cdots \times N_n$,($n>1$): $\{A_1,A_2,\dots , A_k, \dots , A_{N_1}\}$, with the unspecified value (i.e. the background) being $b$.
And inside any $A_k$, there are $C_k$ numbers other than $b$: $\{\xi_{k,1},\xi_{k,2},\dots,\xi_{k,C_k}\}$, which located at positions $\{\rm{pos}_{k,1},\rm{pos}_{k,2},\dots,\rm{pos}_{k,C_k}\}$. So every $\rm{pos}_{k,\_}$ is a one-dimensional list with length $n-1$. (Except for the case of $A$ whose dimension is $1$ itself.)
Let $C_0=0$. Than the SparseArray
expression of $A$ would be:
I have described the details here and here. The second post describes the version number of the sparse array implementation, which is still at version 1. So no big changes since it's introduction and V9.
If you like to read about sparse arrays I can recommend this from Tim Davis.