Following the good instructions that I found here: https://github.com/haginile/SwiftAccelerate I verified that matrix inversion works. In fact it did for the example given. But I get a EXC_BAD_ACCESS
error for any other matrix (bigger than 2x2) for example the following 2D matrix (converted as a 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 it does not work.
It doesn't work because the instructions that you found are not so good. Specifically, both pivots and workspace need to be Arrays, not scalar values; it was only working for two-by-two matrices by random chance.
Here's a modified version of the invert
function that allocates the 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 note that your 5x5 matrix is extremely ill-conditioned, so even when you can compute the "inverse" the error of that computation will be very large, and the inverse really shouldn't 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
}
I have written a library for linear algebra in Swift. I call this library swix and it includes functions to invert matrices (this function is called inv
).
Example use case:
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/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.