github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/lapack/lapack64/lapack64.go (about) 1 // Copyright ©2015 The Gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package lapack64 6 7 import ( 8 "github.com/jingcheng-WU/gonum/blas" 9 "github.com/jingcheng-WU/gonum/blas/blas64" 10 "github.com/jingcheng-WU/gonum/lapack" 11 "github.com/jingcheng-WU/gonum/lapack/gonum" 12 ) 13 14 var lapack64 lapack.Float64 = gonum.Implementation{} 15 16 // Use sets the LAPACK float64 implementation to be used by subsequent BLAS calls. 17 // The default implementation is native.Implementation. 18 func Use(l lapack.Float64) { 19 lapack64 = l 20 } 21 22 // Tridiagonal represents a tridiagonal matrix using its three diagonals. 23 type Tridiagonal struct { 24 N int 25 DL []float64 26 D []float64 27 DU []float64 28 } 29 30 func max(a, b int) int { 31 if a > b { 32 return a 33 } 34 return b 35 } 36 37 // Potrf computes the Cholesky factorization of a. 38 // The factorization has the form 39 // A = Uᵀ * U if a.Uplo == blas.Upper, or 40 // A = L * Lᵀ if a.Uplo == blas.Lower, 41 // where U is an upper triangular matrix and L is lower triangular. 42 // The triangular matrix is returned in t, and the underlying data between 43 // a and t is shared. The returned bool indicates whether a is positive 44 // definite and the factorization could be finished. 45 func Potrf(a blas64.Symmetric) (t blas64.Triangular, ok bool) { 46 ok = lapack64.Dpotrf(a.Uplo, a.N, a.Data, max(1, a.Stride)) 47 t.Uplo = a.Uplo 48 t.N = a.N 49 t.Data = a.Data 50 t.Stride = a.Stride 51 t.Diag = blas.NonUnit 52 return 53 } 54 55 // Potri computes the inverse of a real symmetric positive definite matrix A 56 // using its Cholesky factorization. 57 // 58 // On entry, t contains the triangular factor U or L from the Cholesky 59 // factorization A = Uᵀ*U or A = L*Lᵀ, as computed by Potrf. 60 // 61 // On return, the upper or lower triangle of the (symmetric) inverse of A is 62 // stored in t, overwriting the input factor U or L, and also returned in a. The 63 // underlying data between a and t is shared. 64 // 65 // The returned bool indicates whether the inverse was computed successfully. 66 func Potri(t blas64.Triangular) (a blas64.Symmetric, ok bool) { 67 ok = lapack64.Dpotri(t.Uplo, t.N, t.Data, max(1, t.Stride)) 68 a.Uplo = t.Uplo 69 a.N = t.N 70 a.Data = t.Data 71 a.Stride = t.Stride 72 return 73 } 74 75 // Potrs solves a system of n linear equations A*X = B where A is an n×n 76 // symmetric positive definite matrix and B is an n×nrhs matrix, using the 77 // Cholesky factorization A = Uᵀ*U or A = L*Lᵀ. t contains the corresponding 78 // triangular factor as returned by Potrf. On entry, B contains the right-hand 79 // side matrix B, on return it contains the solution matrix X. 80 func Potrs(t blas64.Triangular, b blas64.General) { 81 lapack64.Dpotrs(t.Uplo, t.N, b.Cols, t.Data, max(1, t.Stride), b.Data, max(1, b.Stride)) 82 } 83 84 // Pbcon returns an estimate of the reciprocal of the condition number (in the 85 // 1-norm) of an n×n symmetric positive definite band matrix using the Cholesky 86 // factorization 87 // A = Uᵀ*U if uplo == blas.Upper 88 // A = L*Lᵀ if uplo == blas.Lower 89 // computed by Pbtrf. The estimate is obtained for norm(inv(A)), and the 90 // reciprocal of the condition number is computed as 91 // rcond = 1 / (anorm * norm(inv(A))). 92 // 93 // The length of work must be at least 3*n and the length of iwork must be at 94 // least n. 95 func Pbcon(a blas64.SymmetricBand, anorm float64, work []float64, iwork []int) float64 { 96 return lapack64.Dpbcon(a.Uplo, a.N, a.K, a.Data, a.Stride, anorm, work, iwork) 97 } 98 99 // Pbtrf computes the Cholesky factorization of an n×n symmetric positive 100 // definite band matrix 101 // A = Uᵀ * U if a.Uplo == blas.Upper 102 // A = L * Lᵀ if a.Uplo == blas.Lower 103 // where U and L are upper, respectively lower, triangular band matrices. 104 // 105 // The triangular matrix U or L is returned in t, and the underlying data 106 // between a and t is shared. The returned bool indicates whether A is positive 107 // definite and the factorization could be finished. 108 func Pbtrf(a blas64.SymmetricBand) (t blas64.TriangularBand, ok bool) { 109 ok = lapack64.Dpbtrf(a.Uplo, a.N, a.K, a.Data, max(1, a.Stride)) 110 t.Uplo = a.Uplo 111 t.Diag = blas.NonUnit 112 t.N = a.N 113 t.K = a.K 114 t.Data = a.Data 115 t.Stride = a.Stride 116 return t, ok 117 } 118 119 // Pbtrs solves a system of linear equations A*X = B with an n×n symmetric 120 // positive definite band matrix A using the Cholesky factorization 121 // A = Uᵀ * U if t.Uplo == blas.Upper 122 // A = L * Lᵀ if t.Uplo == blas.Lower 123 // t contains the corresponding triangular factor as returned by Pbtrf. 124 // 125 // On entry, b contains the right hand side matrix B. On return, it is 126 // overwritten with the solution matrix X. 127 func Pbtrs(t blas64.TriangularBand, b blas64.General) { 128 lapack64.Dpbtrs(t.Uplo, t.N, t.K, b.Cols, t.Data, max(1, t.Stride), b.Data, max(1, b.Stride)) 129 } 130 131 // Gecon estimates the reciprocal of the condition number of the n×n matrix A 132 // given the LU decomposition of the matrix. The condition number computed may 133 // be based on the 1-norm or the ∞-norm. 134 // 135 // a contains the result of the LU decomposition of A as computed by Getrf. 136 // 137 // anorm is the corresponding 1-norm or ∞-norm of the original matrix A. 138 // 139 // work is a temporary data slice of length at least 4*n and Gecon will panic otherwise. 140 // 141 // iwork is a temporary data slice of length at least n and Gecon will panic otherwise. 142 func Gecon(norm lapack.MatrixNorm, a blas64.General, anorm float64, work []float64, iwork []int) float64 { 143 return lapack64.Dgecon(norm, a.Cols, a.Data, max(1, a.Stride), anorm, work, iwork) 144 } 145 146 // Gels finds a minimum-norm solution based on the matrices A and B using the 147 // QR or LQ factorization. Gels returns false if the matrix 148 // A is singular, and true if this solution was successfully found. 149 // 150 // The minimization problem solved depends on the input parameters. 151 // 152 // 1. If m >= n and trans == blas.NoTrans, Gels finds X such that || A*X - B||_2 153 // is minimized. 154 // 2. If m < n and trans == blas.NoTrans, Gels finds the minimum norm solution of 155 // A * X = B. 156 // 3. If m >= n and trans == blas.Trans, Gels finds the minimum norm solution of 157 // Aᵀ * X = B. 158 // 4. If m < n and trans == blas.Trans, Gels finds X such that || A*X - B||_2 159 // is minimized. 160 // Note that the least-squares solutions (cases 1 and 3) perform the minimization 161 // per column of B. This is not the same as finding the minimum-norm matrix. 162 // 163 // The matrix A is a general matrix of size m×n and is modified during this call. 164 // The input matrix B is of size max(m,n)×nrhs, and serves two purposes. On entry, 165 // the elements of b specify the input matrix B. B has size m×nrhs if 166 // trans == blas.NoTrans, and n×nrhs if trans == blas.Trans. On exit, the 167 // leading submatrix of b contains the solution vectors X. If trans == blas.NoTrans, 168 // this submatrix is of size n×nrhs, and of size m×nrhs otherwise. 169 // 170 // Work is temporary storage, and lwork specifies the usable memory length. 171 // At minimum, lwork >= max(m,n) + max(m,n,nrhs), and this function will panic 172 // otherwise. A longer work will enable blocked algorithms to be called. 173 // In the special case that lwork == -1, work[0] will be set to the optimal working 174 // length. 175 func Gels(trans blas.Transpose, a blas64.General, b blas64.General, work []float64, lwork int) bool { 176 return lapack64.Dgels(trans, a.Rows, a.Cols, b.Cols, a.Data, max(1, a.Stride), b.Data, max(1, b.Stride), work, lwork) 177 } 178 179 // Geqrf computes the QR factorization of the m×n matrix A using a blocked 180 // algorithm. A is modified to contain the information to construct Q and R. 181 // The upper triangle of a contains the matrix R. The lower triangular elements 182 // (not including the diagonal) contain the elementary reflectors. tau is modified 183 // to contain the reflector scales. tau must have length at least min(m,n), and 184 // this function will panic otherwise. 185 // 186 // The ith elementary reflector can be explicitly constructed by first extracting 187 // the 188 // v[j] = 0 j < i 189 // v[j] = 1 j == i 190 // v[j] = a[j*lda+i] j > i 191 // and computing H_i = I - tau[i] * v * vᵀ. 192 // 193 // The orthonormal matrix Q can be constucted from a product of these elementary 194 // reflectors, Q = H_0 * H_1 * ... * H_{k-1}, where k = min(m,n). 195 // 196 // Work is temporary storage, and lwork specifies the usable memory length. 197 // At minimum, lwork >= m and this function will panic otherwise. 198 // Geqrf is a blocked QR factorization, but the block size is limited 199 // by the temporary space available. If lwork == -1, instead of performing Geqrf, 200 // the optimal work length will be stored into work[0]. 201 func Geqrf(a blas64.General, tau, work []float64, lwork int) { 202 lapack64.Dgeqrf(a.Rows, a.Cols, a.Data, max(1, a.Stride), tau, work, lwork) 203 } 204 205 // Gelqf computes the LQ factorization of the m×n matrix A using a blocked 206 // algorithm. A is modified to contain the information to construct L and Q. The 207 // lower triangle of a contains the matrix L. The elements above the diagonal 208 // and the slice tau represent the matrix Q. tau is modified to contain the 209 // reflector scales. tau must have length at least min(m,n), and this function 210 // will panic otherwise. 211 // 212 // See Geqrf for a description of the elementary reflectors and orthonormal 213 // matrix Q. Q is constructed as a product of these elementary reflectors, 214 // Q = H_{k-1} * ... * H_1 * H_0. 215 // 216 // Work is temporary storage, and lwork specifies the usable memory length. 217 // At minimum, lwork >= m and this function will panic otherwise. 218 // Gelqf is a blocked LQ factorization, but the block size is limited 219 // by the temporary space available. If lwork == -1, instead of performing Gelqf, 220 // the optimal work length will be stored into work[0]. 221 func Gelqf(a blas64.General, tau, work []float64, lwork int) { 222 lapack64.Dgelqf(a.Rows, a.Cols, a.Data, max(1, a.Stride), tau, work, lwork) 223 } 224 225 // Gesvd computes the singular value decomposition of the input matrix A. 226 // 227 // The singular value decomposition is 228 // A = U * Sigma * Vᵀ 229 // where Sigma is an m×n diagonal matrix containing the singular values of A, 230 // U is an m×m orthogonal matrix and V is an n×n orthogonal matrix. The first 231 // min(m,n) columns of U and V are the left and right singular vectors of A 232 // respectively. 233 // 234 // jobU and jobVT are options for computing the singular vectors. The behavior 235 // is as follows 236 // jobU == lapack.SVDAll All m columns of U are returned in u 237 // jobU == lapack.SVDStore The first min(m,n) columns are returned in u 238 // jobU == lapack.SVDOverwrite The first min(m,n) columns of U are written into a 239 // jobU == lapack.SVDNone The columns of U are not computed. 240 // The behavior is the same for jobVT and the rows of Vᵀ. At most one of jobU 241 // and jobVT can equal lapack.SVDOverwrite, and Gesvd will panic otherwise. 242 // 243 // On entry, a contains the data for the m×n matrix A. During the call to Gesvd 244 // the data is overwritten. On exit, A contains the appropriate singular vectors 245 // if either job is lapack.SVDOverwrite. 246 // 247 // s is a slice of length at least min(m,n) and on exit contains the singular 248 // values in decreasing order. 249 // 250 // u contains the left singular vectors on exit, stored columnwise. If 251 // jobU == lapack.SVDAll, u is of size m×m. If jobU == lapack.SVDStore u is 252 // of size m×min(m,n). If jobU == lapack.SVDOverwrite or lapack.SVDNone, u is 253 // not used. 254 // 255 // vt contains the left singular vectors on exit, stored rowwise. If 256 // jobV == lapack.SVDAll, vt is of size n×m. If jobVT == lapack.SVDStore vt is 257 // of size min(m,n)×n. If jobVT == lapack.SVDOverwrite or lapack.SVDNone, vt is 258 // not used. 259 // 260 // work is a slice for storing temporary memory, and lwork is the usable size of 261 // the slice. lwork must be at least max(5*min(m,n), 3*min(m,n)+max(m,n)). 262 // If lwork == -1, instead of performing Gesvd, the optimal work length will be 263 // stored into work[0]. Gesvd will panic if the working memory has insufficient 264 // storage. 265 // 266 // Gesvd returns whether the decomposition successfully completed. 267 func Gesvd(jobU, jobVT lapack.SVDJob, a, u, vt blas64.General, s, work []float64, lwork int) (ok bool) { 268 return lapack64.Dgesvd(jobU, jobVT, a.Rows, a.Cols, a.Data, max(1, a.Stride), s, u.Data, max(1, u.Stride), vt.Data, max(1, vt.Stride), work, lwork) 269 } 270 271 // Getrf computes the LU decomposition of the m×n matrix A. 272 // The LU decomposition is a factorization of A into 273 // A = P * L * U 274 // where P is a permutation matrix, L is a unit lower triangular matrix, and 275 // U is a (usually) non-unit upper triangular matrix. On exit, L and U are stored 276 // in place into a. 277 // 278 // ipiv is a permutation vector. It indicates that row i of the matrix was 279 // changed with ipiv[i]. ipiv must have length at least min(m,n), and will panic 280 // otherwise. ipiv is zero-indexed. 281 // 282 // Getrf is the blocked version of the algorithm. 283 // 284 // Getrf returns whether the matrix A is singular. The LU decomposition will 285 // be computed regardless of the singularity of A, but division by zero 286 // will occur if the false is returned and the result is used to solve a 287 // system of equations. 288 func Getrf(a blas64.General, ipiv []int) bool { 289 return lapack64.Dgetrf(a.Rows, a.Cols, a.Data, max(1, a.Stride), ipiv) 290 } 291 292 // Getri computes the inverse of the matrix A using the LU factorization computed 293 // by Getrf. On entry, a contains the PLU decomposition of A as computed by 294 // Getrf and on exit contains the reciprocal of the original matrix. 295 // 296 // Getri will not perform the inversion if the matrix is singular, and returns 297 // a boolean indicating whether the inversion was successful. 298 // 299 // Work is temporary storage, and lwork specifies the usable memory length. 300 // At minimum, lwork >= n and this function will panic otherwise. 301 // Getri is a blocked inversion, but the block size is limited 302 // by the temporary space available. If lwork == -1, instead of performing Getri, 303 // the optimal work length will be stored into work[0]. 304 func Getri(a blas64.General, ipiv []int, work []float64, lwork int) (ok bool) { 305 return lapack64.Dgetri(a.Cols, a.Data, max(1, a.Stride), ipiv, work, lwork) 306 } 307 308 // Getrs solves a system of equations using an LU factorization. 309 // The system of equations solved is 310 // A * X = B if trans == blas.Trans 311 // Aᵀ * X = B if trans == blas.NoTrans 312 // A is a general n×n matrix with stride lda. B is a general matrix of size n×nrhs. 313 // 314 // On entry b contains the elements of the matrix B. On exit, b contains the 315 // elements of X, the solution to the system of equations. 316 // 317 // a and ipiv contain the LU factorization of A and the permutation indices as 318 // computed by Getrf. ipiv is zero-indexed. 319 func Getrs(trans blas.Transpose, a blas64.General, b blas64.General, ipiv []int) { 320 lapack64.Dgetrs(trans, a.Cols, b.Cols, a.Data, max(1, a.Stride), ipiv, b.Data, max(1, b.Stride)) 321 } 322 323 // Ggsvd3 computes the generalized singular value decomposition (GSVD) 324 // of an m×n matrix A and p×n matrix B: 325 // Uᵀ*A*Q = D1*[ 0 R ] 326 // 327 // Vᵀ*B*Q = D2*[ 0 R ] 328 // where U, V and Q are orthogonal matrices. 329 // 330 // Ggsvd3 returns k and l, the dimensions of the sub-blocks. k+l 331 // is the effective numerical rank of the (m+p)×n matrix [ Aᵀ Bᵀ ]ᵀ. 332 // R is a (k+l)×(k+l) nonsingular upper triangular matrix, D1 and 333 // D2 are m×(k+l) and p×(k+l) diagonal matrices and of the following 334 // structures, respectively: 335 // 336 // If m-k-l >= 0, 337 // 338 // k l 339 // D1 = k [ I 0 ] 340 // l [ 0 C ] 341 // m-k-l [ 0 0 ] 342 // 343 // k l 344 // D2 = l [ 0 S ] 345 // p-l [ 0 0 ] 346 // 347 // n-k-l k l 348 // [ 0 R ] = k [ 0 R11 R12 ] k 349 // l [ 0 0 R22 ] l 350 // 351 // where 352 // 353 // C = diag( alpha_k, ... , alpha_{k+l} ), 354 // S = diag( beta_k, ... , beta_{k+l} ), 355 // C^2 + S^2 = I. 356 // 357 // R is stored in 358 // A[0:k+l, n-k-l:n] 359 // on exit. 360 // 361 // If m-k-l < 0, 362 // 363 // k m-k k+l-m 364 // D1 = k [ I 0 0 ] 365 // m-k [ 0 C 0 ] 366 // 367 // k m-k k+l-m 368 // D2 = m-k [ 0 S 0 ] 369 // k+l-m [ 0 0 I ] 370 // p-l [ 0 0 0 ] 371 // 372 // n-k-l k m-k k+l-m 373 // [ 0 R ] = k [ 0 R11 R12 R13 ] 374 // m-k [ 0 0 R22 R23 ] 375 // k+l-m [ 0 0 0 R33 ] 376 // 377 // where 378 // C = diag( alpha_k, ... , alpha_m ), 379 // S = diag( beta_k, ... , beta_m ), 380 // C^2 + S^2 = I. 381 // 382 // R = [ R11 R12 R13 ] is stored in A[1:m, n-k-l+1:n] 383 // [ 0 R22 R23 ] 384 // and R33 is stored in 385 // B[m-k:l, n+m-k-l:n] on exit. 386 // 387 // Ggsvd3 computes C, S, R, and optionally the orthogonal transformation 388 // matrices U, V and Q. 389 // 390 // jobU, jobV and jobQ are options for computing the orthogonal matrices. The behavior 391 // is as follows 392 // jobU == lapack.GSVDU Compute orthogonal matrix U 393 // jobU == lapack.GSVDNone Do not compute orthogonal matrix. 394 // The behavior is the same for jobV and jobQ with the exception that instead of 395 // lapack.GSVDU these accept lapack.GSVDV and lapack.GSVDQ respectively. 396 // The matrices U, V and Q must be m×m, p×p and n×n respectively unless the 397 // relevant job parameter is lapack.GSVDNone. 398 // 399 // alpha and beta must have length n or Ggsvd3 will panic. On exit, alpha and 400 // beta contain the generalized singular value pairs of A and B 401 // alpha[0:k] = 1, 402 // beta[0:k] = 0, 403 // if m-k-l >= 0, 404 // alpha[k:k+l] = diag(C), 405 // beta[k:k+l] = diag(S), 406 // if m-k-l < 0, 407 // alpha[k:m]= C, alpha[m:k+l]= 0 408 // beta[k:m] = S, beta[m:k+l] = 1. 409 // if k+l < n, 410 // alpha[k+l:n] = 0 and 411 // beta[k+l:n] = 0. 412 // 413 // On exit, iwork contains the permutation required to sort alpha descending. 414 // 415 // iwork must have length n, work must have length at least max(1, lwork), and 416 // lwork must be -1 or greater than n, otherwise Ggsvd3 will panic. If 417 // lwork is -1, work[0] holds the optimal lwork on return, but Ggsvd3 does 418 // not perform the GSVD. 419 func Ggsvd3(jobU, jobV, jobQ lapack.GSVDJob, a, b blas64.General, alpha, beta []float64, u, v, q blas64.General, work []float64, lwork int, iwork []int) (k, l int, ok bool) { 420 return lapack64.Dggsvd3(jobU, jobV, jobQ, a.Rows, a.Cols, b.Rows, a.Data, max(1, a.Stride), b.Data, max(1, b.Stride), alpha, beta, u.Data, max(1, u.Stride), v.Data, max(1, v.Stride), q.Data, max(1, q.Stride), work, lwork, iwork) 421 } 422 423 // Gtsv solves one of the equations 424 // A * X = B if trans == blas.NoTrans 425 // Aᵀ * X = B if trans == blas.Trans or blas.ConjTrans 426 // where A is an n×n tridiagonal matrix. It uses Gaussian elimination with 427 // partial pivoting. 428 // 429 // On entry, a contains the matrix A, on return it will be overwritten. 430 // 431 // On entry, b contains the n×nrhs right-hand side matrix B. On return, it will 432 // be overwritten. If ok is true, it will be overwritten by the solution matrix X. 433 // 434 // Gtsv returns whether the solution X has been successfuly computed. 435 // 436 // Dgtsv is not part of the lapack.Float64 interface and so calls to Gtsv are 437 // always executed by the Gonum implementation. 438 func Gtsv(trans blas.Transpose, a Tridiagonal, b blas64.General) (ok bool) { 439 if trans != blas.NoTrans { 440 a.DL, a.DU = a.DU, a.DL 441 } 442 return gonum.Implementation{}.Dgtsv(a.N, b.Cols, a.DL, a.D, a.DU, b.Data, max(1, b.Stride)) 443 } 444 445 // Lagtm performs one of the matrix-matrix operations 446 // C = alpha * A * B + beta * C if trans == blas.NoTrans 447 // C = alpha * Aᵀ * B + beta * C if trans == blas.Trans or blas.ConjTrans 448 // where A is an m×m tridiagonal matrix represented by its diagonals dl, d, du, 449 // B and C are m×n dense matrices, and alpha and beta are scalars. 450 // 451 // Dlagtm is not part of the lapack.Float64 interface and so calls to Lagtm are 452 // always executed by the Gonum implementation. 453 func Lagtm(trans blas.Transpose, alpha float64, a Tridiagonal, b blas64.General, beta float64, c blas64.General) { 454 gonum.Implementation{}.Dlagtm(trans, c.Rows, c.Cols, alpha, a.DL, a.D, a.DU, b.Data, max(1, b.Stride), beta, c.Data, max(1, c.Stride)) 455 } 456 457 // Lange computes the matrix norm of the general m×n matrix A. The input norm 458 // specifies the norm computed. 459 // lapack.MaxAbs: the maximum absolute value of an element. 460 // lapack.MaxColumnSum: the maximum column sum of the absolute values of the entries. 461 // lapack.MaxRowSum: the maximum row sum of the absolute values of the entries. 462 // lapack.Frobenius: the square root of the sum of the squares of the entries. 463 // If norm == lapack.MaxColumnSum, work must be of length n, and this function will panic otherwise. 464 // There are no restrictions on work for the other matrix norms. 465 func Lange(norm lapack.MatrixNorm, a blas64.General, work []float64) float64 { 466 return lapack64.Dlange(norm, a.Rows, a.Cols, a.Data, max(1, a.Stride), work) 467 } 468 469 // Langt computes the specified norm of an n×n tridiagonal matrix. 470 // 471 // Dlangt is not part of the lapack.Float64 interface and so calls to Langt are 472 // always executed by the Gonum implementation. 473 func Langt(norm lapack.MatrixNorm, a Tridiagonal) float64 { 474 return gonum.Implementation{}.Dlangt(norm, a.N, a.DL, a.D, a.DU) 475 } 476 477 // Lansb computes the specified norm of an n×n symmetric band matrix. If 478 // norm == lapack.MaxColumnSum or norm == lapack.MaxRowSum, work must have length 479 // at least n and this function will panic otherwise. 480 // There are no restrictions on work for the other matrix norms. 481 // 482 // Dlansb is not part of the lapack.Float64 interface and so calls to Lansb are always 483 // executed by the Gonum implementation. 484 func Lansb(norm lapack.MatrixNorm, a blas64.SymmetricBand, work []float64) float64 { 485 return gonum.Implementation{}.Dlansb(norm, a.Uplo, a.N, a.K, a.Data, max(1, a.Stride), work) 486 } 487 488 // Lansy computes the specified norm of an n×n symmetric matrix. If 489 // norm == lapack.MaxColumnSum or norm == lapack.MaxRowSum, work must have length 490 // at least n and this function will panic otherwise. 491 // There are no restrictions on work for the other matrix norms. 492 func Lansy(norm lapack.MatrixNorm, a blas64.Symmetric, work []float64) float64 { 493 return lapack64.Dlansy(norm, a.Uplo, a.N, a.Data, max(1, a.Stride), work) 494 } 495 496 // Lantr computes the specified norm of an m×n trapezoidal matrix A. If 497 // norm == lapack.MaxColumnSum work must have length at least n and this function 498 // will panic otherwise. There are no restrictions on work for the other matrix norms. 499 func Lantr(norm lapack.MatrixNorm, a blas64.Triangular, work []float64) float64 { 500 return lapack64.Dlantr(norm, a.Uplo, a.Diag, a.N, a.N, a.Data, max(1, a.Stride), work) 501 } 502 503 // Lantb computes the specified norm of an n×n triangular band matrix A. If 504 // norm == lapack.MaxColumnSum work must have length at least n and this function 505 // will panic otherwise. There are no restrictions on work for the other matrix 506 // norms. 507 func Lantb(norm lapack.MatrixNorm, a blas64.TriangularBand, work []float64) float64 { 508 return gonum.Implementation{}.Dlantb(norm, a.Uplo, a.Diag, a.N, a.K, a.Data, max(1, a.Stride), work) 509 } 510 511 // Lapmt rearranges the columns of the m×n matrix X as specified by the 512 // permutation k_0, k_1, ..., k_{n-1} of the integers 0, ..., n-1. 513 // 514 // If forward is true a forward permutation is performed: 515 // 516 // X[0:m, k[j]] is moved to X[0:m, j] for j = 0, 1, ..., n-1. 517 // 518 // otherwise a backward permutation is performed: 519 // 520 // X[0:m, j] is moved to X[0:m, k[j]] for j = 0, 1, ..., n-1. 521 // 522 // k must have length n, otherwise Lapmt will panic. k is zero-indexed. 523 func Lapmt(forward bool, x blas64.General, k []int) { 524 lapack64.Dlapmt(forward, x.Rows, x.Cols, x.Data, max(1, x.Stride), k) 525 } 526 527 // Ormlq multiplies the matrix C by the othogonal matrix Q defined by 528 // A and tau. A and tau are as returned from Gelqf. 529 // C = Q * C if side == blas.Left and trans == blas.NoTrans 530 // C = Qᵀ * C if side == blas.Left and trans == blas.Trans 531 // C = C * Q if side == blas.Right and trans == blas.NoTrans 532 // C = C * Qᵀ if side == blas.Right and trans == blas.Trans 533 // If side == blas.Left, A is a matrix of side k×m, and if side == blas.Right 534 // A is of size k×n. This uses a blocked algorithm. 535 // 536 // Work is temporary storage, and lwork specifies the usable memory length. 537 // At minimum, lwork >= m if side == blas.Left and lwork >= n if side == blas.Right, 538 // and this function will panic otherwise. 539 // Ormlq uses a block algorithm, but the block size is limited 540 // by the temporary space available. If lwork == -1, instead of performing Ormlq, 541 // the optimal work length will be stored into work[0]. 542 // 543 // Tau contains the Householder scales and must have length at least k, and 544 // this function will panic otherwise. 545 func Ormlq(side blas.Side, trans blas.Transpose, a blas64.General, tau []float64, c blas64.General, work []float64, lwork int) { 546 lapack64.Dormlq(side, trans, c.Rows, c.Cols, a.Rows, a.Data, max(1, a.Stride), tau, c.Data, max(1, c.Stride), work, lwork) 547 } 548 549 // Ormqr multiplies an m×n matrix C by an orthogonal matrix Q as 550 // C = Q * C if side == blas.Left and trans == blas.NoTrans, 551 // C = Qᵀ * C if side == blas.Left and trans == blas.Trans, 552 // C = C * Q if side == blas.Right and trans == blas.NoTrans, 553 // C = C * Qᵀ if side == blas.Right and trans == blas.Trans, 554 // where Q is defined as the product of k elementary reflectors 555 // Q = H_0 * H_1 * ... * H_{k-1}. 556 // 557 // If side == blas.Left, A is an m×k matrix and 0 <= k <= m. 558 // If side == blas.Right, A is an n×k matrix and 0 <= k <= n. 559 // The ith column of A contains the vector which defines the elementary 560 // reflector H_i and tau[i] contains its scalar factor. tau must have length k 561 // and Ormqr will panic otherwise. Geqrf returns A and tau in the required 562 // form. 563 // 564 // work must have length at least max(1,lwork), and lwork must be at least n if 565 // side == blas.Left and at least m if side == blas.Right, otherwise Ormqr will 566 // panic. 567 // 568 // work is temporary storage, and lwork specifies the usable memory length. At 569 // minimum, lwork >= m if side == blas.Left and lwork >= n if side == 570 // blas.Right, and this function will panic otherwise. Larger values of lwork 571 // will generally give better performance. On return, work[0] will contain the 572 // optimal value of lwork. 573 // 574 // If lwork is -1, instead of performing Ormqr, the optimal workspace size will 575 // be stored into work[0]. 576 func Ormqr(side blas.Side, trans blas.Transpose, a blas64.General, tau []float64, c blas64.General, work []float64, lwork int) { 577 lapack64.Dormqr(side, trans, c.Rows, c.Cols, a.Cols, a.Data, max(1, a.Stride), tau, c.Data, max(1, c.Stride), work, lwork) 578 } 579 580 // Pocon estimates the reciprocal of the condition number of a positive-definite 581 // matrix A given the Cholesky decmposition of A. The condition number computed 582 // is based on the 1-norm and the ∞-norm. 583 // 584 // anorm is the 1-norm and the ∞-norm of the original matrix A. 585 // 586 // work is a temporary data slice of length at least 3*n and Pocon will panic otherwise. 587 // 588 // iwork is a temporary data slice of length at least n and Pocon will panic otherwise. 589 func Pocon(a blas64.Symmetric, anorm float64, work []float64, iwork []int) float64 { 590 return lapack64.Dpocon(a.Uplo, a.N, a.Data, max(1, a.Stride), anorm, work, iwork) 591 } 592 593 // Syev computes all eigenvalues and, optionally, the eigenvectors of a real 594 // symmetric matrix A. 595 // 596 // w contains the eigenvalues in ascending order upon return. w must have length 597 // at least n, and Syev will panic otherwise. 598 // 599 // On entry, a contains the elements of the symmetric matrix A in the triangular 600 // portion specified by uplo. If jobz == lapack.EVCompute, a contains the 601 // orthonormal eigenvectors of A on exit, otherwise jobz must be lapack.EVNone 602 // and on exit the specified triangular region is overwritten. 603 // 604 // Work is temporary storage, and lwork specifies the usable memory length. At minimum, 605 // lwork >= 3*n-1, and Syev will panic otherwise. The amount of blocking is 606 // limited by the usable length. If lwork == -1, instead of computing Syev the 607 // optimal work length is stored into work[0]. 608 func Syev(jobz lapack.EVJob, a blas64.Symmetric, w, work []float64, lwork int) (ok bool) { 609 return lapack64.Dsyev(jobz, a.Uplo, a.N, a.Data, max(1, a.Stride), w, work, lwork) 610 } 611 612 // Tbtrs solves a triangular system of the form 613 // A * X = B if trans == blas.NoTrans 614 // Aᵀ * X = B if trans == blas.Trans or blas.ConjTrans 615 // where A is an n×n triangular band matrix, and B is an n×nrhs matrix. 616 // 617 // Tbtrs returns whether A is non-singular. If A is singular, no solutions X 618 // are computed. 619 func Tbtrs(trans blas.Transpose, a blas64.TriangularBand, b blas64.General) (ok bool) { 620 return lapack64.Dtbtrs(a.Uplo, trans, a.Diag, a.N, a.K, b.Cols, a.Data, max(1, a.Stride), b.Data, max(1, b.Stride)) 621 } 622 623 // Trcon estimates the reciprocal of the condition number of a triangular matrix A. 624 // The condition number computed may be based on the 1-norm or the ∞-norm. 625 // 626 // work is a temporary data slice of length at least 3*n and Trcon will panic otherwise. 627 // 628 // iwork is a temporary data slice of length at least n and Trcon will panic otherwise. 629 func Trcon(norm lapack.MatrixNorm, a blas64.Triangular, work []float64, iwork []int) float64 { 630 return lapack64.Dtrcon(norm, a.Uplo, a.Diag, a.N, a.Data, max(1, a.Stride), work, iwork) 631 } 632 633 // Trtri computes the inverse of a triangular matrix, storing the result in place 634 // into a. 635 // 636 // Trtri will not perform the inversion if the matrix is singular, and returns 637 // a boolean indicating whether the inversion was successful. 638 func Trtri(a blas64.Triangular) (ok bool) { 639 return lapack64.Dtrtri(a.Uplo, a.Diag, a.N, a.Data, max(1, a.Stride)) 640 } 641 642 // Trtrs solves a triangular system of the form A * X = B or Aᵀ * X = B. Trtrs 643 // returns whether the solve completed successfully. If A is singular, no solve is performed. 644 func Trtrs(trans blas.Transpose, a blas64.Triangular, b blas64.General) (ok bool) { 645 return lapack64.Dtrtrs(a.Uplo, trans, a.Diag, a.N, b.Cols, a.Data, max(1, a.Stride), b.Data, max(1, b.Stride)) 646 } 647 648 // Geev computes the eigenvalues and, optionally, the left and/or right 649 // eigenvectors for an n×n real nonsymmetric matrix A. 650 // 651 // The right eigenvector v_j of A corresponding to an eigenvalue λ_j 652 // is defined by 653 // A v_j = λ_j v_j, 654 // and the left eigenvector u_j corresponding to an eigenvalue λ_j is defined by 655 // u_jᴴ A = λ_j u_jᴴ, 656 // where u_jᴴ is the conjugate transpose of u_j. 657 // 658 // On return, A will be overwritten and the left and right eigenvectors will be 659 // stored, respectively, in the columns of the n×n matrices VL and VR in the 660 // same order as their eigenvalues. If the j-th eigenvalue is real, then 661 // u_j = VL[:,j], 662 // v_j = VR[:,j], 663 // and if it is not real, then j and j+1 form a complex conjugate pair and the 664 // eigenvectors can be recovered as 665 // u_j = VL[:,j] + i*VL[:,j+1], 666 // u_{j+1} = VL[:,j] - i*VL[:,j+1], 667 // v_j = VR[:,j] + i*VR[:,j+1], 668 // v_{j+1} = VR[:,j] - i*VR[:,j+1], 669 // where i is the imaginary unit. The computed eigenvectors are normalized to 670 // have Euclidean norm equal to 1 and largest component real. 671 // 672 // Left eigenvectors will be computed only if jobvl == lapack.LeftEVCompute, 673 // otherwise jobvl must be lapack.LeftEVNone. 674 // Right eigenvectors will be computed only if jobvr == lapack.RightEVCompute, 675 // otherwise jobvr must be lapack.RightEVNone. 676 // For other values of jobvl and jobvr Geev will panic. 677 // 678 // On return, wr and wi will contain the real and imaginary parts, respectively, 679 // of the computed eigenvalues. Complex conjugate pairs of eigenvalues appear 680 // consecutively with the eigenvalue having the positive imaginary part first. 681 // wr and wi must have length n, and Geev will panic otherwise. 682 // 683 // work must have length at least lwork and lwork must be at least max(1,4*n) if 684 // the left or right eigenvectors are computed, and at least max(1,3*n) if no 685 // eigenvectors are computed. For good performance, lwork must generally be 686 // larger. On return, optimal value of lwork will be stored in work[0]. 687 // 688 // If lwork == -1, instead of performing Geev, the function only calculates the 689 // optimal vaule of lwork and stores it into work[0]. 690 // 691 // On return, first will be the index of the first valid eigenvalue. 692 // If first == 0, all eigenvalues and eigenvectors have been computed. 693 // If first is positive, Geev failed to compute all the eigenvalues, no 694 // eigenvectors have been computed and wr[first:] and wi[first:] contain those 695 // eigenvalues which have converged. 696 func Geev(jobvl lapack.LeftEVJob, jobvr lapack.RightEVJob, a blas64.General, wr, wi []float64, vl, vr blas64.General, work []float64, lwork int) (first int) { 697 n := a.Rows 698 if a.Cols != n { 699 panic("lapack64: matrix not square") 700 } 701 if jobvl == lapack.LeftEVCompute && (vl.Rows != n || vl.Cols != n) { 702 panic("lapack64: bad size of VL") 703 } 704 if jobvr == lapack.RightEVCompute && (vr.Rows != n || vr.Cols != n) { 705 panic("lapack64: bad size of VR") 706 } 707 return lapack64.Dgeev(jobvl, jobvr, n, a.Data, max(1, a.Stride), wr, wi, vl.Data, max(1, vl.Stride), vr.Data, max(1, vr.Stride), work, lwork) 708 }