Solve Equations Of Type A*X = B Using dgtsv_ or sgtsv_

社会主义新天地 提交于 2019-12-24 02:31:11

问题


I am trying to solve a system of linear equations of the type: A*X = B in SWIFT.

I have been able to do this using LU factorization based algorithm that consumes O(N^2) memory.

Since my arrays are generally big (10000 samples and more), I am looking at LAPACK that has some functions specific to tridiagonal matrices which consumes only O(N) memory space & are more efficient.

http://www.netlib.org/lapack/explore-html-3.4.2/d4/d62/group__double_g_tsolve.html#

Essentially, I am looking to solve the equations using dgtsv_ or sgtsv_ functions above. But there are no examples I can find.

As I am fairly new to SWIFT, I am struggling to pass the 8 input parameters the function asks for. Is there an example somewhere?

I paste below my working code (using LU factorization).

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](repeating: 0, count: Int(N))

var error: __CLPK_integer   = 0

// Perform LU factorization
dgetrf_(&N, &N, &inMatrix, &N, &pivots, &error)

// Calculate solution from LU factorization
_ = "T".withCString {
    dgetrs_( UnsafeMutablePointer(mutating: $0), &N, &NRHS, &inMatrix, &LDA, &pivots, &solution, &LDB, &error )
}
return solution
  }


  //Call the function
  var A: [Double] = [
      1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
      1.0, 4.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
      0.0, 1.0, 4.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
      0.0, 0.0, 1.0, 4.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
      0.0, 0.0, 0.0, 1.0, 4.0, 1.0, 0.0, 0.0, 0.0, 0.0,
      0.0, 0.0, 0.0, 0.0, 1.0, 4.0, 1.0, 0.0, 0.0, 0.0,
      0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 4.0, 1.0, 0.0, 0.0,
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 4.0, 1.0, 0.0,
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 4.0, 1.0,
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]

  var b: [Double] = [0, -15, -15, -3, -3, 45, -12, -6, 0, 0]

  var cj = solve(A: A, b)

  print( cj ) // --> [0.0, -2.9185349611542728, -3.3258601553829079,   1.2219755826859044, -4.5620421753607099, 14.026193118756936, -6.5427302996670358, 0.14472807991120964, -0.036182019977802411, 0.0]
  //Call the function


  //TRY LAPACK (need examples to get above solution)
  let xx = dgtsv_(<#T##__n:    UnsafeMutablePointer<__CLPK_integer>!##UnsafeMutablePointer<__CLPK_integer>!#>, <#T##__nrhs: UnsafeMutablePointer<__CLPK_integer>!##UnsafeMutablePointer<__CLPK_integer>!#>, <#T##__dl: UnsafeMutablePointer<__CLPK_doublereal>!##UnsafeMutablePointer<__CLPK_doublereal>!#>, <#T##__d__: UnsafeMutablePointer<__CLPK_doublereal>!##UnsafeMutablePointer<__CLPK_doublereal>!#>, <#T##__du: UnsafeMutablePointer<__CLPK_doublereal>!##UnsafeMutablePointer<__CLPK_doublereal>!#>, <#T##__b: UnsafeMutablePointer<__CLPK_doublereal>!##UnsafeMutablePointer<__CLPK_doublereal>!#>, <#T##__ldb: UnsafeMutablePointer<__CLPK_integer>!##UnsafeMutablePointer<__CLPK_integer>!#>, <#T##__info: UnsafeMutablePointer<__CLPK_integer>!##UnsafeMutablePointer<__CLPK_integer>!#>)

  let xx2 = sgtsv_(<#T##__n: UnsafeMutablePointer<__CLPK_integer>!##UnsafeMutablePointer<__CLPK_integer>!#>, <#T##__nrhs: UnsafeMutablePointer<__CLPK_integer>!##UnsafeMutablePointer<__CLPK_integer>!#>, <#T##__dl: UnsafeMutablePointer<__CLPK_real>!##UnsafeMutablePointer<__CLPK_real>!#>, <#T##__d__: UnsafeMutablePointer<__CLPK_real>!##UnsafeMutablePointer<__CLPK_real>!#>, <#T##__du: UnsafeMutablePointer<__CLPK_real>!##UnsafeMutablePointer<__CLPK_real>!#>, <#T##__b: UnsafeMutablePointer<__CLPK_real>!##UnsafeMutablePointer<__CLPK_real>!#>, <#T##__ldb: UnsafeMutablePointer<__CLPK_integer>!##UnsafeMutablePointer<__CLPK_integer>!#>, <#T##__info: UnsafeMutablePointer<__CLPK_integer>!##UnsafeMutablePointer<__CLPK_integer>!#>)
  //TRY LAPACK (need examples to get above solution)

回答1:


dgtsv_() expects the lower/main/upper diagonal of the tri-diagonal matrix as separate arguments. You can pass the address of variable arrays with &.

All integer parameters are addresses of __CLPK_integer aka Int32 variables.

The right-hand side vector b is overwritten with the solution x to the A x = b equation. The three vectors describing A are overwritten as well, so you might want to make copies of the original data.

Example:

import Swift
import Accelerate

var mainDiagA = [ 1.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 1.0 ]
var upperDiagA = [ 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ]
var lowerDiagA = [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0 ]

var b = [0.0, -15.0, -15.0, -3.0, -3.0, 45.0, -12.0, -6.0, 0.0, 0.0 ]

var n = Int32(mainDiagA.count) // Order of matrix A
var nrhs = Int32(1) // Number of right-hand sides
var info = Int32(0) // Result code

dgtsv_(&n, &nrhs, &lowerDiagA, &mainDiagA, &upperDiagA, &b, &n, &info)
if info == 0 { // success
    print(b)
    // [0.0, -2.9185349611542732, -3.3258601553829075, 1.2219755826859044, -4.5620421753607099, 14.026193118756938, -6.5427302996670367, 0.14472807991120964, -0.036182019977802411, 0.0]

}


来源:https://stackoverflow.com/questions/41660708/solve-equations-of-type-ax-b-using-dgtsv-or-sgtsv

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!