github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/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 // This repository is no longer maintained. 6 // Development has moved to https://github.com/gonum/gonum. 7 // 8 // Package lapack64 provides a set of convenient wrapper functions for LAPACK 9 // calls, as specified in the netlib standard (www.netlib.org). 10 // 11 // The native Go routines are used by default, and the Use function can be used 12 // to set an alternative implementation. 13 // 14 // If the type of matrix (General, Symmetric, etc.) is known and fixed, it is 15 // used in the wrapper signature. In many cases, however, the type of the matrix 16 // changes during the call to the routine, for example the matrix is symmetric on 17 // entry and is triangular on exit. In these cases the correct types should be checked 18 // in the documentation. 19 // 20 // The full set of Lapack functions is very large, and it is not clear that a 21 // full implementation is desirable, let alone feasible. Please open up an issue 22 // if there is a specific function you need and/or are willing to implement. 23 package lapack64 24 25 import ( 26 "github.com/gonum/blas" 27 "github.com/gonum/blas/blas64" 28 "github.com/gonum/lapack" 29 "github.com/gonum/lapack/native" 30 ) 31 32 var lapack64 lapack.Float64 = native.Implementation{} 33 34 // Use sets the LAPACK float64 implementation to be used by subsequent BLAS calls. 35 // The default implementation is native.Implementation. 36 func Use(l lapack.Float64) { 37 lapack64 = l 38 } 39 40 // Potrf computes the Cholesky factorization of a. 41 // The factorization has the form 42 // A = U^T * U if a.Uplo == blas.Upper, or 43 // A = L * L^T if a.Uplo == blas.Lower, 44 // where U is an upper triangular matrix and L is lower triangular. 45 // The triangular matrix is returned in t, and the underlying data between 46 // a and t is shared. The returned bool indicates whether a is positive 47 // definite and the factorization could be finished. 48 func Potrf(a blas64.Symmetric) (t blas64.Triangular, ok bool) { 49 ok = lapack64.Dpotrf(a.Uplo, a.N, a.Data, a.Stride) 50 t.Uplo = a.Uplo 51 t.N = a.N 52 t.Data = a.Data 53 t.Stride = a.Stride 54 t.Diag = blas.NonUnit 55 return 56 } 57 58 // Gecon estimates the reciprocal of the condition number of the n×n matrix A 59 // given the LU decomposition of the matrix. The condition number computed may 60 // be based on the 1-norm or the ∞-norm. 61 // 62 // a contains the result of the LU decomposition of A as computed by Getrf. 63 // 64 // anorm is the corresponding 1-norm or ∞-norm of the original matrix A. 65 // 66 // work is a temporary data slice of length at least 4*n and Gecon will panic otherwise. 67 // 68 // iwork is a temporary data slice of length at least n and Gecon will panic otherwise. 69 func Gecon(norm lapack.MatrixNorm, a blas64.General, anorm float64, work []float64, iwork []int) float64 { 70 return lapack64.Dgecon(norm, a.Cols, a.Data, a.Stride, anorm, work, iwork) 71 } 72 73 // Gels finds a minimum-norm solution based on the matrices A and B using the 74 // QR or LQ factorization. Gels returns false if the matrix 75 // A is singular, and true if this solution was successfully found. 76 // 77 // The minimization problem solved depends on the input parameters. 78 // 79 // 1. If m >= n and trans == blas.NoTrans, Gels finds X such that || A*X - B||_2 80 // is minimized. 81 // 2. If m < n and trans == blas.NoTrans, Gels finds the minimum norm solution of 82 // A * X = B. 83 // 3. If m >= n and trans == blas.Trans, Gels finds the minimum norm solution of 84 // A^T * X = B. 85 // 4. If m < n and trans == blas.Trans, Gels finds X such that || A*X - B||_2 86 // is minimized. 87 // Note that the least-squares solutions (cases 1 and 3) perform the minimization 88 // per column of B. This is not the same as finding the minimum-norm matrix. 89 // 90 // The matrix A is a general matrix of size m×n and is modified during this call. 91 // The input matrix B is of size max(m,n)×nrhs, and serves two purposes. On entry, 92 // the elements of b specify the input matrix B. B has size m×nrhs if 93 // trans == blas.NoTrans, and n×nrhs if trans == blas.Trans. On exit, the 94 // leading submatrix of b contains the solution vectors X. If trans == blas.NoTrans, 95 // this submatrix is of size n×nrhs, and of size m×nrhs otherwise. 96 // 97 // Work is temporary storage, and lwork specifies the usable memory length. 98 // At minimum, lwork >= max(m,n) + max(m,n,nrhs), and this function will panic 99 // otherwise. A longer work will enable blocked algorithms to be called. 100 // In the special case that lwork == -1, work[0] will be set to the optimal working 101 // length. 102 func Gels(trans blas.Transpose, a blas64.General, b blas64.General, work []float64, lwork int) bool { 103 return lapack64.Dgels(trans, a.Rows, a.Cols, b.Cols, a.Data, a.Stride, b.Data, b.Stride, work, lwork) 104 } 105 106 // Geqrf computes the QR factorization of the m×n matrix A using a blocked 107 // algorithm. A is modified to contain the information to construct Q and R. 108 // The upper triangle of a contains the matrix R. The lower triangular elements 109 // (not including the diagonal) contain the elementary reflectors. tau is modified 110 // to contain the reflector scales. tau must have length at least min(m,n), and 111 // this function will panic otherwise. 112 // 113 // The ith elementary reflector can be explicitly constructed by first extracting 114 // the 115 // v[j] = 0 j < i 116 // v[j] = 1 j == i 117 // v[j] = a[j*lda+i] j > i 118 // and computing H_i = I - tau[i] * v * v^T. 119 // 120 // The orthonormal matrix Q can be constucted from a product of these elementary 121 // reflectors, Q = H_0 * H_1 * ... * H_{k-1}, where k = min(m,n). 122 // 123 // Work is temporary storage, and lwork specifies the usable memory length. 124 // At minimum, lwork >= m and this function will panic otherwise. 125 // Geqrf is a blocked QR factorization, but the block size is limited 126 // by the temporary space available. If lwork == -1, instead of performing Geqrf, 127 // the optimal work length will be stored into work[0]. 128 func Geqrf(a blas64.General, tau, work []float64, lwork int) { 129 lapack64.Dgeqrf(a.Rows, a.Cols, a.Data, a.Stride, tau, work, lwork) 130 } 131 132 // Gelqf computes the LQ factorization of the m×n matrix A using a blocked 133 // algorithm. A is modified to contain the information to construct L and Q. The 134 // lower triangle of a contains the matrix L. The elements above the diagonal 135 // and the slice tau represent the matrix Q. tau is modified to contain the 136 // reflector scales. tau must have length at least min(m,n), and this function 137 // will panic otherwise. 138 // 139 // See Geqrf for a description of the elementary reflectors and orthonormal 140 // matrix Q. Q is constructed as a product of these elementary reflectors, 141 // Q = H_{k-1} * ... * H_1 * H_0. 142 // 143 // Work is temporary storage, and lwork specifies the usable memory length. 144 // At minimum, lwork >= m and this function will panic otherwise. 145 // Gelqf is a blocked LQ factorization, but the block size is limited 146 // by the temporary space available. If lwork == -1, instead of performing Gelqf, 147 // the optimal work length will be stored into work[0]. 148 func Gelqf(a blas64.General, tau, work []float64, lwork int) { 149 lapack64.Dgelqf(a.Rows, a.Cols, a.Data, a.Stride, tau, work, lwork) 150 } 151 152 // Gesvd computes the singular value decomposition of the input matrix A. 153 // 154 // The singular value decomposition is 155 // A = U * Sigma * V^T 156 // where Sigma is an m×n diagonal matrix containing the singular values of A, 157 // U is an m×m orthogonal matrix and V is an n×n orthogonal matrix. The first 158 // min(m,n) columns of U and V are the left and right singular vectors of A 159 // respectively. 160 // 161 // jobU and jobVT are options for computing the singular vectors. The behavior 162 // is as follows 163 // jobU == lapack.SVDAll All m columns of U are returned in u 164 // jobU == lapack.SVDInPlace The first min(m,n) columns are returned in u 165 // jobU == lapack.SVDOverwrite The first min(m,n) columns of U are written into a 166 // jobU == lapack.SVDNone The columns of U are not computed. 167 // The behavior is the same for jobVT and the rows of V^T. At most one of jobU 168 // and jobVT can equal lapack.SVDOverwrite, and Gesvd will panic otherwise. 169 // 170 // On entry, a contains the data for the m×n matrix A. During the call to Gesvd 171 // the data is overwritten. On exit, A contains the appropriate singular vectors 172 // if either job is lapack.SVDOverwrite. 173 // 174 // s is a slice of length at least min(m,n) and on exit contains the singular 175 // values in decreasing order. 176 // 177 // u contains the left singular vectors on exit, stored columnwise. If 178 // jobU == lapack.SVDAll, u is of size m×m. If jobU == lapack.SVDInPlace u is 179 // of size m×min(m,n). If jobU == lapack.SVDOverwrite or lapack.SVDNone, u is 180 // not used. 181 // 182 // vt contains the left singular vectors on exit, stored rowwise. If 183 // jobV == lapack.SVDAll, vt is of size n×m. If jobVT == lapack.SVDInPlace vt is 184 // of size min(m,n)×n. If jobVT == lapack.SVDOverwrite or lapack.SVDNone, vt is 185 // not used. 186 // 187 // work is a slice for storing temporary memory, and lwork is the usable size of 188 // the slice. lwork must be at least max(5*min(m,n), 3*min(m,n)+max(m,n)). 189 // If lwork == -1, instead of performing Gesvd, the optimal work length will be 190 // stored into work[0]. Gesvd will panic if the working memory has insufficient 191 // storage. 192 // 193 // Gesvd returns whether the decomposition successfully completed. 194 func Gesvd(jobU, jobVT lapack.SVDJob, a, u, vt blas64.General, s, work []float64, lwork int) (ok bool) { 195 return lapack64.Dgesvd(jobU, jobVT, a.Rows, a.Cols, a.Data, a.Stride, s, u.Data, u.Stride, vt.Data, vt.Stride, work, lwork) 196 } 197 198 // Getrf computes the LU decomposition of the m×n matrix A. 199 // The LU decomposition is a factorization of A into 200 // A = P * L * U 201 // where P is a permutation matrix, L is a unit lower triangular matrix, and 202 // U is a (usually) non-unit upper triangular matrix. On exit, L and U are stored 203 // in place into a. 204 // 205 // ipiv is a permutation vector. It indicates that row i of the matrix was 206 // changed with ipiv[i]. ipiv must have length at least min(m,n), and will panic 207 // otherwise. ipiv is zero-indexed. 208 // 209 // Getrf is the blocked version of the algorithm. 210 // 211 // Getrf returns whether the matrix A is singular. The LU decomposition will 212 // be computed regardless of the singularity of A, but division by zero 213 // will occur if the false is returned and the result is used to solve a 214 // system of equations. 215 func Getrf(a blas64.General, ipiv []int) bool { 216 return lapack64.Dgetrf(a.Rows, a.Cols, a.Data, a.Stride, ipiv) 217 } 218 219 // Getri computes the inverse of the matrix A using the LU factorization computed 220 // by Getrf. On entry, a contains the PLU decomposition of A as computed by 221 // Getrf and on exit contains the reciprocal of the original matrix. 222 // 223 // Getri will not perform the inversion if the matrix is singular, and returns 224 // a boolean indicating whether the inversion was successful. 225 // 226 // Work is temporary storage, and lwork specifies the usable memory length. 227 // At minimum, lwork >= n and this function will panic otherwise. 228 // Getri is a blocked inversion, but the block size is limited 229 // by the temporary space available. If lwork == -1, instead of performing Getri, 230 // the optimal work length will be stored into work[0]. 231 func Getri(a blas64.General, ipiv []int, work []float64, lwork int) (ok bool) { 232 return lapack64.Dgetri(a.Cols, a.Data, a.Stride, ipiv, work, lwork) 233 } 234 235 // Getrs solves a system of equations using an LU factorization. 236 // The system of equations solved is 237 // A * X = B if trans == blas.Trans 238 // A^T * X = B if trans == blas.NoTrans 239 // A is a general n×n matrix with stride lda. B is a general matrix of size n×nrhs. 240 // 241 // On entry b contains the elements of the matrix B. On exit, b contains the 242 // elements of X, the solution to the system of equations. 243 // 244 // a and ipiv contain the LU factorization of A and the permutation indices as 245 // computed by Getrf. ipiv is zero-indexed. 246 func Getrs(trans blas.Transpose, a blas64.General, b blas64.General, ipiv []int) { 247 lapack64.Dgetrs(trans, a.Cols, b.Cols, a.Data, a.Stride, ipiv, b.Data, b.Stride) 248 } 249 250 // Ggsvd3 computes the generalized singular value decomposition (GSVD) 251 // of an m×n matrix A and p×n matrix B: 252 // U^T*A*Q = D1*[ 0 R ] 253 // 254 // V^T*B*Q = D2*[ 0 R ] 255 // where U, V and Q are orthogonal matrices. 256 // 257 // Ggsvd3 returns k and l, the dimensions of the sub-blocks. k+l 258 // is the effective numerical rank of the (m+p)×n matrix [ A^T B^T ]^T. 259 // R is a (k+l)×(k+l) nonsingular upper triangular matrix, D1 and 260 // D2 are m×(k+l) and p×(k+l) diagonal matrices and of the following 261 // structures, respectively: 262 // 263 // If m-k-l >= 0, 264 // 265 // k l 266 // D1 = k [ I 0 ] 267 // l [ 0 C ] 268 // m-k-l [ 0 0 ] 269 // 270 // k l 271 // D2 = l [ 0 S ] 272 // p-l [ 0 0 ] 273 // 274 // n-k-l k l 275 // [ 0 R ] = k [ 0 R11 R12 ] k 276 // l [ 0 0 R22 ] l 277 // 278 // where 279 // 280 // C = diag( alpha_k, ... , alpha_{k+l} ), 281 // S = diag( beta_k, ... , beta_{k+l} ), 282 // C^2 + S^2 = I. 283 // 284 // R is stored in 285 // A[0:k+l, n-k-l:n] 286 // on exit. 287 // 288 // If m-k-l < 0, 289 // 290 // k m-k k+l-m 291 // D1 = k [ I 0 0 ] 292 // m-k [ 0 C 0 ] 293 // 294 // k m-k k+l-m 295 // D2 = m-k [ 0 S 0 ] 296 // k+l-m [ 0 0 I ] 297 // p-l [ 0 0 0 ] 298 // 299 // n-k-l k m-k k+l-m 300 // [ 0 R ] = k [ 0 R11 R12 R13 ] 301 // m-k [ 0 0 R22 R23 ] 302 // k+l-m [ 0 0 0 R33 ] 303 // 304 // where 305 // C = diag( alpha_k, ... , alpha_m ), 306 // S = diag( beta_k, ... , beta_m ), 307 // C^2 + S^2 = I. 308 // 309 // R = [ R11 R12 R13 ] is stored in A[1:m, n-k-l+1:n] 310 // [ 0 R22 R23 ] 311 // and R33 is stored in 312 // B[m-k:l, n+m-k-l:n] on exit. 313 // 314 // Ggsvd3 computes C, S, R, and optionally the orthogonal transformation 315 // matrices U, V and Q. 316 // 317 // jobU, jobV and jobQ are options for computing the orthogonal matrices. The behavior 318 // is as follows 319 // jobU == lapack.GSVDU Compute orthogonal matrix U 320 // jobU == lapack.GSVDNone Do not compute orthogonal matrix. 321 // The behavior is the same for jobV and jobQ with the exception that instead of 322 // lapack.GSVDU these accept lapack.GSVDV and lapack.GSVDQ respectively. 323 // The matrices U, V and Q must be m×m, p×p and n×n respectively unless the 324 // relevant job parameter is lapack.GSVDNone. 325 // 326 // alpha and beta must have length n or Ggsvd3 will panic. On exit, alpha and 327 // beta contain the generalized singular value pairs of A and B 328 // alpha[0:k] = 1, 329 // beta[0:k] = 0, 330 // if m-k-l >= 0, 331 // alpha[k:k+l] = diag(C), 332 // beta[k:k+l] = diag(S), 333 // if m-k-l < 0, 334 // alpha[k:m]= C, alpha[m:k+l]= 0 335 // beta[k:m] = S, beta[m:k+l] = 1. 336 // if k+l < n, 337 // alpha[k+l:n] = 0 and 338 // beta[k+l:n] = 0. 339 // 340 // On exit, iwork contains the permutation required to sort alpha descending. 341 // 342 // iwork must have length n, work must have length at least max(1, lwork), and 343 // lwork must be -1 or greater than n, otherwise Ggsvd3 will panic. If 344 // lwork is -1, work[0] holds the optimal lwork on return, but Ggsvd3 does 345 // not perform the GSVD. 346 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) { 347 return lapack64.Dggsvd3(jobU, jobV, jobQ, a.Rows, a.Cols, b.Rows, a.Data, a.Stride, b.Data, b.Stride, alpha, beta, u.Data, u.Stride, v.Data, v.Stride, q.Data, q.Stride, work, lwork, iwork) 348 } 349 350 // Lange computes the matrix norm of the general m×n matrix A. The input norm 351 // specifies the norm computed. 352 // lapack.MaxAbs: the maximum absolute value of an element. 353 // lapack.MaxColumnSum: the maximum column sum of the absolute values of the entries. 354 // lapack.MaxRowSum: the maximum row sum of the absolute values of the entries. 355 // lapack.Frobenius: the square root of the sum of the squares of the entries. 356 // If norm == lapack.MaxColumnSum, work must be of length n, and this function will panic otherwise. 357 // There are no restrictions on work for the other matrix norms. 358 func Lange(norm lapack.MatrixNorm, a blas64.General, work []float64) float64 { 359 return lapack64.Dlange(norm, a.Rows, a.Cols, a.Data, a.Stride, work) 360 } 361 362 // Lansy computes the specified norm of an n×n symmetric matrix. If 363 // norm == lapack.MaxColumnSum or norm == lapackMaxRowSum work must have length 364 // at least n and this function will panic otherwise. 365 // There are no restrictions on work for the other matrix norms. 366 func Lansy(norm lapack.MatrixNorm, a blas64.Symmetric, work []float64) float64 { 367 return lapack64.Dlansy(norm, a.Uplo, a.N, a.Data, a.Stride, work) 368 } 369 370 // Lantr computes the specified norm of an m×n trapezoidal matrix A. If 371 // norm == lapack.MaxColumnSum work must have length at least n and this function 372 // will panic otherwise. There are no restrictions on work for the other matrix norms. 373 func Lantr(norm lapack.MatrixNorm, a blas64.Triangular, work []float64) float64 { 374 return lapack64.Dlantr(norm, a.Uplo, a.Diag, a.N, a.N, a.Data, a.Stride, work) 375 } 376 377 // Lapmt rearranges the columns of the m×n matrix X as specified by the 378 // permutation k_0, k_1, ..., k_{n-1} of the integers 0, ..., n-1. 379 // 380 // If forward is true a forward permutation is performed: 381 // 382 // X[0:m, k[j]] is moved to X[0:m, j] for j = 0, 1, ..., n-1. 383 // 384 // otherwise a backward permutation is performed: 385 // 386 // X[0:m, j] is moved to X[0:m, k[j]] for j = 0, 1, ..., n-1. 387 // 388 // k must have length n, otherwise Lapmt will panic. k is zero-indexed. 389 func Lapmt(forward bool, x blas64.General, k []int) { 390 lapack64.Dlapmt(forward, x.Rows, x.Cols, x.Data, x.Stride, k) 391 } 392 393 // Ormlq multiplies the matrix C by the othogonal matrix Q defined by 394 // A and tau. A and tau are as returned from Gelqf. 395 // C = Q * C if side == blas.Left and trans == blas.NoTrans 396 // C = Q^T * C if side == blas.Left and trans == blas.Trans 397 // C = C * Q if side == blas.Right and trans == blas.NoTrans 398 // C = C * Q^T if side == blas.Right and trans == blas.Trans 399 // If side == blas.Left, A is a matrix of side k×m, and if side == blas.Right 400 // A is of size k×n. This uses a blocked algorithm. 401 // 402 // Work is temporary storage, and lwork specifies the usable memory length. 403 // At minimum, lwork >= m if side == blas.Left and lwork >= n if side == blas.Right, 404 // and this function will panic otherwise. 405 // Ormlq uses a block algorithm, but the block size is limited 406 // by the temporary space available. If lwork == -1, instead of performing Ormlq, 407 // the optimal work length will be stored into work[0]. 408 // 409 // Tau contains the Householder scales and must have length at least k, and 410 // this function will panic otherwise. 411 func Ormlq(side blas.Side, trans blas.Transpose, a blas64.General, tau []float64, c blas64.General, work []float64, lwork int) { 412 lapack64.Dormlq(side, trans, c.Rows, c.Cols, a.Rows, a.Data, a.Stride, tau, c.Data, c.Stride, work, lwork) 413 } 414 415 // Ormqr multiplies an m×n matrix C by an orthogonal matrix Q as 416 // C = Q * C, if side == blas.Left and trans == blas.NoTrans, 417 // C = Q^T * C, if side == blas.Left and trans == blas.Trans, 418 // C = C * Q, if side == blas.Right and trans == blas.NoTrans, 419 // C = C * Q^T, if side == blas.Right and trans == blas.Trans, 420 // where Q is defined as the product of k elementary reflectors 421 // Q = H_0 * H_1 * ... * H_{k-1}. 422 // 423 // If side == blas.Left, A is an m×k matrix and 0 <= k <= m. 424 // If side == blas.Right, A is an n×k matrix and 0 <= k <= n. 425 // The ith column of A contains the vector which defines the elementary 426 // reflector H_i and tau[i] contains its scalar factor. tau must have length k 427 // and Ormqr will panic otherwise. Geqrf returns A and tau in the required 428 // form. 429 // 430 // work must have length at least max(1,lwork), and lwork must be at least n if 431 // side == blas.Left and at least m if side == blas.Right, otherwise Ormqr will 432 // panic. 433 // 434 // work is temporary storage, and lwork specifies the usable memory length. At 435 // minimum, lwork >= m if side == blas.Left and lwork >= n if side == 436 // blas.Right, and this function will panic otherwise. Larger values of lwork 437 // will generally give better performance. On return, work[0] will contain the 438 // optimal value of lwork. 439 // 440 // If lwork is -1, instead of performing Ormqr, the optimal workspace size will 441 // be stored into work[0]. 442 func Ormqr(side blas.Side, trans blas.Transpose, a blas64.General, tau []float64, c blas64.General, work []float64, lwork int) { 443 lapack64.Dormqr(side, trans, c.Rows, c.Cols, a.Cols, a.Data, a.Stride, tau, c.Data, c.Stride, work, lwork) 444 } 445 446 // Pocon estimates the reciprocal of the condition number of a positive-definite 447 // matrix A given the Cholesky decmposition of A. The condition number computed 448 // is based on the 1-norm and the ∞-norm. 449 // 450 // anorm is the 1-norm and the ∞-norm of the original matrix A. 451 // 452 // work is a temporary data slice of length at least 3*n and Pocon will panic otherwise. 453 // 454 // iwork is a temporary data slice of length at least n and Pocon will panic otherwise. 455 func Pocon(a blas64.Symmetric, anorm float64, work []float64, iwork []int) float64 { 456 return lapack64.Dpocon(a.Uplo, a.N, a.Data, a.Stride, anorm, work, iwork) 457 } 458 459 // Syev computes all eigenvalues and, optionally, the eigenvectors of a real 460 // symmetric matrix A. 461 // 462 // w contains the eigenvalues in ascending order upon return. w must have length 463 // at least n, and Syev will panic otherwise. 464 // 465 // On entry, a contains the elements of the symmetric matrix A in the triangular 466 // portion specified by uplo. If jobz == lapack.ComputeEV a contains the 467 // orthonormal eigenvectors of A on exit, otherwise on exit the specified 468 // triangular region is overwritten. 469 // 470 // Work is temporary storage, and lwork specifies the usable memory length. At minimum, 471 // lwork >= 3*n-1, and Syev will panic otherwise. The amount of blocking is 472 // limited by the usable length. If lwork == -1, instead of computing Syev the 473 // optimal work length is stored into work[0]. 474 func Syev(jobz lapack.EVJob, a blas64.Symmetric, w, work []float64, lwork int) (ok bool) { 475 return lapack64.Dsyev(jobz, a.Uplo, a.N, a.Data, a.Stride, w, work, lwork) 476 } 477 478 // Trcon estimates the reciprocal of the condition number of a triangular matrix A. 479 // The condition number computed may be based on the 1-norm or the ∞-norm. 480 // 481 // work is a temporary data slice of length at least 3*n and Trcon will panic otherwise. 482 // 483 // iwork is a temporary data slice of length at least n and Trcon will panic otherwise. 484 func Trcon(norm lapack.MatrixNorm, a blas64.Triangular, work []float64, iwork []int) float64 { 485 return lapack64.Dtrcon(norm, a.Uplo, a.Diag, a.N, a.Data, a.Stride, work, iwork) 486 } 487 488 // Trtri computes the inverse of a triangular matrix, storing the result in place 489 // into a. 490 // 491 // Trtri will not perform the inversion if the matrix is singular, and returns 492 // a boolean indicating whether the inversion was successful. 493 func Trtri(a blas64.Triangular) (ok bool) { 494 return lapack64.Dtrtri(a.Uplo, a.Diag, a.N, a.Data, a.Stride) 495 } 496 497 // Trtrs solves a triangular system of the form A * X = B or A^T * X = B. Trtrs 498 // returns whether the solve completed successfully. If A is singular, no solve is performed. 499 func Trtrs(trans blas.Transpose, a blas64.Triangular, b blas64.General) (ok bool) { 500 return lapack64.Dtrtrs(a.Uplo, trans, a.Diag, a.N, b.Cols, a.Data, a.Stride, b.Data, b.Stride) 501 } 502 503 // Geev computes the eigenvalues and, optionally, the left and/or right 504 // eigenvectors for an n×n real nonsymmetric matrix A. 505 // 506 // The right eigenvector v_j of A corresponding to an eigenvalue λ_j 507 // is defined by 508 // A v_j = λ_j v_j, 509 // and the left eigenvector u_j corresponding to an eigenvalue λ_j is defined by 510 // u_j^H A = λ_j u_j^H, 511 // where u_j^H is the conjugate transpose of u_j. 512 // 513 // On return, A will be overwritten and the left and right eigenvectors will be 514 // stored, respectively, in the columns of the n×n matrices VL and VR in the 515 // same order as their eigenvalues. If the j-th eigenvalue is real, then 516 // u_j = VL[:,j], 517 // v_j = VR[:,j], 518 // and if it is not real, then j and j+1 form a complex conjugate pair and the 519 // eigenvectors can be recovered as 520 // u_j = VL[:,j] + i*VL[:,j+1], 521 // u_{j+1} = VL[:,j] - i*VL[:,j+1], 522 // v_j = VR[:,j] + i*VR[:,j+1], 523 // v_{j+1} = VR[:,j] - i*VR[:,j+1], 524 // where i is the imaginary unit. The computed eigenvectors are normalized to 525 // have Euclidean norm equal to 1 and largest component real. 526 // 527 // Left eigenvectors will be computed only if jobvl == lapack.ComputeLeftEV, 528 // otherwise jobvl must be lapack.None. 529 // Right eigenvectors will be computed only if jobvr == lapack.ComputeRightEV, 530 // otherwise jobvr must be lapack.None. 531 // For other values of jobvl and jobvr Geev will panic. 532 // 533 // On return, wr and wi will contain the real and imaginary parts, respectively, 534 // of the computed eigenvalues. Complex conjugate pairs of eigenvalues appear 535 // consecutively with the eigenvalue having the positive imaginary part first. 536 // wr and wi must have length n, and Geev will panic otherwise. 537 // 538 // work must have length at least lwork and lwork must be at least max(1,4*n) if 539 // the left or right eigenvectors are computed, and at least max(1,3*n) if no 540 // eigenvectors are computed. For good performance, lwork must generally be 541 // larger. On return, optimal value of lwork will be stored in work[0]. 542 // 543 // If lwork == -1, instead of performing Geev, the function only calculates the 544 // optimal vaule of lwork and stores it into work[0]. 545 // 546 // On return, first will be the index of the first valid eigenvalue. 547 // If first == 0, all eigenvalues and eigenvectors have been computed. 548 // If first is positive, Geev failed to compute all the eigenvalues, no 549 // eigenvectors have been computed and wr[first:] and wi[first:] contain those 550 // eigenvalues which have converged. 551 func Geev(jobvl lapack.LeftEVJob, jobvr lapack.RightEVJob, a blas64.General, wr, wi []float64, vl, vr blas64.General, work []float64, lwork int) (first int) { 552 n := a.Rows 553 if a.Cols != n { 554 panic("lapack64: matrix not square") 555 } 556 if jobvl == lapack.ComputeLeftEV && (vl.Rows != n || vl.Cols != n) { 557 panic("lapack64: bad size of VL") 558 } 559 if jobvr == lapack.ComputeRightEV && (vr.Rows != n || vr.Cols != n) { 560 panic("lapack64: bad size of VR") 561 } 562 return lapack64.Dgeev(jobvl, jobvr, n, a.Data, a.Stride, wr, wi, vl.Data, vl.Stride, vr.Data, vr.Stride, work, lwork) 563 }