2016-06-15 42 views
5

Python'dan Swift'e yeniden kodu yeniden yazmalıyım ama en küçük kareler çözümünü bir doğrusal matris denklemine döndürmesi gereken işlev üzerinde sıkışmış durumdayım. Herhangi birinizin Swift dilinde yazılmış bir kütüphaneyi tanıdığı var mı? numpy.linalg.lstsq? Yardımın için minnettar olurum.Bir doğrusal matris denklemine en küçük kareler çözümünü döndüren işlev

Python kodu: Şimdiye kadar

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 kodu:

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

kodu buraya ekleyin! Kodsuz yardımcı olamaz. – Dershowitz123

+1

[hızlandırılması çerçeve] (https://developer.apple.com/library/ios/documentation/Accelerate/Reference/AccelerateFWRef /) [Linear Least Squares Problems] (http://www.netlib.org/blas/faq.html) fonksiyonunu içeren [BLAS kütüphanesi] : //www.netlib.org/lapack/lug/node27.html). Swift'den bu fonksiyonları kullanmak biraz iş gerektiriyor olsa da :) –

+0

Ne yazık ki, LLS problemlerini çözen bir yöntem yok. – wtznc

cevap

3

çerçeve az ya da üstbelirlenmiş doğrusal sistemleri çözmek için DGELS işlevi vardır LAPACK lineer cebir paketi, dahil hızlandırın . belgeleri:

DGELS tam sahip olduğu kabul edilen bir QR veya A. LQ çarpanlara kullanılarak M-NN matris A veya devrik içeren üstbelirlenmiş veya gereğinden az gerçek lineer sistemleri çözer rütben.

İşte bu örnek Swift'den nasıl kullanılabilir. Esasen this C sample code bir çevirisidir.

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

bazı notlar:

  • dgels_() geçirilen matris ve vektör verileri değiştirir ve A sütun içeren "düz" bir dizi olarak matris bekler. Ayrıca sağ taraf, uzunluk max(M, N) olan bir dizi olarak bekleniyor. Bu nedenle, giriş verileri önce yerel değişkenlere kopyalanır.
  • Tüm bağımsız değişkenler dgels_() numaralı başvuruya göre iletilmelidir, bu nedenle hepsi var s dizininde saklanır.
  • A C tamsayı, Int ve CInt arasında gerekli olan bazı dönüşümler yapan 32 bitlik bir tamsayıdır.

Örnek 1: http://www.seas.ucla.edu/~vandenbe/103/lectures/ls.pdf den Aşırı belirlenmemiş sistem.

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] 
} 

Örnek 2: gereğinden az sistemi, en az bir norm x_1 + x_2 + x_3 = 1.0 için çözeltisi.

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] 
} 

için Güncelleştirme Swift 3 ve Swift 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))) 
}