mirror of
https://github.com/gonum/gonum.git
synced 2025-10-05 23:26:52 +08:00
lapack/gonum: unify parameter checks
This commit is contained in:

committed by
Vladimír Chalupecký

parent
149afe6ec0
commit
7cc92e21e0
@@ -95,7 +95,7 @@ func (impl Implementation) Dgesvd(jobU, jobVT lapack.SVDJob, m, n int, a []float
|
|||||||
panic(nLT0)
|
panic(nLT0)
|
||||||
case lda < max(1, n):
|
case lda < max(1, n):
|
||||||
panic(badLdA)
|
panic(badLdA)
|
||||||
case ldu < 1 || (wantua && ldu < m) || (wantus && ldu < minmn):
|
case ldu < 1, wantua && ldu < m, wantus && ldu < minmn:
|
||||||
panic(badLdU)
|
panic(badLdU)
|
||||||
case ldvt < 1 || (wantvas && ldvt < n):
|
case ldvt < 1 || (wantvas && ldvt < n):
|
||||||
panic(badLdVT)
|
panic(badLdVT)
|
||||||
|
@@ -128,11 +128,11 @@ func (impl Implementation) Dggsvd3(jobU, jobV, jobQ lapack.GSVDJob, m, n, p int,
|
|||||||
panic(badLdA)
|
panic(badLdA)
|
||||||
case ldb < max(1, n):
|
case ldb < max(1, n):
|
||||||
panic(badLdB)
|
panic(badLdB)
|
||||||
case ldu < 1 || (wantu && ldu < m):
|
case ldu < 1, wantu && ldu < m:
|
||||||
panic(badLdU)
|
panic(badLdU)
|
||||||
case ldv < 1 || (wantv && ldv < p):
|
case ldv < 1, wantv && ldv < p:
|
||||||
panic(badLdV)
|
panic(badLdV)
|
||||||
case ldq < 1 || (wantq && ldq < n):
|
case ldq < 1, wantq && ldq < n:
|
||||||
panic(badLdQ)
|
panic(badLdQ)
|
||||||
case len(iwork) < n:
|
case len(iwork) < n:
|
||||||
panic(shortWork)
|
panic(shortWork)
|
||||||
|
@@ -74,11 +74,11 @@ func (impl Implementation) Dggsvp3(jobU, jobV, jobQ lapack.GSVDJob, m, p, n int,
|
|||||||
panic(badLdA)
|
panic(badLdA)
|
||||||
case ldb < max(1, n):
|
case ldb < max(1, n):
|
||||||
panic(badLdB)
|
panic(badLdB)
|
||||||
case ldu < 1 || (wantu && ldu < m):
|
case ldu < 1, wantu && ldu < m:
|
||||||
panic(badLdU)
|
panic(badLdU)
|
||||||
case ldv < 1 || (wantv && ldv < p):
|
case ldv < 1, wantv && ldv < p:
|
||||||
panic(badLdV)
|
panic(badLdV)
|
||||||
case ldq < 1 || (wantq && ldq < n):
|
case ldq < 1, wantq && ldq < n:
|
||||||
panic(badLdQ)
|
panic(badLdQ)
|
||||||
case len(iwork) != n:
|
case len(iwork) != n:
|
||||||
panic(shortWork)
|
panic(shortWork)
|
||||||
|
@@ -135,7 +135,7 @@ func (impl Implementation) Dhseqr(job lapack.SchurJob, compz lapack.SchurComp, n
|
|||||||
panic(badIhi)
|
panic(badIhi)
|
||||||
case ldh < max(1, n):
|
case ldh < max(1, n):
|
||||||
panic(badLdH)
|
panic(badLdH)
|
||||||
case ldz < 1 || (wantz && ldz < max(1, n)):
|
case ldz < 1, wantz && ldz < n:
|
||||||
panic(badLdZ)
|
panic(badLdZ)
|
||||||
case lwork < max(1, n) && lwork != -1:
|
case lwork < max(1, n) && lwork != -1:
|
||||||
panic(badWork)
|
panic(badWork)
|
||||||
|
@@ -75,7 +75,7 @@ func (impl Implementation) Dlahqr(wantt, wantz bool, n, ilo, ihi int, h []float6
|
|||||||
switch {
|
switch {
|
||||||
case n < 0:
|
case n < 0:
|
||||||
panic(nLT0)
|
panic(nLT0)
|
||||||
case ilo < 0 || max(0, ihi) < ilo:
|
case ilo < 0, max(0, ihi) < ilo:
|
||||||
panic(badIlo)
|
panic(badIlo)
|
||||||
case ihi >= n:
|
case ihi >= n:
|
||||||
panic(badIhi)
|
panic(badIhi)
|
||||||
@@ -85,7 +85,7 @@ func (impl Implementation) Dlahqr(wantt, wantz bool, n, ilo, ihi int, h []float6
|
|||||||
panic("lapack: iloz out of range")
|
panic("lapack: iloz out of range")
|
||||||
case wantz && (ihiz < ihi || n <= ihiz):
|
case wantz && (ihiz < ihi || n <= ihiz):
|
||||||
panic("lapack: ihiz out of range")
|
panic("lapack: ihiz out of range")
|
||||||
case ldz < 1 || (wantz && ldz < max(1, n)):
|
case ldz < 1, wantz && ldz < n:
|
||||||
panic(badLdZ)
|
panic(badLdZ)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -135,7 +135,7 @@ func (impl Implementation) Dlaqr04(wantt, wantz bool, n, ilo, ihi int, h []float
|
|||||||
panic("lapack: invalid value of iloz")
|
panic("lapack: invalid value of iloz")
|
||||||
case wantz && (ihiz < ihi || n <= ihiz):
|
case wantz && (ihiz < ihi || n <= ihiz):
|
||||||
panic("lapack: invalid value of ihiz")
|
panic("lapack: invalid value of ihiz")
|
||||||
case ldz < 1 || (wantz && ldz < max(1, n)):
|
case ldz < 1, wantz && ldz < n:
|
||||||
panic(badLdZ)
|
panic(badLdZ)
|
||||||
case lwork < 1 && lwork != -1:
|
case lwork < 1 && lwork != -1:
|
||||||
panic(badWork)
|
panic(badWork)
|
||||||
|
@@ -5,7 +5,6 @@
|
|||||||
package gonum
|
package gonum
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"gonum.org/v1/gonum/blas"
|
"gonum.org/v1/gonum/blas"
|
||||||
@@ -88,7 +87,6 @@ func (impl Implementation) Dlaqr23(wantt, wantz bool, n, ktop, kbot, nw int, h [
|
|||||||
case kbot < min(ktop, n-1) || n <= kbot:
|
case kbot < min(ktop, n-1) || n <= kbot:
|
||||||
panic("lapack: invalid value of kbot")
|
panic("lapack: invalid value of kbot")
|
||||||
case nw < 0 || kbot-ktop+1+1 < nw:
|
case nw < 0 || kbot-ktop+1+1 < nw:
|
||||||
fmt.Println(nw, kbot, ktop)
|
|
||||||
panic("lapack: invalid value of nw")
|
panic("lapack: invalid value of nw")
|
||||||
case ldh < max(1, n):
|
case ldh < max(1, n):
|
||||||
panic(badLdH)
|
panic(badLdH)
|
||||||
@@ -96,7 +94,7 @@ func (impl Implementation) Dlaqr23(wantt, wantz bool, n, ktop, kbot, nw int, h [
|
|||||||
panic("lapack: invalid value of iloz")
|
panic("lapack: invalid value of iloz")
|
||||||
case wantz && (ihiz < kbot || n <= ihiz):
|
case wantz && (ihiz < kbot || n <= ihiz):
|
||||||
panic("lapack: invalid value of ihiz")
|
panic("lapack: invalid value of ihiz")
|
||||||
case ldz < 1 || (wantz && ldz < max(1, n)):
|
case ldz < 1, wantz && ldz < n:
|
||||||
panic(badLdZ)
|
panic(badLdZ)
|
||||||
case ldv < max(1, nw):
|
case ldv < max(1, nw):
|
||||||
panic(badLdV)
|
panic(badLdV)
|
||||||
|
@@ -91,7 +91,7 @@ func (impl Implementation) Dlaqr5(wantt, wantz bool, kacc22 int, n, ktop, kbot,
|
|||||||
panic("lapack: invalid value of ihiz")
|
panic("lapack: invalid value of ihiz")
|
||||||
case wantz && iloz < 0 || ihiz < iloz:
|
case wantz && iloz < 0 || ihiz < iloz:
|
||||||
panic("lapack: invalid value of iloz")
|
panic("lapack: invalid value of iloz")
|
||||||
case ldz < 1 || (wantz && ldz < max(1, n)):
|
case ldz < 1, wantz && ldz < n:
|
||||||
panic(badLdZ)
|
panic(badLdZ)
|
||||||
case wantz && len(z) < (n-1)*ldz+n:
|
case wantz && len(z) < (n-1)*ldz+n:
|
||||||
panic(shortZ)
|
panic(shortZ)
|
||||||
|
@@ -22,23 +22,34 @@ import (
|
|||||||
//
|
//
|
||||||
// Dorg2l is an internal routine. It is exported for testing purposes.
|
// Dorg2l is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorg2l(m, n, k int, a []float64, lda int, tau, work []float64) {
|
func (impl Implementation) Dorg2l(m, n, k int, a []float64, lda int, tau, work []float64) {
|
||||||
checkMatrix(m, n, a, lda)
|
switch {
|
||||||
if len(tau) < k {
|
case m < 0:
|
||||||
panic(badTau)
|
panic(mLT0)
|
||||||
}
|
case n < 0:
|
||||||
if len(work) < n {
|
panic(nLT0)
|
||||||
panic(badWork)
|
case n > m:
|
||||||
}
|
panic(nGTM)
|
||||||
if m < n {
|
case k < 0:
|
||||||
panic(mLTN)
|
panic(kLT0)
|
||||||
}
|
case k > n:
|
||||||
if k > n {
|
|
||||||
panic(kGTN)
|
panic(kGTN)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (m-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(tau) < k:
|
||||||
|
panic(badTau)
|
||||||
|
case len(work) < n:
|
||||||
|
panic(shortWork)
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize columns 0:n-k to columns of the unit matrix.
|
// Initialize columns 0:n-k to columns of the unit matrix.
|
||||||
for j := 0; j < n-k; j++ {
|
for j := 0; j < n-k; j++ {
|
||||||
for l := 0; l < m; l++ {
|
for l := 0; l < m; l++ {
|
||||||
|
@@ -17,26 +17,36 @@ import (
|
|||||||
//
|
//
|
||||||
// Dorg2r is an internal routine. It is exported for testing purposes.
|
// Dorg2r is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorg2r(m, n, k int, a []float64, lda int, tau []float64, work []float64) {
|
func (impl Implementation) Dorg2r(m, n, k int, a []float64, lda int, tau []float64, work []float64) {
|
||||||
checkMatrix(m, n, a, lda)
|
switch {
|
||||||
if len(tau) < k {
|
case m < 0:
|
||||||
panic(badTau)
|
panic(mLT0)
|
||||||
}
|
case n < 0:
|
||||||
if len(work) < n {
|
panic(nLT0)
|
||||||
panic(badWork)
|
case n > m:
|
||||||
}
|
panic(nGTM)
|
||||||
if k > n {
|
case k < 0:
|
||||||
|
panic(kLT0)
|
||||||
|
case k > n:
|
||||||
panic(kGTN)
|
panic(kGTN)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
if n > m {
|
|
||||||
panic(mLTN)
|
|
||||||
}
|
|
||||||
if len(work) < n {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (m-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(tau) < k:
|
||||||
|
panic(badTau)
|
||||||
|
case len(work) < n:
|
||||||
|
panic(shortWork)
|
||||||
|
}
|
||||||
|
|
||||||
bi := blas64.Implementation()
|
bi := blas64.Implementation()
|
||||||
|
|
||||||
// Initialize columns k+1:n to columns of the unit matrix.
|
// Initialize columns k+1:n to columns of the unit matrix.
|
||||||
for l := 0; l < m; l++ {
|
for l := 0; l < m; l++ {
|
||||||
for j := k; j < n; j++ {
|
for j := k; j < n; j++ {
|
||||||
|
@@ -20,38 +20,45 @@ import "gonum.org/v1/gonum/lapack"
|
|||||||
//
|
//
|
||||||
// Dorgbr is an internal routine. It is exported for testing purposes.
|
// Dorgbr is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorgbr(vect lapack.GenOrtho, m, n, k int, a []float64, lda int, tau, work []float64, lwork int) {
|
func (impl Implementation) Dorgbr(vect lapack.GenOrtho, m, n, k int, a []float64, lda int, tau, work []float64, lwork int) {
|
||||||
|
wantq := vect == lapack.GenerateQ
|
||||||
mn := min(m, n)
|
mn := min(m, n)
|
||||||
var wantq bool
|
switch {
|
||||||
switch vect {
|
case vect != lapack.GenerateQ && vect != lapack.GeneratePT:
|
||||||
case lapack.GenerateQ:
|
|
||||||
wantq = true
|
|
||||||
case lapack.GeneratePT:
|
|
||||||
default:
|
|
||||||
panic(badGenOrtho)
|
panic(badGenOrtho)
|
||||||
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case k < 0:
|
||||||
|
panic(kLT0)
|
||||||
|
case wantq && n > m:
|
||||||
|
panic(nGTM)
|
||||||
|
case wantq && n < min(m, k):
|
||||||
|
panic("lapack: n < min(m,k)")
|
||||||
|
case !wantq && m > n:
|
||||||
|
panic(mGTN)
|
||||||
|
case !wantq && m < min(n, k):
|
||||||
|
panic("lapack: m < min(n,k)")
|
||||||
|
case lda < max(1, n) && lwork != -1:
|
||||||
|
// Normally, we follow the reference and require the leading
|
||||||
|
// dimension to be always valid, even in case of workspace
|
||||||
|
// queries. However, if a caller provided a placeholder value
|
||||||
|
// for lda (and a) when doing a workspace query that didn't
|
||||||
|
// fulfill the condition here, it would cause a panic. This is
|
||||||
|
// exactly what Dgesvd does.
|
||||||
|
panic(badLdA)
|
||||||
|
case lwork < max(1, mn) && lwork != -1:
|
||||||
|
panic(badWork)
|
||||||
|
case len(work) < max(1, lwork):
|
||||||
|
panic(shortWork)
|
||||||
}
|
}
|
||||||
if wantq {
|
|
||||||
if m < n || n < min(m, k) || m < min(m, k) {
|
// Quick return if possible.
|
||||||
panic(badDims)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if n < m || m < min(n, k) || n < min(n, k) {
|
|
||||||
panic(badDims)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if wantq {
|
|
||||||
if m >= k {
|
|
||||||
checkMatrix(m, k, a, lda)
|
|
||||||
} else {
|
|
||||||
checkMatrix(m, m, a, lda)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if n >= k {
|
|
||||||
checkMatrix(k, n, a, lda)
|
|
||||||
} else {
|
|
||||||
checkMatrix(n, n, a, lda)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
work[0] = 1
|
work[0] = 1
|
||||||
|
if m == 0 || n == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if wantq {
|
if wantq {
|
||||||
if m >= k {
|
if m >= k {
|
||||||
impl.Dorgqr(m, n, k, a, lda, tau, work, -1)
|
impl.Dorgqr(m, n, k, a, lda, tau, work, -1)
|
||||||
@@ -71,16 +78,16 @@ func (impl Implementation) Dorgbr(vect lapack.GenOrtho, m, n, k int, a []float64
|
|||||||
work[0] = float64(lworkopt)
|
work[0] = float64(lworkopt)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(work) < lwork {
|
|
||||||
panic(badWork)
|
switch {
|
||||||
}
|
case len(a) < (m-1)*lda+n:
|
||||||
if lwork < mn {
|
panic(shortA)
|
||||||
panic(badWork)
|
case wantq && len(tau) < min(m, k):
|
||||||
}
|
panic(badTau)
|
||||||
if m == 0 || n == 0 {
|
case !wantq && len(tau) < min(n, k):
|
||||||
work[0] = 1
|
panic(badTau)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if wantq {
|
if wantq {
|
||||||
// Form Q, determined by a call to Dgebrd to reduce an m×k matrix.
|
// Form Q, determined by a call to Dgebrd to reduce an m×k matrix.
|
||||||
if m >= k {
|
if m >= k {
|
||||||
|
@@ -33,29 +33,37 @@ package gonum
|
|||||||
//
|
//
|
||||||
// Dorghr is an internal routine. It is exported for testing purposes.
|
// Dorghr is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorghr(n, ilo, ihi int, a []float64, lda int, tau, work []float64, lwork int) {
|
func (impl Implementation) Dorghr(n, ilo, ihi int, a []float64, lda int, tau, work []float64, lwork int) {
|
||||||
checkMatrix(n, n, a, lda)
|
|
||||||
nh := ihi - ilo
|
nh := ihi - ilo
|
||||||
switch {
|
switch {
|
||||||
case ilo < 0 || max(1, n) <= ilo:
|
case ilo < 0 || max(1, n) <= ilo:
|
||||||
panic(badIlo)
|
panic(badIlo)
|
||||||
case ihi < min(ilo, n-1) || n <= ihi:
|
case ihi < min(ilo, n-1) || n <= ihi:
|
||||||
panic(badIhi)
|
panic(badIhi)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
case lwork < max(1, nh) && lwork != -1:
|
case lwork < max(1, nh) && lwork != -1:
|
||||||
panic(badWork)
|
panic(badWork)
|
||||||
case len(work) < max(1, lwork):
|
case len(work) < max(1, lwork):
|
||||||
panic(shortWork)
|
panic(shortWork)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
|
if n == 0 {
|
||||||
|
work[0] = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
lwkopt := max(1, nh) * impl.Ilaenv(1, "DORGQR", " ", nh, nh, nh, -1)
|
lwkopt := max(1, nh) * impl.Ilaenv(1, "DORGQR", " ", nh, nh, nh, -1)
|
||||||
if lwork == -1 {
|
if lwork == -1 {
|
||||||
work[0] = float64(lwkopt)
|
work[0] = float64(lwkopt)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quick return if possible.
|
switch {
|
||||||
if n == 0 {
|
case len(a) < (n-1)*lda+n:
|
||||||
work[0] = 1
|
panic(shortA)
|
||||||
return
|
case len(tau) < n-1:
|
||||||
|
panic(badTau)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift the vectors which define the elementary reflectors one column
|
// Shift the vectors which define the elementary reflectors one column
|
||||||
|
@@ -17,26 +17,34 @@ import (
|
|||||||
//
|
//
|
||||||
// Dorgl2 is an internal routine. It is exported for testing purposes.
|
// Dorgl2 is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorgl2(m, n, k int, a []float64, lda int, tau, work []float64) {
|
func (impl Implementation) Dorgl2(m, n, k int, a []float64, lda int, tau, work []float64) {
|
||||||
checkMatrix(m, n, a, lda)
|
switch {
|
||||||
if len(tau) < k {
|
case m < 0:
|
||||||
panic(badTau)
|
panic(mLT0)
|
||||||
}
|
case n < m:
|
||||||
if k > m {
|
|
||||||
panic(kGTM)
|
|
||||||
}
|
|
||||||
if k > m {
|
|
||||||
panic(kGTM)
|
|
||||||
}
|
|
||||||
if m > n {
|
|
||||||
panic(nLTM)
|
panic(nLTM)
|
||||||
|
case k < 0:
|
||||||
|
panic(kLT0)
|
||||||
|
case k > m:
|
||||||
|
panic(kGTM)
|
||||||
|
case lda < max(1, m):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
if len(work) < m {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
if m == 0 {
|
if m == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (m-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(tau) < k:
|
||||||
|
panic(badTau)
|
||||||
|
case len(work) < m:
|
||||||
|
panic(shortWork)
|
||||||
|
}
|
||||||
|
|
||||||
bi := blas64.Implementation()
|
bi := blas64.Implementation()
|
||||||
|
|
||||||
if k < m {
|
if k < m {
|
||||||
for i := k; i < m; i++ {
|
for i := k; i < m; i++ {
|
||||||
for j := 0; j < n; j++ {
|
for j := 0; j < n; j++ {
|
||||||
|
@@ -27,12 +27,14 @@ import (
|
|||||||
// Dorglq is an internal routine. It is exported for testing purposes.
|
// Dorglq is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorglq(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) {
|
func (impl Implementation) Dorglq(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) {
|
||||||
switch {
|
switch {
|
||||||
case k < 0:
|
case m < 0:
|
||||||
panic(kLT0)
|
panic(mLT0)
|
||||||
case m < k:
|
|
||||||
panic(kGTM)
|
|
||||||
case n < m:
|
case n < m:
|
||||||
panic(nLTM)
|
panic(nLTM)
|
||||||
|
case k < 0:
|
||||||
|
panic(kLT0)
|
||||||
|
case k > m:
|
||||||
|
panic(kGTM)
|
||||||
case lda < max(1, n):
|
case lda < max(1, n):
|
||||||
panic(badLdA)
|
panic(badLdA)
|
||||||
case lwork < max(1, m) && lwork != -1:
|
case lwork < max(1, m) && lwork != -1:
|
||||||
@@ -52,10 +54,10 @@ func (impl Implementation) Dorglq(m, n, k int, a []float64, lda int, tau, work [
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(a) < (m-1)*lda+n {
|
switch {
|
||||||
panic("lapack: insufficient length of a")
|
case len(a) < (m-1)*lda+n:
|
||||||
}
|
panic(shortA)
|
||||||
if len(tau) < k {
|
case len(tau) < k:
|
||||||
panic(badTau)
|
panic(badTau)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,10 +33,12 @@ import (
|
|||||||
// Dorgql is an internal routine. It is exported for testing purposes.
|
// Dorgql is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorgql(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) {
|
func (impl Implementation) Dorgql(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) {
|
||||||
switch {
|
switch {
|
||||||
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
case n < 0:
|
case n < 0:
|
||||||
panic(nLT0)
|
panic(nLT0)
|
||||||
case m < n:
|
case n > m:
|
||||||
panic(mLTN)
|
panic(nGTM)
|
||||||
case k < 0:
|
case k < 0:
|
||||||
panic(kLT0)
|
panic(kLT0)
|
||||||
case k > n:
|
case k > n:
|
||||||
@@ -61,10 +63,10 @@ func (impl Implementation) Dorgql(m, n, k int, a []float64, lda int, tau, work [
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(a) < (m-1)*lda+n {
|
switch {
|
||||||
panic("lapack: insufficient length of a")
|
case len(a) < (m-1)*lda+n:
|
||||||
}
|
panic(shortA)
|
||||||
if len(tau) < k {
|
case len(tau) < k:
|
||||||
panic(badTau)
|
panic(badTau)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,12 +29,24 @@ import (
|
|||||||
// Dorgqr is an internal routine. It is exported for testing purposes.
|
// Dorgqr is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorgqr(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) {
|
func (impl Implementation) Dorgqr(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) {
|
||||||
switch {
|
switch {
|
||||||
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case n > m:
|
||||||
|
panic(nGTM)
|
||||||
case k < 0:
|
case k < 0:
|
||||||
panic(kLT0)
|
panic(kLT0)
|
||||||
case n < k:
|
case k > n:
|
||||||
panic(kGTN)
|
panic(kGTN)
|
||||||
case m < n:
|
case lda < max(1, n) && lwork != -1:
|
||||||
panic(mLTN)
|
// Normally, we follow the reference and require the leading
|
||||||
|
// dimension to be always valid, even in case of workspace
|
||||||
|
// queries. However, if a caller provided a placeholder value
|
||||||
|
// for lda (and a) when doing a workspace query that didn't
|
||||||
|
// fulfill the condition here, it would cause a panic. This is
|
||||||
|
// exactly what Dgesvd does.
|
||||||
|
panic(badLdA)
|
||||||
case lwork < max(1, n) && lwork != -1:
|
case lwork < max(1, n) && lwork != -1:
|
||||||
panic(badWork)
|
panic(badWork)
|
||||||
case len(work) < max(1, lwork):
|
case len(work) < max(1, lwork):
|
||||||
@@ -54,10 +66,8 @@ func (impl Implementation) Dorgqr(m, n, k int, a []float64, lda int, tau, work [
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case lda < max(1, n):
|
|
||||||
panic(badLdA)
|
|
||||||
case len(a) < (m-1)*lda+n:
|
case len(a) < (m-1)*lda+n:
|
||||||
panic("lapack: insuffcient length of a")
|
panic(shortA)
|
||||||
case len(tau) < k:
|
case len(tau) < k:
|
||||||
panic(badTau)
|
panic(badTau)
|
||||||
}
|
}
|
||||||
|
@@ -25,19 +25,17 @@ import "gonum.org/v1/gonum/blas"
|
|||||||
//
|
//
|
||||||
// Dorgtr is an internal routine. It is exported for testing purposes.
|
// Dorgtr is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorgtr(uplo blas.Uplo, n int, a []float64, lda int, tau, work []float64, lwork int) {
|
func (impl Implementation) Dorgtr(uplo blas.Uplo, n int, a []float64, lda int, tau, work []float64, lwork int) {
|
||||||
checkMatrix(n, n, a, lda)
|
switch {
|
||||||
if len(tau) < n-1 {
|
case uplo != blas.Upper && uplo != blas.Lower:
|
||||||
panic(badTau)
|
|
||||||
}
|
|
||||||
if len(work) < lwork {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
if lwork < n-1 && lwork != -1 {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
upper := uplo == blas.Upper
|
|
||||||
if !upper && uplo != blas.Lower {
|
|
||||||
panic(badUplo)
|
panic(badUplo)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
|
case lwork < max(1, n-1) && lwork != -1:
|
||||||
|
panic(badWork)
|
||||||
|
case len(work) < max(1, lwork):
|
||||||
|
panic(shortWork)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
@@ -46,7 +44,7 @@ func (impl Implementation) Dorgtr(uplo blas.Uplo, n int, a []float64, lda int, t
|
|||||||
}
|
}
|
||||||
|
|
||||||
var nb int
|
var nb int
|
||||||
if upper {
|
if uplo == blas.Upper {
|
||||||
nb = impl.Ilaenv(1, "DORGQL", " ", n-1, n-1, n-1, -1)
|
nb = impl.Ilaenv(1, "DORGQL", " ", n-1, n-1, n-1, -1)
|
||||||
} else {
|
} else {
|
||||||
nb = impl.Ilaenv(1, "DORGQR", " ", n-1, n-1, n-1, -1)
|
nb = impl.Ilaenv(1, "DORGQR", " ", n-1, n-1, n-1, -1)
|
||||||
@@ -57,7 +55,14 @@ func (impl Implementation) Dorgtr(uplo blas.Uplo, n int, a []float64, lda int, t
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if upper {
|
switch {
|
||||||
|
case len(a) < (n-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(tau) < n-1:
|
||||||
|
panic(badTau)
|
||||||
|
}
|
||||||
|
|
||||||
|
if uplo == blas.Upper {
|
||||||
// Q was determined by a call to Dsytrd with uplo == blas.Upper.
|
// Q was determined by a call to Dsytrd with uplo == blas.Upper.
|
||||||
// Shift the vectors which define the elementary reflectors one column
|
// Shift the vectors which define the elementary reflectors one column
|
||||||
// to the left, and set the last row and column of Q to those of the unit
|
// to the left, and set the last row and column of Q to those of the unit
|
||||||
|
@@ -23,37 +23,50 @@ import "gonum.org/v1/gonum/blas"
|
|||||||
//
|
//
|
||||||
// Dorm2r is an internal routine. It is exported for testing purposes.
|
// Dorm2r is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorm2r(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) {
|
func (impl Implementation) Dorm2r(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) {
|
||||||
if side != blas.Left && side != blas.Right {
|
left := side == blas.Left
|
||||||
|
switch {
|
||||||
|
case !left && side != blas.Right:
|
||||||
panic(badSide)
|
panic(badSide)
|
||||||
}
|
case trans != blas.Trans && trans != blas.NoTrans:
|
||||||
if trans != blas.Trans && trans != blas.NoTrans {
|
|
||||||
panic(badTrans)
|
panic(badTrans)
|
||||||
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case k < 0:
|
||||||
|
panic(kLT0)
|
||||||
|
case left && k > m:
|
||||||
|
panic(kGTM)
|
||||||
|
case !left && k > n:
|
||||||
|
panic(kGTN)
|
||||||
|
case lda < max(1, k):
|
||||||
|
panic(badLdA)
|
||||||
|
case ldc < max(1, n):
|
||||||
|
panic(badLdC)
|
||||||
}
|
}
|
||||||
|
|
||||||
left := side == blas.Left
|
// Quick return if possible.
|
||||||
notran := trans == blas.NoTrans
|
|
||||||
if left {
|
|
||||||
// Q is m x m
|
|
||||||
checkMatrix(m, k, a, lda)
|
|
||||||
if len(work) < n {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Q is n x n
|
|
||||||
checkMatrix(n, k, a, lda)
|
|
||||||
if len(work) < m {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkMatrix(m, n, c, ldc)
|
|
||||||
if m == 0 || n == 0 || k == 0 {
|
if m == 0 || n == 0 || k == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(tau) < k {
|
|
||||||
|
switch {
|
||||||
|
case left && len(a) < (m-1)*lda+k:
|
||||||
|
panic(shortA)
|
||||||
|
case !left && len(a) < (n-1)*lda+k:
|
||||||
|
panic(shortA)
|
||||||
|
case len(c) < (m-1)*ldc+n:
|
||||||
|
panic(shortC)
|
||||||
|
case len(tau) < k:
|
||||||
panic(badTau)
|
panic(badTau)
|
||||||
|
case left && len(work) < n:
|
||||||
|
panic(shortWork)
|
||||||
|
case !left && len(work) < m:
|
||||||
|
panic(badWork)
|
||||||
}
|
}
|
||||||
|
|
||||||
if left {
|
if left {
|
||||||
if notran {
|
if trans == blas.NoTrans {
|
||||||
for i := k - 1; i >= 0; i-- {
|
for i := k - 1; i >= 0; i-- {
|
||||||
aii := a[i*lda+i]
|
aii := a[i*lda+i]
|
||||||
a[i*lda+i] = 1
|
a[i*lda+i] = 1
|
||||||
@@ -70,7 +83,7 @@ func (impl Implementation) Dorm2r(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if notran {
|
if trans == blas.NoTrans {
|
||||||
for i := 0; i < k; i++ {
|
for i := 0; i < k; i++ {
|
||||||
aii := a[i*lda+i]
|
aii := a[i*lda+i]
|
||||||
a[i*lda+i] = 1
|
a[i*lda+i] = 1
|
||||||
|
@@ -45,40 +45,43 @@ import (
|
|||||||
//
|
//
|
||||||
// Dormbr is an internal routine. It is exported for testing purposes.
|
// Dormbr is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dormbr(vect lapack.ApplyOrtho, side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) {
|
func (impl Implementation) Dormbr(vect lapack.ApplyOrtho, side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) {
|
||||||
if side != blas.Left && side != blas.Right {
|
|
||||||
panic(badSide)
|
|
||||||
}
|
|
||||||
if trans != blas.NoTrans && trans != blas.Trans {
|
|
||||||
panic(badTrans)
|
|
||||||
}
|
|
||||||
if vect != lapack.ApplyP && vect != lapack.ApplyQ {
|
|
||||||
panic(badApplyOrtho)
|
|
||||||
}
|
|
||||||
nq := n
|
nq := n
|
||||||
nw := m
|
nw := m
|
||||||
if side == blas.Left {
|
if side == blas.Left {
|
||||||
nq = m
|
nq = m
|
||||||
nw = n
|
nw = n
|
||||||
}
|
}
|
||||||
if vect == lapack.ApplyQ {
|
applyQ := vect == lapack.ApplyQ
|
||||||
checkMatrix(nq, min(nq, k), a, lda)
|
switch {
|
||||||
} else {
|
case !applyQ && vect != lapack.ApplyP:
|
||||||
checkMatrix(min(nq, k), nq, a, lda)
|
panic(badApplyOrtho)
|
||||||
}
|
case side != blas.Left && side != blas.Right:
|
||||||
if len(tau) < min(nq, k) {
|
panic(badSide)
|
||||||
panic(badTau)
|
case trans != blas.NoTrans && trans != blas.Trans:
|
||||||
}
|
panic(badTrans)
|
||||||
checkMatrix(m, n, c, ldc)
|
case m < 0:
|
||||||
if len(work) < lwork {
|
panic(mLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case k < 0:
|
||||||
|
panic(kLT0)
|
||||||
|
case applyQ && lda < max(1, min(nq, k)):
|
||||||
|
panic(badLdA)
|
||||||
|
case !applyQ && lda < max(1, nq):
|
||||||
|
panic(badLdA)
|
||||||
|
case ldc < max(1, n):
|
||||||
|
panic(badLdC)
|
||||||
|
case lwork < max(1, nw) && lwork != -1:
|
||||||
|
panic(badWork)
|
||||||
|
case len(work) < max(1, lwork):
|
||||||
panic(shortWork)
|
panic(shortWork)
|
||||||
}
|
}
|
||||||
if lwork < max(1, nw) && lwork != -1 {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
|
|
||||||
applyQ := vect == lapack.ApplyQ
|
// Quick return if possible.
|
||||||
left := side == blas.Left
|
if m == 0 || n == 0 {
|
||||||
var nb int
|
work[0] = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// The current implementation does not use opts, but a future change may
|
// The current implementation does not use opts, but a future change may
|
||||||
// use these options so construct them.
|
// use these options so construct them.
|
||||||
@@ -93,14 +96,15 @@ func (impl Implementation) Dormbr(vect lapack.ApplyOrtho, side blas.Side, trans
|
|||||||
} else {
|
} else {
|
||||||
opts += "N"
|
opts += "N"
|
||||||
}
|
}
|
||||||
|
var nb int
|
||||||
if applyQ {
|
if applyQ {
|
||||||
if left {
|
if side == blas.Left {
|
||||||
nb = impl.Ilaenv(1, "DORMQR", opts, m-1, n, m-1, -1)
|
nb = impl.Ilaenv(1, "DORMQR", opts, m-1, n, m-1, -1)
|
||||||
} else {
|
} else {
|
||||||
nb = impl.Ilaenv(1, "DORMQR", opts, m, n-1, n-1, -1)
|
nb = impl.Ilaenv(1, "DORMQR", opts, m, n-1, n-1, -1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if left {
|
if side == blas.Left {
|
||||||
nb = impl.Ilaenv(1, "DORMLQ", opts, m-1, n, m-1, -1)
|
nb = impl.Ilaenv(1, "DORMLQ", opts, m-1, n, m-1, -1)
|
||||||
} else {
|
} else {
|
||||||
nb = impl.Ilaenv(1, "DORMLQ", opts, m, n-1, n-1, -1)
|
nb = impl.Ilaenv(1, "DORMLQ", opts, m, n-1, n-1, -1)
|
||||||
@@ -109,7 +113,21 @@ func (impl Implementation) Dormbr(vect lapack.ApplyOrtho, side blas.Side, trans
|
|||||||
lworkopt := max(1, nw) * nb
|
lworkopt := max(1, nw) * nb
|
||||||
if lwork == -1 {
|
if lwork == -1 {
|
||||||
work[0] = float64(lworkopt)
|
work[0] = float64(lworkopt)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
minnqk := min(nq, k)
|
||||||
|
switch {
|
||||||
|
case applyQ && len(a) < (nq-1)*lda+minnqk:
|
||||||
|
panic(shortA)
|
||||||
|
case !applyQ && len(a) < (minnqk-1)*lda+nq:
|
||||||
|
panic(shortA)
|
||||||
|
case len(tau) < minnqk:
|
||||||
|
panic(badTau)
|
||||||
|
case len(c) < (m-1)*ldc+n:
|
||||||
|
panic(shortC)
|
||||||
|
}
|
||||||
|
|
||||||
if applyQ {
|
if applyQ {
|
||||||
// Change the operation to get Q depending on the size of the initial
|
// Change the operation to get Q depending on the size of the initial
|
||||||
// matrix to Dgebrd. The size matters due to the storage location of
|
// matrix to Dgebrd. The size matters due to the storage location of
|
||||||
@@ -121,7 +139,7 @@ func (impl Implementation) Dormbr(vect lapack.ApplyOrtho, side blas.Side, trans
|
|||||||
ni := n - 1
|
ni := n - 1
|
||||||
i1 := 0
|
i1 := 0
|
||||||
i2 := 1
|
i2 := 1
|
||||||
if left {
|
if side == blas.Left {
|
||||||
mi = m - 1
|
mi = m - 1
|
||||||
ni = n
|
ni = n
|
||||||
i1 = 1
|
i1 = 1
|
||||||
@@ -132,10 +150,12 @@ func (impl Implementation) Dormbr(vect lapack.ApplyOrtho, side blas.Side, trans
|
|||||||
work[0] = float64(lworkopt)
|
work[0] = float64(lworkopt)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
transt := blas.Trans
|
transt := blas.Trans
|
||||||
if trans == blas.Trans {
|
if trans == blas.Trans {
|
||||||
transt = blas.NoTrans
|
transt = blas.NoTrans
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the operation to get P depending on the size of the initial
|
// Change the operation to get P depending on the size of the initial
|
||||||
// matrix to Dgebrd. The size matters due to the storage location of
|
// matrix to Dgebrd. The size matters due to the storage location of
|
||||||
// the off-diagonal elements.
|
// the off-diagonal elements.
|
||||||
@@ -146,7 +166,7 @@ func (impl Implementation) Dormbr(vect lapack.ApplyOrtho, side blas.Side, trans
|
|||||||
ni := n - 1
|
ni := n - 1
|
||||||
i1 := 0
|
i1 := 0
|
||||||
i2 := 1
|
i2 := 1
|
||||||
if left {
|
if side == blas.Left {
|
||||||
mi = m - 1
|
mi = m - 1
|
||||||
ni = n
|
ni = n
|
||||||
i1 = 1
|
i1 = 1
|
||||||
|
@@ -50,39 +50,37 @@ import "gonum.org/v1/gonum/blas"
|
|||||||
//
|
//
|
||||||
// Dormhr is an internal routine. It is exported for testing purposes.
|
// Dormhr is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dormhr(side blas.Side, trans blas.Transpose, m, n, ilo, ihi int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) {
|
func (impl Implementation) Dormhr(side blas.Side, trans blas.Transpose, m, n, ilo, ihi int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) {
|
||||||
var (
|
nq := n // The order of Q.
|
||||||
nq int // The order of Q.
|
nw := m // The minimum length of work.
|
||||||
nw int // The minimum length of work.
|
if side == blas.Left {
|
||||||
)
|
|
||||||
switch side {
|
|
||||||
case blas.Left:
|
|
||||||
nq = m
|
nq = m
|
||||||
nw = n
|
nw = n
|
||||||
case blas.Right:
|
|
||||||
nq = n
|
|
||||||
nw = m
|
|
||||||
default:
|
|
||||||
panic(badSide)
|
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
|
case side != blas.Left && side != blas.Right:
|
||||||
|
panic(badSide)
|
||||||
case trans != blas.NoTrans && trans != blas.Trans:
|
case trans != blas.NoTrans && trans != blas.Trans:
|
||||||
panic(badTrans)
|
panic(badTrans)
|
||||||
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
case ilo < 0 || max(1, nq) <= ilo:
|
case ilo < 0 || max(1, nq) <= ilo:
|
||||||
panic(badIlo)
|
panic(badIlo)
|
||||||
case ihi < min(ilo, nq-1) || nq <= ihi:
|
case ihi < min(ilo, nq-1) || nq <= ihi:
|
||||||
panic(badIhi)
|
panic(badIhi)
|
||||||
|
case lda < max(1, nq):
|
||||||
|
panic(badLdA)
|
||||||
case lwork < max(1, nw) && lwork != -1:
|
case lwork < max(1, nw) && lwork != -1:
|
||||||
panic(badWork)
|
panic(badWork)
|
||||||
case len(work) < max(1, lwork):
|
case len(work) < max(1, lwork):
|
||||||
panic(shortWork)
|
panic(shortWork)
|
||||||
}
|
}
|
||||||
if lwork != -1 {
|
|
||||||
checkMatrix(m, n, c, ldc)
|
|
||||||
checkMatrix(nq, nq, a, lda)
|
|
||||||
if len(tau) != nq-1 && nq > 0 {
|
|
||||||
panic(badTau)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
|
if m == 0 || n == 0 {
|
||||||
|
work[0] = 1
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nh := ihi - ilo
|
nh := ihi - ilo
|
||||||
@@ -106,10 +104,20 @@ func (impl Implementation) Dormhr(side blas.Side, trans blas.Transpose, m, n, il
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if m == 0 || n == 0 || nh == 0 {
|
if nh == 0 {
|
||||||
work[0] = 1
|
work[0] = 1
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (nq-1)*lda+nq:
|
||||||
|
panic(shortA)
|
||||||
|
case len(c) < (m-1)*ldc+n:
|
||||||
|
panic(shortC)
|
||||||
|
case len(tau) != nq-1:
|
||||||
|
panic(badTau)
|
||||||
|
}
|
||||||
|
|
||||||
if side == blas.Left {
|
if side == blas.Left {
|
||||||
impl.Dormqr(side, trans, nh, n, nh, a[(ilo+1)*lda+ilo:], lda,
|
impl.Dormqr(side, trans, nh, n, nh, a[(ilo+1)*lda+ilo:], lda,
|
||||||
tau[ilo:ihi], c[(ilo+1)*ldc:], ldc, work, lwork)
|
tau[ilo:ihi], c[(ilo+1)*ldc:], ldc, work, lwork)
|
||||||
|
@@ -23,32 +23,51 @@ import "gonum.org/v1/gonum/blas"
|
|||||||
//
|
//
|
||||||
// Dorml2 is an internal routine. It is exported for testing purposes.
|
// Dorml2 is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dorml2(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) {
|
func (impl Implementation) Dorml2(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) {
|
||||||
if side != blas.Left && side != blas.Right {
|
left := side == blas.Left
|
||||||
|
switch {
|
||||||
|
case !left && side != blas.Right:
|
||||||
panic(badSide)
|
panic(badSide)
|
||||||
}
|
case trans != blas.Trans && trans != blas.NoTrans:
|
||||||
if trans != blas.Trans && trans != blas.NoTrans {
|
|
||||||
panic(badTrans)
|
panic(badTrans)
|
||||||
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case k < 0:
|
||||||
|
panic(kLT0)
|
||||||
|
case left && k > m:
|
||||||
|
panic(kGTM)
|
||||||
|
case !left && k > n:
|
||||||
|
panic(kGTN)
|
||||||
|
case left && lda < max(1, m):
|
||||||
|
panic(badLdA)
|
||||||
|
case !left && lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
|
|
||||||
left := side == blas.Left
|
// Quick return if possible.
|
||||||
notran := trans == blas.NoTrans
|
|
||||||
if left {
|
|
||||||
checkMatrix(k, m, a, lda)
|
|
||||||
if len(work) < n {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
checkMatrix(k, n, a, lda)
|
|
||||||
if len(work) < m {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkMatrix(m, n, c, ldc)
|
|
||||||
if m == 0 || n == 0 || k == 0 {
|
if m == 0 || n == 0 || k == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case left && notran:
|
case left && len(a) < (k-1)*lda+m:
|
||||||
|
panic(shortA)
|
||||||
|
case !left && len(a) < (k-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(tau) < k:
|
||||||
|
panic(badTau)
|
||||||
|
case len(c) < (m-1)*ldc+n:
|
||||||
|
panic(shortC)
|
||||||
|
case left && len(work) < n:
|
||||||
|
panic(shortWork)
|
||||||
|
case !left && len(work) < m:
|
||||||
|
panic(shortWork)
|
||||||
|
}
|
||||||
|
|
||||||
|
notrans := trans == blas.NoTrans
|
||||||
|
switch {
|
||||||
|
case left && notrans:
|
||||||
for i := 0; i < k; i++ {
|
for i := 0; i < k; i++ {
|
||||||
aii := a[i*lda+i]
|
aii := a[i*lda+i]
|
||||||
a[i*lda+i] = 1
|
a[i*lda+i] = 1
|
||||||
@@ -56,7 +75,7 @@ func (impl Implementation) Dorml2(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
a[i*lda+i] = aii
|
a[i*lda+i] = aii
|
||||||
}
|
}
|
||||||
|
|
||||||
case left && !notran:
|
case left && !notrans:
|
||||||
for i := k - 1; i >= 0; i-- {
|
for i := k - 1; i >= 0; i-- {
|
||||||
aii := a[i*lda+i]
|
aii := a[i*lda+i]
|
||||||
a[i*lda+i] = 1
|
a[i*lda+i] = 1
|
||||||
@@ -64,7 +83,7 @@ func (impl Implementation) Dorml2(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
a[i*lda+i] = aii
|
a[i*lda+i] = aii
|
||||||
}
|
}
|
||||||
|
|
||||||
case !left && notran:
|
case !left && notrans:
|
||||||
for i := k - 1; i >= 0; i-- {
|
for i := k - 1; i >= 0; i-- {
|
||||||
aii := a[i*lda+i]
|
aii := a[i*lda+i]
|
||||||
a[i*lda+i] = 1
|
a[i*lda+i] = 1
|
||||||
@@ -72,7 +91,7 @@ func (impl Implementation) Dorml2(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
a[i*lda+i] = aii
|
a[i*lda+i] = aii
|
||||||
}
|
}
|
||||||
|
|
||||||
case !left && !notran:
|
case !left && !notrans:
|
||||||
for i := 0; i < k; i++ {
|
for i := 0; i < k; i++ {
|
||||||
aii := a[i*lda+i]
|
aii := a[i*lda+i]
|
||||||
a[i*lda+i] = 1
|
a[i*lda+i] = 1
|
||||||
|
@@ -28,33 +28,37 @@ import (
|
|||||||
// tau contains the Householder scales and must have length at least k, and
|
// tau contains the Householder scales and must have length at least k, and
|
||||||
// this function will panic otherwise.
|
// this function will panic otherwise.
|
||||||
func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) {
|
func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) {
|
||||||
if side != blas.Left && side != blas.Right {
|
|
||||||
panic(badSide)
|
|
||||||
}
|
|
||||||
if trans != blas.Trans && trans != blas.NoTrans {
|
|
||||||
panic(badTrans)
|
|
||||||
}
|
|
||||||
left := side == blas.Left
|
left := side == blas.Left
|
||||||
if left {
|
|
||||||
checkMatrix(k, m, a, lda)
|
|
||||||
} else {
|
|
||||||
checkMatrix(k, n, a, lda)
|
|
||||||
}
|
|
||||||
checkMatrix(m, n, c, ldc)
|
|
||||||
if len(tau) < k {
|
|
||||||
panic(badTau)
|
|
||||||
}
|
|
||||||
if len(work) < lwork {
|
|
||||||
panic(shortWork)
|
|
||||||
}
|
|
||||||
nw := m
|
nw := m
|
||||||
if left {
|
if left {
|
||||||
nw = n
|
nw = n
|
||||||
}
|
}
|
||||||
if lwork < max(1, nw) && lwork != -1 {
|
switch {
|
||||||
|
case !left && side != blas.Right:
|
||||||
|
panic(badSide)
|
||||||
|
case trans != blas.Trans && trans != blas.NoTrans:
|
||||||
|
panic(badTrans)
|
||||||
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case k < 0:
|
||||||
|
panic(kLT0)
|
||||||
|
case left && k > m:
|
||||||
|
panic(kGTM)
|
||||||
|
case !left && k > n:
|
||||||
|
panic(kGTN)
|
||||||
|
case left && lda < max(1, m):
|
||||||
|
panic(badLdA)
|
||||||
|
case !left && lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
|
case lwork < max(1, nw) && lwork != -1:
|
||||||
panic(badWork)
|
panic(badWork)
|
||||||
|
case len(work) < max(1, lwork):
|
||||||
|
panic(shortWork)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
if m == 0 || n == 0 || k == 0 {
|
if m == 0 || n == 0 || k == 0 {
|
||||||
work[0] = 1
|
work[0] = 1
|
||||||
return
|
return
|
||||||
@@ -73,6 +77,17 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case left && len(a) < (k-1)*lda+m:
|
||||||
|
panic(shortA)
|
||||||
|
case !left && len(a) < (k-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(tau) < k:
|
||||||
|
panic(badTau)
|
||||||
|
case len(c) < (m-1)*ldc+n:
|
||||||
|
panic(shortC)
|
||||||
|
}
|
||||||
|
|
||||||
nbmin := 2
|
nbmin := 2
|
||||||
if 1 < nb && nb < k {
|
if 1 < nb && nb < k {
|
||||||
iws := nw*nb + tsize
|
iws := nw*nb + tsize
|
||||||
@@ -92,14 +107,14 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
wrk := work[tsize:]
|
wrk := work[tsize:]
|
||||||
ldwrk := nb
|
ldwrk := nb
|
||||||
|
|
||||||
notran := trans == blas.NoTrans
|
notrans := trans == blas.NoTrans
|
||||||
transt := blas.NoTrans
|
transt := blas.NoTrans
|
||||||
if notran {
|
if notrans {
|
||||||
transt = blas.Trans
|
transt = blas.Trans
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case left && notran:
|
case left && notrans:
|
||||||
for i := 0; i < k; i += nb {
|
for i := 0; i < k; i += nb {
|
||||||
ib := min(nb, k-i)
|
ib := min(nb, k-i)
|
||||||
impl.Dlarft(lapack.Forward, lapack.RowWise, m-i, ib,
|
impl.Dlarft(lapack.Forward, lapack.RowWise, m-i, ib,
|
||||||
@@ -113,7 +128,7 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
wrk, ldwrk)
|
wrk, ldwrk)
|
||||||
}
|
}
|
||||||
|
|
||||||
case left && !notran:
|
case left && !notrans:
|
||||||
for i := ((k - 1) / nb) * nb; i >= 0; i -= nb {
|
for i := ((k - 1) / nb) * nb; i >= 0; i -= nb {
|
||||||
ib := min(nb, k-i)
|
ib := min(nb, k-i)
|
||||||
impl.Dlarft(lapack.Forward, lapack.RowWise, m-i, ib,
|
impl.Dlarft(lapack.Forward, lapack.RowWise, m-i, ib,
|
||||||
@@ -127,7 +142,7 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
wrk, ldwrk)
|
wrk, ldwrk)
|
||||||
}
|
}
|
||||||
|
|
||||||
case !left && notran:
|
case !left && notrans:
|
||||||
for i := ((k - 1) / nb) * nb; i >= 0; i -= nb {
|
for i := ((k - 1) / nb) * nb; i >= 0; i -= nb {
|
||||||
ib := min(nb, k-i)
|
ib := min(nb, k-i)
|
||||||
impl.Dlarft(lapack.Forward, lapack.RowWise, n-i, ib,
|
impl.Dlarft(lapack.Forward, lapack.RowWise, n-i, ib,
|
||||||
@@ -141,7 +156,7 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
wrk, ldwrk)
|
wrk, ldwrk)
|
||||||
}
|
}
|
||||||
|
|
||||||
case !left && !notran:
|
case !left && !notrans:
|
||||||
for i := 0; i < k; i += nb {
|
for i := 0; i < k; i += nb {
|
||||||
ib := min(nb, k-i)
|
ib := min(nb, k-i)
|
||||||
impl.Dlarft(lapack.Forward, lapack.RowWise, n-i, ib,
|
impl.Dlarft(lapack.Forward, lapack.RowWise, n-i, ib,
|
||||||
|
@@ -37,37 +37,39 @@ import (
|
|||||||
// If lwork is -1, instead of performing Dormqr, the optimal workspace size will
|
// If lwork is -1, instead of performing Dormqr, the optimal workspace size will
|
||||||
// be stored into work[0].
|
// be stored into work[0].
|
||||||
func (impl Implementation) Dormqr(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) {
|
func (impl Implementation) Dormqr(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) {
|
||||||
var nq, nw int
|
left := side == blas.Left
|
||||||
switch side {
|
nq := n
|
||||||
default:
|
nw := m
|
||||||
panic(badSide)
|
if left {
|
||||||
case blas.Left:
|
|
||||||
nq = m
|
nq = m
|
||||||
nw = n
|
nw = n
|
||||||
case blas.Right:
|
|
||||||
nq = n
|
|
||||||
nw = m
|
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
|
case !left && side != blas.Right:
|
||||||
|
panic(badSide)
|
||||||
case trans != blas.NoTrans && trans != blas.Trans:
|
case trans != blas.NoTrans && trans != blas.Trans:
|
||||||
panic(badTrans)
|
panic(badTrans)
|
||||||
case m < 0 || n < 0:
|
case m < 0:
|
||||||
panic(negDimension)
|
panic(mLT0)
|
||||||
case k < 0 || nq < k:
|
case n < 0:
|
||||||
panic("lapack: invalid value of k")
|
panic(nLT0)
|
||||||
case len(work) < lwork:
|
case k < 0:
|
||||||
panic(shortWork)
|
panic(kLT0)
|
||||||
|
case left && k > m:
|
||||||
|
panic(kGTM)
|
||||||
|
case !left && k > n:
|
||||||
|
panic(kGTN)
|
||||||
|
case lda < max(1, k):
|
||||||
|
panic(badLdA)
|
||||||
|
case ldc < max(1, n):
|
||||||
|
panic(badLdC)
|
||||||
case lwork < max(1, nw) && lwork != -1:
|
case lwork < max(1, nw) && lwork != -1:
|
||||||
panic(badWork)
|
panic(badWork)
|
||||||
}
|
case len(work) < max(1, lwork):
|
||||||
if lwork != -1 {
|
panic(shortWork)
|
||||||
checkMatrix(nq, k, a, lda)
|
|
||||||
checkMatrix(m, n, c, ldc)
|
|
||||||
if len(tau) != k {
|
|
||||||
panic(badTau)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
if m == 0 || n == 0 || k == 0 {
|
if m == 0 || n == 0 || k == 0 {
|
||||||
work[0] = 1
|
work[0] = 1
|
||||||
return
|
return
|
||||||
@@ -86,6 +88,15 @@ func (impl Implementation) Dormqr(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (nq-1)*lda+k:
|
||||||
|
panic(shortA)
|
||||||
|
case len(tau) != k:
|
||||||
|
panic(badTau)
|
||||||
|
case len(c) < (m-1)*ldc+n:
|
||||||
|
panic(shortC)
|
||||||
|
}
|
||||||
|
|
||||||
nbmin := 2
|
nbmin := 2
|
||||||
if 1 < nb && nb < k {
|
if 1 < nb && nb < k {
|
||||||
if lwork < nw*nb+tsize {
|
if lwork < nw*nb+tsize {
|
||||||
@@ -102,12 +113,11 @@ func (impl Implementation) Dormqr(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ldwork = nb
|
ldwork = nb
|
||||||
left = side == blas.Left
|
notrans = trans == blas.NoTrans
|
||||||
notran = trans == blas.NoTrans
|
|
||||||
)
|
)
|
||||||
switch {
|
switch {
|
||||||
case left && notran:
|
case left && notrans:
|
||||||
for i := ((k - 1) / nb) * nb; i >= 0; i -= nb {
|
for i := ((k - 1) / nb) * nb; i >= 0; i -= nb {
|
||||||
ib := min(nb, k-i)
|
ib := min(nb, k-i)
|
||||||
impl.Dlarft(lapack.Forward, lapack.ColumnWise, m-i, ib,
|
impl.Dlarft(lapack.Forward, lapack.ColumnWise, m-i, ib,
|
||||||
@@ -121,7 +131,7 @@ func (impl Implementation) Dormqr(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
work[tsize:], ldwork)
|
work[tsize:], ldwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
case left && !notran:
|
case left && !notrans:
|
||||||
for i := 0; i < k; i += nb {
|
for i := 0; i < k; i += nb {
|
||||||
ib := min(nb, k-i)
|
ib := min(nb, k-i)
|
||||||
impl.Dlarft(lapack.Forward, lapack.ColumnWise, m-i, ib,
|
impl.Dlarft(lapack.Forward, lapack.ColumnWise, m-i, ib,
|
||||||
@@ -135,7 +145,7 @@ func (impl Implementation) Dormqr(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
work[tsize:], ldwork)
|
work[tsize:], ldwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
case !left && notran:
|
case !left && notrans:
|
||||||
for i := 0; i < k; i += nb {
|
for i := 0; i < k; i += nb {
|
||||||
ib := min(nb, k-i)
|
ib := min(nb, k-i)
|
||||||
impl.Dlarft(lapack.Forward, lapack.ColumnWise, n-i, ib,
|
impl.Dlarft(lapack.Forward, lapack.ColumnWise, n-i, ib,
|
||||||
@@ -149,7 +159,7 @@ func (impl Implementation) Dormqr(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
work[tsize:], ldwork)
|
work[tsize:], ldwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
case !left && !notran:
|
case !left && !notrans:
|
||||||
for i := ((k - 1) / nb) * nb; i >= 0; i -= nb {
|
for i := ((k - 1) / nb) * nb; i >= 0; i -= nb {
|
||||||
ib := min(nb, k-i)
|
ib := min(nb, k-i)
|
||||||
impl.Dlarft(lapack.Forward, lapack.ColumnWise, n-i, ib,
|
impl.Dlarft(lapack.Forward, lapack.ColumnWise, n-i, ib,
|
||||||
|
@@ -23,42 +23,52 @@ import "gonum.org/v1/gonum/blas"
|
|||||||
//
|
//
|
||||||
// Dormr2 is an internal routine. It is exported for testing purposes.
|
// Dormr2 is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dormr2(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) {
|
func (impl Implementation) Dormr2(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) {
|
||||||
if side != blas.Left && side != blas.Right {
|
|
||||||
panic(badSide)
|
|
||||||
}
|
|
||||||
if trans != blas.Trans && trans != blas.NoTrans {
|
|
||||||
panic(badTrans)
|
|
||||||
}
|
|
||||||
|
|
||||||
left := side == blas.Left
|
left := side == blas.Left
|
||||||
notran := trans == blas.NoTrans
|
nq := n
|
||||||
|
nw := m
|
||||||
if left {
|
if left {
|
||||||
if k > m {
|
nq = m
|
||||||
panic(kGTM)
|
nw = n
|
||||||
}
|
|
||||||
checkMatrix(k, m, a, lda)
|
|
||||||
if len(work) < n {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if k > n {
|
|
||||||
panic(kGTN)
|
|
||||||
}
|
|
||||||
checkMatrix(k, n, a, lda)
|
|
||||||
if len(work) < m {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if len(tau) < k {
|
switch {
|
||||||
panic(badTau)
|
case !left && side != blas.Right:
|
||||||
|
panic(badSide)
|
||||||
|
case trans != blas.NoTrans && trans != blas.Trans:
|
||||||
|
panic(badTrans)
|
||||||
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case k < 0:
|
||||||
|
panic(kLT0)
|
||||||
|
case left && k > m:
|
||||||
|
panic(kGTM)
|
||||||
|
case !left && k > n:
|
||||||
|
panic(kGTN)
|
||||||
|
case lda < max(1, nq):
|
||||||
|
panic(badLdA)
|
||||||
|
case ldc < max(1, n):
|
||||||
|
panic(badLdC)
|
||||||
}
|
}
|
||||||
checkMatrix(m, n, c, ldc)
|
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
if m == 0 || n == 0 || k == 0 {
|
if m == 0 || n == 0 || k == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (k-1)*lda+nq:
|
||||||
|
panic(shortA)
|
||||||
|
case len(tau) < k:
|
||||||
|
panic(badTau)
|
||||||
|
case len(c) < (m-1)*ldc+n:
|
||||||
|
panic(shortC)
|
||||||
|
case len(work) < nw:
|
||||||
|
panic(shortWork)
|
||||||
|
}
|
||||||
|
|
||||||
if left {
|
if left {
|
||||||
if notran {
|
if trans == blas.NoTrans {
|
||||||
for i := k - 1; i >= 0; i-- {
|
for i := k - 1; i >= 0; i-- {
|
||||||
aii := a[i*lda+(m-k+i)]
|
aii := a[i*lda+(m-k+i)]
|
||||||
a[i*lda+(m-k+i)] = 1
|
a[i*lda+(m-k+i)] = 1
|
||||||
@@ -75,7 +85,7 @@ func (impl Implementation) Dormr2(side blas.Side, trans blas.Transpose, m, n, k
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if notran {
|
if trans == blas.NoTrans {
|
||||||
for i := 0; i < k; i++ {
|
for i := 0; i < k; i++ {
|
||||||
aii := a[i*lda+(n-k+i)]
|
aii := a[i*lda+(n-k+i)]
|
||||||
a[i*lda+(n-k+i)] = 1
|
a[i*lda+(n-k+i)] = 1
|
||||||
|
@@ -48,14 +48,27 @@ import (
|
|||||||
//
|
//
|
||||||
// Dpbtf2 is an internal routine, exported for testing purposes.
|
// Dpbtf2 is an internal routine, exported for testing purposes.
|
||||||
func (Implementation) Dpbtf2(ul blas.Uplo, n, kd int, ab []float64, ldab int) (ok bool) {
|
func (Implementation) Dpbtf2(ul blas.Uplo, n, kd int, ab []float64, ldab int) (ok bool) {
|
||||||
if ul != blas.Upper && ul != blas.Lower {
|
switch {
|
||||||
|
case ul != blas.Upper && ul != blas.Lower:
|
||||||
panic(badUplo)
|
panic(badUplo)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case kd < 0:
|
||||||
|
panic(kdLT0)
|
||||||
|
case ldab < kd+1:
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
checkSymBanded(ab, n, kd, ldab)
|
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(ab) < (n-1)*ldab+kd {
|
||||||
|
panic(shortAB)
|
||||||
|
}
|
||||||
|
|
||||||
bi := blas64.Implementation()
|
bi := blas64.Implementation()
|
||||||
|
|
||||||
kld := max(1, ldab-1)
|
kld := max(1, ldab-1)
|
||||||
if ul == blas.Upper {
|
if ul == blas.Upper {
|
||||||
for j := 0; j < n; j++ {
|
for j := 0; j < n; j++ {
|
||||||
|
@@ -21,41 +21,55 @@ import (
|
|||||||
//
|
//
|
||||||
// iwork is a temporary data slice of length at least n and Dpocon will panic otherwise.
|
// iwork is a temporary data slice of length at least n and Dpocon will panic otherwise.
|
||||||
func (impl Implementation) Dpocon(uplo blas.Uplo, n int, a []float64, lda int, anorm float64, work []float64, iwork []int) float64 {
|
func (impl Implementation) Dpocon(uplo blas.Uplo, n int, a []float64, lda int, anorm float64, work []float64, iwork []int) float64 {
|
||||||
checkMatrix(n, n, a, lda)
|
switch {
|
||||||
if uplo != blas.Upper && uplo != blas.Lower {
|
case uplo != blas.Upper && uplo != blas.Lower:
|
||||||
panic(badUplo)
|
panic(badUplo)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
|
case anorm < 0:
|
||||||
|
panic(negANorm)
|
||||||
}
|
}
|
||||||
if len(work) < 3*n {
|
|
||||||
panic(badWork)
|
// Quick return if possible.
|
||||||
}
|
|
||||||
if len(iwork) < n {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
var rcond float64
|
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (n-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(work) < 3*n:
|
||||||
|
panic(shortWork)
|
||||||
|
case len(iwork) < n:
|
||||||
|
panic(shortIWork)
|
||||||
|
}
|
||||||
|
|
||||||
if anorm == 0 {
|
if anorm == 0 {
|
||||||
return rcond
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
bi := blas64.Implementation()
|
bi := blas64.Implementation()
|
||||||
var ainvnm float64
|
|
||||||
smlnum := dlamchS
|
var (
|
||||||
upper := uplo == blas.Upper
|
smlnum = dlamchS
|
||||||
var kase int
|
rcond float64
|
||||||
var normin bool
|
sl, su float64
|
||||||
isave := new([3]int)
|
normin bool
|
||||||
var sl, su float64
|
ainvnm float64
|
||||||
|
kase int
|
||||||
|
isave [3]int
|
||||||
|
)
|
||||||
for {
|
for {
|
||||||
ainvnm, kase = impl.Dlacn2(n, work[n:], work, iwork, ainvnm, kase, isave)
|
ainvnm, kase = impl.Dlacn2(n, work[n:], work, iwork, ainvnm, kase, &isave)
|
||||||
if kase == 0 {
|
if kase == 0 {
|
||||||
if ainvnm != 0 {
|
if ainvnm != 0 {
|
||||||
rcond = (1 / ainvnm) / anorm
|
rcond = (1 / ainvnm) / anorm
|
||||||
}
|
}
|
||||||
return rcond
|
return rcond
|
||||||
}
|
}
|
||||||
if upper {
|
if uplo == blas.Upper {
|
||||||
sl = impl.Dlatrs(blas.Upper, blas.Trans, blas.NonUnit, normin, n, a, lda, work, work[2*n:])
|
sl = impl.Dlatrs(blas.Upper, blas.Trans, blas.NonUnit, normin, n, a, lda, work, work[2*n:])
|
||||||
normin = true
|
normin = true
|
||||||
su = impl.Dlatrs(blas.Upper, blas.NoTrans, blas.NonUnit, normin, n, a, lda, work, work[2*n:])
|
su = impl.Dlatrs(blas.Upper, blas.NoTrans, blas.NonUnit, normin, n, a, lda, work, work[2*n:])
|
||||||
|
@@ -19,16 +19,26 @@ import (
|
|||||||
//
|
//
|
||||||
// Dpotf2 is an internal routine. It is exported for testing purposes.
|
// Dpotf2 is an internal routine. It is exported for testing purposes.
|
||||||
func (Implementation) Dpotf2(ul blas.Uplo, n int, a []float64, lda int) (ok bool) {
|
func (Implementation) Dpotf2(ul blas.Uplo, n int, a []float64, lda int) (ok bool) {
|
||||||
if ul != blas.Upper && ul != blas.Lower {
|
switch {
|
||||||
|
case ul != blas.Upper && ul != blas.Lower:
|
||||||
panic(badUplo)
|
panic(badUplo)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
checkMatrix(n, n, a, lda)
|
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(a) < (n-1)*lda+n {
|
||||||
|
panic(shortA)
|
||||||
|
}
|
||||||
|
|
||||||
bi := blas64.Implementation()
|
bi := blas64.Implementation()
|
||||||
|
|
||||||
if ul == blas.Upper {
|
if ul == blas.Upper {
|
||||||
for j := 0; j < n; j++ {
|
for j := 0; j < n; j++ {
|
||||||
ajj := a[j*lda+j]
|
ajj := a[j*lda+j]
|
||||||
|
@@ -15,15 +15,24 @@ import (
|
|||||||
// is computed and stored in-place into a. If a is not positive definite, false
|
// is computed and stored in-place into a. If a is not positive definite, false
|
||||||
// is returned. This is the blocked version of the algorithm.
|
// is returned. This is the blocked version of the algorithm.
|
||||||
func (impl Implementation) Dpotrf(ul blas.Uplo, n int, a []float64, lda int) (ok bool) {
|
func (impl Implementation) Dpotrf(ul blas.Uplo, n int, a []float64, lda int) (ok bool) {
|
||||||
if ul != blas.Upper && ul != blas.Lower {
|
switch {
|
||||||
|
case ul != blas.Upper && ul != blas.Lower:
|
||||||
panic(badUplo)
|
panic(badUplo)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
checkMatrix(n, n, a, lda)
|
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(a) < (n-1)*lda+n {
|
||||||
|
panic(shortA)
|
||||||
|
}
|
||||||
|
|
||||||
nb := impl.Ilaenv(1, "DPOTRF", string(ul), n, -1, -1, -1)
|
nb := impl.Ilaenv(1, "DPOTRF", string(ul), n, -1, -1, -1)
|
||||||
if nb <= 1 || n <= nb {
|
if nb <= 1 || n <= nb {
|
||||||
return impl.Dpotf2(ul, n, a, lda)
|
return impl.Dpotf2(ul, n, a, lda)
|
||||||
|
@@ -21,8 +21,6 @@ func (impl Implementation) Dpotri(uplo blas.Uplo, n int, a []float64, lda int) (
|
|||||||
panic(nLT0)
|
panic(nLT0)
|
||||||
case lda < max(1, n):
|
case lda < max(1, n):
|
||||||
panic(badLdA)
|
panic(badLdA)
|
||||||
case len(a) < (n-1)*lda+n:
|
|
||||||
panic("lapack: a has insufficient length")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quick return if possible.
|
// Quick return if possible.
|
||||||
@@ -30,6 +28,10 @@ func (impl Implementation) Dpotri(uplo blas.Uplo, n int, a []float64, lda int) (
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(a) < (n-1)*lda+n {
|
||||||
|
panic(shortA)
|
||||||
|
}
|
||||||
|
|
||||||
// Invert the triangular Cholesky factor U or L.
|
// Invert the triangular Cholesky factor U or L.
|
||||||
ok = impl.Dtrtri(uplo, blas.NonUnit, n, a, lda)
|
ok = impl.Dtrtri(uplo, blas.NonUnit, n, a, lda)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@@ -17,17 +17,33 @@ import (
|
|||||||
// as computed by Dpotrf. On entry, B contains the right-hand side matrix B, on
|
// as computed by Dpotrf. On entry, B contains the right-hand side matrix B, on
|
||||||
// return it contains the solution matrix X.
|
// return it contains the solution matrix X.
|
||||||
func (Implementation) Dpotrs(uplo blas.Uplo, n, nrhs int, a []float64, lda int, b []float64, ldb int) {
|
func (Implementation) Dpotrs(uplo blas.Uplo, n, nrhs int, a []float64, lda int, b []float64, ldb int) {
|
||||||
if uplo != blas.Upper && uplo != blas.Lower {
|
switch {
|
||||||
|
case uplo != blas.Upper && uplo != blas.Lower:
|
||||||
panic(badUplo)
|
panic(badUplo)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case nrhs < 0:
|
||||||
|
panic(nrhsLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
|
case ldb < max(1, nrhs):
|
||||||
|
panic(badLdB)
|
||||||
}
|
}
|
||||||
checkMatrix(n, n, a, lda)
|
|
||||||
checkMatrix(n, nrhs, b, ldb)
|
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
if n == 0 || nrhs == 0 {
|
if n == 0 || nrhs == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (n-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(b) < (n-1)*ldb+nrhs:
|
||||||
|
panic(shortB)
|
||||||
|
}
|
||||||
|
|
||||||
bi := blas64.Implementation()
|
bi := blas64.Implementation()
|
||||||
|
|
||||||
if uplo == blas.Upper {
|
if uplo == blas.Upper {
|
||||||
// Solve U^T * U * X = B where U is stored in the upper triangle of A.
|
// Solve U^T * U * X = B where U is stored in the upper triangle of A.
|
||||||
|
|
||||||
|
@@ -15,8 +15,24 @@ import (
|
|||||||
//
|
//
|
||||||
// Drscl is an internal routine. It is exported for testing purposes.
|
// Drscl is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Drscl(n int, a float64, x []float64, incX int) {
|
func (impl Implementation) Drscl(n int, a float64, x []float64, incX int) {
|
||||||
checkVector(n, x, incX)
|
switch {
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case incX <= 0:
|
||||||
|
panic(badIncX)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
|
if n == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(x) < 1+(n-1)*incX {
|
||||||
|
panic(shortX)
|
||||||
|
}
|
||||||
|
|
||||||
bi := blas64.Implementation()
|
bi := blas64.Implementation()
|
||||||
|
|
||||||
cden := a
|
cden := a
|
||||||
cnum := 1.0
|
cnum := 1.0
|
||||||
smlnum := dlamchS
|
smlnum := dlamchS
|
||||||
|
@@ -37,23 +37,29 @@ import (
|
|||||||
//
|
//
|
||||||
// Dsteqr is an internal routine. It is exported for testing purposes.
|
// Dsteqr is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dsteqr(compz lapack.EVComp, n int, d, e, z []float64, ldz int, work []float64) (ok bool) {
|
func (impl Implementation) Dsteqr(compz lapack.EVComp, n int, d, e, z []float64, ldz int, work []float64) (ok bool) {
|
||||||
if n < 0 {
|
switch {
|
||||||
panic(nLT0)
|
case compz != lapack.EVCompNone && compz != lapack.EVTridiag && compz != lapack.EVOrig:
|
||||||
}
|
|
||||||
if len(d) < n {
|
|
||||||
panic(badD)
|
|
||||||
}
|
|
||||||
if len(e) < n-1 {
|
|
||||||
panic(badE)
|
|
||||||
}
|
|
||||||
if compz != lapack.EVCompNone && compz != lapack.EVTridiag && compz != lapack.EVOrig {
|
|
||||||
panic(badEVComp)
|
panic(badEVComp)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case ldz < 1, compz != lapack.EVCompNone && ldz < n:
|
||||||
|
panic(badLdZ)
|
||||||
}
|
}
|
||||||
if compz != lapack.EVCompNone {
|
|
||||||
if len(work) < max(1, 2*n-2) {
|
// Quick return if possible.
|
||||||
panic(badWork)
|
if n == 0 {
|
||||||
}
|
return true
|
||||||
checkMatrix(n, n, z, ldz)
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(d) < n:
|
||||||
|
panic(badD)
|
||||||
|
case len(e) < n-1:
|
||||||
|
panic(badE)
|
||||||
|
case compz != lapack.EVCompNone && len(z) < (n-1)*ldz+n:
|
||||||
|
panic(shortZ)
|
||||||
|
case compz != lapack.EVCompNone && len(work) < max(1, 2*n-2):
|
||||||
|
panic(shortWork)
|
||||||
}
|
}
|
||||||
|
|
||||||
var icompz int
|
var icompz int
|
||||||
@@ -63,9 +69,6 @@ func (impl Implementation) Dsteqr(compz lapack.EVComp, n int, d, e, z []float64,
|
|||||||
icompz = 2
|
icompz = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
if n == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if n == 1 {
|
if n == 1 {
|
||||||
if icompz == 2 {
|
if icompz == 2 {
|
||||||
z[0] = 1
|
z[0] = 1
|
||||||
|
@@ -26,16 +26,23 @@ func (impl Implementation) Dsterf(n int, d, e []float64) (ok bool) {
|
|||||||
if n < 0 {
|
if n < 0 {
|
||||||
panic(nLT0)
|
panic(nLT0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if len(d) < n {
|
|
||||||
|
switch {
|
||||||
|
case len(d) < n:
|
||||||
panic(badD)
|
panic(badD)
|
||||||
}
|
case len(e) < n-1:
|
||||||
if len(e) < n-1 {
|
|
||||||
panic(badE)
|
panic(badE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if n == 1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
none = 0 // The values are not scaled.
|
none = 0 // The values are not scaled.
|
||||||
down = 1 // The values are scaled below ssfmax threshold.
|
down = 1 // The values are scaled below ssfmax threshold.
|
||||||
|
@@ -28,45 +28,55 @@ import (
|
|||||||
// limited by the usable length. If lwork == -1, instead of computing Dsyev the
|
// limited by the usable length. If lwork == -1, instead of computing Dsyev the
|
||||||
// optimal work length is stored into work[0].
|
// optimal work length is stored into work[0].
|
||||||
func (impl Implementation) Dsyev(jobz lapack.EVJob, uplo blas.Uplo, n int, a []float64, lda int, w, work []float64, lwork int) (ok bool) {
|
func (impl Implementation) Dsyev(jobz lapack.EVJob, uplo blas.Uplo, n int, a []float64, lda int, w, work []float64, lwork int) (ok bool) {
|
||||||
checkMatrix(n, n, a, lda)
|
switch {
|
||||||
upper := uplo == blas.Upper
|
case jobz != lapack.EVNone && jobz != lapack.EVCompute:
|
||||||
var wantz bool
|
|
||||||
switch jobz {
|
|
||||||
default:
|
|
||||||
panic(badEVJob)
|
panic(badEVJob)
|
||||||
case lapack.EVCompute:
|
case uplo != blas.Upper && uplo != blas.Lower:
|
||||||
wantz = true
|
panic(badUplo)
|
||||||
case lapack.EVNone:
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
|
case lwork < max(1, 3*n-1) && lwork != -1:
|
||||||
|
panic(badWork)
|
||||||
|
case len(work) < max(1, lwork):
|
||||||
|
panic(shortWork)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
|
if n == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
var opts string
|
var opts string
|
||||||
if upper {
|
if uplo == blas.Upper {
|
||||||
opts = "U"
|
opts = "U"
|
||||||
} else {
|
} else {
|
||||||
opts = "L"
|
opts = "L"
|
||||||
}
|
}
|
||||||
nb := impl.Ilaenv(1, "DSYTRD", opts, n, -1, -1, -1)
|
nb := impl.Ilaenv(1, "DSYTRD", opts, n, -1, -1, -1)
|
||||||
lworkopt := max(1, (nb+2)*n)
|
lworkopt := max(1, (nb+2)*n)
|
||||||
work[0] = float64(lworkopt)
|
|
||||||
if lwork == -1 {
|
if lwork == -1 {
|
||||||
|
work[0] = float64(lworkopt)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(work) < lwork {
|
|
||||||
panic(badWork)
|
switch {
|
||||||
}
|
case len(a) < (n-1)*lda+n:
|
||||||
if lwork < 3*n-1 {
|
panic(shortA)
|
||||||
panic(badWork)
|
case len(w) < n:
|
||||||
}
|
panic(shortW)
|
||||||
if n == 0 {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if n == 1 {
|
if n == 1 {
|
||||||
w[0] = a[0]
|
w[0] = a[0]
|
||||||
work[0] = 2
|
work[0] = 2
|
||||||
if wantz {
|
if jobz == lapack.EVCompute {
|
||||||
a[0] = 1
|
a[0] = 1
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
safmin := dlamchS
|
safmin := dlamchS
|
||||||
eps := dlamchP
|
eps := dlamchP
|
||||||
smlnum := safmin / eps
|
smlnum := safmin / eps
|
||||||
@@ -87,7 +97,7 @@ func (impl Implementation) Dsyev(jobz lapack.EVJob, uplo blas.Uplo, n int, a []f
|
|||||||
}
|
}
|
||||||
if scaled {
|
if scaled {
|
||||||
kind := lapack.LowerTri
|
kind := lapack.LowerTri
|
||||||
if upper {
|
if uplo == blas.Upper {
|
||||||
kind = lapack.UpperTri
|
kind = lapack.UpperTri
|
||||||
}
|
}
|
||||||
impl.Dlascl(kind, 0, 0, 1, sigma, n, n, a, lda)
|
impl.Dlascl(kind, 0, 0, 1, sigma, n, n, a, lda)
|
||||||
@@ -100,7 +110,7 @@ func (impl Implementation) Dsyev(jobz lapack.EVJob, uplo blas.Uplo, n int, a []f
|
|||||||
|
|
||||||
// For eigenvalues only, call Dsterf. For eigenvectors, first call Dorgtr
|
// For eigenvalues only, call Dsterf. For eigenvectors, first call Dorgtr
|
||||||
// to generate the orthogonal matrix, then call Dsteqr.
|
// to generate the orthogonal matrix, then call Dsteqr.
|
||||||
if !wantz {
|
if jobz == lapack.EVNone {
|
||||||
ok = impl.Dsterf(n, w, work[inde:])
|
ok = impl.Dsterf(n, w, work[inde:])
|
||||||
} else {
|
} else {
|
||||||
impl.Dorgtr(uplo, n, a, lda, work[indtau:], work[indwork:], llwork)
|
impl.Dorgtr(uplo, n, a, lda, work[indtau:], work[indwork:], llwork)
|
||||||
|
@@ -49,20 +49,33 @@ import (
|
|||||||
//
|
//
|
||||||
// Dsytd2 is an internal routine. It is exported for testing purposes.
|
// Dsytd2 is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dsytd2(uplo blas.Uplo, n int, a []float64, lda int, d, e, tau []float64) {
|
func (impl Implementation) Dsytd2(uplo blas.Uplo, n int, a []float64, lda int, d, e, tau []float64) {
|
||||||
checkMatrix(n, n, a, lda)
|
switch {
|
||||||
if len(d) < n {
|
case uplo != blas.Upper && uplo != blas.Lower:
|
||||||
panic(badD)
|
panic(badUplo)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
if len(e) < n-1 {
|
|
||||||
panic(badE)
|
// Quick return if possible.
|
||||||
}
|
if n == 0 {
|
||||||
if len(tau) < n-1 {
|
|
||||||
panic(badTau)
|
|
||||||
}
|
|
||||||
if n <= 0 {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (n-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(d) < n:
|
||||||
|
panic(badD)
|
||||||
|
case len(e) < n-1:
|
||||||
|
panic(badE)
|
||||||
|
case len(tau) < n-1:
|
||||||
|
panic(badTau)
|
||||||
|
}
|
||||||
|
|
||||||
bi := blas64.Implementation()
|
bi := blas64.Implementation()
|
||||||
|
|
||||||
if uplo == blas.Upper {
|
if uplo == blas.Upper {
|
||||||
// Reduce the upper triangle of A.
|
// Reduce the upper triangle of A.
|
||||||
for i := n - 2; i >= 0; i-- {
|
for i := n - 2; i >= 0; i-- {
|
||||||
|
@@ -55,16 +55,9 @@ import (
|
|||||||
//
|
//
|
||||||
// Dsytrd is an internal routine. It is exported for testing purposes.
|
// Dsytrd is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dsytrd(uplo blas.Uplo, n int, a []float64, lda int, d, e, tau, work []float64, lwork int) {
|
func (impl Implementation) Dsytrd(uplo blas.Uplo, n int, a []float64, lda int, d, e, tau, work []float64, lwork int) {
|
||||||
var opts string
|
|
||||||
switch uplo {
|
|
||||||
case blas.Upper:
|
|
||||||
opts = "U"
|
|
||||||
case blas.Lower:
|
|
||||||
opts = "L"
|
|
||||||
default:
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
switch {
|
switch {
|
||||||
|
case uplo != blas.Upper && uplo != blas.Lower:
|
||||||
|
panic(badUplo)
|
||||||
case n < 0:
|
case n < 0:
|
||||||
panic(nLT0)
|
panic(nLT0)
|
||||||
case lda < max(1, n):
|
case lda < max(1, n):
|
||||||
@@ -75,12 +68,13 @@ func (impl Implementation) Dsytrd(uplo blas.Uplo, n int, a []float64, lda int, d
|
|||||||
panic(shortWork)
|
panic(shortWork)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
work[0] = 1
|
work[0] = 1
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nb := impl.Ilaenv(1, "DSYTRD", opts, n, -1, -1, -1)
|
nb := impl.Ilaenv(1, "DSYTRD", string(uplo), n, -1, -1, -1)
|
||||||
lworkopt := n * nb
|
lworkopt := n * nb
|
||||||
if lwork == -1 {
|
if lwork == -1 {
|
||||||
work[0] = float64(lworkopt)
|
work[0] = float64(lworkopt)
|
||||||
@@ -89,7 +83,7 @@ func (impl Implementation) Dsytrd(uplo blas.Uplo, n int, a []float64, lda int, d
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
case len(a) < (n-1)*lda+n:
|
case len(a) < (n-1)*lda+n:
|
||||||
panic("lapack: insufficient length of a")
|
panic(shortA)
|
||||||
case len(d) < n:
|
case len(d) < n:
|
||||||
panic(badD)
|
panic(badD)
|
||||||
case len(e) < n-1:
|
case len(e) < n-1:
|
||||||
@@ -98,14 +92,15 @@ func (impl Implementation) Dsytrd(uplo blas.Uplo, n int, a []float64, lda int, d
|
|||||||
panic(badTau)
|
panic(badTau)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bi := blas64.Implementation()
|
||||||
|
|
||||||
nx := n
|
nx := n
|
||||||
iws := 1
|
iws := 1
|
||||||
bi := blas64.Implementation()
|
|
||||||
var ldwork int
|
var ldwork int
|
||||||
if 1 < nb && nb < n {
|
if 1 < nb && nb < n {
|
||||||
// Determine when to cross over from blocked to unblocked code. The last
|
// Determine when to cross over from blocked to unblocked code. The last
|
||||||
// block is always handled by unblocked code.
|
// block is always handled by unblocked code.
|
||||||
nx = max(nb, impl.Ilaenv(3, "DSYTRD", opts, n, -1, -1, -1))
|
nx = max(nb, impl.Ilaenv(3, "DSYTRD", string(uplo), n, -1, -1, -1))
|
||||||
if nx < n {
|
if nx < n {
|
||||||
// Determine if workspace is large enough for blocked code.
|
// Determine if workspace is large enough for blocked code.
|
||||||
ldwork = nb
|
ldwork = nb
|
||||||
@@ -115,7 +110,7 @@ func (impl Implementation) Dsytrd(uplo blas.Uplo, n int, a []float64, lda int, d
|
|||||||
// value of nb and reduce nb or force use of unblocked code by
|
// value of nb and reduce nb or force use of unblocked code by
|
||||||
// setting nx = n.
|
// setting nx = n.
|
||||||
nb = max(lwork/n, 1)
|
nb = max(lwork/n, 1)
|
||||||
nbmin := impl.Ilaenv(2, "DSYTRD", opts, n, -1, -1, -1)
|
nbmin := impl.Ilaenv(2, "DSYTRD", string(uplo), n, -1, -1, -1)
|
||||||
if nb < nbmin {
|
if nb < nbmin {
|
||||||
nx = n
|
nx = n
|
||||||
}
|
}
|
||||||
|
@@ -159,45 +159,61 @@ import (
|
|||||||
func (impl Implementation) Dtgsja(jobU, jobV, jobQ lapack.GSVDJob, m, p, n, k, l int, a []float64, lda int, b []float64, ldb int, tola, tolb float64, alpha, beta, u []float64, ldu int, v []float64, ldv int, q []float64, ldq int, work []float64) (cycles int, ok bool) {
|
func (impl Implementation) Dtgsja(jobU, jobV, jobQ lapack.GSVDJob, m, p, n, k, l int, a []float64, lda int, b []float64, ldb int, tola, tolb float64, alpha, beta, u []float64, ldu int, v []float64, ldv int, q []float64, ldq int, work []float64) (cycles int, ok bool) {
|
||||||
const maxit = 40
|
const maxit = 40
|
||||||
|
|
||||||
checkMatrix(m, n, a, lda)
|
|
||||||
checkMatrix(p, n, b, ldb)
|
|
||||||
|
|
||||||
if len(alpha) != n {
|
|
||||||
panic(badAlpha)
|
|
||||||
}
|
|
||||||
if len(beta) != n {
|
|
||||||
panic(badBeta)
|
|
||||||
}
|
|
||||||
|
|
||||||
initu := jobU == lapack.GSVDUnit
|
initu := jobU == lapack.GSVDUnit
|
||||||
wantu := initu || jobU == lapack.GSVDU
|
wantu := initu || jobU == lapack.GSVDU
|
||||||
if !initu && !wantu && jobU != lapack.GSVDNone {
|
|
||||||
panic(badGSVDJob + "U")
|
|
||||||
}
|
|
||||||
if jobU != lapack.GSVDNone {
|
|
||||||
checkMatrix(m, m, u, ldu)
|
|
||||||
}
|
|
||||||
|
|
||||||
initv := jobV == lapack.GSVDUnit
|
initv := jobV == lapack.GSVDUnit
|
||||||
wantv := initv || jobV == lapack.GSVDV
|
wantv := initv || jobV == lapack.GSVDV
|
||||||
if !initv && !wantv && jobV != lapack.GSVDNone {
|
|
||||||
panic(badGSVDJob + "V")
|
|
||||||
}
|
|
||||||
if jobV != lapack.GSVDNone {
|
|
||||||
checkMatrix(p, p, v, ldv)
|
|
||||||
}
|
|
||||||
|
|
||||||
initq := jobQ == lapack.GSVDUnit
|
initq := jobQ == lapack.GSVDUnit
|
||||||
wantq := initq || jobQ == lapack.GSVDQ
|
wantq := initq || jobQ == lapack.GSVDQ
|
||||||
if !initq && !wantq && jobQ != lapack.GSVDNone {
|
|
||||||
panic(badGSVDJob + "Q")
|
|
||||||
}
|
|
||||||
if jobQ != lapack.GSVDNone {
|
|
||||||
checkMatrix(n, n, q, ldq)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(work) < 2*n {
|
switch {
|
||||||
panic(badWork)
|
case !initu && !wantu && jobU != lapack.GSVDNone:
|
||||||
|
panic(badGSVDJob + "U")
|
||||||
|
case !initv && !wantv && jobV != lapack.GSVDNone:
|
||||||
|
panic(badGSVDJob + "V")
|
||||||
|
case !initq && !wantq && jobQ != lapack.GSVDNone:
|
||||||
|
panic(badGSVDJob + "Q")
|
||||||
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
|
case p < 0:
|
||||||
|
panic(pLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
|
case len(a) < (m-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
|
||||||
|
case ldb < max(1, n):
|
||||||
|
panic(badLdB)
|
||||||
|
case len(b) < (p-1)*ldb+n:
|
||||||
|
panic(shortB)
|
||||||
|
|
||||||
|
case len(alpha) != n:
|
||||||
|
panic(badAlpha)
|
||||||
|
case len(beta) != n:
|
||||||
|
panic(badBeta)
|
||||||
|
|
||||||
|
case ldu < 1, wantu && ldu < m:
|
||||||
|
panic(badLdU)
|
||||||
|
case wantu && len(u) < (m-1)*ldu+m:
|
||||||
|
panic(shortU)
|
||||||
|
|
||||||
|
case ldv < 1, wantv && ldv < p:
|
||||||
|
panic(badLdV)
|
||||||
|
case wantv && len(v) < (p-1)*ldv+p:
|
||||||
|
panic(shortV)
|
||||||
|
|
||||||
|
case ldq < 1, wantq && ldq < n:
|
||||||
|
panic(badLdQ)
|
||||||
|
case wantq && len(q) < (n-1)*ldq+n:
|
||||||
|
panic(shortQ)
|
||||||
|
|
||||||
|
case len(work) < 2*n:
|
||||||
|
panic(shortWork)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize U, V and Q, if necessary
|
// Initialize U, V and Q, if necessary
|
||||||
|
@@ -19,24 +19,32 @@ import (
|
|||||||
//
|
//
|
||||||
// iwork is a temporary data slice of length at least n and Dtrcon will panic otherwise.
|
// iwork is a temporary data slice of length at least n and Dtrcon will panic otherwise.
|
||||||
func (impl Implementation) Dtrcon(norm lapack.MatrixNorm, uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int, work []float64, iwork []int) float64 {
|
func (impl Implementation) Dtrcon(norm lapack.MatrixNorm, uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int, work []float64, iwork []int) float64 {
|
||||||
if norm != lapack.MaxColumnSum && norm != lapack.MaxRowSum {
|
switch {
|
||||||
|
case norm != lapack.MaxColumnSum && norm != lapack.MaxRowSum:
|
||||||
panic(badNorm)
|
panic(badNorm)
|
||||||
}
|
case uplo != blas.Upper && uplo != blas.Lower:
|
||||||
if uplo != blas.Upper && uplo != blas.Lower {
|
|
||||||
panic(badUplo)
|
panic(badUplo)
|
||||||
}
|
case diag != blas.NonUnit && diag != blas.Unit:
|
||||||
if diag != blas.NonUnit && diag != blas.Unit {
|
|
||||||
panic(badDiag)
|
panic(badDiag)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
if len(work) < 3*n {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
if len(iwork) < n {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (n-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(work) < 3*n:
|
||||||
|
panic(shortWork)
|
||||||
|
case len(iwork) < n:
|
||||||
|
panic(shortIWork)
|
||||||
|
}
|
||||||
|
|
||||||
bi := blas64.Implementation()
|
bi := blas64.Implementation()
|
||||||
|
|
||||||
var rcond float64
|
var rcond float64
|
||||||
|
@@ -106,86 +106,110 @@ import (
|
|||||||
//
|
//
|
||||||
// Dtrevc3 is an internal routine. It is exported for testing purposes.
|
// Dtrevc3 is an internal routine. It is exported for testing purposes.
|
||||||
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) {
|
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 {
|
bothv := side == lapack.EVBoth
|
||||||
default:
|
rightv := side == lapack.EVRight || bothv
|
||||||
panic(badEVSide)
|
leftv := side == lapack.EVLeft || bothv
|
||||||
case lapack.EVRight, lapack.EVLeft, lapack.EVBoth:
|
|
||||||
}
|
|
||||||
switch howmny {
|
|
||||||
default:
|
|
||||||
panic(badEVHowMany)
|
|
||||||
case lapack.EVAll, lapack.EVAllMulQ, lapack.EVSelected:
|
|
||||||
}
|
|
||||||
switch {
|
switch {
|
||||||
|
case !rightv && !leftv:
|
||||||
|
panic(badEVSide)
|
||||||
|
case howmny != lapack.EVAll && howmny != lapack.EVAllMulQ && howmny != lapack.EVSelected:
|
||||||
|
panic(badEVHowMany)
|
||||||
case n < 0:
|
case n < 0:
|
||||||
panic(nLT0)
|
panic(nLT0)
|
||||||
case len(work) < lwork:
|
case ldt < max(1, n):
|
||||||
panic(shortWork)
|
panic(badLdT)
|
||||||
|
case mm < 0:
|
||||||
|
panic(mmLT0)
|
||||||
|
case ldvl < 1:
|
||||||
|
// ldvl and ldvr are also checked below after the computation of
|
||||||
|
// m (number of columns of VL and VR) in case of howmny == EVSelected.
|
||||||
|
panic(badLdVL)
|
||||||
|
case ldvr < 1:
|
||||||
|
panic(badLdVR)
|
||||||
case lwork < max(1, 3*n) && lwork != -1:
|
case lwork < max(1, 3*n) && lwork != -1:
|
||||||
panic(badWork)
|
panic(badWork)
|
||||||
}
|
case len(work) < max(1, lwork):
|
||||||
if lwork != -1 {
|
panic(shortWork)
|
||||||
if howmny == lapack.EVSelected {
|
|
||||||
if len(selected) != n {
|
|
||||||
panic("lapack: bad selected length")
|
|
||||||
}
|
|
||||||
// Set m to the number of columns required to store the
|
|
||||||
// selected eigenvectors, and standardize the slice
|
|
||||||
// selected.
|
|
||||||
for j := 0; j < n; {
|
|
||||||
if j == n-1 || t[(j+1)*ldt+j] == 0 {
|
|
||||||
// Diagonal 1×1 block corresponding to a
|
|
||||||
// real eigenvalue.
|
|
||||||
if selected[j] {
|
|
||||||
m++
|
|
||||||
}
|
|
||||||
j++
|
|
||||||
} else {
|
|
||||||
// Diagonal 2×2 block corresponding to a
|
|
||||||
// complex eigenvalue.
|
|
||||||
if selected[j] || selected[j+1] {
|
|
||||||
selected[j] = true
|
|
||||||
selected[j+1] = false
|
|
||||||
m += 2
|
|
||||||
}
|
|
||||||
j += 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m = n
|
|
||||||
}
|
|
||||||
if m > mm {
|
|
||||||
panic("lapack: insufficient number of columns")
|
|
||||||
}
|
|
||||||
checkMatrix(n, n, t, ldt)
|
|
||||||
if (side == lapack.EVRight || side == lapack.EVBoth) && m > 0 {
|
|
||||||
checkMatrix(n, m, vr, ldvr)
|
|
||||||
}
|
|
||||||
if (side == lapack.EVLeft || side == lapack.EVBoth) && m > 0 {
|
|
||||||
checkMatrix(n, m, vl, ldvl)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quick return if possible.
|
// Quick return if possible.
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
work[0] = 1
|
work[0] = 1
|
||||||
return m
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
// Normally we don't check slice lengths until after the workspace
|
||||||
nbmin = 8
|
// query. However, even in case of the workspace query we need to
|
||||||
nbmax = 128
|
// compute and return the value of m, and since the computation accesses t,
|
||||||
)
|
// we put the length check of t here.
|
||||||
nb := impl.Ilaenv(1, "DTREVC", string(side)+string(howmny), n, -1, -1, -1)
|
if len(t) < (n-1)*ldt+n {
|
||||||
|
panic(shortT)
|
||||||
|
}
|
||||||
|
|
||||||
|
if howmny == lapack.EVSelected {
|
||||||
|
if len(selected) != n {
|
||||||
|
panic(badSelected)
|
||||||
|
}
|
||||||
|
// Set m to the number of columns required to store the selected
|
||||||
|
// eigenvectors, and standardize the slice selected.
|
||||||
|
// Each selected real eigenvector occupies one column and each
|
||||||
|
// selected complex eigenvector occupies two columns.
|
||||||
|
for j := 0; j < n; {
|
||||||
|
if j == n-1 || t[(j+1)*ldt+j] == 0 {
|
||||||
|
// Diagonal 1×1 block corresponding to a
|
||||||
|
// real eigenvalue.
|
||||||
|
if selected[j] {
|
||||||
|
m++
|
||||||
|
}
|
||||||
|
j++
|
||||||
|
} else {
|
||||||
|
// Diagonal 2×2 block corresponding to a
|
||||||
|
// complex eigenvalue.
|
||||||
|
if selected[j] || selected[j+1] {
|
||||||
|
selected[j] = true
|
||||||
|
selected[j+1] = false
|
||||||
|
m += 2
|
||||||
|
}
|
||||||
|
j += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m = n
|
||||||
|
}
|
||||||
|
if mm < m {
|
||||||
|
panic(badMM)
|
||||||
|
}
|
||||||
|
|
||||||
// Quick return in case of a workspace query.
|
// Quick return in case of a workspace query.
|
||||||
|
nb := impl.Ilaenv(1, "DTREVC", string(side)+string(howmny), n, -1, -1, -1)
|
||||||
if lwork == -1 {
|
if lwork == -1 {
|
||||||
work[0] = float64(n + 2*n*nb)
|
work[0] = float64(n + 2*n*nb)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quick return if no eigenvectors were selected.
|
||||||
|
if m == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case leftv && ldvl < mm:
|
||||||
|
panic(badLdVL)
|
||||||
|
case leftv && len(vl) < (n-1)*ldvl+mm:
|
||||||
|
panic(shortVL)
|
||||||
|
|
||||||
|
case rightv && ldvr < mm:
|
||||||
|
panic(badLdVR)
|
||||||
|
case rightv && len(vr) < (n-1)*ldvr+mm:
|
||||||
|
panic(shortVR)
|
||||||
|
}
|
||||||
|
|
||||||
// Use blocked version of back-transformation if sufficient workspace.
|
// Use blocked version of back-transformation if sufficient workspace.
|
||||||
// Zero-out the workspace to avoid potential NaN propagation.
|
// Zero-out the workspace to avoid potential NaN propagation.
|
||||||
|
const (
|
||||||
|
nbmin = 8
|
||||||
|
nbmax = 128
|
||||||
|
)
|
||||||
if howmny == lapack.EVAllMulQ && lwork >= n+2*n*nbmin {
|
if howmny == lapack.EVAllMulQ && lwork >= n+2*n*nbmin {
|
||||||
nb = min((lwork-n)/(2*n), nbmax)
|
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)
|
impl.Dlaset(blas.All, n, 1+2*nb, 0, 0, work[:n+2*nb*n], 1+2*nb)
|
||||||
|
@@ -46,31 +46,37 @@ import "gonum.org/v1/gonum/lapack"
|
|||||||
//
|
//
|
||||||
// Dtrexc is an internal routine. It is exported for testing purposes.
|
// Dtrexc is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dtrexc(compq lapack.UpdateSchurComp, n int, t []float64, ldt int, q []float64, ldq int, ifst, ilst int, work []float64) (ifstOut, ilstOut int, ok bool) {
|
func (impl Implementation) Dtrexc(compq lapack.UpdateSchurComp, n int, t []float64, ldt int, q []float64, ldq int, ifst, ilst int, work []float64) (ifstOut, ilstOut int, ok bool) {
|
||||||
checkMatrix(n, n, t, ldt)
|
switch {
|
||||||
var wantq bool
|
case compq != lapack.UpdateSchur && compq != lapack.UpdateSchurNone:
|
||||||
switch compq {
|
panic(badUpdateSchurComp)
|
||||||
default:
|
case n < 0:
|
||||||
panic("lapack: bad value of compq")
|
panic(nLT0)
|
||||||
case lapack.UpdateSchurNone:
|
case ldt < max(1, n):
|
||||||
// Nothing to do because wantq is already false.
|
panic(badLdT)
|
||||||
case lapack.UpdateSchur:
|
case ldq < 1, compq == lapack.UpdateSchur && ldq < n:
|
||||||
wantq = true
|
panic(badLdQ)
|
||||||
checkMatrix(n, n, q, ldq)
|
case (ifst < 0 || n <= ifst) && n > 0:
|
||||||
|
panic(badIfst)
|
||||||
|
case (ilst < 0 || n <= ilst) && n > 0:
|
||||||
|
panic(badIlst)
|
||||||
}
|
}
|
||||||
if (ifst < 0 || n <= ifst) && n > 0 {
|
|
||||||
panic("lapack: ifst out of range")
|
|
||||||
}
|
|
||||||
if (ilst < 0 || n <= ilst) && n > 0 {
|
|
||||||
panic("lapack: ilst out of range")
|
|
||||||
}
|
|
||||||
if len(work) < n {
|
|
||||||
panic(badWork)
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = true
|
|
||||||
|
|
||||||
// Quick return if possible.
|
// Quick return if possible.
|
||||||
if n <= 1 {
|
if n == 0 {
|
||||||
|
return ifst, ilst, true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(t) < (n-1)*ldt+n:
|
||||||
|
panic(shortT)
|
||||||
|
case compq == lapack.UpdateSchur && len(q) < (n-1)*ldq+n:
|
||||||
|
panic(shortQ)
|
||||||
|
case len(work) < n:
|
||||||
|
panic(shortWork)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quick return if possible.
|
||||||
|
if n == 1 {
|
||||||
return ifst, ilst, true
|
return ifst, ilst, true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,6 +99,9 @@ func (impl Implementation) Dtrexc(compq lapack.UpdateSchurComp, n int, t []float
|
|||||||
nbl = 2
|
nbl = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ok = true
|
||||||
|
wantq := compq == lapack.UpdateSchur
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case ifst == ilst:
|
case ifst == ilst:
|
||||||
return ifst, ilst, true
|
return ifst, ilst, true
|
||||||
|
@@ -14,13 +14,25 @@ import (
|
|||||||
//
|
//
|
||||||
// Dtrti2 is an internal routine. It is exported for testing purposes.
|
// Dtrti2 is an internal routine. It is exported for testing purposes.
|
||||||
func (impl Implementation) Dtrti2(uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int) {
|
func (impl Implementation) Dtrti2(uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int) {
|
||||||
checkMatrix(n, n, a, lda)
|
switch {
|
||||||
if uplo != blas.Upper && uplo != blas.Lower {
|
case uplo != blas.Upper && uplo != blas.Lower:
|
||||||
panic(badUplo)
|
panic(badUplo)
|
||||||
}
|
case diag != blas.NonUnit && diag != blas.Unit:
|
||||||
if diag != blas.NonUnit && diag != blas.Unit {
|
|
||||||
panic(badDiag)
|
panic(badDiag)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(a) < (n-1)*lda+n {
|
||||||
|
panic(shortA)
|
||||||
|
}
|
||||||
|
|
||||||
bi := blas64.Implementation()
|
bi := blas64.Implementation()
|
||||||
|
|
||||||
nonUnit := diag == blas.NonUnit
|
nonUnit := diag == blas.NonUnit
|
||||||
|
@@ -16,18 +16,26 @@ import (
|
|||||||
// Dtrtri will not perform the inversion if the matrix is singular, and returns
|
// Dtrtri will not perform the inversion if the matrix is singular, and returns
|
||||||
// a boolean indicating whether the inversion was successful.
|
// a boolean indicating whether the inversion was successful.
|
||||||
func (impl Implementation) Dtrtri(uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int) (ok bool) {
|
func (impl Implementation) Dtrtri(uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int) (ok bool) {
|
||||||
checkMatrix(n, n, a, lda)
|
switch {
|
||||||
if uplo != blas.Upper && uplo != blas.Lower {
|
case uplo != blas.Upper && uplo != blas.Lower:
|
||||||
panic(badUplo)
|
panic(badUplo)
|
||||||
}
|
case diag != blas.NonUnit && diag != blas.Unit:
|
||||||
if diag != blas.NonUnit && diag != blas.Unit {
|
|
||||||
panic(badDiag)
|
panic(badDiag)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
nonUnit := diag == blas.NonUnit
|
|
||||||
if nonUnit {
|
if len(a) < (n-1)*lda+n {
|
||||||
|
panic(shortA)
|
||||||
|
}
|
||||||
|
|
||||||
|
if diag == blas.NonUnit {
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
if a[i*lda+i] == 0 {
|
if a[i*lda+i] == 0 {
|
||||||
return false
|
return false
|
||||||
|
@@ -12,11 +12,36 @@ import (
|
|||||||
// Dtrtrs solves a triangular system of the form A * X = B or A^T * X = B. Dtrtrs
|
// Dtrtrs solves a triangular system of the form A * X = B or A^T * X = B. Dtrtrs
|
||||||
// returns whether the solve completed successfully. If A is singular, no solve is performed.
|
// returns whether the solve completed successfully. If A is singular, no solve is performed.
|
||||||
func (impl Implementation) Dtrtrs(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n, nrhs int, a []float64, lda int, b []float64, ldb int) (ok bool) {
|
func (impl Implementation) Dtrtrs(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n, nrhs int, a []float64, lda int, b []float64, ldb int) (ok bool) {
|
||||||
nounit := diag == blas.NonUnit
|
switch {
|
||||||
if n == 0 {
|
case uplo != blas.Upper && uplo != blas.Lower:
|
||||||
return false
|
panic(badUplo)
|
||||||
|
case trans != blas.NoTrans && trans != blas.Trans && trans != blas.ConjTrans:
|
||||||
|
panic(badTrans)
|
||||||
|
case diag != blas.NonUnit && diag != blas.Unit:
|
||||||
|
panic(badDiag)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case nrhs < 0:
|
||||||
|
panic(nrhsLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
|
case ldb < max(1, nrhs):
|
||||||
|
panic(badLdB)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(a) < (n-1)*lda+n:
|
||||||
|
panic(shortA)
|
||||||
|
case len(b) < (n-1)*ldb+nrhs:
|
||||||
|
panic(shortB)
|
||||||
|
}
|
||||||
|
|
||||||
// Check for singularity.
|
// Check for singularity.
|
||||||
|
nounit := diag == blas.NonUnit
|
||||||
if nounit {
|
if nounit {
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
if a[i*lda+i] == 0 {
|
if a[i*lda+i] == 0 {
|
||||||
|
@@ -25,6 +25,8 @@ const (
|
|||||||
badIlo = "lapack: ilo out of range"
|
badIlo = "lapack: ilo out of range"
|
||||||
badIhi = "lapack: ihi out of range"
|
badIhi = "lapack: ihi out of range"
|
||||||
badIpiv = "lapack: bad permutation length"
|
badIpiv = "lapack: bad permutation length"
|
||||||
|
badIfst = "lapack: ifst out of range"
|
||||||
|
badIlst = "lapack: ilst out of range"
|
||||||
badBalanceJob = "lapack: bad BalanceJob"
|
badBalanceJob = "lapack: bad BalanceJob"
|
||||||
badJ1 = "lapack: j1 out of range"
|
badJ1 = "lapack: j1 out of range"
|
||||||
badK1 = "lapack: k1 out of range"
|
badK1 = "lapack: k1 out of range"
|
||||||
@@ -49,6 +51,7 @@ const (
|
|||||||
badLdX = "lapack: bad leading dimension of X"
|
badLdX = "lapack: bad leading dimension of X"
|
||||||
badLdY = "lapack: bad leading dimension of Y"
|
badLdY = "lapack: bad leading dimension of Y"
|
||||||
badLdZ = "lapack: bad leading dimension of Z"
|
badLdZ = "lapack: bad leading dimension of Z"
|
||||||
|
badMM = "lapack: bad value of mm"
|
||||||
badNb = "lapack: nb out of range"
|
badNb = "lapack: nb out of range"
|
||||||
badNorm = "lapack: bad norm"
|
badNorm = "lapack: bad norm"
|
||||||
badPivot = "lapack: bad pivot"
|
badPivot = "lapack: bad pivot"
|
||||||
@@ -56,6 +59,7 @@ const (
|
|||||||
badS = "lapack: s has insufficient length"
|
badS = "lapack: s has insufficient length"
|
||||||
badSchurComp = "lapack: bad SchurComp"
|
badSchurComp = "lapack: bad SchurComp"
|
||||||
badSchurJob = "lapack: bad SchurJob"
|
badSchurJob = "lapack: bad SchurJob"
|
||||||
|
badSelected = "lapack: bad length of selected"
|
||||||
badShifts = "lapack: bad shifts"
|
badShifts = "lapack: bad shifts"
|
||||||
badSide = "lapack: bad side"
|
badSide = "lapack: bad side"
|
||||||
badSlice = "lapack: bad input slice length"
|
badSlice = "lapack: bad input slice length"
|
||||||
@@ -79,9 +83,14 @@ const (
|
|||||||
kGTN = "lapack: k > n"
|
kGTN = "lapack: k > n"
|
||||||
kLT0 = "lapack: k < 0"
|
kLT0 = "lapack: k < 0"
|
||||||
kLT1 = "lapack: k < 1"
|
kLT1 = "lapack: k < 1"
|
||||||
|
kdLT0 = "lapack: kd < 0"
|
||||||
mLT0 = "lapack: m < 0"
|
mLT0 = "lapack: m < 0"
|
||||||
mLTN = "lapack: m < n"
|
mLTN = "lapack: m < n"
|
||||||
|
mmLT0 = "lapack: mm < 0"
|
||||||
|
nGTM = "lapack: n > m"
|
||||||
|
mGTN = "lapack: m > n"
|
||||||
nanScale = "lapack: NaN scale factor"
|
nanScale = "lapack: NaN scale factor"
|
||||||
|
negANorm = "lapack: anorm < 0"
|
||||||
negDimension = "lapack: negative matrix dimension"
|
negDimension = "lapack: negative matrix dimension"
|
||||||
negZ = "lapack: negative z value"
|
negZ = "lapack: negative z value"
|
||||||
nLT0 = "lapack: n < 0"
|
nLT0 = "lapack: n < 0"
|
||||||
@@ -96,6 +105,7 @@ const (
|
|||||||
offsetLT0 = "lapack: offset < 0"
|
offsetLT0 = "lapack: offset < 0"
|
||||||
offsetGTM = "lapack: offset > m"
|
offsetGTM = "lapack: offset > m"
|
||||||
shortA = "lapack: insufficient length of a"
|
shortA = "lapack: insufficient length of a"
|
||||||
|
shortAB = "lapack: insufficient length of ab"
|
||||||
shortB = "lapack: insufficient length of b"
|
shortB = "lapack: insufficient length of b"
|
||||||
shortC = "lapack: insufficient length of c"
|
shortC = "lapack: insufficient length of c"
|
||||||
shortCNorm = "lapack: insufficient length of cnorm"
|
shortCNorm = "lapack: insufficient length of cnorm"
|
||||||
@@ -121,6 +131,9 @@ const (
|
|||||||
shortX = "lapack: insufficient length of x"
|
shortX = "lapack: insufficient length of x"
|
||||||
shortY = "lapack: insufficient length of y"
|
shortY = "lapack: insufficient length of y"
|
||||||
shortZ = "lapack: insufficient length of z"
|
shortZ = "lapack: insufficient length of z"
|
||||||
|
shortIWork = "lapack: insufficient length of iwork"
|
||||||
shortWork = "lapack: working array shorter than declared"
|
shortWork = "lapack: working array shorter than declared"
|
||||||
zeroDiv = "lapack: zero divisor"
|
zeroDiv = "lapack: zero divisor"
|
||||||
|
|
||||||
|
badUpdateSchurComp = "lapack: bad UpdateSchurComp"
|
||||||
)
|
)
|
||||||
|
@@ -13,46 +13,6 @@ type Implementation struct{}
|
|||||||
|
|
||||||
var _ lapack.Float64 = Implementation{}
|
var _ lapack.Float64 = Implementation{}
|
||||||
|
|
||||||
// checkMatrix verifies the parameters of a matrix input.
|
|
||||||
func checkMatrix(m, n int, a []float64, lda int) {
|
|
||||||
if m < 0 {
|
|
||||||
panic("lapack: has negative number of rows")
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic("lapack: has negative number of columns")
|
|
||||||
}
|
|
||||||
if lda < n {
|
|
||||||
panic("lapack: stride less than number of columns")
|
|
||||||
}
|
|
||||||
if len(a) < (m-1)*lda+n {
|
|
||||||
panic("lapack: insufficient matrix slice length")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkVector(n int, v []float64, inc int) {
|
|
||||||
if n < 0 {
|
|
||||||
panic("lapack: negative vector length")
|
|
||||||
}
|
|
||||||
if (inc > 0 && (n-1)*inc >= len(v)) || (inc < 0 && (1-n)*inc >= len(v)) {
|
|
||||||
panic("lapack: insufficient vector slice length")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkSymBanded(ab []float64, n, kd, lda int) {
|
|
||||||
if n < 0 {
|
|
||||||
panic("lapack: negative banded length")
|
|
||||||
}
|
|
||||||
if kd < 0 {
|
|
||||||
panic("lapack: negative bandwidth value")
|
|
||||||
}
|
|
||||||
if lda < kd+1 {
|
|
||||||
panic("lapack: stride less than number of bands")
|
|
||||||
}
|
|
||||||
if len(ab) < (n-1)*lda+kd {
|
|
||||||
panic("lapack: insufficient banded vector length")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func min(a, b int) int {
|
func min(a, b int) int {
|
||||||
if a < b {
|
if a < b {
|
||||||
return a
|
return a
|
||||||
|
@@ -9,10 +9,22 @@ package gonum
|
|||||||
//
|
//
|
||||||
// Iladlc is an internal routine. It is exported for testing purposes.
|
// Iladlc is an internal routine. It is exported for testing purposes.
|
||||||
func (Implementation) Iladlc(m, n int, a []float64, lda int) int {
|
func (Implementation) Iladlc(m, n int, a []float64, lda int) int {
|
||||||
if n == 0 || m == 0 {
|
switch {
|
||||||
return n - 1
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 0 || m == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(a) < (m-1)*lda+n {
|
||||||
|
panic(shortA)
|
||||||
}
|
}
|
||||||
checkMatrix(m, n, a, lda)
|
|
||||||
|
|
||||||
// Test common case where corner is non-zero.
|
// Test common case where corner is non-zero.
|
||||||
if a[n-1] != 0 || a[(m-1)*lda+(n-1)] != 0 {
|
if a[n-1] != 0 || a[(m-1)*lda+(n-1)] != 0 {
|
||||||
|
@@ -9,11 +9,22 @@ package gonum
|
|||||||
//
|
//
|
||||||
// Iladlr is an internal routine. It is exported for testing purposes.
|
// Iladlr is an internal routine. It is exported for testing purposes.
|
||||||
func (Implementation) Iladlr(m, n int, a []float64, lda int) int {
|
func (Implementation) Iladlr(m, n int, a []float64, lda int) int {
|
||||||
if m == 0 {
|
switch {
|
||||||
return m - 1
|
case m < 0:
|
||||||
|
panic(mLT0)
|
||||||
|
case n < 0:
|
||||||
|
panic(nLT0)
|
||||||
|
case lda < max(1, n):
|
||||||
|
panic(badLdA)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkMatrix(m, n, a, lda)
|
if n == 0 || m == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(a) < (m-1)*lda+n {
|
||||||
|
panic(shortA)
|
||||||
|
}
|
||||||
|
|
||||||
// Check the common case where the corner is non-zero
|
// Check the common case where the corner is non-zero
|
||||||
if a[(m-1)*lda] != 0 || a[(m-1)*lda+n-1] != 0 {
|
if a[(m-1)*lda] != 0 || a[(m-1)*lda+n-1] != 0 {
|
||||||
|
@@ -109,12 +109,12 @@ func testDtrevc3(t *testing.T, impl Dtrevc3er, side lapack.EVSide, howmny lapack
|
|||||||
work := make([]float64, max(1, 3*n))
|
work := make([]float64, max(1, 3*n))
|
||||||
if optwork {
|
if optwork {
|
||||||
impl.Dtrevc3(side, howmny, selected, n, tmat.Data, tmat.Stride,
|
impl.Dtrevc3(side, howmny, selected, n, tmat.Data, tmat.Stride,
|
||||||
vl.Data, vl.Stride, vr.Data, vr.Stride, mWant, work, -1)
|
vl.Data, max(1, vl.Stride), vr.Data, max(1, vr.Stride), mWant, work, -1)
|
||||||
work = make([]float64, int(work[0]))
|
work = make([]float64, int(work[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
m := impl.Dtrevc3(side, howmny, selected, n, tmat.Data, tmat.Stride,
|
m := impl.Dtrevc3(side, howmny, selected, n, tmat.Data, tmat.Stride,
|
||||||
vl.Data, vl.Stride, vr.Data, vr.Stride, mWant, work, len(work))
|
vl.Data, max(1, vl.Stride), vr.Data, max(1, vr.Stride), mWant, work, len(work))
|
||||||
|
|
||||||
prefix := fmt.Sprintf("Case side=%v, howmny=%v, n=%v, extra=%v, optwk=%v",
|
prefix := fmt.Sprintf("Case side=%v, howmny=%v, n=%v, extra=%v, optwk=%v",
|
||||||
side, howmny, n, extra, optwork)
|
side, howmny, n, extra, optwork)
|
||||||
|
@@ -63,7 +63,7 @@ func testDtrexc(t *testing.T, impl Dtrexcer, compq lapack.UpdateSchurComp, tmat
|
|||||||
|
|
||||||
work := nanSlice(n)
|
work := nanSlice(n)
|
||||||
|
|
||||||
ifstGot, ilstGot, ok := impl.Dtrexc(compq, n, tmat.Data, tmat.Stride, q.Data, q.Stride, ifst, ilst, work)
|
ifstGot, ilstGot, ok := impl.Dtrexc(compq, n, tmat.Data, tmat.Stride, q.Data, max(1, q.Stride), ifst, ilst, work)
|
||||||
|
|
||||||
prefix := fmt.Sprintf("Case compq=%v, n=%v, ifst=%v, nbf=%v, ilst=%v, nbl=%v, extra=%v",
|
prefix := fmt.Sprintf("Case compq=%v, n=%v, ifst=%v, nbf=%v, ilst=%v, nbl=%v, extra=%v",
|
||||||
compq, n, ifst, fstSize, ilst, lstSize, extra)
|
compq, n, ifst, fstSize, ilst, lstSize, extra)
|
||||||
|
Reference in New Issue
Block a user