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  }