@@ -15,7 +15,207 @@ public enum LapackError: Error {
1515///
1616/// Float array extension
1717public extension Array where Element == Float {
18+ /// SGETRF computes an LU factorization of a general M-by-N matrix A
19+ /// using partial pivoting with row interchanges.
20+ ///
21+ /// The factorization has the form
22+ /// A = P * L * U
23+ /// where P is a permutation matrix, L is lower triangular with unit
24+ /// diagonal elements (lower trapezoidal if m > n), and U is upper
25+ /// triangular (upper trapezoidal if m < n).
26+ ///
27+ /// This is the right-looking Level 3 BLAS version of the algorithm.
28+ ///
29+ /// This array must be in column major storage.
30+ ///
31+ /// http://www.netlib.org/lapack/explore-html/d8/ddc/group__real_g_ecomputational_ga8d99c11b94db3d5eac75cac46a0f2e17.html#ga8d99c11b94db3d5eac75cac46a0f2e17
32+ ///
33+ /// - Parameters:
34+ /// - m: number of rows
35+ /// - n: number of columns
36+ ///
37+ /// - Returns: The pivot indices; for 1 <= i <= min(M,N), row i of the matrix was interchanged with row IPIV(i).
38+ mutating func getrf( m: Int , n: Int ) throws -> [ Int32 ] {
39+ var ipiv = [ Int32] ( repeating: 0 , count: Swift . min ( m, n) )
40+ try getrf ( m: m, n: n, ipiv: & ipiv)
41+ return ipiv
42+ }
43+
44+ /// SGETRF computes an LU factorization of a general M-by-N matrix A
45+ /// using partial pivoting with row interchanges.
46+ ///
47+ /// The factorization has the form
48+ /// A = P * L * U
49+ /// where P is a permutation matrix, L is lower triangular with unit
50+ /// diagonal elements (lower trapezoidal if m > n), and U is upper
51+ /// triangular (upper trapezoidal if m < n).
52+ ///
53+ /// This is the right-looking Level 3 BLAS version of the algorithm.
54+ ///
55+ /// This array must be in column major storage.
56+ ///
57+ /// http://www.netlib.org/lapack/explore-html/d8/ddc/group__real_g_ecomputational_ga8d99c11b94db3d5eac75cac46a0f2e17.html#ga8d99c11b94db3d5eac75cac46a0f2e17
58+ ///
59+ /// - Parameters:
60+ /// - m: number of rows
61+ /// - n: number of columns
62+ /// - ipiv: the pivot indices; for 1 <= i <= min(m,n), row i of the matrix was interchanged with row ipiv[i].
63+ mutating func getrf( m m_: Int , n n_: Int , ipiv: inout [ Int32 ] ) throws {
64+ var m = Int32 ( m_)
65+ assert ( m >= 0 , " \( m) >= 0 " )
66+ var n = Int32 ( n_)
67+ assert ( n >= 0 , " \( n) >= 0 " )
68+ // leading dimension is the number of rows in column major order
69+ var lda = Int32 ( m)
70+ assert ( lda >= Swift . max ( 1 , m) , " \( lda) >= max(1, \( m) " )
71+ assert ( count == lda * n, " \( count) == ( \( lda) , \( n) ) " )
72+
73+ assert ( ipiv. count >= Swift . min ( m, n) , " \( ipiv. count) > min( \( m) , \( n) " )
74+
75+ var info : Int32 = 0
76+ sgetrf_ ( & m, & n, & self , & lda, & ipiv, & info)
77+ if info != 0 {
78+ throw LapackError . getrf ( info)
79+ }
80+ }
81+
82+ /// SGETRI computes the inverse of a matrix using the LU factorization
83+ /// computed by DGETRF.
84+ ///
85+ /// This method inverts U and then computes inv(A) by solving the system
86+ /// inv(A)*L = inv(U) for inv(A).
87+ ///
88+ ///
89+ mutating func getri( ) throws {
90+ var n = Int32 ( Double ( count) . squareRoot ( ) )
91+ assert ( count == n * n, " \( count) == \( n) * \( n) " )
92+ var ipiv = try getrf ( m: Int ( n) , n: Int ( n) )
93+
94+ var lda = Int32 ( count / Int( n) )
95+ assert ( lda >= Swift . max ( 1 , n) , " \( lda) >= max(1, \( n) " )
96+
97+ var info : Int32 = 0
98+
99+ // do optimal workspace query
100+ var lwork : Int32 = - 1
101+ var work = [ __CLPK_real] ( repeating: 0.0 , count: 1 )
102+ sgetri_ ( & n, & self , & lda, & ipiv, & work, & lwork, & info)
103+ if info != 0 {
104+ throw LapackError . getri ( info)
105+ }
106+
107+ // retrieve optimal workspace
108+ lwork = Int32 ( work [ 0 ] )
109+ work = [ __CLPK_real] ( repeating: 0.0 , count: Int ( lwork) )
110+
111+ // do the inversion
112+ sgetri_ ( & n, & self , & lda, & ipiv, & work, & lwork, & info)
113+ if info != 0 {
114+ throw LapackError . getri ( info)
115+ }
116+ }
117+
118+ /// DGESV computes the solution to a real system of linear equations
119+ /// A * X = B,
120+ /// where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
121+ ///
122+ /// The LU decomposition with partial pivoting and row interchanges is
123+ /// used to factor A as
124+ /// A = P * L * U,
125+ /// where P is a permutation matrix, L is unit lower triangular, and U is
126+ /// upper triangular. The factored form of A is then used to solve the
127+ /// system of equations A * X = B.
128+ ///
129+ /// This array must be in column major storage.
130+ ///
131+ /// http://www.netlib.org/lapack/explore-html/d8/ddc/group__real_g_ecomputational_ga1af62182327d0be67b1717db399d7d83.html#ga1af62182327d0be67b1717db399d7d83
132+ mutating func gesv( B: inout [ Element ] ) throws {
133+ var ipiv : [ Int32 ] = [ Int32 ] . init ( repeating: 0 , count: n)
134+ try gesv ( ipiv: & ipiv, B: & B)
135+ }
136+
137+ /// SGESV computes the solution to a real system of linear equations
138+ /// A * X = B,
139+ /// where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
140+ ///
141+ /// The LU decomposition with partial pivoting and row interchanges is
142+ /// used to factor A as
143+ /// A = P * L * U,
144+ /// where P is a permutation matrix, L is unit lower triangular, and U is
145+ /// upper triangular. The factored form of A is then used to solve the
146+ /// system of equations A * X = B.
147+ ///
148+ /// This array and B must be in column major storage.
149+ ///
150+ /// http://www.netlib.org/lapack/explore-html/d8/ddc/group__real_g_ecomputational_ga461f4ac32685a5ca30e293ee73d32920.html#ga461f4ac32685a5ca30e293ee73d32920
151+ mutating func gesv( ipiv: inout [ Int32 ] , B: inout [ Element ] ) throws {
152+ var n = Int32 ( self . n)
153+ assert ( count == n * n, " \( count) == \( n) * \( n) " )
154+ assert ( ipiv. count == n, " \( ipiv. count) == \( n) " )
18155
156+ var nrhs = Int32 ( B . count / Int( n) )
157+ assert ( nrhs >= 1 , " \( nrhs) >= 1 " )
158+ assert ( B . count == nrhs * n, " \( B . count) == \( nrhs) * \( n) " )
159+
160+ var lda = n
161+ assert ( lda >= Swift . max ( 1 , n) , " \( lda) >= max(1, \( n) " )
162+
163+ var ldb = Int32 ( B . count / Int( nrhs) )
164+ assert ( ldb * nrhs == B . count, " \( ldb) * \( nrhs) == \( B . count) " )
165+ assert ( ldb >= Swift . max ( 1 , n) , " \( ldb) >= max(1, \( n) ) " )
166+
167+ var info : Int32 = 0
168+ sgesv_ ( & n, & nrhs, & self , & lda, & ipiv, & B, & ldb, & info)
169+ if info != 0 {
170+ throw LapackError . dgesv ( info)
171+ }
172+ }
173+
174+ /// SGTSV solves the equation
175+ ///
176+ /// A*X = B,
177+ ///
178+ /// where A is an n by n tridiagonal matrix, by Gaussian elimination with
179+ /// partial pivoting.
180+ ///
181+ /// Note that the equation A**T*X = B may be solved by interchanging the
182+ /// order of the arguments DU and DL.
183+ ///
184+ /// This array represents the diagonal of A.
185+ ///
186+ /// http://www.netlib.org/lapack/explore-html/d1/d88/group__real_g_tsolve_gae1cbb7cd9c376c9cc72575d472eba346.html#gae1cbb7cd9c376c9cc72575d472eba346
187+ ///
188+ /// - Parameters:
189+ /// - nrhs: The number of right hand sides, i.e., the number of columns of the matrix B. NRHS >= 0.
190+ /// - dl: On entry, DL must contain the (n-1) sub-diagonal elements of A.
191+ /// On exit, DL is overwritten by the (n-2) elements of the
192+ /// second super-diagonal of the upper triangular matrix U from
193+ /// the LU factorization of A, in DL(1), ..., DL(n-2).
194+ /// - du: On entry, DU must contain the (n-1) super-diagonal elements of A.
195+ /// On exit, DU is overwritten by the (n-1) elements of the first
196+ /// super-diagonal of U.
197+ /// - B: On entry, the N by NRHS matrix of right hand side matrix B.
198+ /// On exit, if no error was thrown, the N by NRHS solution matrix X.
199+ ///
200+ mutating func gtsv( nrhs: Int , dl: inout [ Element ] , du: inout [ Element ] , B: inout [ Element ] ) throws {
201+ assert ( count - 1 == dl. count, " \( count) - 1 == \( dl. count) " )
202+ assert ( count - 1 == du. count, " \( count) - 1 == \( du. count) " )
203+ var n = Int32 ( count)
204+
205+ var nrhs = Int32 ( B . count / Int( n) )
206+ assert ( nrhs >= 1 , " \( nrhs) >= 1 " )
207+ assert ( B . count == Int ( nrhs) * count, " \( B . count) == \( nrhs) * \( n) " )
208+
209+ var ldb = Int32 ( B . count / Int( nrhs) )
210+ assert ( ldb * nrhs == B . count, " \( ldb) * \( nrhs) == \( B . count) " )
211+ assert ( ldb >= Swift . max ( 1 , n) , " \( ldb) >= max(1, \( n) ) " )
212+
213+ var info : Int32 = 0
214+ sgtsv_ ( & n, & nrhs, & dl, & self , & du, & B, & ldb, & info)
215+ if info != 0 {
216+ throw LapackError . dgesv ( info)
217+ }
218+ }
19219}
20220
21221/// Array extension employing the LAPACK framework.
@@ -206,7 +406,7 @@ public extension Array where Element == Double {
206406 /// - B: On entry, the N by NRHS matrix of right hand side matrix B.
207407 /// On exit, if no error was thrown, the N by NRHS solution matrix X.
208408 ///
209- mutating func gtsv( nrhs: Int , dl: inout [ Double ] , du: inout [ Double ] , B: inout [ Double ] ) throws {
409+ mutating func gtsv( nrhs: Int , dl: inout [ Element ] , du: inout [ Element ] , B: inout [ Element ] ) throws {
210410 assert ( count - 1 == dl. count, " \( count) - 1 == \( dl. count) " )
211411 assert ( count - 1 == du. count, " \( count) - 1 == \( du. count) " )
212412 var n = Int32 ( count)
0 commit comments