In this post we’ll cover solving a system of linear equations using Swift and Accelerate. It get’s a little bit hairy, but it’s not so bad once you get the hang of it.
We’ll need to perform an LU factorization as before. Then we’ll solve the system of linear equations using the dgetrs_() function from the Accelerate framework, along with the documentation at netlib.org.
To make matters interesting, the first argument of the dgetrs_()
function is a letter telling the function whether your matrix should be interpreted as column-major, as in Fortran, or whether it should be interpreted as row-major, as in C and every other language. If you want column major, use “N”, otherwise for row-major, use “T”. This gets interesting because the C code expects a UInt8
pointer or something, and a Swift string just isn’t going to cut it. To make C and Swift play nicely, we had to do some weird stuff on line 20 that I’m not wholly comfortable with yet, but it worked.
import Accelerate func solve( A:[Double], _ B:[Double] ) -> [Double] { var inMatrix:[Double] = A var solution:[Double] = B // Get the dimensions of the matrix. An NxN matrix has N^2 // elements, so sqrt( N^2 ) will return N, the dimension var N:__CLPK_integer = __CLPK_integer( sqrt( Double( A.count ) ) ) // Number of columns on the RHS var NRHS:__CLPK_integer = 1 // Leading dimension of A and B var LDA:__CLPK_integer = N var LDB:__CLPK_integer = N // Initialize some arrays for the dgetrf_(), and dgetri_() functions var pivots:[__CLPK_integer] = [__CLPK_integer](count: Int(N), repeatedValue: 0) var error: __CLPK_integer = 0 // Perform LU factorization dgetrf_(&N, &N, &inMatrix, &N, &pivots, &error) // Calculate solution from LU factorization _ = "T".withCString { dgetrs_( UnsafeMutablePointer($0), &N, &NRHS, &inMatrix, &LDA, &pivots, &solution, &LDB, &error ) } return solution } var A: [Double] = [ 1, 1, 4, 6 ] var B: [Double] = [ 383, 2034 ] var soln = solve( A, B ) print( soln ) // --> [ 132.0, 251.0 ]