Swift matrix sum

2019-02-20 14:35发布

问题:

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:

回答1:

Actually your error is Index out of range

Replace your extension with this code.

extension Matrix: Operation {

    mutating func sumWith(matrixB: Matrix) throws -> Matrix {

        guard self == matrixB else { throw RisedError.DimensionNotEquals }

        for row in 0...self.rows - 1 {
            for column in 0...self.columns - 1 {
                self[row, column] = matrixB[row, column] + self[row, column]
            }
         }
        return self
    }
}

Hope it would solve your problem.



回答2:

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:

for row in 0..<self.rows {
    for column in 0..<self.columns {
        self[row, column] = matrixB[row, column] + self[row, column]
    }
}

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 and b are interchangeable).

I would consider changing your == to check both dimensions and values, and then implement your own dimension check in your sumWith method (or create a new method to compare dimensions).



回答3:

swift 4 - Addition 0f 3 x 3 Matrices

enum RisedError: Error {
        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

    }
    class ViewController: UIViewController {


    //Matrix creation
        func matrixCreation(){
            var matrixA = Matrix(rows: 3, columns: 3)
            var matrixB = Matrix(rows: 3, columns: 3)
            matrixA[0,0] = 1.0
            matrixA[0, 1] = 2.0
            matrixA[0, 2] = 2.0
            matrixA[1, 0] = 3.0
            matrixA[1, 1] = 4.0
            matrixA[1, 2] = 4.0
            matrixA[2, 0] = 1.0
            matrixA[2, 1] = 1.0
            matrixA[2, 2] = 1.0
            matrixB[0,0] = 5.0
            matrixB[0, 1] = 6.0
            matrixB[0, 2] = 6.0
            matrixB[1, 0] = 7.0
            matrixB[1, 1] = 8.0
            matrixB[1, 2] = 8.0
            matrixB[2, 0] = 1.0
            matrixB[2, 1] = 1.0
            matrixB[2, 2] = 1.0

            var outputMartix = Matrix(rows: 3, columns: 3)
            print(matrixB , matrixA)
            do {
                outputMartix = try! matrixA.sumWith(matrixB: matrixB)
                print(outputMartix)
            }catch RisedError.DimensionNotEquals{
                print("Dimensions are not equal")

            }
        }

    }

    //Matrix Configuration

    struct Matrix {
        let rows: Int, columns: Int
        var grid: [Double]
        init(rows: Int, columns: Int) {
            self.rows = rows
            self.columns = columns
            grid = Array(repeating: 0.0, count: rows * columns)
        }
        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: row, column: column), "Index out of range")
                return grid[(row * columns) + column]
            }
            set {
                assert(indexIsValidForRow(row: row, column: column), "Index out of range")
                grid[(row * columns) + column] = newValue
            }
        }
    }
    extension Matrix: Operation {

        mutating func sumWith(matrixB: Matrix) throws -> Matrix {

            guard self == matrixB else { throw RisedError.DimensionNotEquals }

            for row in 0...self.rows - 1 {
                for column in 0...self.columns - 1 {
                    self[row, column] = matrixB[row, column] + self[row, column]
                }
            }
            return self
        }
    }


标签: swift matrix sum