---
title: "SparseArray"
language: "en"
type: "Symbol"
summary: "SparseArray[{pos1 -> v1, pos2 -> v2, ...}] yields a sparse array with all elements zero except for values vi at positions posi. SparseArray[list] yields a sparse array version of list. SparseArray[data, {d1, d2, ...}] yields a sparse array representing a d1*d2*... array. SparseArray[data, dims, val] yields a sparse array in which unspecified elements are taken to have value val."
keywords: 
- arrays
- band-diagonal matrices
- hashing
- lists
- matrices
- position-value pairs
- sparse matrix
- sparse representation
- sparse vector
- FULSTR
- SPRSIN
- GetFullMatrix
- spalloc
- sparse
- speye
- spones
- sprand
- sprandn
- sprandsym
canonical_url: "https://reference.wolfram.com/language/ref/SparseArray.html"
source: "Wolfram Language Documentation"
related_guides: 
  - 
    title: "Sparse Arrays"
    link: "https://reference.wolfram.com/language/guide/SparseArrays.en.md"
  - 
    title: "Constructing Matrices"
    link: "https://reference.wolfram.com/language/guide/ConstructingMatrices.en.md"
  - 
    title: "Matrices and Linear Algebra"
    link: "https://reference.wolfram.com/language/guide/MatricesAndLinearAlgebra.en.md"
  - 
    title: "Constructing Lists"
    link: "https://reference.wolfram.com/language/guide/ConstructingLists.en.md"
  - 
    title: "Tensors"
    link: "https://reference.wolfram.com/language/guide/Tensors.en.md"
  - 
    title: "Graphs and Matrices"
    link: "https://reference.wolfram.com/language/guide/GraphsAndMatrices.en.md"
  - 
    title: "Operations on Vectors"
    link: "https://reference.wolfram.com/language/guide/OperationsOnVectors.en.md"
  - 
    title: "Structure Matrices & Convolution Kernels"
    link: "https://reference.wolfram.com/language/guide/StructureMatricesAndConvolutionKernels.en.md"
  - 
    title: "3D Images"
    link: "https://reference.wolfram.com/language/guide/3DImages.en.md"
  - 
    title: "List Manipulation"
    link: "https://reference.wolfram.com/language/guide/ListManipulation.en.md"
  - 
    title: "Handling Arrays of Data"
    link: "https://reference.wolfram.com/language/guide/HandlingArraysOfData.en.md"
  - 
    title: "Systems Modeling"
    link: "https://reference.wolfram.com/language/guide/SystemsModeling.en.md"
  - 
    title: "Linear and Nonlinear Filters"
    link: "https://reference.wolfram.com/language/guide/LinearAndNonlinearFilters.en.md"
related_workflows: 
  - 
    title: "Create a Matrix"
    link: "https://reference.wolfram.com/language/workflow/CreateAMatrix.en.md"
related_functions: 
  - 
    title: "ArrayRules"
    link: "https://reference.wolfram.com/language/ref/ArrayRules.en.md"
  - 
    title: "SparseArrayQ"
    link: "https://reference.wolfram.com/language/ref/SparseArrayQ.en.md"
  - 
    title: "Normal"
    link: "https://reference.wolfram.com/language/ref/Normal.en.md"
  - 
    title: "Band"
    link: "https://reference.wolfram.com/language/ref/Band.en.md"
  - 
    title: "CoefficientArrays"
    link: "https://reference.wolfram.com/language/ref/CoefficientArrays.en.md"
  - 
    title: "ArrayPlot"
    link: "https://reference.wolfram.com/language/ref/ArrayPlot.en.md"
  - 
    title: "Array"
    link: "https://reference.wolfram.com/language/ref/Array.en.md"
  - 
    title: "ConstantArray"
    link: "https://reference.wolfram.com/language/ref/ConstantArray.en.md"
  - 
    title: "NumericArray"
    link: "https://reference.wolfram.com/language/ref/NumericArray.en.md"
  - 
    title: "Association"
    link: "https://reference.wolfram.com/language/ref/Association.en.md"
related_tutorials: 
  - 
    title: "Constructing Lists"
    link: "https://reference.wolfram.com/language/tutorial/ManipulatingLists.en.md#28009"
  - 
    title: "Sparse Arrays: Manipulating Lists"
    link: "https://reference.wolfram.com/language/tutorial/ManipulatingLists.en.md#23168"
  - 
    title: "Sparse Arrays: Linear Algebra"
    link: "https://reference.wolfram.com/language/tutorial/LinearAlgebra.en.md#17571"
  - 
    title: "Implementation notes: Numerical and Related Functions"
    link: "https://reference.wolfram.com/language/tutorial/SomeNotesOnInternalImplementation.en.md#7977"
---
# SparseArray

SparseArray[{pos1 -> v1, pos2 -> v2, …}] yields a sparse array with all elements zero except for values vi at positions posi.

SparseArray[list] yields a sparse array version of list. 

SparseArray[data, {d1, d2, …}] yields a sparse array representing a d1×d2×… array. 

SparseArray[data, dims, val] yields a sparse array in which unspecified elements are taken to have value val.

## Details

* ``SparseArray`` is also known as sparse matrix.

* Sparse arrays are typically used for efficient linear algebra where most of the entries are zero and for graph adjacency matrices.

* A sparse array stores only the positions where there are nonzero values, but represents the full array:

[image]

* The ``data`` can have the following forms:

|                     |                                        |
| ------------------- | -------------------------------------- |
| rules               | rules specifying positions and values. |
| list                | convert an array to SparseArray        |
| SymmetrizedArray[…] | convert to SparseArray                 |
| QuantityArray[…]    | convert to SparseArray of Quantity     |
| SparseArray[…]      | minimize the explicit nonzero elements |

* With ``s = SparseArray[rules, …]`` the following specifications can be used:

|                                              |                                                                                               |
| -------------------------------------------- | --------------------------------------------------------------------------------------------- |
| {{i1⁢1, …, i1r} -> v1, {i21, …, i2r} -> v2, …} | s[[i11, …, i1r]] has value v1, s[[i21, …, i2r]] has value v2, etc.                            |
| patt -> v                                     | {{i11, …, i1r} -> v, {i21, …, i2r} -> v, …} for all {ik1, …, ikr} that matches the pattern patt |
| patt :> v                                    | evaluate the value v for each matching position                                               |
| Band[…] -> vals                               | specify values for bands and subblocks                                                        |
| {pos1, pos2, …} -> {v1, v2, …}                | equivalent to {pos1 -> v1, pos2 -> v2, …}                                                       |

* ``SparseArray`` conversions include:

|                                  |                                                     |
| -------------------------------- | --------------------------------------------------- |
| Normal[SparseArray[…]]           | convert to the ordinary List array.                 |
| SymmetrizedArray[SparseArray[…]] | convert to a symmetrized array.                     |
| ArrayRules[SparseArray[…]]       | give the list of rules {pos1 -> v1, pos2 -> v2, …}  |

* A ``SparseArray`` object is a representation of an ordinary array, so many functions work like they would on the ordinary array. Examples include functions like ``Dimensions``, ``Part``, ``Plus`` and ``LinearSolve``.

* ``SparseArray[data, …]`` is always converted to an optimized standard form with structure ``SparseArray[Automatic, dims, val, …]``.

* ``SparseArray`` is treated as a raw object by functions like ``AtomQ`` and for purposes of pattern matching.

* By default, ``SparseArray`` takes unspecified elements ``val`` to be zero.

* The elements in ``SparseArray`` need not be numeric, but cannot themselves be lists.

* ``SparseArray[…][prop]`` gives the property ``prop`` of the ``SparseArray`` object. The following properties may be given:

|                     |                                                                                    |
| ------------------- | ---------------------------------------------------------------------------------- |
| "ImplicitValue"     | gives the value for elements that are not given explicitly                         |
| "ExplicitLength"    | gives the number of explicit values                                                |
| "ExplicitValues"    | gives the list of explicit values                                                  |
| "ExplicitPositions" | gives the list of positions corresponding to the explicit values                   |
| "ColumnIndices"     | gives the column indices from the compressed sparse row representation             |
| "RowPointers"       | gives the row pointer list from the compressed sparse row representation           |
| "BandWidth"         | gives the off-diagonal bandwidth for a sparse matrix                               |
| "Density"           | gives the ratio of the number of explicit elements to the total number of elements |

---

## Examples (27)

### Basic Examples (1)

Construct a sparse matrix with values at only a few specified positions:

```wl
In[1]:= s = SparseArray[{{1, 1} -> 1, {2, 2} -> 2, {3, 3} -> 3, {1, 3} -> 4}]

Out[1]= SparseArray[Automatic, {3, 3}, 0, {1, {{0, 2, 3, 4}, {{1}, {3}, {2}, {3}}}, {1, 4, 2, 3}}]
```

View it as a matrix:

```wl
In[2]:= MatrixForm[s]

Out[2]//MatrixForm=
(⁠|   |   |   |
| - | - | - |
| 1 | 0 | 4 |
| 0 | 2 | 0 |
| 0 | 0 | 3 |⁠)
```

Convert it to an ordinary dense matrix:

```wl
In[3]:= Normal[s]

Out[3]= {{1, 0, 4}, {0, 2, 0}, {0, 0, 3}}
```

### Scope (7)

Make a large sparse vector:

```wl
In[1]:= SparseArray[Table[{2 ^ i} -> 1, {i, 10}]]

Out[1]=
SparseArray[Automatic, {1024}, 0, 
 {1, {{0, 10}, {{2}, {4}, {8}, {16}, {32}, {64}, {128}, {256}, {512}, {1024}}}, 
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}}]
```

Make a large sparse matrix:

```wl
In[2]:= SparseArray[Table[{2 ^ i, 3 ^ i + i} -> 1, {i, 10}]]

Out[2]=
SparseArray[Automatic, {1024, 59059}, 0, 
 {1, {CompressedData["«79»"], {{4}, {11}, {30}, {85}, {248}, {735}, {2194}, {6569}, {19692}, {59059}}}, 
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}}]
```

Make a large sparse depth-3 array:

```wl
In[3]:= SparseArray[Table[{2 ^ i, 3 ^ i + i, i ^ 5} -> 1, {i, 10}]]

Out[3]=
SparseArray[Automatic, {1024, 59059, 100000}, 0, 
 {1, {CompressedData["«79»"], {{4, 1}, {11, 32}, {30, 243}, {85, 1024}, {248, 3125}, {735, 7776}, {2194, 16807}, 
    {6569, 32768}, {19692, 59049}, {59059, 100000}}}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}}]
```

---

Construct a tridiagonal matrix using patterns for indices:

```wl
In[1]:= s = SparseArray[{{i_, i_} -> -2, {i_, j_} /; Abs[i - j] == 1 -> 1}, {5, 5}]

Out[1]=
SparseArray[Automatic, {5, 5}, 0, 
 {1, {{0, 2, 5, 8, 11, 13}, {{2}, {1}, {1}, {2}, {3}, {4}, {3}, {2}, {3}, {5}, {4}, {4}, {5}}}, 
  {1, -2, 1, -2, 1, 1, -2, 1, 1, 1, -2, 1, -2}}]

In[2]:= MatrixForm[s]

Out[2]//MatrixForm=
(⁠|    |    |    |    |    |
| -- | -- | -- | -- | -- |
| -2 | 1  | 0  | 0  | 0  |
| 1  | -2 | 1  | 0  | 0  |
| 0  | 1  | -2 | 1  | 0  |
| 0  | 0  | 1  | -2 | 1  |
| 0  | 0  | 0  | 1  | -2 |⁠)
```

Construct a 10,000×10,000 version:

```wl
In[3]:= s = SparseArray[{{i_, i_} -> -2, {i_, j_} /; Abs[i - j] == 1 -> 1}, {10 ^ 4, 10 ^ 4}]

Out[3]=
SparseArray[Automatic, {10000, 10000}, 0, 
 {1, {CompressedData["«19715»"], CompressedData["«38735»"]}, CompressedData["«6756»"]}]
```

---

Make a sparse diagonal matrix:

```wl
In[1]:= d = RandomReal[1, {100}];

In[2]:= m = SparseArray[{i_, i_} :> d[[i]], Length[d]{1, 1}]

Out[2]=
SparseArray[Automatic, {100, 100}, 0, 
 {1, {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 
    25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 
    49, 50 ... 6}, {67}, {68}, {69}, {70}, {71}, {72}, {73}, {74}, {75}, {76}, {77}, {78}, 
    {79}, {80}, {81}, {82}, {83}, {84}, {85}, {86}, {87}, {88}, {89}, {90}, {91}, {92}, {93}, {94}, 
    {95}, {96}, {97}, {98}, {99}, {100}}}, CompressedData["«1170»"]}]
```

This is equivalent to ``DiagonalMatrix`` :

```wl
In[3]:= m == DiagonalMatrix[d]

Out[3]= True
```

Except that as a sparse matrix, it uses much less memory:

```wl
In[4]:= {ByteCount[m], ByteCount[DiagonalMatrix[d]]}

Out[4]= {2992, 80208}
```

---

Construct a block diagonal matrix using rules with ``Band`` :

```wl
In[1]:= s = SparseArray[Band[{1, 1}] -> {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}]

Out[1]=
SparseArray[Automatic, {4, 4}, 0, {1, {{0, 2, 4, 6, 8}, {{2}, {1}, {2}, {1}, {4}, {3}, {4}, {3}}}, 
  {2, 1, 4, 3, 6, 5, 8, 7}}]

In[2]:= MatrixForm[s]

Out[2]//MatrixForm=
(⁠|   |   |   |   |
| - | - | - | - |
| 1 | 2 | 0 | 0 |
| 3 | 4 | 0 | 0 |
| 0 | 0 | 5 | 6 |
| 0 | 0 | 7 | 8 |⁠)
```

---

Convert an ordinary matrix into a sparse matrix:

```wl
In[1]:= SparseArray[{{1, 0, 0}, {1, 2, 0}, {1, 2, 3}}]

Out[1]=
SparseArray[Automatic, {3, 3}, 0, {1, {{0, 1, 3, 6}, {{1}, {1}, {2}, {1}, {2}, {3}}}, 
  {1, 1, 2, 1, 2, 3}}]
```

---

Make a rank-4 sparse tensor with values at random positions:

```wl
In[1]:= rules = Table[RandomInteger[{1, 2}, 4] -> i, {i, 10}]

Out[1]= {{1, 1, 2, 1} -> 1, {1, 2, 2, 2} -> 2, {1, 2, 2, 2} -> 3, {1, 2, 2, 2} -> 4, {2, 1, 1, 1} -> 5, {2, 1, 2, 1} -> 6, {2, 2, 2, 1} -> 7, {1, 2, 2, 1} -> 8, {2, 1, 2, 1} -> 9, {1, 2, 1, 1} -> 10}

In[2]:= s = SparseArray[rules]

Out[2]=
SparseArray[Automatic, {2, 2, 2, 2}, 0, 
 {1, {{0, 4, 7}, {{1, 2, 1}, {2, 2, 2}, {2, 2, 1}, {2, 1, 1}, {1, 1, 1}, {1, 2, 1}, {2, 2, 1}}}, 
  {1, 2, 8, 10, 5, 6, 7}}]

In[3]:= Normal[%]

Out[3]= {{{{0, 0}, {1, 0}}, {{10, 0}, {8, 2}}}, {{{5, 0}, {6, 0}}, {{0, 0}, {7, 0}}}}
```

``ArrayRules`` produces the minimal list of rules needed to specify the ``SparseArray``:

```wl
In[4]:= ArrayRules[s]

Out[4]= {{1, 1, 2, 1} -> 1, {1, 2, 2, 2} -> 2, {1, 2, 2, 1} -> 8, {1, 2, 1, 1} -> 10, {2, 1, 1, 1} -> 5, {2, 1, 2, 1} -> 6, {2, 2, 2, 1} -> 7, {_, _, _, _} -> 0}
```

---

Many typical operations work with ``SparseArray`` objects as they would for equivalent lists:

```wl
In[1]:=
m1 = SparseArray[{{i_, i_} -> -2, {i_, j_} /; Abs[i - j] == 1 -> 1}, {5, 5}];
m2 = SparseArray[{{i_, i_} -> 1}, {5, 5}];

In[2]:= Map[MatrixForm, {m1, m2}]

Out[2]=
{(⁠|    |    |    |    |    |
| -- | -- | -- | -- | -- |
| -2 | 1  | 0  | 0  | 0  |
| 1  | -2 | 1  | 0  | 0  |
| 0  | 1  | -2 | 1  | 0  |
| 0  | 0  | 1  | -2 | 1  |
| 0  | 0  | 0  | 1  | -2 |⁠), (⁠|   |   |   |   |   |
| - | - | - | - | - |
| 1 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 | 0 |
| 0 | 0 | 0 | 1 | 0 |
| 0 | 0 | 0 | 0 | 1 |⁠)}
```

Arithmetic works elementwise just as it does for lists:

```wl
In[3]:= MatrixForm[m1 + 2 m2]

Out[3]//MatrixForm=
(⁠|   |   |   |   |   |
| - | - | - | - | - |
| 0 | 1 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 | 0 |
| 0 | 1 | 0 | 1 | 0 |
| 0 | 0 | 1 | 0 | 1 |
| 0 | 0 | 0 | 1 | 0 |⁠)
```

Matrix products are done with ``Dot`` :

```wl
In[4]:= MatrixForm[m1.m1]

Out[4]//MatrixForm=
(⁠|    |    |    |    |    |
| -- | -- | -- | -- | -- |
| 5  | -4 | 1  | 0  | 0  |
| -4 | 6  | -4 | 1  | 0  |
| 1  | -4 | 6  | -4 | 1  |
| 0  | 1  | -4 | 6  | -4 |
| 0  | 0  | 1  | -4 | 5  |⁠)
```

Many linear algebra functions are done efficiently with the sparse form:

```wl
In[5]:= LinearSolve[N[m1], {0, 1, 2, 1, 0}]

Out[5]= {-2., -4., -5., -4., -2.}
```

Many other list commands work automatically:

```wl
In[6]:= Map[f, m1, {2}]

Out[6]=
SparseArray[Automatic, {5, 5}, f[0], 
 {1, {{0, 2, 5, 8, 11, 13}, {{2}, {1}, {1}, {2}, {3}, {4}, {3}, {2}, {3}, {5}, {4}, {4}, {5}}}, 
  {f[1], f[-2], f[1], f[-2], f[1], f[1], f[-2], f[1], f[1], f[1], f[-2], f[1], f[-2]}}]

In[7]:= MatrixForm[%]

Out[7]//MatrixForm=
(⁠|       |       |       |       |       |
| ----- | ----- | ----- | ----- | ----- |
| f[-2] | f[1]  | f[0]  | f[0]  | f[0]  |
| f[1]  | f[-2] | f[1]  | f[0]  | f[0]  |
| f[0]  | f[1]  | f[-2] | f[1]  | f[0]  |
| f[0]  | f[0]  | f[1]  | f[-2] | f[1]  |
| f[0]  | f[0]  | f[0]  | f[1]  | f[-2] |⁠)
```

### Generalizations & Extensions (2)

The unspecified elements can have any value:

```wl
In[1]:= s = SparseArray[{i_, i_} -> y, {3, 3}, x]

Out[1]= SparseArray[Automatic, {3, 3}, x, {1, {{0, 1, 2, 3}, {{1}, {2}, {3}}}, {y, y, y}}]

In[2]:= MatrixForm[s]

Out[2]//MatrixForm=
(⁠|   |   |   |
| - | - | - |
| y | x | x |
| x | y | x |
| x | x | y |⁠)
```

---

Construct a sparse matrix with all machine-number values:

```wl
In[1]:= ns = SparseArray[{{i_, i_} -> -2., {i_, j_} /; Abs[i - j] == 1 -> 1.}, {5, 5}, 0.]

Out[1]=
SparseArray[Automatic, {5, 5}, 0., 
 {1, {{0, 2, 5, 8, 11, 13}, {{2}, {1}, {1}, {2}, {3}, {4}, {3}, {2}, {3}, {5}, {4}, {4}, {5}}}, 
  {1., -2., 1., -2., 1., 1., -2., 1., 1., 1., -2., 1., -2.}}]

In[2]:= MatrixForm[ns]

Out[2]//MatrixForm=
(⁠|     |     |     |     |     |
| --- | --- | --- | --- | --- |
| -2. | 1.  | 0.  | 0.  | 0.  |
| 1.  | -2. | 1.  | 0.  | 0.  |
| 0.  | 1.  | -2. | 1.  | 0.  |
| 0.  | 0.  | 1.  | -2. | 1.  |
| 0.  | 0.  | 0.  | 1.  | -2. |⁠)
```

Construct a sparse matrix with exact integer values:

```wl
In[3]:= s = SparseArray[{{i_, i_} -> -2, {i_, j_} /; Abs[i - j] == 1 -> 1}, {5, 5}]

Out[3]=
SparseArray[Automatic, {5, 5}, 0, 
 {1, {{0, 2, 5, 8, 11, 13}, {{2}, {1}, {1}, {2}, {3}, {4}, {3}, {2}, {3}, {5}, {4}, {4}, {5}}}, 
  {1, -2, 1, -2, 1, 1, -2, 1, 1, 1, -2, 1, -2}}]
```

``N[s]`` is the same as ``ns`` :

```wl
In[4]:= SameQ[ns, N[s]]

Out[4]= True
```

### Applications (4)

Create a list with a single nonzero element:

```wl
In[1]:= Normal[SparseArray[10 -> 1, 19]]

Out[1]= {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}

In[2]:= Normal[SparseArray[{3, 3} -> 1, 5]]

Out[2]= {{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 1, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}}
```

---

Plot a list of rules:

```wl
In[1]:= ListLinePlot[SparseArray[{1 -> 2, 10 -> 7, 3 -> 2}]]

Out[1]= [image]
```

---

Represent a network with an adjacency matrix:

```wl
In[1]:= s = SparseArray[{{i_, j_} /; Mod[2i + j, 7] == 1 -> 1}, {20, 20}]

Out[1]=
SparseArray[Automatic, {20, 20}, 0, 
 {1, {{0, 3, 6, 9, 11, 14, 17, 20, 23, 26, 29, 31, 34, 37, 40, 43, 46, 49, 51, 54, 57}, 
   {{13}, {20}, {6}, {4}, {11}, {18}, {2}, {9}, {16}, {7}, {14}, {19}, {5}, {12}, {3}, {10}, {17}, 
    {1}, {15}, {8}, {2 ... 6}, {9}, {2}, {14}, {7}, 
    {5}, {19}, {12}, {3}, {10}, {17}}}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
   1, 1, 1, 1, 1, 1}}]

In[2]:= GraphPlot[s]

Out[2]= [image]
```

---

Solve a boundary-value problem $\frac{\partial ^2u}{\partial x^2}+f(x)u=g(x),u(0)=0, u'(1)=0$ using finite differences:

```wl
In[1]:=
n = 1000;
h = 1. / n;
xgrid = h Range[1, n];
f[x_] := 1 + 100 Exp[-(321(x - 1 / 2)) ^ 2];
g[x_] := Sin[Pi x];

In[2]:=
id = SparseArray[{i_, i_} -> 1., {n, n}, 0.];
d2 = SparseArray[{{i_, i_} -> -2., {n, n - 1} -> 2., {i_, j_} /; Abs[i - j] == 1 -> 1.}, {n, n}, 0.]

Out[2]=
SparseArray[Automatic, {1000, 1000}, 0., 
 {1, {CompressedData["«2075»"], 
   CompressedData["«3957»"]}, CompressedData["«890»"]}]

In[3]:= u = LinearSolve[d2 / h ^ 2 + id f[xgrid], g[xgrid]];

In[4]:= ListPlot[Transpose[{xgrid, u}]]

Out[4]= [image]
```

### Properties & Relations (3)

A ``SparseArray`` object is ``Equal`` to the corresponding ordinary list:

```wl
In[1]:= s = SparseArray[{{1, 2} -> 3, {4, 5} -> 6}]

Out[1]= SparseArray[Automatic, {4, 5}, 0, {1, {{0, 1, 1, 1, 2}, {{2}, {5}}}, {3, 6}}]

In[2]:= s == Normal[s]

Out[2]= True
```

They are not ``SameQ`` because the expression structure is different:

```wl
In[3]:= s === Normal[s]

Out[3]= False
```

---

For functions ``f`` that work with ``SparseArray`` objects, typically ``f[s] == f[Normal[s]]`` :

```wl
In[1]:= s = SparseArray[RandomInteger[{1, 100}, {1000, 2}] -> RandomReal[1, 1000]]

Out[1]=
SparseArray[Automatic, {100, 100}, 0, 
 {1, {CompressedData["«305»"], CompressedData["«1203»"]}, CompressedData["«10156»"]}]

In[2]:= Transpose[s] == Transpose[Normal[s]]

Out[2]= True

In[3]:= s.s == Normal[s].Normal[s]

Out[3]= True
```

This includes all functions with the attribute ``Listable`` :

```wl
In[4]:= listable = Map[ToExpression, Cases[Names["System`*"], s_String /; MemberQ[Attributes[s], Listable]]];

In[5]:= f = First[RandomChoice[listable, 1]]

Out[5]= ExpToTrig

In[6]:= f[s] == f[Normal[s]]

Out[6]= True
```

---

Convert linear expressions to ``SparseArray`` objects using ``CoefficientArrays`` :

```wl
In[1]:= expr = ListCorrelate[{1, 2, 1}, Array[x, {100}], {2, 2}]; Short[expr]

Out[1]//Short= {2 x[1] + x[2] + x[100], x[1] + 2 x[2] + x[3], «96», x[98] + 2 x[99] + x[100], x[1] + x[99] + 2 x[100]}

In[2]:= {v, m} = CoefficientArrays[expr, Array[x, {100}]]

Out[2]=
{SparseArray[Automatic, {100}, 0, {1, {{0, 0}, {}}, {}}], SparseArray[Automatic, {100, 100}, 0, 
 {1, {CompressedData["«299»"], {{1}, {2}, {100}, {1}, {2}, {3}, {2}, {3}, {4}, {3}, {4}, {5}, {4}, {5}, {6}, 
    {5}, {6}, {7}, {6}, {7}, {8}, {7}, {8 ... , 2, 
   1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 
   2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 
   1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2}}]}
```

Convert from ``SparseArray`` to expressions using ``Dot`` :

```wl
In[3]:= m.Array[x, {100}]//Short

Out[3]//Short= {2 x[1] + x[2] + x[100], x[1] + 2 x[2] + x[3], «96», x[98] + 2 x[99] + x[100], x[1] + x[99] + 2 x[100]}
```

### Possible Issues (9)

If a position is repeated in the rule list for ``SparseArray``, the first instance is used:

```wl
In[1]:= SparseArray[{{1, 1} -> 1, {1, 1} -> 2}]//Normal

Out[1]= {{1}}

In[2]:= SparseArray[{{i_, i_} -> 1, {1, 1} -> 2}]//Normal

Out[2]= {{1}}
```

---

``SparseArray`` objects can represent data too large to represent in normal form:

```wl
In[1]:= s = SparseArray[{{i_, i_} -> i}, {100000, 100000}]

Out[1]= SparseArray[<100000>, {100000, 100000}]
```

Using ``Normal`` will give a ``SystemException`` :

```wl
In[2]:= Normal[s]
```

General::nomem: The current computation was aborted because there was insufficient memory available to complete the computation.

Throw::sysexc: Uncaught SystemException returned to top level. Can be caught with Catch[\[Ellipsis], \_SystemException].

```wl
Out[2]= SystemException["MemoryAllocationFailure"]
```

---

Sparse operations do not by default check for cancellation:

```wl
In[1]:= s = SparseArray[{{i_, i_} -> 1, {i_, j_} /; Abs[i - j] == 1 -> 1}, {3, 3}]

Out[1]=
SparseArray[Automatic, {3, 3}, 0, {1, {{0, 2, 5, 7}, {{2}, {1}, {1}, {2}, {3}, {3}, {2}}}, 
  {1, 1, 1, 1, 1, 1, 1}}]

In[2]:= r = s.s - 2s

Out[2]=
SparseArray[Automatic, {3, 3}, 0, 
 {1, {{0, 3, 6, 9}, {{2}, {1}, {3}, {1}, {2}, {3}, {3}, {2}, {1}}}, {0, 0, 1, 0, 1, 0, 0, 0, 1}}]

In[3]:= MatrixForm[r]

Out[3]//MatrixForm=
(⁠|   |   |   |
| - | - | - |
| 0 | 0 | 1 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |⁠)
```

Use ``SparseArray`` to recompute the sparse structure:

```wl
In[4]:= SparseArray[r]

Out[4]= SparseArray[Automatic, {3, 3}, 0, {1, {{0, 1, 2, 3}, {{3}, {2}, {1}}}, {1, 1, 1}}]
```

---

The internal structure of a ``SparseArray`` representation is not unique and ``SameQ`` detects this:

```wl
In[1]:=
s1 = SparseArray[{1, 1} -> 1, {2, 2}];
(s1 - s1) === SparseArray[{}, {2, 2}]

Out[1]= False
```

Use ``SparseArray`` to recompute the sparse structure:

```wl
In[2]:= SparseArray[s1 - s1] === SparseArray[{}, {2, 2}]

Out[2]= True
```

Note that ``Equal`` works as expected:

```wl
In[3]:= (s1 - s1) == SparseArray[{}, {2, 2}]

Out[3]= True
```

---

The internal structure of ``SparseArray`` representation is not unique and setting parts can change that structure:

```wl
In[1]:=
s1 = SparseArray[{{3}, {5}} -> 1, {6}];
s2 = SparseArray[{{5}} -> 1, {6}];
s2[[3]] = 1;
```

Test if the ``SparseArray`` instances are the same:

```wl
In[2]:= s1 === s2

Out[2]= False
```

Use ``SparseArray`` to recompute the sparse structure:

```wl
In[3]:= s1 === SparseArray[s2]

Out[3]= True
```

Note that ``Equal`` works as expected:

```wl
In[4]:= s1 == s2

Out[4]= True
```

---

Operations with side effects may give different values when iterating over ``SparseArray`` :

```wl
In[1]:= s = SparseArray[{{1} -> 2, {4} -> 3}]

Out[1]= SparseArray[Automatic, {4}, 0, {1, {{0, 2}, {{1}, {4}}}, {2, 3}}]

In[2]:= Module[{i = 1}, Scan[i++&, s];i]

Out[2]= 4

In[3]:= Module[{i = 1}, Scan[i++&, Normal[s]];i]

Out[3]= 5
```

With ``Reap`` and ``Sow`` you can see what elements are accessed:

```wl
In[4]:= Reap[Map[Sow, s]]

Out[4]= {SparseArray[Automatic, {4}, 0, {1, {{0, 2}, {{1}, {4}}}, {2, 3}}], {{2, 3, 0}}}

In[5]:= Reap[Map[Sow, Normal[s]]]

Out[5]= {{2, 0, 0, 3}, {{2, 0, 0, 3}}}
```

---

For a ``SparseArray`` object, ``Part`` gives parts of the represented list:

```wl
In[1]:= s = SparseArray[{i_} -> i, {5}]

Out[1]= SparseArray[Automatic, {5}, 0, {1, {{0, 5}, {{1}, {2}, {3}, {4}, {5}}}, {1, 2, 3, 4, 5}}]

In[2]:= Part[s, 1]

Out[2]= 1
```

The ``FullForm`` is a way of reconstructing the object from basic storage information:

```wl
In[3]:= FullForm[s]

Out[3]//FullForm= SparseArray[Automatic, List[5], 0, List[1, List[List[0, 5], List[List[1], List[2], List[3], List[4], List[5]]], List[1, 2, 3, 4, 5]]]
```

---

A ``SparseArray`` object is treated as atomic for functions that do not work on the representation:

```wl
In[1]:= s = SparseArray[{i_, i_} -> i, {5, 5}]

Out[1]=
SparseArray[Automatic, {5, 5}, 0, {1, {{0, 1, 2, 3, 4, 5}, {{1}, {2}, {3}, {4}, {5}}}, 
  {1, 2, 3, 4, 5}}]
```

``Cases`` does not work on the represented matrix:

```wl
In[2]:= Cases[s, i_ /; i > 0, Infinity]

Out[2]= {}

In[3]:= Cases[Normal[s], i_ /; i > 0, Infinity]

Out[3]= {1, 2, 3, 4, 5}
```

You can often use the result of ``ArrayRules`` to get the information without expanding:

```wl
In[4]:= Cases[ArrayRules[s], (p_ -> i_ /; i > 0) -> i, 1]

Out[4]= {1, 2, 3, 4, 5}
```

---

Even for a dense ``SparseArray`` there can be a division by 0:

```wl
In[1]:= s = SparseArray[{{2, 1}, {1, 2}}]

Out[1]= SparseArray[Automatic, {2, 2}, 0, {1, {{0, 2, 4}, {{1}, {2}, {1}, {2}}}, {2, 1, 1, 2}}]

In[2]:= 1 / s
```

Power::infy: Infinite expression 1/0 encountered.

```wl
Out[2]=
SparseArray[Automatic, {2, 2}, ComplexInfinity, {1, {{0, 2, 4}, {{1}, {2}, {1}, {2}}}, 
  {Rational[1, 2], 1, 1, Rational[1, 2]}}]
```

The density of a ``SparseArray`` is 1:

```wl
In[3]:= s["Density"]

Out[3]= 1.
```

Since a density 1. ``SparseArray`` is a very special case, making this work would be computationally excessively expansive. In this case, the use of ``Normal`` is justified as the matrix is dense:

```wl
In[4]:= 1 / Normal[s]

Out[4]= {{(1/2), 1}, {1, (1/2)}}
```

### Neat Examples (1)

The Game of Life:

```wl
In[1]:=
SetAttributes[cellupdate, Listable];
cellupdate[1, 2] = cellupdate[_, 3] = 1;
cellupdate[_, _] = 0;

In[2]:= update[m_] := cellupdate[m, Sum[RotateRight[m, r], {r, {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}}]]

In[3]:=
Block[{n = 100, m = 10, h}, h = Floor[n / 2 - m / 2];s = SparseArray[Band[{h, h}] -> RandomInteger[1, {m, m}], {n, n}]];
Table[ArrayPlot[Do[s = update[s], {10}];s = SparseArray[s]], {8}]

Out[3]= {[image], [image], [image], [image], [image], [image], [image], [image]}
```

## See Also

* [`ArrayRules`](https://reference.wolfram.com/language/ref/ArrayRules.en.md)
* [`SparseArrayQ`](https://reference.wolfram.com/language/ref/SparseArrayQ.en.md)
* [`Normal`](https://reference.wolfram.com/language/ref/Normal.en.md)
* [`Band`](https://reference.wolfram.com/language/ref/Band.en.md)
* [`CoefficientArrays`](https://reference.wolfram.com/language/ref/CoefficientArrays.en.md)
* [`ArrayPlot`](https://reference.wolfram.com/language/ref/ArrayPlot.en.md)
* [`Array`](https://reference.wolfram.com/language/ref/Array.en.md)
* [`ConstantArray`](https://reference.wolfram.com/language/ref/ConstantArray.en.md)
* [`NumericArray`](https://reference.wolfram.com/language/ref/NumericArray.en.md)
* [`Association`](https://reference.wolfram.com/language/ref/Association.en.md)

## Tech Notes

* [Constructing Lists](https://reference.wolfram.com/language/tutorial/ManipulatingLists.en.md#28009)
* [Sparse Arrays: Manipulating Lists](https://reference.wolfram.com/language/tutorial/ManipulatingLists.en.md#23168)
* [Sparse Arrays: Linear Algebra](https://reference.wolfram.com/language/tutorial/LinearAlgebra.en.md#17571)
* [Implementation notes: Numerical and Related Functions](https://reference.wolfram.com/language/tutorial/SomeNotesOnInternalImplementation.en.md#7977)

## Related Guides

* [Sparse Arrays](https://reference.wolfram.com/language/guide/SparseArrays.en.md)
* [Constructing Matrices](https://reference.wolfram.com/language/guide/ConstructingMatrices.en.md)
* [Matrices and Linear Algebra](https://reference.wolfram.com/language/guide/MatricesAndLinearAlgebra.en.md)
* [Constructing Lists](https://reference.wolfram.com/language/guide/ConstructingLists.en.md)
* [`Tensors`](https://reference.wolfram.com/language/guide/Tensors.en.md)
* [Graphs and Matrices](https://reference.wolfram.com/language/guide/GraphsAndMatrices.en.md)
* [Operations on Vectors](https://reference.wolfram.com/language/guide/OperationsOnVectors.en.md)
* [Structure Matrices & Convolution Kernels](https://reference.wolfram.com/language/guide/StructureMatricesAndConvolutionKernels.en.md)
* [3D Images](https://reference.wolfram.com/language/guide/3DImages.en.md)
* [List Manipulation](https://reference.wolfram.com/language/guide/ListManipulation.en.md)
* [Handling Arrays of Data](https://reference.wolfram.com/language/guide/HandlingArraysOfData.en.md)
* [Systems Modeling](https://reference.wolfram.com/language/guide/SystemsModeling.en.md)
* [Linear and Nonlinear Filters](https://reference.wolfram.com/language/guide/LinearAndNonlinearFilters.en.md)

## Related Workflows

* [Create a Matrix](https://reference.wolfram.com/language/workflow/CreateAMatrix.en.md)

## Related Links

* [An Elementary Introduction to the Wolfram Language: Arrays, or Lists of Lists](https://www.wolfram.com/language/elementary-introduction/13-arrays-or-lists-of-lists.html)

## History

* Introduced in 2003 (5.0) \| [Updated in 2007 (6.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn60.en.md) ▪ [2021 (13.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn130.en.md)