diff --git a/lapack/gonum/dgeev.go b/lapack/gonum/dgeev.go index d7204fa8..eb911d2a 100644 --- a/lapack/gonum/dgeev.go +++ b/lapack/gonum/dgeev.go @@ -123,7 +123,7 @@ func (impl Implementation) Dgeev(jobvl lapack.LeftEVJob, jobvr lapack.RightEVJob if wantvr { side = lapack.EVRight } - impl.Dtrevc3(side, lapack.AllEVMulQ, nil, n, nil, 1, nil, 1, nil, 1, + impl.Dtrevc3(side, lapack.EVAllMulQ, nil, n, nil, 1, nil, 1, nil, 1, n, work, -1) maxwrk = max(maxwrk, n+int(work[0])) maxwrk = max(maxwrk, 4*n) @@ -215,7 +215,7 @@ func (impl Implementation) Dgeev(jobvl lapack.LeftEVJob, jobvr lapack.RightEVJob if wantvl || wantvr { // Compute left and/or right eigenvectors. - impl.Dtrevc3(side, lapack.AllEVMulQ, nil, n, + impl.Dtrevc3(side, lapack.EVAllMulQ, nil, n, a, lda, vl, ldvl, vr, ldvr, n, work[iwrk:], lwork-iwrk) } bi := blas64.Implementation() diff --git a/lapack/gonum/dtrevc3.go b/lapack/gonum/dtrevc3.go index 309db9b8..3121764d 100644 --- a/lapack/gonum/dtrevc3.go +++ b/lapack/gonum/dtrevc3.go @@ -36,16 +36,16 @@ import ( // If side == lapack.EVRightLeft, both right and left eigenvectors will be computed. // For other values of side, Dtrevc3 will panic. // -// If howmny == lapack.AllEV, all right and/or left eigenvectors will be +// If howmny == lapack.EVAll, all right and/or left eigenvectors will be // computed. -// If howmny == lapack.AllEVMulQ, all right and/or left eigenvectors will be +// If howmny == lapack.EVAllMulQ, all right and/or left eigenvectors will be // computed and multiplied from left by the matrices in VR and/or VL. -// If howmny == lapack.SelectedEV, right and/or left eigenvectors will be +// If howmny == lapack.EVSelected, right and/or left eigenvectors will be // computed as indicated by selected. // For other values of howmny, Dtrevc3 will panic. // // selected specifies which eigenvectors will be computed. It must have length n -// if howmny == lapack.SelectedEV, and it is not referenced otherwise. +// if howmny == lapack.EVSelected, and it is not referenced otherwise. // If w_j is a real eigenvalue, the corresponding real eigenvector will be // computed if selected[j] is true. // If w_j and w_{j+1} are the real and imaginary parts of a complex eigenvalue, @@ -53,9 +53,9 @@ import ( // selected[j+1] is true, and on return selected[j] will be set to true and // selected[j+1] will be set to false. // -// VL and VR are n×mm matrices. If howmny is lapack.AllEV or -// lapack.AllEVMulQ, mm must be at least n. If howmny == -// lapack.SelectedEV, mm must be large enough to store the selected +// VL and VR are n×mm matrices. If howmny is lapack.EVAll or +// lapack.AllEVMulQ, mm must be at least n. If howmny is +// lapack.EVSelected, mm must be large enough to store the selected // eigenvectors. Each selected real eigenvector occupies one column and each // selected complex eigenvector occupies two columns. If mm is not sufficiently // large, Dtrevc3 will panic. @@ -68,9 +68,9 @@ import ( // // On return, if side is lapack.EVLeft or lapack.EVRightLeft, // VL will contain: -// if howmny == lapack.AllEV, the matrix Y of left eigenvectors of T, -// if howmny == lapack.AllEVMulQ, the matrix Q*Y, -// if howmny == lapack.SelectedEV, the left eigenvectors of T specified by +// if howmny == lapack.EVAll, the matrix Y of left eigenvectors of T, +// if howmny == lapack.EVAllMulQ, the matrix Q*Y, +// if howmny == lapack.EVSelected, the left eigenvectors of T specified by // selected, stored consecutively in the // columns of VL, in the same order as their // eigenvalues. @@ -78,9 +78,9 @@ import ( // // On return, if side is lapack.EVRight or lapack.EVRightLeft, // VR will contain: -// if howmny == lapack.AllEV, the matrix X of right eigenvectors of T, -// if howmny == lapack.AllEVMulQ, the matrix Q*X, -// if howmny == lapack.SelectedEV, the left eigenvectors of T specified by +// if howmny == lapack.EVAll, the matrix X of right eigenvectors of T, +// if howmny == lapack.EVAllMulQ, the matrix Q*X, +// if howmny == lapack.EVSelected, the left eigenvectors of T specified by // selected, stored consecutively in the // columns of VR, in the same order as their // eigenvalues. @@ -105,7 +105,7 @@ import ( // the eigenvectors. // // Dtrevc3 is an internal routine. It is exported for testing purposes. -func (impl Implementation) Dtrevc3(side lapack.EVSide, howmny lapack.HowMany, selected []bool, n int, t []float64, ldt int, vl []float64, ldvl int, vr []float64, ldvr int, mm int, work []float64, lwork int) (m int) { +func (impl Implementation) Dtrevc3(side lapack.EVSide, howmny lapack.EVHowMany, selected []bool, n int, t []float64, ldt int, vl []float64, ldvl int, vr []float64, ldvr int, mm int, work []float64, lwork int) (m int) { switch side { default: panic(badEVSide) @@ -113,8 +113,8 @@ func (impl Implementation) Dtrevc3(side lapack.EVSide, howmny lapack.HowMany, se } switch howmny { default: - panic(badHowMany) - case lapack.AllEV, lapack.AllEVMulQ, lapack.SelectedEV: + panic(badEVHowMany) + case lapack.EVAll, lapack.EVAllMulQ, lapack.EVSelected: } switch { case n < 0: @@ -125,7 +125,7 @@ func (impl Implementation) Dtrevc3(side lapack.EVSide, howmny lapack.HowMany, se panic(badWork) } if lwork != -1 { - if howmny == lapack.SelectedEV { + if howmny == lapack.EVSelected { if len(selected) != n { panic("lapack: bad selected length") } @@ -186,7 +186,7 @@ func (impl Implementation) Dtrevc3(side lapack.EVSide, howmny lapack.HowMany, se // Use blocked version of back-transformation if sufficient workspace. // Zero-out the workspace to avoid potential NaN propagation. - if howmny == lapack.AllEVMulQ && lwork >= n+2*n*nbmin { + if howmny == lapack.EVAllMulQ && lwork >= n+2*n*nbmin { nb = min((lwork-n)/(2*n), nbmax) impl.Dlaset(blas.All, n, 1+2*nb, 0, 0, work[:n+2*nb*n], 1+2*nb) } else { @@ -261,7 +261,7 @@ func (impl Implementation) Dtrevc3(side lapack.EVSide, howmny lapack.HowMany, se ip = -1 } - if howmny == lapack.SelectedEV { + if howmny == lapack.EVSelected { if ip == 0 { if !selected[ki] { continue @@ -336,7 +336,7 @@ func (impl Implementation) Dtrevc3(side lapack.EVSide, howmny lapack.HowMany, se } // Copy the vector x or Q*x to VR and normalize. switch { - case howmny != lapack.AllEVMulQ: + case howmny != lapack.EVAllMulQ: // No back-transform: copy x to VR and normalize. bi.Dcopy(ki+1, b[iv:], ldb, vr[is:], ldvr) ii := bi.Idamax(ki+1, vr[is:], ldvr) @@ -447,7 +447,7 @@ func (impl Implementation) Dtrevc3(side lapack.EVSide, howmny lapack.HowMany, se // Copy the vector x or Q*x to VR and normalize. switch { - case howmny != lapack.AllEVMulQ: + case howmny != lapack.EVAllMulQ: // No back-transform: copy x to VR and normalize. bi.Dcopy(ki+1, b[iv-1:], ldb, vr[is-1:], ldvr) bi.Dcopy(ki+1, b[iv:], ldb, vr[is:], ldvr) @@ -569,7 +569,7 @@ leftev: // conjugate pair. ip = 1 } - if howmny == lapack.SelectedEV && !selected[ki] { + if howmny == lapack.EVSelected && !selected[ki] { continue } @@ -648,7 +648,7 @@ leftev: } // Copy the vector x or Q*x to VL and normalize. switch { - case howmny != lapack.AllEVMulQ: + case howmny != lapack.EVAllMulQ: // No back-transform: copy x to VL and normalize. bi.Dcopy(n-ki, b[ki*ldb+iv:], ldb, vl[ki*ldvl+is:], ldvl) ii := bi.Idamax(n-ki, vl[ki*ldvl+is:], ldvl) + ki @@ -767,7 +767,7 @@ leftev: } // Copy the vector x or Q*x to VL and normalize. switch { - case howmny != lapack.AllEVMulQ: + case howmny != lapack.EVAllMulQ: // No back-transform: copy x to VL and normalize. bi.Dcopy(n-ki, b[ki*ldb+iv:], ldb, vl[ki*ldvl+is:], ldvl) bi.Dcopy(n-ki, b[ki*ldb+iv+1:], ldb, vl[ki*ldvl+is+1:], ldvl) diff --git a/lapack/gonum/general.go b/lapack/gonum/general.go index f5f66dd8..04b49c73 100644 --- a/lapack/gonum/general.go +++ b/lapack/gonum/general.go @@ -28,10 +28,10 @@ const ( badDirect = "lapack: bad direct" badE = "lapack: e has insufficient length" badEVComp = "lapack: bad EVComp" + badEVHowMany = "lapack: bad EVHowMany" badEVJob = "lapack: bad EVJob" badEVSide = "lapack: bad EVSide" badGSVDJob = "lapack: bad GSVDJob" - badHowMany = "lapack: bad HowMany" badIlo = "lapack: ilo out of range" badIhi = "lapack: ihi out of range" badIpiv = "lapack: bad permutation length" diff --git a/lapack/lapack.go b/lapack/lapack.go index f5cfe2ee..3e1f13f4 100644 --- a/lapack/lapack.go +++ b/lapack/lapack.go @@ -187,12 +187,11 @@ const ( EVRightLeft EVSide = 'B' // Both right and left eigenvectors are computed. ) -// HowMany specifies which eigenvectors will be computed. -type HowMany byte +// EVHowMany specifies which eigenvectors are computed in Dtrevc3 and how. +type EVHowMany byte -// HowMany constants for Dhseqr. const ( - AllEV HowMany = 'A' // Compute all right and/or left eigenvectors. - AllEVMulQ HowMany = 'B' // Compute all right and/or left eigenvectors multiplied by an input matrix. - SelectedEV HowMany = 'S' // Compute selected right and/or left eigenvectors. + EVAll EVHowMany = 'A' // Compute all right and/or left eigenvectors. + EVAllMulQ EVHowMany = 'B' // Compute all right and/or left eigenvectors multiplied by an input matrix. + EVSelected EVHowMany = 'S' // Compute selected right and/or left eigenvectors. ) diff --git a/lapack/testlapack/dtrevc3.go b/lapack/testlapack/dtrevc3.go index eee26411..5031678d 100644 --- a/lapack/testlapack/dtrevc3.go +++ b/lapack/testlapack/dtrevc3.go @@ -17,7 +17,7 @@ import ( ) type Dtrevc3er interface { - Dtrevc3(side lapack.EVSide, howmny lapack.HowMany, selected []bool, n int, t []float64, ldt int, vl []float64, ldvl int, vr []float64, ldvr int, mm int, work []float64, lwork int) int + Dtrevc3(side lapack.EVSide, howmny lapack.EVHowMany, selected []bool, n int, t []float64, ldt int, vl []float64, ldvl int, vr []float64, ldvr int, mm int, work []float64, lwork int) int } func Dtrevc3Test(t *testing.T, impl Dtrevc3er) { @@ -38,7 +38,7 @@ func Dtrevc3Test(t *testing.T, impl Dtrevc3er) { } } -func testDtrevc3(t *testing.T, impl Dtrevc3er, side lapack.EVSide, howmny lapack.HowMany, tmat blas64.General, optwork bool, rnd *rand.Rand) { +func testDtrevc3(t *testing.T, impl Dtrevc3er, side lapack.EVSide, howmny lapack.EVHowMany, tmat blas64.General, optwork bool, rnd *rand.Rand) { const tol = 1e-14 n := tmat.Rows @@ -48,7 +48,7 @@ func testDtrevc3(t *testing.T, impl Dtrevc3er, side lapack.EVSide, howmny lapack var selected, selectedWant []bool var mWant int // How many columns will the eigenvectors occupy. - if howmny == lapack.SelectedEV { + if howmny == lapack.EVSelected { selected = make([]bool, n) selectedWant = make([]bool, n) // Dtrevc3 will compute only selected eigenvectors. Pick them @@ -88,7 +88,7 @@ func testDtrevc3(t *testing.T, impl Dtrevc3er, side lapack.EVSide, howmny lapack var vr blas64.General if right { - if howmny == lapack.AllEVMulQ { + if howmny == lapack.EVAllMulQ { vr = eye(n, n+extra) } else { // VR will be overwritten. @@ -98,7 +98,7 @@ func testDtrevc3(t *testing.T, impl Dtrevc3er, side lapack.EVSide, howmny lapack var vl blas64.General if left { - if howmny == lapack.AllEVMulQ { + if howmny == lapack.EVAllMulQ { vl = eye(n, n+extra) } else { // VL will be overwritten. @@ -132,7 +132,7 @@ func testDtrevc3(t *testing.T, impl Dtrevc3er, side lapack.EVSide, howmny lapack t.Errorf("%v: unexpected value of m. Want %v, got %v", prefix, mWant, m) } - if howmny == lapack.SelectedEV { + if howmny == lapack.EVSelected { for i := range selected { if selected[i] != selectedWant[i] { t.Errorf("%v: unexpected selected[%v]", prefix, i) @@ -146,7 +146,7 @@ func testDtrevc3(t *testing.T, impl Dtrevc3er, side lapack.EVSide, howmny lapack for j := 0; j < n; { re := tmat.Data[j*tmat.Stride+j] if j == n-1 || tmat.Data[(j+1)*tmat.Stride+j] == 0 { - if howmny == lapack.SelectedEV && !selected[j] { + if howmny == lapack.EVSelected && !selected[j] { j++ continue } @@ -174,7 +174,7 @@ func testDtrevc3(t *testing.T, impl Dtrevc3er, side lapack.EVSide, howmny lapack j++ continue } - if howmny == lapack.SelectedEV && !selected[j] { + if howmny == lapack.EVSelected && !selected[j] { j += 2 continue }