Быстрая матричная сумма

Я пытаюсь разработать функцию, которая позволяет суммировать две матрицы, если они равны одному измерению, но я получаю ошибку "EXC_BAD_INSTRUCTION" при попытке.

Вот моя детская площадка:

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")
}

Вот журнал ошибок:

 Fogmeister10 июн. 2016 г., 12:29
Можете ли вы показать остальную часть журнала ошибок?
 Martin R10 июн. 2016 г., 12:50
Вы действительно определяетеA == B чтобы быть правдой, если только матрицаразмеры подобные?
 Martin R10 июн. 2016 г., 12:53
Если что-то неожиданное происходит на игровой площадке: 1) используйте вместо этого скомпилированный проект и 2) используйтеотладчик чтобы пошагово пройти через ваш код. В вашем случае с матрицами 2x2 проблема станет очевидной практически сразу!

Ответы на вопрос(3)

Индекс вне диапазона

Замените ваше расширение этим кодом.

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
    }
}

Надеюсь, это решит вашу проблему.

 Bertrand Bloc'h10 июн. 2016 г., 12:47
Позор мне .. Вы решили мою проблему :)
 Bhumika10 июн. 2016 г., 12:54
это мое удовольствие :)
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
        }
    }

Проблема в том, что вы используетеоператор закрытого диапазона в вашем для цикла0...self.rows, Это будет включать верхнюю границу диапазона в итерации, которая в вашем случае выходит за границы и, следовательно, приведет к сбою.

Вы хотите использовать оператор полуоткрытого диапазона..< вместо:

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

Это будет повторять до, но не включая верхнюю границу.

Я бы также отметил@ MartinR комментарий выше - определение равенства для матриц, основанных исключительно на одинаковых измерениях, представляется нелогичным. Помните, что равенство подразумеваетвзаимозаменяемость (т.е. еслиa == b, a а такжеb взаимозаменяемы).

Я хотел бы рассмотреть возможность изменения вашего== проверить оба размераа также значения, а затем реализовать свою собственную проверку размеров в вашемsumWith метод (или создать новый метод для сравнения размеров).

Ваш ответ на вопрос