Matrix inversion in Swift using Accelerate Framework

Following the good instructions I found here: https://github.com/haginile/SwiftAccelerate I have verified that matrix inversion works. In fact, this was done for the given example. But I am getting error EXC_BAD_ACCESS

for any other matrix (larger than 2x2), for example the following 2D matrix (converted as 1D array) has been tested in matlab and python successfully and it does not work.

m = [0.55481645013013, -1.15522603580724, 0.962090414322894, -0.530226035807236, 0.168545207161447, -0.38627124296868, 0.93401699437494, -0.999999999999995, 0.684016994374945, -0.23176274578121, 0.123606797749979, -0.323606797749979, 0.432893622827287, -0.323606797749979, 0.123606797749979, 0.231762745781211, -0.684016994374948, 1.0, -0.934016994374947, 0.386271242968684, 0.168545207161448, -0.530226035807237, 0.962090414322895, -1.15522603580724, 0.554816450130132]

      

Its inverted matrix should be

inv(AA)

ans =

  Columns 1 through 3

          -262796763616197          -656991909040516          4.90007819375216
          -162417332048282          -406043330120712          14.6405748712708
         0.718958226823704          7.87760147961979          30.4010295628018
           162417332048287           406043330120730          46.1614842543337
           262796763616208           656991909040536          55.9019809318537

  Columns 4 through 5

          -656991909040528           262796763616211
          -406043330120721           162417332048287
         -4.28281034550088        -0.718958226823794
           406043330120704          -162417332048283
           656991909040497          -262796763616196

      

Could you please give me another way of matrix inversion in Swift? Or explain me how to fix this? I really don't understand why this doesn't work.

+3


source to share


2 answers


It doesn't work because the instructions you found aren't that good. In particular, both the anchor points and the workspace must be arrays, not scalar values; it only worked for two or two matrices at random.

Here's a modified version of the function invert

that distributes workspaces correctly:

func invert(matrix : [Double]) -> [Double] {
  var inMatrix = matrix
  var N = __CLPK_integer(sqrt(Double(matrix.count)))
  var pivots = [__CLPK_integer](count: Int(N), repeatedValue: 0)
  var workspace = [Double](count: Int(N), repeatedValue: 0.0)
  var error : __CLPK_integer = 0
  dgetrf_(&N, &N, &inMatrix, &N, &pivots, &error)
  dgetri_(&N, &inMatrix, &N, &pivots, &workspace, &N, &error)
  return inMatrix
}

      



I should also point out that your 5x5 matrix is ​​very poorly conditioned, so even when you can compute the "inverse" error, this computation will be very large, and the reverse should really not be used.

A Swift 4 version:

func invert(matrix : [Double]) -> [Double] {
    var inMatrix = matrix
    var N = __CLPK_integer(sqrt(Double(matrix.count)))
    var pivots = [__CLPK_integer](repeating: 0, count: Int(N))
    var workspace = [Double](repeating: 0.0, count: Int(N))
    var error : __CLPK_integer = 0

    withUnsafeMutablePointer(to: &N) {
        dgetrf_($0, $0, &inMatrix, $0, &pivots, &error)
        dgetri_($0, &inMatrix, $0, &pivots, &workspace, $0, &error)
    }
    return inMatrix
}

      

+8


source


I wrote a library for linear algebra in Swift. I call this library swix and it includes matrix inversion functions (this function is called inv

).

Usage example:

var b = ones(10)
var A = rand((10, 10))
var AI = inv(A)
var x = AI.dot(b)

      



Source: https://github.com/stsievert/swix

Documentation: http://scottsievert.com/swix/

+1


source







All Articles