は、フレームワークが不足又は過剰決定線形システムを解くため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ビット整数で、
Int
とCInt
の間の変換が必要です。
例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)))
}
ここにコードを追加します!コードなしで助けることはできません。 – Dershowitz123
[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のこれらの関数を使うにはいくつかの作業が必要です:) –
残念ながら、LLSの問題を解決する方法はありません。 – wtznc