Apple operating systems like iOS and macOS contain a performance optimized framework called Accelerate for fast matrix operations. This post presents examples for matrix addition, subtraction, multiplication, and division:

- Preparing Matrices
- Matrix Multiplication

a. Single Precision Matrix Multiplication

b. Double Precision Matrix Multiplication

c. Transpose, Row-Major, and Column-Major Matrix Multiplication Using CBLAS

d. Element-wise Matrix Multiplication - Element-wise Matrix Division
- Matrix Addition
- Matrix Subtraction
- Sum of All Values In A Matrix

## Preparing Matrices

To prepare for matrix arithmetic using Accelerate matrices need to be transformed into a format Accelerate can accept. Two-dimensional matrices first need to be flattened (turned into one-dimensional vectors that represent two-dimension matrices).

The matrix multiplication examples in this post evaluate `A * B = C`

.

```
import Accelerate
// Define matrix row and column sizes
let M = Int32(3)
let N = Int32(1)
let K = Int32(2)
// Matrix A, a MxK sized matrix
let A: [Float] = [
[3, 6],
[1, 5],
[8, 0]
].flatMap { $0 }
// Matrix B, a KxN sized matrix
let B: [Float] = [
[2],
[6]
].flatMap { $0 }
// Matrix C, a MxN sized matrix
var C: [Float] = [
[0],
[0],
[0]
].flatMap { $0 }
```

## Matrix Multiplication

The Accelerate framework contains multiple interfaces for single, double, and element-wise matrix multiplication in Swift.

### Single Precision Matrix Multiplication

Use the `vDSP_mmul`

function to perform single precision matrix multiplication:

```
// Using A, B, C and M, N, K as defined
// The stride is the distance between elements to read.
// To use all consecutive elements, set the stride to 1.
let aStride = vDSP_Stride(1)
let bStride = vDSP_Stride(1)
let cStride = vDSP_Stride(1)
vDSP_mmul(
A, aStride,
B, bStride,
&C, cStride,
vDSP_Length(M),
vDSP_Length(N),
vDSP_Length(K)
)
// C will be [42.0, 32.0, 16.0]
```

### Double Precision Matrix Multiplication

The process for double precision matrix multiplication using vDSP is the same as single precision except:

a. `vDSP_mmulD`

is used instead of `vDSP_mmul`

b. `A`

, `B`

, and `C`

must be of type `[Double]`

instead of `[Float]`

### Transpose, Row-Major, and Column-Major Matrix Multiplication Using CBLAS

Accelerate includes another performance optimized interface for matrix multiplication supporting single precision (`cblas_sgemm`

) and double precision (`cblas_dgemm`

) multiplication.

The `cblas_sgemm`

and `cblas_dgemm`

functions include additional configuration options for row-major and column-major data formats, `A`

and/or `B`

matrix transposition, and scaling factors. The cblas functions enable the following matrix multiplication operation: `αAB + βC = C`

```
// Using A, B, C and M, N, K as defined
// Row-major indicates the row is contiguous in
// memory. The other option is column-major ordering
let Order = CblasRowMajor
// If matrix A should be transposed
let TransposeA = CblasNoTrans
// If matrix B should be transposed
let TransposeB = CblasNoTrans
// Scaling factor for A * B
let alpha = Float(1.0)
// Scaling factor for matrix C
let beta = Float(1.0)
// In row-major ordering, the number of items
// in a row of matrix A (K)
let lda = K
// In row-major ordering, the number of items
// in a row of matrix B (N)
let ldb = N
// In row-major ordering, the number of items
// in a row of matrix C (N)
let ldc = N
cblas_sgemm(
Order,
TransposeA, TransposeB,
M, N, K,
alpha,
A, lda,
B, ldb,
beta,
&C, ldc
)
// C will be [42.0, 32.0, 16.0]
```

The process for double precision matrix multiplication using CBLAS is the same as single precision except:

a. `cblas_dgemm`

is used instead of `cblas_sgemm`

b. `alpha`

and `beta`

must be of type `Double`

c. `A`

, `B`

, and `C`

must be of type `[Double]`

instead of `[Float]`

### Element-wise Matrix Multiplication

To multiply each element in a matrix with a constant value, use `vDSP.multiply`

and pass a constant as the first argument:

```
let matrix: [Float] = [
[3, 6],
[1, 5]
].flatMap { $0 }
let result = vDSP.multiply(2, matrix)
```

## Element-wise Matrix Division

To divide each element in a matrix with a constant value, use `vDSP.divide`

and pass a constant as the first argument:

```
let matrix: [Float] = [
[3, 6],
[1, 5]
].flatMap { $0 }
let result = vDSP.divide(2, matrix)
```

## Matrix Addition

Use `vDSP.add`

to add two matrices:

```
let matrix: [Float] = [
[3, 6],
[1, 5]
].flatMap { $0 }
let result = vDSP.add(matrix, matrix)
```

## Matrix Subtraction

Use `vDSP.subtraact`

to subtract two matrices:

```
let matrix: [Float] = [
[3, 6],
[1, 5]
].flatMap { $0 }
let result = vDSP.subtract(matrix, matrix)
```

## Sum of All Values In A Matrix

Use `vDSP.sum`

to sum all the values in a matrix:

```
let matrix: [Float] = [
[3, 6],
[1, 5]
].flatMap { $0 }
let matrixSum = vDSP.sum(matrix)
```

## Performance Optimized Matrix Operations In Swift

That’s it! By using Accelerate and vDSP you can multiply, divide, subtract, and add matrices in Swift in a performance optimized manner.