gonum.org/v1/gonum@v0.15.1-0.20240517103525-f853624cb1bb/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 "gonum.org/v1/gonum/blas" 9 "gonum.org/v1/gonum/blas/blas64" 10 "gonum.org/v1/gonum/lapack" 11 "gonum.org/v1/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 // Potrf computes the Cholesky factorization of a. 31 // The factorization has the form 32 // 33 // A = Uᵀ * U if a.Uplo == blas.Upper, or 34 // A = L * Lᵀ if a.Uplo == blas.Lower, 35 // 36 // where U is an upper triangular matrix and L is lower triangular. 37 // The triangular matrix is returned in t, and the underlying data between 38 // a and t is shared. The returned bool indicates whether a is positive 39 // definite and the factorization could be finished. 40 func Potrf(a blas64.Symmetric) (t blas64.Triangular, ok bool) { 41 ok = lapack64.Dpotrf(a.Uplo, a.N, a.Data, max(1, a.Stride)) 42 t.Uplo = a.Uplo 43 t.N = a.N 44 t.Data = a.Data 45 t.Stride = a.Stride 46 t.Diag = blas.NonUnit 47 return 48 } 49 50 // Potri computes the inverse of a real symmetric positive definite matrix A 51 // using its Cholesky factorization. 52 // 53 // On entry, t contains the triangular factor U or L from the Cholesky 54 // factorization A = Uᵀ*U or A = L*Lᵀ, as computed by Potrf. 55 // 56 // On return, the upper or lower triangle of the (symmetric) inverse of A is 57 // stored in t, overwriting the input factor U or L, and also returned in a. The 58 // underlying data between a and t is shared. 59 // 60 // The returned bool indicates whether the inverse was computed successfully. 61 func Potri(t blas64.Triangular) (a blas64.Symmetric, ok bool) { 62 ok = lapack64.Dpotri(t.Uplo, t.N, t.Data, max(1, t.Stride)) 63 a.Uplo = t.Uplo 64 a.N = t.N 65 a.Data = t.Data 66 a.Stride = t.Stride 67 return 68 } 69 70 // Potrs solves a system of n linear equations A*X = B where A is an n×n 71 // symmetric positive definite matrix and B is an n×nrhs matrix, using the 72 // Cholesky factorization A = Uᵀ*U or A = L*Lᵀ. t contains the corresponding 73 // triangular factor as returned by Potrf. On entry, B contains the right-hand 74 // side matrix B, on return it contains the solution matrix X. 75 func Potrs(t blas64.Triangular, b blas64.General) { 76 lapack64.Dpotrs(t.Uplo, t.N, b.Cols, t.Data, max(1, t.Stride), b.Data, max(1, b.Stride)) 77 } 78 79 // Pbcon returns an estimate of the reciprocal of the condition number (in the 80 // 1-norm) of an n×n symmetric positive definite band matrix using the Cholesky 81 // factorization 82 // 83 // A = Uᵀ*U if uplo == blas.Upper 84 // A = L*Lᵀ if uplo == blas.Lower 85 // 86 // computed by Pbtrf. The estimate is obtained for norm(inv(A)), and the 87 // reciprocal of the condition number is computed as 88 // 89 // rcond = 1 / (anorm * norm(inv(A))). 90 // 91 // The length of work must be at least 3*n and the length of iwork must be at 92 // least n. 93 func Pbcon(a blas64.SymmetricBand, anorm float64, work []float64, iwork []int) float64 { 94 return lapack64.Dpbcon(a.Uplo, a.N, a.K, a.Data, a.Stride, anorm, work, iwork) 95 } 96 97 // Pbtrf computes the Cholesky factorization of an n×n symmetric positive 98 // definite band matrix 99 // 100 // A = Uᵀ * U if a.Uplo == blas.Upper 101 // A = L * Lᵀ if a.Uplo == blas.Lower 102 // 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 // 122 // A = Uᵀ * U if t.Uplo == blas.Upper 123 // A = L * Lᵀ if t.Uplo == blas.Lower 124 // 125 // t contains the corresponding triangular factor as returned by Pbtrf. 126 // 127 // On entry, b contains the right hand side matrix B. On return, it is 128 // overwritten with the solution matrix X. 129 func Pbtrs(t blas64.TriangularBand, b blas64.General) { 130 lapack64.Dpbtrs(t.Uplo, t.N, t.K, b.Cols, t.Data, max(1, t.Stride), b.Data, max(1, b.Stride)) 131 } 132 133 // Pstrf computes the Cholesky factorization with complete pivoting of an n×n 134 // symmetric positive semidefinite matrix A. 135 // 136 // The factorization has the form 137 // 138 // Pᵀ * A * P = Uᵀ * U , if a.Uplo = blas.Upper, 139 // Pᵀ * A * P = L * Lᵀ, if a.Uplo = blas.Lower, 140 // 141 // where U is an upper triangular matrix, L is lower triangular, and P is a 142 // permutation matrix. 143 // 144 // tol is a user-defined tolerance. The algorithm terminates if the pivot is 145 // less than or equal to tol. If tol is negative, then n*eps*max(A[k,k]) will be 146 // used instead. 147 // 148 // The triangular factor U or L from the Cholesky factorization is returned in t 149 // and the underlying data between a and t is shared. P is stored on return in 150 // vector piv such that P[piv[k],k] = 1. 151 // 152 // Pstrf returns the computed rank of A and whether the factorization can be 153 // used to solve a system. Pstrf does not attempt to check that A is positive 154 // semi-definite, so if ok is false, the matrix A is either rank deficient or is 155 // not positive semidefinite. 156 // 157 // The length of piv must be n and the length of work must be at least 2*n, 158 // otherwise Pstrf will panic. 159 func Pstrf(a blas64.Symmetric, piv []int, tol float64, work []float64) (t blas64.Triangular, rank int, ok bool) { 160 rank, ok = lapack64.Dpstrf(a.Uplo, a.N, a.Data, max(1, a.Stride), piv, tol, work) 161 t.Uplo = a.Uplo 162 t.Diag = blas.NonUnit 163 t.N = a.N 164 t.Data = a.Data 165 t.Stride = a.Stride 166 return t, rank, ok 167 } 168 169 // Gecon estimates the reciprocal of the condition number of the n×n matrix A 170 // given the LU decomposition of the matrix. The condition number computed may 171 // be based on the 1-norm or the ∞-norm. 172 // 173 // a contains the result of the LU decomposition of A as computed by Getrf. 174 // 175 // anorm is the corresponding 1-norm or ∞-norm of the original matrix A. 176 // 177 // work is a temporary data slice of length at least 4*n and Gecon will panic otherwise. 178 // 179 // iwork is a temporary data slice of length at least n and Gecon will panic otherwise. 180 func Gecon(norm lapack.MatrixNorm, a blas64.General, anorm float64, work []float64, iwork []int) float64 { 181 return lapack64.Dgecon(norm, a.Cols, a.Data, max(1, a.Stride), anorm, work, iwork) 182 } 183 184 // Gels finds a minimum-norm solution based on the matrices A and B using the 185 // QR or LQ factorization. Gels returns false if the matrix 186 // A is singular, and true if this solution was successfully found. 187 // 188 // The minimization problem solved depends on the input parameters. 189 // 190 // 1. If m >= n and trans == blas.NoTrans, Gels finds X such that || A*X - B||_2 191 // is minimized. 192 // 2. If m < n and trans == blas.NoTrans, Gels finds the minimum norm solution of 193 // A * X = B. 194 // 3. If m >= n and trans == blas.Trans, Gels finds the minimum norm solution of 195 // Aᵀ * X = B. 196 // 4. If m < n and trans == blas.Trans, Gels finds X such that || A*X - B||_2 197 // is minimized. 198 // 199 // Note that the least-squares solutions (cases 1 and 3) perform the minimization 200 // per column of B. This is not the same as finding the minimum-norm matrix. 201 // 202 // The matrix A is a general matrix of size m×n and is modified during this call. 203 // The input matrix B is of size max(m,n)×nrhs, and serves two purposes. On entry, 204 // the elements of b specify the input matrix B. B has size m×nrhs if 205 // trans == blas.NoTrans, and n×nrhs if trans == blas.Trans. On exit, the 206 // leading submatrix of b contains the solution vectors X. If trans == blas.NoTrans, 207 // this submatrix is of size n×nrhs, and of size m×nrhs otherwise. 208 // 209 // Work is temporary storage, and lwork specifies the usable memory length. 210 // At minimum, lwork >= max(m,n) + max(m,n,nrhs), and this function will panic 211 // otherwise. A longer work will enable blocked algorithms to be called. 212 // In the special case that lwork == -1, work[0] will be set to the optimal working 213 // length. 214 func Gels(trans blas.Transpose, a blas64.General, b blas64.General, work []float64, lwork int) bool { 215 return lapack64.Dgels(trans, a.Rows, a.Cols, b.Cols, a.Data, max(1, a.Stride), b.Data, max(1, b.Stride), work, lwork) 216 } 217 218 // Geqp3 computes a QR factorization with column pivoting of the m×n matrix A: 219 // 220 // A*P = Q*R 221 // 222 // where P is a permutation matrix, Q is an orthogonal matrix and R is a 223 // min(m,n)×n upper trapezoidal matrix. 224 // 225 // On return, the upper triangle of A contains the matrix R. The elements below 226 // the diagonal together with tau represent the matrix Q as a product of 227 // elementary reflectors 228 // 229 // Q = H_0 * H_1 * ... * H_{k-1}, where k = min(m,n). 230 // 231 // Each H_i has the form 232 // 233 // H_i = I - tau * v * vᵀ 234 // 235 // where tau is a scalar and v is a vector with v[0:i] = 0 and v[i] = 1; 236 // v[i+1:m] is stored on exit in A[i+1:m,i], and tau in tau[i]. 237 // 238 // jpvt specifies a column pivot to be applied to A. On entry, if jpvt[j] is at 239 // least zero, the jth column of A is permuted to the front of A*P (a leading 240 // column), if jpvt[j] is -1 the jth column of A is a free column. If jpvt[j] < 241 // -1, Geqp3 will panic. On return, jpvt holds the permutation that was applied; 242 // the jth column of A*P was the jpvt[j] column of A. jpvt must have length n or 243 // Geqp3 will panic. 244 // 245 // tau holds the scalar factors of the elementary reflectors. It must have 246 // length min(m,n), otherwise Geqp3 will panic. 247 // 248 // work must have length at least max(1,lwork), and lwork must be at least 249 // 3*n+1, otherwise Geqp3 will panic. For optimal performance lwork must be at 250 // least 2*n+(n+1)*nb, where nb is the optimal blocksize. On return, work[0] 251 // will contain the optimal value of lwork. 252 // 253 // If lwork == -1, instead of performing Geqp3, only the optimal value of lwork 254 // will be stored in work[0]. 255 func Geqp3(a blas64.General, jpvt []int, tau, work []float64, lwork int) { 256 lapack64.Dgeqp3(a.Rows, a.Cols, a.Data, max(1, a.Stride), jpvt, tau, work, lwork) 257 } 258 259 // Geqrf computes the QR factorization of the m×n matrix A using a blocked 260 // algorithm. A is modified to contain the information to construct Q and R. 261 // The upper triangle of a contains the matrix R. The lower triangular elements 262 // (not including the diagonal) contain the elementary reflectors. tau is modified 263 // to contain the reflector scales. tau must have length min(m,n), and 264 // this function will panic otherwise. 265 // 266 // The ith elementary reflector can be explicitly constructed by first extracting 267 // the 268 // 269 // v[j] = 0 j < i 270 // v[j] = 1 j == i 271 // v[j] = a[j*lda+i] j > i 272 // 273 // and computing H_i = I - tau[i] * v * vᵀ. 274 // 275 // The orthonormal matrix Q can be constructed from a product of these elementary 276 // reflectors, Q = H_0 * H_1 * ... * H_{k-1}, where k = min(m,n). 277 // 278 // Work is temporary storage, and lwork specifies the usable memory length. 279 // At minimum, lwork >= m and this function will panic otherwise. 280 // Geqrf is a blocked QR factorization, but the block size is limited 281 // by the temporary space available. If lwork == -1, instead of performing Geqrf, 282 // the optimal work length will be stored into work[0]. 283 func Geqrf(a blas64.General, tau, work []float64, lwork int) { 284 lapack64.Dgeqrf(a.Rows, a.Cols, a.Data, max(1, a.Stride), tau, work, lwork) 285 } 286 287 // Gelqf computes the LQ factorization of the m×n matrix A using a blocked 288 // algorithm. A is modified to contain the information to construct L and Q. The 289 // lower triangle of a contains the matrix L. The elements above the diagonal 290 // and the slice tau represent the matrix Q. tau is modified to contain the 291 // reflector scales. tau must have length at least min(m,n), and this function 292 // will panic otherwise. 293 // 294 // See Geqrf for a description of the elementary reflectors and orthonormal 295 // matrix Q. Q is constructed as a product of these elementary reflectors, 296 // Q = H_{k-1} * ... * H_1 * H_0. 297 // 298 // Work is temporary storage, and lwork specifies the usable memory length. 299 // At minimum, lwork >= m and this function will panic otherwise. 300 // Gelqf is a blocked LQ factorization, but the block size is limited 301 // by the temporary space available. If lwork == -1, instead of performing Gelqf, 302 // the optimal work length will be stored into work[0]. 303 func Gelqf(a blas64.General, tau, work []float64, lwork int) { 304 lapack64.Dgelqf(a.Rows, a.Cols, a.Data, max(1, a.Stride), tau, work, lwork) 305 } 306 307 // Gesvd computes the singular value decomposition of the input matrix A. 308 // 309 // The singular value decomposition is 310 // 311 // A = U * Sigma * Vᵀ 312 // 313 // where Sigma is an m×n diagonal matrix containing the singular values of A, 314 // U is an m×m orthogonal matrix and V is an n×n orthogonal matrix. The first 315 // min(m,n) columns of U and V are the left and right singular vectors of A 316 // respectively. 317 // 318 // jobU and jobVT are options for computing the singular vectors. The behavior 319 // is as follows 320 // 321 // jobU == lapack.SVDAll All m columns of U are returned in u 322 // jobU == lapack.SVDStore The first min(m,n) columns are returned in u 323 // jobU == lapack.SVDOverwrite The first min(m,n) columns of U are written into a 324 // jobU == lapack.SVDNone The columns of U are not computed. 325 // 326 // The behavior is the same for jobVT and the rows of Vᵀ. At most one of jobU 327 // and jobVT can equal lapack.SVDOverwrite, and Gesvd will panic otherwise. 328 // 329 // On entry, a contains the data for the m×n matrix A. During the call to Gesvd 330 // the data is overwritten. On exit, A contains the appropriate singular vectors 331 // if either job is lapack.SVDOverwrite. 332 // 333 // s is a slice of length at least min(m,n) and on exit contains the singular 334 // values in decreasing order. 335 // 336 // u contains the left singular vectors on exit, stored columnwise. If 337 // jobU == lapack.SVDAll, u is of size m×m. If jobU == lapack.SVDStore u is 338 // of size m×min(m,n). If jobU == lapack.SVDOverwrite or lapack.SVDNone, u is 339 // not used. 340 // 341 // vt contains the left singular vectors on exit, stored rowwise. If 342 // jobV == lapack.SVDAll, vt is of size n×m. If jobVT == lapack.SVDStore vt is 343 // of size min(m,n)×n. If jobVT == lapack.SVDOverwrite or lapack.SVDNone, vt is 344 // not used. 345 // 346 // work is a slice for storing temporary memory, and lwork is the usable size of 347 // the slice. lwork must be at least max(5*min(m,n), 3*min(m,n)+max(m,n)). 348 // If lwork == -1, instead of performing Gesvd, the optimal work length will be 349 // stored into work[0]. Gesvd will panic if the working memory has insufficient 350 // storage. 351 // 352 // Gesvd returns whether the decomposition successfully completed. 353 func Gesvd(jobU, jobVT lapack.SVDJob, a, u, vt blas64.General, s, work []float64, lwork int) (ok bool) { 354 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) 355 } 356 357 // Getrf computes the LU decomposition of an m×n matrix A using partial 358 // pivoting with row interchanges. 359 // 360 // The LU decomposition is a factorization of A into 361 // 362 // A = P * L * U 363 // 364 // where P is a permutation matrix, L is a lower triangular with unit diagonal 365 // elements (lower trapezoidal if m > n), and U is upper triangular (upper 366 // trapezoidal if m < n). 367 // 368 // On entry, a contains the matrix A. On return, L and U are stored in place 369 // into a, and P is represented by ipiv. 370 // 371 // ipiv contains a sequence of row swaps. It indicates that row i of the matrix 372 // was interchanged with ipiv[i]. ipiv must have length min(m,n), and Getrf will 373 // panic otherwise. ipiv is zero-indexed. 374 // 375 // Getrf returns whether the matrix A is nonsingular. The LU decomposition will 376 // be computed regardless of the singularity of A, but the result should not be 377 // used to solve a system of equation. 378 func Getrf(a blas64.General, ipiv []int) bool { 379 return lapack64.Dgetrf(a.Rows, a.Cols, a.Data, max(1, a.Stride), ipiv) 380 } 381 382 // Getri computes the inverse of the matrix A using the LU factorization computed 383 // by Getrf. On entry, a contains the PLU decomposition of A as computed by 384 // Getrf and on exit contains the reciprocal of the original matrix. 385 // 386 // Getri will not perform the inversion if the matrix is singular, and returns 387 // a boolean indicating whether the inversion was successful. 388 // 389 // Work is temporary storage, and lwork specifies the usable memory length. 390 // At minimum, lwork >= n and this function will panic otherwise. 391 // Getri is a blocked inversion, but the block size is limited 392 // by the temporary space available. If lwork == -1, instead of performing Getri, 393 // the optimal work length will be stored into work[0]. 394 func Getri(a blas64.General, ipiv []int, work []float64, lwork int) (ok bool) { 395 return lapack64.Dgetri(a.Cols, a.Data, max(1, a.Stride), ipiv, work, lwork) 396 } 397 398 // Getrs solves a system of equations using an LU factorization. 399 // The system of equations solved is 400 // 401 // A * X = B if trans == blas.Trans 402 // Aᵀ * X = B if trans == blas.NoTrans 403 // 404 // A is a general n×n matrix with stride lda. B is a general matrix of size n×nrhs. 405 // 406 // On entry b contains the elements of the matrix B. On exit, b contains the 407 // elements of X, the solution to the system of equations. 408 // 409 // a and ipiv contain the LU factorization of A and the permutation indices as 410 // computed by Getrf. ipiv is zero-indexed. 411 func Getrs(trans blas.Transpose, a blas64.General, b blas64.General, ipiv []int) { 412 lapack64.Dgetrs(trans, a.Cols, b.Cols, a.Data, max(1, a.Stride), ipiv, b.Data, max(1, b.Stride)) 413 } 414 415 // Ggsvd3 computes the generalized singular value decomposition (GSVD) 416 // of an m×n matrix A and p×n matrix B: 417 // 418 // Uᵀ*A*Q = D1*[ 0 R ] 419 // 420 // Vᵀ*B*Q = D2*[ 0 R ] 421 // 422 // where U, V and Q are orthogonal matrices. 423 // 424 // Ggsvd3 returns k and l, the dimensions of the sub-blocks. k+l 425 // is the effective numerical rank of the (m+p)×n matrix [ Aᵀ Bᵀ ]ᵀ. 426 // R is a (k+l)×(k+l) nonsingular upper triangular matrix, D1 and 427 // D2 are m×(k+l) and p×(k+l) diagonal matrices and of the following 428 // structures, respectively: 429 // 430 // If m-k-l >= 0, 431 // 432 // k l 433 // D1 = k [ I 0 ] 434 // l [ 0 C ] 435 // m-k-l [ 0 0 ] 436 // 437 // k l 438 // D2 = l [ 0 S ] 439 // p-l [ 0 0 ] 440 // 441 // n-k-l k l 442 // [ 0 R ] = k [ 0 R11 R12 ] k 443 // l [ 0 0 R22 ] l 444 // 445 // where 446 // 447 // C = diag( alpha_k, ... , alpha_{k+l} ), 448 // S = diag( beta_k, ... , beta_{k+l} ), 449 // C^2 + S^2 = I. 450 // 451 // R is stored in 452 // 453 // A[0:k+l, n-k-l:n] 454 // 455 // on exit. 456 // 457 // If m-k-l < 0, 458 // 459 // k m-k k+l-m 460 // D1 = k [ I 0 0 ] 461 // m-k [ 0 C 0 ] 462 // 463 // k m-k k+l-m 464 // D2 = m-k [ 0 S 0 ] 465 // k+l-m [ 0 0 I ] 466 // p-l [ 0 0 0 ] 467 // 468 // n-k-l k m-k k+l-m 469 // [ 0 R ] = k [ 0 R11 R12 R13 ] 470 // m-k [ 0 0 R22 R23 ] 471 // k+l-m [ 0 0 0 R33 ] 472 // 473 // where 474 // 475 // C = diag( alpha_k, ... , alpha_m ), 476 // S = diag( beta_k, ... , beta_m ), 477 // C^2 + S^2 = I. 478 // 479 // R = [ R11 R12 R13 ] is stored in A[1:m, n-k-l+1:n] 480 // [ 0 R22 R23 ] 481 // 482 // and R33 is stored in 483 // 484 // B[m-k:l, n+m-k-l:n] on exit. 485 // 486 // Ggsvd3 computes C, S, R, and optionally the orthogonal transformation 487 // matrices U, V and Q. 488 // 489 // jobU, jobV and jobQ are options for computing the orthogonal matrices. The behavior 490 // is as follows 491 // 492 // jobU == lapack.GSVDU Compute orthogonal matrix U 493 // jobU == lapack.GSVDNone Do not compute orthogonal matrix. 494 // 495 // The behavior is the same for jobV and jobQ with the exception that instead of 496 // lapack.GSVDU these accept lapack.GSVDV and lapack.GSVDQ respectively. 497 // The matrices U, V and Q must be m×m, p×p and n×n respectively unless the 498 // relevant job parameter is lapack.GSVDNone. 499 // 500 // alpha and beta must have length n or Ggsvd3 will panic. On exit, alpha and 501 // beta contain the generalized singular value pairs of A and B 502 // 503 // alpha[0:k] = 1, 504 // beta[0:k] = 0, 505 // 506 // if m-k-l >= 0, 507 // 508 // alpha[k:k+l] = diag(C), 509 // beta[k:k+l] = diag(S), 510 // 511 // if m-k-l < 0, 512 // 513 // alpha[k:m]= C, alpha[m:k+l]= 0 514 // beta[k:m] = S, beta[m:k+l] = 1. 515 // 516 // if k+l < n, 517 // 518 // alpha[k+l:n] = 0 and 519 // beta[k+l:n] = 0. 520 // 521 // On exit, iwork contains the permutation required to sort alpha descending. 522 // 523 // iwork must have length n, work must have length at least max(1, lwork), and 524 // lwork must be -1 or greater than n, otherwise Ggsvd3 will panic. If 525 // lwork is -1, work[0] holds the optimal lwork on return, but Ggsvd3 does 526 // not perform the GSVD. 527 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) { 528 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) 529 } 530 531 // Gtsv solves one of the equations 532 // 533 // A * X = B if trans == blas.NoTrans 534 // Aᵀ * X = B if trans == blas.Trans or blas.ConjTrans 535 // 536 // where A is an n×n tridiagonal matrix. It uses Gaussian elimination with 537 // partial pivoting. 538 // 539 // On entry, a contains the matrix A, on return it will be overwritten. 540 // 541 // On entry, b contains the n×nrhs right-hand side matrix B. On return, it will 542 // be overwritten. If ok is true, it will be overwritten by the solution matrix X. 543 // 544 // Gtsv returns whether the solution X has been successfully computed. 545 // 546 // Dgtsv is not part of the lapack.Float64 interface and so calls to Gtsv are 547 // always executed by the Gonum implementation. 548 func Gtsv(trans blas.Transpose, a Tridiagonal, b blas64.General) (ok bool) { 549 if trans != blas.NoTrans { 550 a.DL, a.DU = a.DU, a.DL 551 } 552 return gonum.Implementation{}.Dgtsv(a.N, b.Cols, a.DL, a.D, a.DU, b.Data, max(1, b.Stride)) 553 } 554 555 // Lagtm performs one of the matrix-matrix operations 556 // 557 // C = alpha * A * B + beta * C if trans == blas.NoTrans 558 // C = alpha * Aᵀ * B + beta * C if trans == blas.Trans or blas.ConjTrans 559 // 560 // where A is an m×m tridiagonal matrix represented by its diagonals dl, d, du, 561 // B and C are m×n dense matrices, and alpha and beta are scalars. 562 // 563 // Dlagtm is not part of the lapack.Float64 interface and so calls to Lagtm are 564 // always executed by the Gonum implementation. 565 func Lagtm(trans blas.Transpose, alpha float64, a Tridiagonal, b blas64.General, beta float64, c blas64.General) { 566 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)) 567 } 568 569 // Lange computes the matrix norm of the general m×n matrix A. The input norm 570 // specifies the norm computed. 571 // 572 // lapack.MaxAbs: the maximum absolute value of an element. 573 // lapack.MaxColumnSum: the maximum column sum of the absolute values of the entries. 574 // lapack.MaxRowSum: the maximum row sum of the absolute values of the entries. 575 // lapack.Frobenius: the square root of the sum of the squares of the entries. 576 // 577 // If norm == lapack.MaxColumnSum, work must be of length n, and this function will panic otherwise. 578 // There are no restrictions on work for the other matrix norms. 579 func Lange(norm lapack.MatrixNorm, a blas64.General, work []float64) float64 { 580 return lapack64.Dlange(norm, a.Rows, a.Cols, a.Data, max(1, a.Stride), work) 581 } 582 583 // Langb returns the given norm of a general m×n band matrix with kl sub-diagonals and 584 // ku super-diagonals. 585 // 586 // Dlangb is not part of the lapack.Float64 interface and so calls to Langb are always 587 // executed by the Gonum implementation. 588 func Langb(norm lapack.MatrixNorm, a blas64.Band) float64 { 589 return gonum.Implementation{}.Dlangb(norm, a.Rows, a.Cols, a.KL, a.KU, a.Data, max(1, a.Stride)) 590 } 591 592 // Langt computes the specified norm of an n×n tridiagonal matrix. 593 // 594 // Dlangt is not part of the lapack.Float64 interface and so calls to Langt are 595 // always executed by the Gonum implementation. 596 func Langt(norm lapack.MatrixNorm, a Tridiagonal) float64 { 597 return gonum.Implementation{}.Dlangt(norm, a.N, a.DL, a.D, a.DU) 598 } 599 600 // Lansb computes the specified norm of an n×n symmetric band matrix. If 601 // norm == lapack.MaxColumnSum or norm == lapack.MaxRowSum, work must have length 602 // at least n and this function will panic otherwise. 603 // There are no restrictions on work for the other matrix norms. 604 // 605 // Dlansb is not part of the lapack.Float64 interface and so calls to Lansb are always 606 // executed by the Gonum implementation. 607 func Lansb(norm lapack.MatrixNorm, a blas64.SymmetricBand, work []float64) float64 { 608 return gonum.Implementation{}.Dlansb(norm, a.Uplo, a.N, a.K, a.Data, max(1, a.Stride), work) 609 } 610 611 // Lansy computes the specified norm of an n×n symmetric matrix. If 612 // norm == lapack.MaxColumnSum or norm == lapack.MaxRowSum, work must have length 613 // at least n and this function will panic otherwise. 614 // There are no restrictions on work for the other matrix norms. 615 func Lansy(norm lapack.MatrixNorm, a blas64.Symmetric, work []float64) float64 { 616 return lapack64.Dlansy(norm, a.Uplo, a.N, a.Data, max(1, a.Stride), work) 617 } 618 619 // Lantr computes the specified norm of an m×n trapezoidal matrix A. If 620 // norm == lapack.MaxColumnSum work must have length at least n and this function 621 // will panic otherwise. There are no restrictions on work for the other matrix norms. 622 func Lantr(norm lapack.MatrixNorm, a blas64.Triangular, work []float64) float64 { 623 return lapack64.Dlantr(norm, a.Uplo, a.Diag, a.N, a.N, a.Data, max(1, a.Stride), work) 624 } 625 626 // Lantb computes the specified norm of an n×n triangular band matrix A. If 627 // norm == lapack.MaxColumnSum work must have length at least n and this function 628 // will panic otherwise. There are no restrictions on work for the other matrix 629 // norms. 630 func Lantb(norm lapack.MatrixNorm, a blas64.TriangularBand, work []float64) float64 { 631 return gonum.Implementation{}.Dlantb(norm, a.Uplo, a.Diag, a.N, a.K, a.Data, max(1, a.Stride), work) 632 } 633 634 // Lapmr rearranges the rows of the m×n matrix X as specified by the permutation 635 // k[0],k[1],...,k[m-1] of the integers 0,...,m-1. 636 // 637 // If forward is true, a forward permutation is applied: 638 // 639 // X[k[i],0:n] is moved to X[i,0:n] for i=0,1,...,m-1. 640 // 641 // If forward is false, a backward permutation is applied: 642 // 643 // X[i,0:n] is moved to X[k[i],0:n] for i=0,1,...,m-1. 644 // 645 // k must have length m, otherwise Lapmr will panic. k is zero-indexed. 646 func Lapmr(forward bool, x blas64.General, k []int) { 647 lapack64.Dlapmr(forward, x.Rows, x.Cols, x.Data, max(1, x.Stride), k) 648 } 649 650 // Lapmt rearranges the columns of the m×n matrix X as specified by the 651 // permutation k[0],k[1],...,k[n-1] of the integers 0,...,n-1. 652 // 653 // If forward is true, a forward permutation is applied: 654 // 655 // X[0:m,k[j]] is moved to X[0:m,j] for j=0,1,...,n-1. 656 // 657 // If forward is false, a backward permutation is applied: 658 // 659 // X[0:m,j] is moved to X[0:m,k[j]] for j=0,1,...,n-1. 660 // 661 // k must have length n, otherwise Lapmt will panic. k is zero-indexed. 662 func Lapmt(forward bool, x blas64.General, k []int) { 663 lapack64.Dlapmt(forward, x.Rows, x.Cols, x.Data, max(1, x.Stride), k) 664 } 665 666 // Orglq generates an m×n matrix Q with orthonormal rows defined as the first m 667 // rows of a product of k elementary reflectors of order n 668 // 669 // Q = H_{k-1} * ... * H_0 670 // 671 // as returned by Dgelqf. 672 // 673 // k is determined by the length of tau. 674 // 675 // On entry, tau and the first k rows of A must contain the scalar factors and 676 // the vectors, respectively, which define the elementary reflectors H_i, 677 // i=0,...,k-1, as returned by Dgelqf. On return, A contains the matrix Q. 678 // 679 // work must have length at least lwork and lwork must be at least max(1,m). On 680 // return, optimal value of lwork will be stored in work[0]. It must also hold 681 // that 0 <= k <= m <= n, otherwise Orglq will panic. 682 // 683 // If lwork == -1, instead of performing Orglq, the function only calculates the 684 // optimal value of lwork and stores it into work[0]. 685 func Orglq(a blas64.General, tau, work []float64, lwork int) { 686 lapack64.Dorglq(a.Rows, a.Cols, len(tau), a.Data, a.Stride, tau, work, lwork) 687 } 688 689 // Ormlq multiplies the matrix C by the othogonal matrix Q defined by 690 // A and tau. A and tau are as returned from Gelqf. 691 // 692 // C = Q * C if side == blas.Left and trans == blas.NoTrans 693 // C = Qᵀ * C if side == blas.Left and trans == blas.Trans 694 // C = C * Q if side == blas.Right and trans == blas.NoTrans 695 // C = C * Qᵀ if side == blas.Right and trans == blas.Trans 696 // 697 // If side == blas.Left, A is a matrix of side k×m, and if side == blas.Right 698 // A is of size k×n. This uses a blocked algorithm. 699 // 700 // Work is temporary storage, and lwork specifies the usable memory length. 701 // At minimum, lwork >= m if side == blas.Left and lwork >= n if side == blas.Right, 702 // and this function will panic otherwise. 703 // Ormlq uses a block algorithm, but the block size is limited 704 // by the temporary space available. If lwork == -1, instead of performing Ormlq, 705 // the optimal work length will be stored into work[0]. 706 // 707 // Tau contains the Householder scales and must have length at least k, and 708 // this function will panic otherwise. 709 func Ormlq(side blas.Side, trans blas.Transpose, a blas64.General, tau []float64, c blas64.General, work []float64, lwork int) { 710 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) 711 } 712 713 // Orgqr generates an m×n matrix Q with orthonormal columns defined by the 714 // product of elementary reflectors 715 // 716 // Q = H_0 * H_1 * ... * H_{k-1} 717 // 718 // as computed by Geqrf. 719 // 720 // k is determined by the length of tau. 721 // 722 // The length of work must be at least n and it also must be that 0 <= k <= n 723 // and 0 <= n <= m. 724 // 725 // work is temporary storage, and lwork specifies the usable memory length. At 726 // minimum, lwork >= n, and the amount of blocking is limited by the usable 727 // length. If lwork == -1, instead of computing Orgqr the optimal work length 728 // is stored into work[0]. 729 // 730 // Orgqr will panic if the conditions on input values are not met. 731 func Orgqr(a blas64.General, tau []float64, work []float64, lwork int) { 732 lapack64.Dorgqr(a.Rows, a.Cols, len(tau), a.Data, a.Stride, tau, work, lwork) 733 } 734 735 // Ormqr multiplies an m×n matrix C by an orthogonal matrix Q as 736 // 737 // C = Q * C if side == blas.Left and trans == blas.NoTrans, 738 // C = Qᵀ * C if side == blas.Left and trans == blas.Trans, 739 // C = C * Q if side == blas.Right and trans == blas.NoTrans, 740 // C = C * Qᵀ if side == blas.Right and trans == blas.Trans, 741 // 742 // where Q is defined as the product of k elementary reflectors 743 // 744 // Q = H_0 * H_1 * ... * H_{k-1}. 745 // 746 // k is determined by the length of tau. 747 // 748 // If side == blas.Left, A is an m×k matrix and 0 <= k <= m. 749 // If side == blas.Right, A is an n×k matrix and 0 <= k <= n. 750 // The ith column of A contains the vector which defines the elementary 751 // reflector H_i and tau[i] contains its scalar factor. Geqrf returns A and tau 752 // in the required form. 753 // 754 // work must have length at least max(1,lwork), and lwork must be at least n if 755 // side == blas.Left and at least m if side == blas.Right, otherwise Ormqr will 756 // panic. 757 // 758 // work is temporary storage, and lwork specifies the usable memory length. At 759 // minimum, lwork >= m if side == blas.Left and lwork >= n if side == 760 // blas.Right, and this function will panic otherwise. Larger values of lwork 761 // will generally give better performance. On return, work[0] will contain the 762 // optimal value of lwork. 763 // 764 // If lwork is -1, instead of performing Ormqr, the optimal workspace size will 765 // be stored into work[0]. 766 func Ormqr(side blas.Side, trans blas.Transpose, a blas64.General, tau []float64, c blas64.General, work []float64, lwork int) { 767 lapack64.Dormqr(side, trans, c.Rows, c.Cols, len(tau), a.Data, max(1, a.Stride), tau, c.Data, max(1, c.Stride), work, lwork) 768 } 769 770 // Pocon estimates the reciprocal of the condition number of a positive-definite 771 // matrix A given the Cholesky decomposition of A. The condition number computed 772 // is based on the 1-norm and the ∞-norm. 773 // 774 // anorm is the 1-norm and the ∞-norm of the original matrix A. 775 // 776 // work is a temporary data slice of length at least 3*n and Pocon will panic otherwise. 777 // 778 // iwork is a temporary data slice of length at least n and Pocon will panic otherwise. 779 func Pocon(a blas64.Symmetric, anorm float64, work []float64, iwork []int) float64 { 780 return lapack64.Dpocon(a.Uplo, a.N, a.Data, max(1, a.Stride), anorm, work, iwork) 781 } 782 783 // Syev computes all eigenvalues and, optionally, the eigenvectors of a real 784 // symmetric matrix A. 785 // 786 // w contains the eigenvalues in ascending order upon return. w must have length 787 // at least n, and Syev will panic otherwise. 788 // 789 // On entry, a contains the elements of the symmetric matrix A in the triangular 790 // portion specified by uplo. If jobz == lapack.EVCompute, a contains the 791 // orthonormal eigenvectors of A on exit, otherwise jobz must be lapack.EVNone 792 // and on exit the specified triangular region is overwritten. 793 // 794 // Work is temporary storage, and lwork specifies the usable memory length. At minimum, 795 // lwork >= 3*n-1, and Syev will panic otherwise. The amount of blocking is 796 // limited by the usable length. If lwork == -1, instead of computing Syev the 797 // optimal work length is stored into work[0]. 798 func Syev(jobz lapack.EVJob, a blas64.Symmetric, w, work []float64, lwork int) (ok bool) { 799 return lapack64.Dsyev(jobz, a.Uplo, a.N, a.Data, max(1, a.Stride), w, work, lwork) 800 } 801 802 // Tbtrs solves a triangular system of the form 803 // 804 // A * X = B if trans == blas.NoTrans 805 // Aᵀ * X = B if trans == blas.Trans or blas.ConjTrans 806 // 807 // where A is an n×n triangular band matrix, and B is an n×nrhs matrix. 808 // 809 // Tbtrs returns whether A is non-singular. If A is singular, no solutions X 810 // are computed. 811 func Tbtrs(trans blas.Transpose, a blas64.TriangularBand, b blas64.General) (ok bool) { 812 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)) 813 } 814 815 // Trcon estimates the reciprocal of the condition number of a triangular matrix A. 816 // The condition number computed may be based on the 1-norm or the ∞-norm. 817 // 818 // work is a temporary data slice of length at least 3*n and Trcon will panic otherwise. 819 // 820 // iwork is a temporary data slice of length at least n and Trcon will panic otherwise. 821 func Trcon(norm lapack.MatrixNorm, a blas64.Triangular, work []float64, iwork []int) float64 { 822 return lapack64.Dtrcon(norm, a.Uplo, a.Diag, a.N, a.Data, max(1, a.Stride), work, iwork) 823 } 824 825 // Trtri computes the inverse of a triangular matrix, storing the result in place 826 // into a. 827 // 828 // Trtri will not perform the inversion if the matrix is singular, and returns 829 // a boolean indicating whether the inversion was successful. 830 func Trtri(a blas64.Triangular) (ok bool) { 831 return lapack64.Dtrtri(a.Uplo, a.Diag, a.N, a.Data, max(1, a.Stride)) 832 } 833 834 // Trtrs solves a triangular system of the form A * X = B or Aᵀ * X = B. Trtrs 835 // returns whether the solve completed successfully. If A is singular, no solve is performed. 836 func Trtrs(trans blas.Transpose, a blas64.Triangular, b blas64.General) (ok bool) { 837 return lapack64.Dtrtrs(a.Uplo, trans, a.Diag, a.N, b.Cols, a.Data, max(1, a.Stride), b.Data, max(1, b.Stride)) 838 } 839 840 // Geev computes the eigenvalues and, optionally, the left and/or right 841 // eigenvectors for an n×n real nonsymmetric matrix A. 842 // 843 // The right eigenvector v_j of A corresponding to an eigenvalue λ_j 844 // is defined by 845 // 846 // A v_j = λ_j v_j, 847 // 848 // and the left eigenvector u_j corresponding to an eigenvalue λ_j is defined by 849 // 850 // u_jᴴ A = λ_j u_jᴴ, 851 // 852 // where u_jᴴ is the conjugate transpose of u_j. 853 // 854 // On return, A will be overwritten and the left and right eigenvectors will be 855 // stored, respectively, in the columns of the n×n matrices VL and VR in the 856 // same order as their eigenvalues. If the j-th eigenvalue is real, then 857 // 858 // u_j = VL[:,j], 859 // v_j = VR[:,j], 860 // 861 // and if it is not real, then j and j+1 form a complex conjugate pair and the 862 // eigenvectors can be recovered as 863 // 864 // u_j = VL[:,j] + i*VL[:,j+1], 865 // u_{j+1} = VL[:,j] - i*VL[:,j+1], 866 // v_j = VR[:,j] + i*VR[:,j+1], 867 // v_{j+1} = VR[:,j] - i*VR[:,j+1], 868 // 869 // where i is the imaginary unit. The computed eigenvectors are normalized to 870 // have Euclidean norm equal to 1 and largest component real. 871 // 872 // Left eigenvectors will be computed only if jobvl == lapack.LeftEVCompute, 873 // otherwise jobvl must be lapack.LeftEVNone. 874 // Right eigenvectors will be computed only if jobvr == lapack.RightEVCompute, 875 // otherwise jobvr must be lapack.RightEVNone. 876 // For other values of jobvl and jobvr Geev will panic. 877 // 878 // On return, wr and wi will contain the real and imaginary parts, respectively, 879 // of the computed eigenvalues. Complex conjugate pairs of eigenvalues appear 880 // consecutively with the eigenvalue having the positive imaginary part first. 881 // wr and wi must have length n, and Geev will panic otherwise. 882 // 883 // work must have length at least lwork and lwork must be at least max(1,4*n) if 884 // the left or right eigenvectors are computed, and at least max(1,3*n) if no 885 // eigenvectors are computed. For good performance, lwork must generally be 886 // larger. On return, optimal value of lwork will be stored in work[0]. 887 // 888 // If lwork == -1, instead of performing Geev, the function only calculates the 889 // optimal value of lwork and stores it into work[0]. 890 // 891 // On return, first will be the index of the first valid eigenvalue. 892 // If first == 0, all eigenvalues and eigenvectors have been computed. 893 // If first is positive, Geev failed to compute all the eigenvalues, no 894 // eigenvectors have been computed and wr[first:] and wi[first:] contain those 895 // eigenvalues which have converged. 896 func Geev(jobvl lapack.LeftEVJob, jobvr lapack.RightEVJob, a blas64.General, wr, wi []float64, vl, vr blas64.General, work []float64, lwork int) (first int) { 897 n := a.Rows 898 if a.Cols != n { 899 panic("lapack64: matrix not square") 900 } 901 if jobvl == lapack.LeftEVCompute && (vl.Rows != n || vl.Cols != n) { 902 panic("lapack64: bad size of VL") 903 } 904 if jobvr == lapack.RightEVCompute && (vr.Rows != n || vr.Cols != n) { 905 panic("lapack64: bad size of VR") 906 } 907 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) 908 }