testlapack: add dlansb helper and use it in DpbconTest
MODIFY
lapack/testlapack/dpbcon.go
lapack/testlapack/dpbcon.go
@@ -19,8 +19,6 @@ type Dpbconer interface {
Dpbcon(uplo blas.Uplo, n, kd int, ab []float64, ldab int, anorm float64, work []float64, iwork []int) float64
Dpbtrser
- Dlanger
- Dlansber
}
// DpbconTest tests Dpbcon by generating a random symmetric band matrix A and
@@ -57,7 +55,7 @@ func dpbconTest(t *testing.T, impl Dpbconer, uplo blas.Uplo, n, kd, ldab int, rn
// Compute the norm of A.
work := make([]float64, 3*n)
- aNorm := impl.Dlansb(lapack.MaxColumnSum, uplo, n, kd, ab, ldab, work)
+ aNorm := dlansb(lapack.MaxColumnSum, uplo, n, kd, ab, ldab, work)
// Compute an estimate of rCond.
iwork := make([]int, n)
@@ -77,7 +75,7 @@ func dpbconTest(t *testing.T, impl Dpbconer, uplo blas.Uplo, n, kd, ldab int, rn
aInv[i*lda+i] = 1
}
impl.Dpbtrs(uplo, n, kd, n, abFac, ldab, aInv, lda)
- aInvNorm := impl.Dlange(lapack.MaxColumnSum, n, n, aInv, lda, work)
+ aInvNorm := dlange(lapack.MaxColumnSum, n, n, aInv, lda)
rCondWant := 1.0
if aNorm > 0 && aInvNorm > 0 {
rCondWant = 1 / aNorm / aInvNorm

MODIFY
lapack/testlapack/general.go
lapack/testlapack/general.go
@@ -1450,3 +1450,70 @@ func dlange(norm lapack.MatrixNorm, m, n int, a []float64, lda int) float64 {
panic("bad MatrixNorm")
}
}
+
+// dlansb is a local implementation of Dlansb to keep code paths independent.
+func dlansb(norm lapack.MatrixNorm, uplo blas.Uplo, n, kd int, ab []float64, ldab int, work []float64) float64 {
+ if n == 0 {
+ return 0
+ }
+ var value float64
+ switch norm {
+ case lapack.MaxAbs:
+ if uplo == blas.Upper {
+ for i := 0; i < n; i++ {
+ for j := 0; j < min(n-i, kd+1); j++ {
+ aij := math.Abs(ab[i*ldab+j])
+ if aij > value || math.IsNaN(aij) {
+ value = aij
+ }
+ }
+ }
+ } else {
+ for i := 0; i < n; i++ {
+ for j := max(0, kd-i); j < kd+1; j++ {
+ aij := math.Abs(ab[i*ldab+j])
+ if aij > value || math.IsNaN(aij) {
+ value = aij
+ }
+ }
+ }
+ }
+ case lapack.MaxColumnSum, lapack.MaxRowSum:
+ work = work[:n]
+ var sum float64
+ if uplo == blas.Upper {
+ for i := range work {
+ work[i] = 0
+ }
+ for i := 0; i < n; i++ {
+ sum := work[i] + math.Abs(ab[i*ldab])
+ for j := i + 1; j < min(i+kd+1, n); j++ {
+ aij := math.Abs(ab[i*ldab+j-i])
+ sum += aij
+ work[j] += aij
+ }
+ if sum > value || math.IsNaN(sum) {
+ value = sum
+ }
+ }
+ } else {
+ for i := 0; i < n; i++ {
+ sum = 0
+ for j := max(0, i-kd); j < i; j++ {
+ aij := math.Abs(ab[i*ldab+kd+j-i])
+ sum += aij
+ work[j] += aij
+ }
+ work[i] = sum + math.Abs(ab[i*ldab+kd])
+ }
+ for _, sum := range work {
+ if sum > value || math.IsNaN(sum) {
+ value = sum
+ }
+ }
+ }
+ case lapack.Frobenius:
+ panic("not implemented")
+ }
+ return value
+}

testlapack: add dlansb helper and use it in DpbconTest