I'm trying to develop a func which allows to sum two matrix if they are equals to the same dimension, but I get an error "EXC_BAD_INSTRUCTION" on the try.
Here is my Playground:
import Foundation
enum RisedError: ErrorType {
case DimensionNotEquals
case Obvious(String)
}
func ==(lhs: Matrix, rhs: Matrix) -> Bool {
return (lhs.rows) == (rhs.rows) && (lhs.columns) == (rhs.columns)
}
protocol Operation {
mutating func sumWith(matrixB: Matrix) throws -> Matrix
}
struct Matrix {
let rows: Int, columns: Int
var grid: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(count: rows * columns, repeatedValue: 0.0)
}
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
subscript(row: Int, column: Int) -> Double {
get {
assert(indexIsValidForRow(row, column: column), "Index out of range")
return grid[(row * columns) + column]
}
set {
assert(indexIsValidForRow(row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue
}
}
}
var matrixA = Matrix(rows: 2, columns: 2)
matrixA[0,0] = 1.0
matrixA[0,1] = 2.0
matrixA[1,0] = 3.0
matrixA[1,1] = 4.0
var matrixB = Matrix(rows: 2, columns: 2)
matrixB[0,0] = 5.0
matrixB[0,1] = 6.0
matrixB[1,0] = 7.0
matrixB[1,1] = 8.0
print(matrixA)
print(matrixB)
extension Matrix: Operation {
mutating func sumWith(matrixB: Matrix) throws -> Matrix {
guard self == matrixB else { throw RisedError.DimensionNotEquals }
for row in 0...self.rows {
for column in 0...self.columns {
self[row, column] = matrixB[row, column] + self[row, column]
}
}
return self
}
}
do {
try matrixA.sumWith(matrixB)
} catch RisedError.DimensionNotEquals {
print("The two matrix's dimensions aren't equals")
} catch {
print("Something very bad happens")
}
Here is the error Log:
Actually your error is Index out of range
Replace your extension with this code.
Hope it would solve your problem.
The problem is you're using the closed range operator in your for loop
0...self.rows
. This will include the upper bound of the range in the iteration, which in your case is out of bounds and will therefore crash.You want to use the half-open range operator
..<
instead:This will iterate up to but not including the upper bound.
I would also note @MartinR's comment above – defining equality for the matrices to be solely based on the dimensions being the same seems illogical. Remember that equality implies substitutability (i.e if
a == b
,a
andb
are interchangeable).I would consider changing your
==
to check both dimensions and values, and then implement your own dimension check in yoursumWith
method (or create a new method to compare dimensions).