2017-01-15 2 views
2

SWIFT에서 A * X = B 유형의 선형 방정식 시스템을 풀려고합니다.타입 A * X = B의 방정식을 푸십시오. dgtsv_ 또는 sgtsv_를 사용합니다.

O (N^2) 메모리를 사용하는 LU 분해 기반 알고리즘을 사용하여이 작업을 수행 할 수있었습니다.

내 배열은 일반적으로 (10000 샘플 이상) 커지므로 LAPACK에는 O (N) 메모리 공간만을 사용하는 3 중 매트릭스에 특정한 기능이 있습니다. &이 더 효율적입니다.

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

기본적으로, 나는 위의 dgtsv_ 사용하여 방정식 또는 sgtsv_ 기능을 해결하기 위해 찾고 있어요. 그러나 찾을 수있는 예제가 없습니다.

저는 SWIFT를 처음 사용하기 때문에 함수가 요구하는 8 개의 입력 매개 변수를 전달하는 데 어려움을 겪고 있습니다. 어딘가에 예제가 있습니까?

(LU 분해를 사용하여) 작업 코드 아래에 붙여 넣습니다.

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) 

답변

2

dgtsv_()는 기대 하부/분리 인수로 트라이 대각 행렬의 대각선 상/주. 변수 어레이의 주소를 &으로 전달할 수 있습니다.

모든 정수 매개 변수는 __CLPK_integer 별명 Int32 개의 주소입니다.

오른쪽 벡터 ~ A x = b 방정식을 사용하면 벡터 b이 덮어 쓰기됩니다. A을 설명하는 세 벡터는 을 덮어 쓰므로 원본 데이터의 복사본을 만들 수도 있습니다.

예 :

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] 

} 
+0

감사 마틴 -이 지금 나를 위해 완벽하게 잘 작동합니다! – Pat