lapack/gonum: fix underflow in Dlanv2
MODIFY
lapack/gonum/dlanv2.go
lapack/gonum/dlanv2.go
@@ -66,7 +66,21 @@ func (impl Implementation) Dlanv2(a, b, c, d float64) (aa, bb, cc, dd float64, r
} else {
// Complex eigenvalues, or real (almost) equal eigenvalues.
// Make diagonal elements equal.
+ safmn2 := math.Pow(dlamchB, math.Log(dlamchS/dlamchE)/math.Log(dlamchB)/2)
+ safmx2 := 1 / safmn2
sigma := b + c
+ for iter := 0; iter < 20; iter++ {
+ scale = math.Max(math.Abs(temp), math.Abs(sigma))
+ switch {
+ case scale >= safmx2:
+ sigma *= safmn2
+ temp *= safmn2
+ case scale <= safmn2:
+ sigma *= safmx2
+ temp *= safmx2
+ }
+ }
+ p = temp / 2
tau := impl.Dlapy2(sigma, temp)
cs = math.Sqrt((1 + math.Abs(sigma)/tau) / 2)
sn = -p / (tau * cs)

MODIFY
lapack/testlapack/dlanv2.go
lapack/testlapack/dlanv2.go
@@ -53,6 +53,9 @@ func Dlanv2Test(t *testing.T, impl Dlanv2er) {
d := rnd.NormFloat64()
dlanv2Test(t, impl, a, b, c, d)
}
+
+ // https://github.com/Reference-LAPACK/lapack/issues/263
+ dlanv2Test(t, impl, 0, 1, -1, math.Nextafter(0, 1))
})
}

lapack/gonum: fix underflow in Dlanv2