Swift矩阵和

时间:2016-06-10 10:19:28

标签: swift matrix sum

我试图开发一个函数,如果它们等于相同的维度,它允许对两个矩阵求和,但是我得到一个错误" 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")
}

这是错误日志:

enter image description here

3 个答案:

答案 0 :(得分:1)

问题是您在for循环0...self.rows中使用closed range operator。这将包括迭代范围的上限,在您的情况下超出范围,因此会崩溃。

您想要使用半开放范围运算符..<代替:

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

这将迭代但不包括上限。

我还要注意@MartinR's comment above - 将矩阵的等式定义为完全基于相同的维度似乎是不合逻辑的。请记住,平等意味着可替代性(即a == bab是否可以互换)。

我会考虑更改您的==以检查维度值,然后在sumWith方法中实施自己的维度检查(或创建一个新方法进行比较尺寸)。

答案 1 :(得分:1)

实际上您的错误索引超出范围

使用此代码替换您的扩展程序。

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

希望它能解决你的问题。

答案 2 :(得分:0)

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