2016-06-15 56 views
5

PythonからSwiftへのコードを書き直す必要がありますが、最小二乗解をリニアマトリクス方程式に戻す関数に固執しています。 Swiftに書かれた図書館は誰でも知っていますか?numpy.linalg.lstsqと同等の方法がありますか?私はあなたの助けに感謝します。最小二乗解をリニアマトリクス方程式に戻す関数

Pythonコード:これまで

a = numpy.array([[p2.x-p1.x,p2.y-p1.y],[p4.x-p3.x,p4.y-p3.y],[p4.x-p2.x,p4.y-p2.y],[p3.x-p1.x,p3.y-p1.y]]) 
b = numpy.array([number1,number2,number3,number4]) 
res = numpy.linalg.lstsq(a,b) 
result = [float(res[0][0]),float(res[0][1])] 
return result 

スウィフトコード:

var matrix1 = [[p2.x-p1.x, p2.y-p1.y],[p4.x-p3.x, p4.y-p3.y], [p4.x-p2.x, p4.y-p2.y], [p3.x-p1.x, p3.y-p1.y]] 
var matrix2 = [number1, number2, number3, number4] 
+0

ここにコードを追加します!コードなしで助けることはできません。 – Dershowitz123

+1

[Accelerate framework](https://developer.apple。[Linear Least Squares Problems](http://www.netlib.org/blas/faq.html)の機能を持つ[BLASライブラリ](http://www.netlib.org/blas/faq.html)が含まれています://www.netlib.org/lapack/lug/node27.html)。 Swiftのこれらの関数を使うにはいくつかの作業が必要です:) –

+0

残念ながら、LLSの問題を解決する方法はありません。 – wtznc

答えて

3

は、フレームワークが不足又は過剰決定線形システムを解くためDGELS機能を有するLAPACK線形代数パッケージ、 を含ま加速。ドキュメントから:

DGELSは、AがフルであるとするQRまたはAのLQ 分解を用いたm行n列の行列をA、又はその転置を伴う過剰決定または劣決定の実線形システム を解きランク。

ここでは、その機能をSwiftからどのように使用できるかの例です。 本質的にはthis C sample codeの翻訳です。

func solveLeastSquare(A A: [[Double]], B: [Double]) -> [Double]? { 
    precondition(A.count == B.count, "Non-matching dimensions") 

    var mode = Int8(bitPattern: UInt8(ascii: "N")) // "Normal" mode 
    var nrows = CInt(A.count) 
    var ncols = CInt(A[0].count) 
    var nrhs = CInt(1) 
    var ldb = max(nrows, ncols) 

    // Flattened columns of matrix A 
    var localA = (0 ..< nrows * ncols).map { 
     A[Int($0 % nrows)][Int($0/nrows)] 
    } 

    // Vector B, expanded by zeros if ncols > nrows 
    var localB = B 
    if ldb > nrows { 
     localB.appendContentsOf([Double](count: ldb - nrows, repeatedValue: 0.0)) 
    } 

    var wkopt = 0.0 
    var lwork: CInt = -1 
    var info: CInt = 0 

    // First call to determine optimal workspace size 
    dgels_(&mode, &nrows, &ncols, &nrhs, &localA, &nrows, &localB, &ldb, &wkopt, &lwork, &info) 
    lwork = Int32(wkopt) 

    // Allocate workspace and do actual calculation 
    var work = [Double](count: Int(lwork), repeatedValue: 0.0) 
    dgels_(&mode, &nrows, &ncols, &nrhs, &localA, &nrows, &localB, &ldb, &work, &lwork, &info) 

    if info != 0 { 
     print("A does not have full rank; the least squares solution could not be computed.") 
     return nil 
    } 
    return Array(localB.prefix(Int(ncols))) 
} 

いくつかの注意事項:

  • dgels_()通過行列およびベクトルデータを修正し、Aの列を含む「平坦な」配列として マトリックスを期待。 また、右側は長さがmax(M, N)の配列として期待されます。 このため、入力データはローカル変数に最初にコピーされます。
  • すべての引数はdgels_()に参照渡しする必要があります。そのため、 はすべてvarに格納されます。
  • C整数は32ビット整数で、 IntCIntの間の変換が必要です。

例1:http://www.seas.ucla.edu/~vandenbe/103/lectures/ls.pdfから優決定システム。

let A = [[ 2.0, 0.0 ], 
     [ -1.0, 1.0 ], 
     [ 0.0, 2.0 ]] 
let B = [ 1.0, 0.0, -1.0 ] 
if let x = solveLeastSquare(A: A, B: B) { 
    print(x) // [0.33333333333333326, -0.33333333333333343] 
} 

例2:劣決定システム、最小ノルムx_1 + x_2 + x_3 = 1.0に 溶液。

let A = [[ 1.0, 1.0, 1.0 ]] 
let B = [ 1.0 ] 
if let x = solveLeastSquare(A: A, B: B) { 
    print(x) // [0.33333333333333337, 0.33333333333333337, 0.33333333333333337] 
} 

の更新スウィフト3スウィフト4:

func solveLeastSquare(A: [[Double]], B: [Double]) -> [Double]? { 
    precondition(A.count == B.count, "Non-matching dimensions") 

    var mode = Int8(bitPattern: UInt8(ascii: "N")) // "Normal" mode 
    var nrows = CInt(A.count) 
    var ncols = CInt(A[0].count) 
    var nrhs = CInt(1) 
    var ldb = max(nrows, ncols) 

    // Flattened columns of matrix A 
    var localA = (0 ..< nrows * ncols).map { (i) -> Double in 
     A[Int(i % nrows)][Int(i/nrows)] 
    } 

    // Vector B, expanded by zeros if ncols > nrows 
    var localB = B 
    if ldb > nrows { 
     localB.append(contentsOf: [Double](repeating: 0.0, count: Int(ldb - nrows))) 
    } 

    var wkopt = 0.0 
    var lwork: CInt = -1 
    var info: CInt = 0 

    // First call to determine optimal workspace size 
    var nrows_copy = nrows // Workaround for SE-0176 
    dgels_(&mode, &nrows, &ncols, &nrhs, &localA, &nrows_copy, &localB, &ldb, &wkopt, &lwork, &info) 
    lwork = Int32(wkopt) 

    // Allocate workspace and do actual calculation 
    var work = [Double](repeating: 0.0, count: Int(lwork)) 
    dgels_(&mode, &nrows, &ncols, &nrhs, &localA, &nrows_copy, &localB, &ldb, &work, &lwork, &info) 

    if info != 0 { 
     print("A does not have full rank; the least squares solution could not be computed.") 
     return nil 
    } 
    return Array(localB.prefix(Int(ncols))) 
} 
関連する問題