gpt4 book ai didi

python - 返回线性矩阵方程的最小二乘解的函数

转载 作者:太空狗 更新时间:2023-10-29 21:49:00 24 4
gpt4 key购买 nike

我一直在尝试将代码从 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

到目前为止的 Swift 代码:

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]

最佳答案

Accelerate 框架包括 LAPACK线性代数包,它有一个 DGELS求解欠定或超定线性系统的函数。来自文档:

DGELS solves overdetermined or underdetermined real linear systems involving an M-by-N matrix A, or its transpose, using a QR or LQ factorization of A. It is assumed that A has full rank.

这是一个如何在 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]
}

Swift 3Swift 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)))
}

关于python - 返回线性矩阵方程的最小二乘解的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37836311/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com