Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save pauljohanneskraft/fd982faf2e2827ee2b14503095d880fa to your computer and use it in GitHub Desktop.
Save pauljohanneskraft/fd982faf2e2827ee2b14503095d880fa to your computer and use it in GitHub Desktop.
Matrix and Vector operators in Swift, using Numeric.swift - see: https://gist.github.com/pauljohanneskraft/56f3757bf4026a1330e601e3af167e24#file-numeric-swift

Matrix operators

Matrices: +, +=, -, -=, *, *=, /, /=, LaTeX
Vectors:  ^⟙
func * <T: NumericType>(left: [[T]], right: [[T]]) throws -> [[T]] {
var left = left
try left *= right
return left
}
func *= <T: Numeric>( left: inout [[T]], right: [[T]]) throws -> [[T]] {
if left[0].count != right.count { throw MatrixError.NotMultipliable }
var matrix : [[T]] = []
for i in 0..<left.count {
var array : [T] = []
for j in 0..<right[0].count {
var value : T = T(0)
for k in 0..<right.count {
value += (left[i][k]*right[k][j])
}
array.append(value)
}
matrix.append(array)
}
left = matrix
return left
}
func -= <T: Numeric>( left: inout [[T]], right: [[T]]) throws -> [[T]] {
if left.count != right.count || left[0].count != right[0].count { throw MatrixError.NotAddable }
for i in 0..<left.count {
for j in 0..<left[0].count {
left[i][j] = left[i][j] - right[i][j]
}
}
return left
}
func - <T: Numeric>(left: [[T]], right: [[T]]) throws -> [[T]] {
var matrix = left
try matrix -= right
return matrix
}
func += <T: Numeric>( left: inout [[T]], right: [[T]]) throws -> [[T]] {
if left.count != right.count || left[0].count != right[0].count { throw MatrixError.NotAddable }
for i in 0..<left.count {
for j in 0..<left[0].count {
left[i][j] = left[i][j] + right[i][j]
}
}
return left
}
func + <T: Numeric>(left: [[T]], right: [[T]]) throws -> [[T]] {
var matrix = left
try matrix += right
return matrix
}
func *= <T: Numeric>( left: inout [[T]], right: T) -> [[T]] {
for row in 0..<left.count {
for column in 0..<left[row].count {
left[row][column] = left[row][column]*right
}
}
return left
}
func * <T: Numeric>(left: [[T]], right: T) -> [[T]] {
var left = left
left *= right
return left
}
func * <T: Numeric>(left: T, right: [[T]]) -> [[T]] {
var right = right
right *= left
return right
}
func /= <T: Numeric>( left: inout [[T]], right: T) -> [[T]] {
for row in 0..<left.count {
for column in 0..<left[row].count {
left[row][column] = left[row][column]/right
}
}
return left
}
func / <T: Numeric>(left: [[T]], right: T) -> [[T]] {
var left = left
left /= right
return left
}
func / <T: Numeric>(left: T, right: [[T]]) -> [[T]] {
var right = right
right /= left
return right
}
func == <T: Numeric>(left: [[T]], right: [[T]]) -> Bool {
if left.count != right.count || left[0].count != right[0].count { return false }
var left = left
for row in 0..<left.count {
for column in 0..<left[row].count {
if left[row][column] != right[row][column] {
return false
}
}
}
return true
}
func != <T: Numeric>(left: [[T]], right: [[T]]) -> Bool {
return !(left == right)
}
extension Array where Element : BidirectionalCollection {
func toLaTeXMatrix() -> String {
var out = "\\begin{pmatrix}\n"
for array in self {
for value in array.dropLast() {
out += "\(value) & "
}
out += "\(array.last!) \\\\\n"
}
return out + "\\end{pmatrix}"
}
}
enum MatrixError: ErrorProtocol {
case NotMultipliable, NotAddable, Unsolvable, NoUniqueSolution
}
postfix operator ^⟙ {}
postfix func ^⟙<A>(lhs: [A]) -> [[A]] {
var res = [[A]]()
for v in lhs {
res.append([v])
}
return res
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment