<!--
{
  "documentType" : "article",
  "framework" : "Accelerate",
  "identifier" : "/documentation/Accelerate/creating-sparse-matrices",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Creating sparse matrices"
}
-->

# Creating sparse matrices

Create sparse matrices for factorization and solving systems.

## Discussion

In the Accelerate framework, the Sparse Solvers library stores sparse matrices using the compressed sparse column (CSC) format. CSC stores a matrix as a series of column vectors that specify the nonzero entries as `(row-index, value)` pairs and omit the zero entries.

The Sparse Solvers library provides routines to convert matrices from other formats to CSC. For more information, see <doc://com.apple.documentation/documentation/Accelerate/conversion-from-other-formats>.

The Sparse Solvers library supports unsymmetric and symmetric sparse matrices, each of which can also be block matrices.

- An *unsymmetric matrix* contains either <doc://com.apple.documentation/documentation/Swift/Double> or <doc://com.apple.documentation/documentation/Swift/Float> values with no symmetry between its lower-left and upper-right triangles.
- A *symmetric matrix* is symmetrical along the diagonal from its upper-left to lower-right corners. In other words, a symmetric matrix is equal to its transpose (*A=Aᵀ*).
- A *block matrix* can be either unsymmetric or symmetric, and consists of sections called blocks. The blocks along the diagonal of a symmetric block matrix must, themselves, be symmetrical.

### Create an unsymmetric matrix

In this example of an unsymmetric sparse matrix, empty cells represent zeros:

![A four-by-three unsymmetric sparse matrix that has three empty cells.](images/com.apple.accelerate/media-2904623@2x.png)

The first step to create a matrix is to define two arrays that store the row indices and corresponding values.

```swift
var rowIndices: [Int32] = [0, 1, 3,     // Column 0
                           0, 1, 2, 3,  // Column 1
                           1, 2]        // Column 2
 
var values = [2.0, -0.2, 2.5,           // Column 0
              1.0, 3.2, -0.1, 1.1,      // Column 1
              1.4, 0.5]                 // Column 2
```

In addition to the `(row-index, value)` pairs, create a third array that specifies where each column starts. This array requires an additional, final entry that defines the final column’s length.

In the following example, the zeroth item in the `values` array starts column 0, the third starts column 1, and the seventh starts column 2:

```swift
var columnStarts = [0,    // Column 0
                    3,    // Column 1
                    7,    // Column 2
                    9]
```

The two structural arrays, `rowIndices` and `columnStarts`, create a [`SparseMatrixStructure`](/documentation/Accelerate/SparseMatrixStructure) instance that describes the matrix’s structure. The initializer requires an attributes object, and the default parameters of a [`SparseAttributes_t`](/documentation/Accelerate/SparseAttributes_t) instance specify an unsymmetric matrix.

```swift
let structure = SparseMatrixStructure(rowCount: 4,
                                      columnCount: 3,
                                      columnStarts: &columnStarts,
                                      rowIndices: &rowIndices,
                                      attributes: SparseAttributes_t(),
                                      blockSize: 1)
```

The following code uses the `structure` and `values` items to create a [`SparseMatrix_Double`](/documentation/Accelerate/SparseMatrix_Double) instance:

```swift
values.withUnsafeMutableBufferPointer { valuesPtr in
    let A = SparseMatrix_Double(
        structure: structure,
        data: valuesPtr.baseAddress!
    )
    
    // Perform operations using `A`.
}
```

### Create a symmetric matrix

In this example of a symmetric sparse matrix, empty cells represent zeros:

![A four-by-four symmetric sparse matrix that has four empty cells.](images/com.apple.accelerate/media-2904624@2x.png)

Because it’s symmetric, the values in the upper triangle of the matrix are redundant, so exclude them from the data that you pass to the [`SparseMatrix_Double`](/documentation/Accelerate/SparseMatrix_Double) initializer.  The example below shows the excluded values in gray:

![A four-by-four symmetric sparse matrix that has four empty cells and four values that appear in a lighter color](images/com.apple.accelerate/media-2904626@2x.png)

As with the unsymmetric example, the `rowIndices` array specifies the row in the matrix that contains the corresponding item in `values`, and the `columnStarts` array specifies where each column starts in the `rowIndices` array.

In the following example, the [`attributes`](/documentation/Accelerate/SparseMatrixStructure/attributes) parameter specifies that the matrix is symmetric and the items in the values array derive from the lower triangle:

```swift
var columnStarts = [0,                  // Column 0    
                    3,                  // Column 1      
                    6,                  // Column 2
                    7,                  // Column 3
                    8]
 
var rowIndices: [Int32] = [0, 1, 3,     // Column 0
                           1, 2, 3,     // Column 1
                           2,           // Column 2
                           3]           // Column 3
  
var attributes = SparseAttributes_t()
attributes.triangle = SparseLowerTriangle
attributes.kind = SparseSymmetric
 
let structure = SparseMatrixStructure(rowCount: 4,
                                      columnCount: 4,
                                      columnStarts: &columnStarts,
                                      rowIndices: &rowIndices,
                                      attributes: attributes,
                                      blockSize: 1)
```

Create the [`SparseMatrix_Double`](/documentation/Accelerate/SparseMatrix_Double) instance using the structure from the code example above and the values from the lower triangle of the matrix.

```swift
var values = [10.0,  1.0, 2.5,  // Column 0
              12.0, -0.3, 1.1,  // Column 1
              9.5,              // Column 2
              6.0]              // Column 3
  
values.withUnsafeMutableBufferPointer { valuesPtr in
    let A = SparseMatrix_Double(
        structure: structure,
        data: valuesPtr.baseAddress!
    )
    
    // Perform operations using `A`.
}
```

### Create a block matrix

You can create block sparse matrices *—* that is, a matrix that consists of blocks that contain multiple values — by defining a [`blockSize`](/documentation/Accelerate/SparseMatrixStructure/blockSize) greater than 1. The block size is the length of the side of the square block.

Block matrices can be symmetric or unsymmetric. This example shows an unsymmetric sparse matrix with a block size of 3:

![A nine-by-nine unsymmetric sparse matrix that has three rows of three blocks each.](images/com.apple.accelerate/media-2904625@2x.png)

The following example shows the code to create a sparse matrix with the structure and values above. The [`SparseMatrixStructure`](/documentation/Accelerate/SparseMatrixStructure) specifies a block size of 3. The values for each block concatenate in column-major order.

```swift
var columnStarts = [ 0, 2, 4, 5 ]
var rowIndices: [Int32] = [ 0, 2, 0, 1, 2 ]
 
var values = [
    1.0, 0.1, 9.2, 0.3, 0.5, 1.3, 0.2, 1.3, 4.5,    // Block 0
    0.2, 0.7, 0.9, 1.8, 1.6, 1.7, 0.8, 0.7, 0.9,    // Block 1
    1.5, 2.5, 7.2, 0.2, 0.8, 0.8, 0.3, 0.4, 0.2,    // Block 2
    0.2, 0.4, 1.8, 1.6, 1.8, 0.6, 0.5, 4.2, 3.3,    // Block 3
    0.2, 0.8, 1.2, 0.4, 0.6, 0.8, 1.8, 1.2, 0.9     // Block 4
]  
var attributes = SparseAttributes_t()
attributes.kind = SparseOrdinary
 
let structure = SparseMatrixStructure(rowCount: 3,
                                      columnCount: 3,
                                      columnStarts: &columnStarts,
                                      rowIndices: &rowIndices,
                                      attributes: attributes,
                                      blockSize: 3)
 
values.withUnsafeMutableBufferPointer { valuesPtr in
    let A = SparseMatrix_Double(
        structure: structure,
        data: valuesPtr.baseAddress!
    )
    
    // Perform operations using `A`.
}
```

When you create a symmetric matrix with a block size greater than 1, the blocks along the matrix’s diagonal must also be symmetric.

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)