Thanks to Swift’s type safety and generics it is possible to define matrix types with safe operations. Where, for instance, you may only multiply an *M×N* matrix by a *P×Q* matrix if *N* is equal to *P*.

In this article I tackle this problem in a very generic way, so that you can add type safety to your favourite existing matrix implementation. This is useful since different matrix libraries may perform better in different applications (machine learning algorithms vs 3D graphics for example).

I have embedded all the necessary code in this article (except for a couple of stubbed methods near the end). The main tool’s code is in **SafeMatrix.swift**. My rudimentary sample implementation of a matrix type is in **Matrix.swift**, which could be replaced by any existing matrix library. The preparation of that **Matrix** type and the matrix dimension types are in **MatrixSetup.swift **and **NumeralsSetup.swift**. The sample code is in **Usage.swift**.

#### The Tool: Safe Matrix Protocol And Type

You may decide to explore the **SafeMatrix.swift** code beforehand or simply skip to the Setup and Usage sections below.

#### Setup Part I: Existing Matrix Implementation

As I explained at the start, we need to begin with an existing matrix library. My sample implementation of the **Matrix **structure below includes initialization, entry lookup, mutable entries, addition, multiplication, and scalar multiplication. In this implementation the entries are of type **Double**, but they could be **Int** or any other type. This implementation is missing transposes, determinants, inverses, and many other standard matrix operations.

After we find (or create) our preferred matrix type implementation, we need to make it conform to **UnsafeMatrixProtocol**. Conformance to**UnsafeMatrixProtocol** simply requires **subscripting** and a **dimensions:MatrixDimensions** getter:

#### Setup Part II: Numerals

In the sections that follow, we are going to initialize and manipulate instances of the **SafeMatrix** generic structure. This structure has three associated types;

**MatrixType**, conforming to**UnsafeMatrixProtocol****Rows**, conforming to**NumeralProtocol****Columns**, conforming to**NumeralProtocol**

As you may have guessed, **MatrixType** is going to be our “existing” **Matrix**type.

So what are **Rows** and **Columns**? These are types whose sole purpose is to provide the number of rows and columns of the specialized **SafeMatrix**structure. This is so that — among other things — two matrices with different dimensions are always of different type.

In our example we assume that we have two global variables *m* and *n*, and that our code will feature *m×n*, *n×m*, *m×m*, and *n×n* matrices.

In real-world use cases you may need these values to be loaded from an external source such as a file or a web service. I am not considering those cases here, but it is possible to tackle them with a modified setup.

#### Usage Part I: Initialization

I am finally ready to show you the resulting *m×n* safe matrix type. This is simply **SafeMatrix<Matrix,M,N>**, and can be initialized with a *m×n***Matrix**.

This line of code is too long and hard to read, an issue that we can fix by conveniently extending **SafeMatrixProtocol** in our **MatrixSetup.swift** file:

Observe that we use **Self.staticDimensions** rather than **self.dimensions**because the latter is not available before initialization. This extension allows us to initialize **SafeMatrix<Matrix,M,N>** in a much shorter fashion:

#### Usage Part II: Operators

Recall that our **Matrix** type supports addition, multiplication, and scalar multiplication operators. We would like to port these over to**SafeMatrix<Matrix>**. For this we again need to edit **MatrixSetup.swift**:

#### Usage Part III: Transpose, Inverse, and Determinant

In this section we assume that the **Matrix** type contains implementations for**transpose**, **inverse** and **determinant** methods. For now we add stubbed implementations in **Matrix.swift**, but be aware that you will need actual implementations for the **usageMethods()** function to run.

To port these methods over to **SafeMatrix<Matrix>** types, we need to add two extensions. This is because **inverse()** and **determinant() **have a special requirement; **Rows == Columns**.