testlapack: test Dgeev for intermediate workspace size

This commit is contained in:
Vladimir Chalupecky
2016-10-05 11:36:39 +09:00
parent 8e7c4f0b6f
commit ee1b8334b2
2 changed files with 32 additions and 11 deletions

View File

@@ -477,8 +477,8 @@ func DgeevTest(t *testing.T, impl Dgeever) {
for _, jobvl := range []lapack.JobLeftEV{lapack.ComputeLeftEV, lapack.None} { for _, jobvl := range []lapack.JobLeftEV{lapack.ComputeLeftEV, lapack.None} {
for _, jobvr := range []lapack.JobRightEV{lapack.ComputeRightEV, lapack.None} { for _, jobvr := range []lapack.JobRightEV{lapack.ComputeRightEV, lapack.None} {
for _, extra := range []int{0, 11} { for _, extra := range []int{0, 11} {
for _, optwork := range []bool{false, true} { for _, wl := range []worklen{minimumWork, mediumWork, optimumWork} {
testDgeev(t, impl, strconv.Itoa(i), test, jobvl, jobvr, extra, optwork) testDgeev(t, impl, strconv.Itoa(i), test, jobvl, jobvr, extra, wl)
} }
} }
} }
@@ -534,14 +534,14 @@ func DgeevTest(t *testing.T, impl Dgeever) {
valTol: 1e-12, valTol: 1e-12,
vecTol: 1e-8, vecTol: 1e-8,
} }
testDgeev(t, impl, "random", test, jobvl, jobvr, 0, true) testDgeev(t, impl, "random", test, jobvl, jobvr, 0, optimumWork)
} }
} }
} }
} }
} }
func testDgeev(t *testing.T, impl Dgeever, tc string, test dgeevTest, jobvl lapack.JobLeftEV, jobvr lapack.JobRightEV, extra int, optwork bool) { func testDgeev(t *testing.T, impl Dgeever, tc string, test dgeevTest, jobvl lapack.JobLeftEV, jobvr lapack.JobRightEV, extra int, wl worklen) {
const defaultTol = 1e-13 const defaultTol = 1e-13
valTol := test.valTol valTol := test.valTol
if valTol == 0 { if valTol == 0 {
@@ -568,11 +568,23 @@ func testDgeev(t *testing.T, impl Dgeever, tc string, test dgeevTest, jobvl lapa
wr := make([]float64, n) wr := make([]float64, n)
wi := make([]float64, n) wi := make([]float64, n)
lwork := max(1, 3*n) var lwork int
switch wl {
case minimumWork:
lwork = max(1, 3*n)
if jobvl == lapack.ComputeLeftEV || jobvr == lapack.ComputeRightEV { if jobvl == lapack.ComputeLeftEV || jobvr == lapack.ComputeRightEV {
lwork = max(1, 4*n) lwork = max(1, 4*n)
} }
if optwork { case mediumWork:
work := make([]float64, 1)
impl.Dgeev(jobvl, jobvr, n, nil, 1, nil, nil, nil, 1, nil, 1, work, -1)
lwork = int(work[0])
lwork = (lwork + 3*n) / 2
if jobvl == lapack.ComputeLeftEV || jobvr == lapack.ComputeRightEV {
lwork = (lwork + 4*n) / 2
}
lwork = max(1, lwork)
case optimumWork:
work := make([]float64, 1) work := make([]float64, 1)
impl.Dgeev(jobvl, jobvr, n, nil, 1, nil, nil, nil, 1, nil, 1, work, -1) impl.Dgeev(jobvl, jobvr, n, nil, 1, nil, nil, nil, 1, nil, 1, work, -1)
lwork = int(work[0]) lwork = int(work[0])
@@ -582,8 +594,8 @@ func testDgeev(t *testing.T, impl Dgeever, tc string, test dgeevTest, jobvl lapa
first := impl.Dgeev(jobvl, jobvr, n, a.Data, a.Stride, wr, wi, first := impl.Dgeev(jobvl, jobvr, n, a.Data, a.Stride, wr, wi,
vl.Data, vl.Stride, vr.Data, vr.Stride, work, len(work)) vl.Data, vl.Stride, vr.Data, vr.Stride, work, len(work))
prefix := fmt.Sprintf("Case #%v: n=%v, jobvl=%v, jobvr=%v, extra=%v, optwk=%v", prefix := fmt.Sprintf("Case #%v: n=%v, jobvl=%v, jobvr=%v, extra=%v, work=%v",
tc, n, jobvl, jobvr, extra, optwork) tc, n, jobvl, jobvr, extra, wl)
if !generalOutsideAllNaN(vl) { if !generalOutsideAllNaN(vl) {
t.Errorf("%v: out-of-range write to VL", prefix) t.Errorf("%v: out-of-range write to VL", prefix)

View File

@@ -31,6 +31,15 @@ func min(a, b int) int {
return b return b
} }
// worklen describes how much workspace a test should use.
type worklen int
const (
minimumWork worklen = iota
mediumWork
optimumWork
)
// nanSlice allocates a new slice of length n filled with NaN. // nanSlice allocates a new slice of length n filled with NaN.
func nanSlice(n int) []float64 { func nanSlice(n int) []float64 {
s := make([]float64, n) s := make([]float64, n)