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

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] = [
,

].flatMap { \$0 }

// Matrix C, a MxN sized matrix
var C: [Float] = [
,
,

].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)
``````

Use `vDSP.add` to add two matrices:

``````let matrix: [Float] = [
[3, 6],
[1, 5]
].flatMap { \$0 }

``````

## 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.