github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/testlapack/dlange.go (about) 1 // Copyright ©2015 The gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package testlapack 6 7 import ( 8 "math" 9 "math/rand" 10 "testing" 11 12 "github.com/gonum/blas/blas64" 13 "github.com/gonum/lapack" 14 ) 15 16 type Dlanger interface { 17 Dlange(norm lapack.MatrixNorm, m, n int, a []float64, lda int, work []float64) float64 18 } 19 20 func DlangeTest(t *testing.T, impl Dlanger) { 21 rnd := rand.New(rand.NewSource(1)) 22 for _, test := range []struct { 23 m, n, lda int 24 }{ 25 {4, 3, 0}, 26 {3, 4, 0}, 27 {4, 3, 100}, 28 {3, 4, 100}, 29 } { 30 m := test.m 31 n := test.n 32 lda := test.lda 33 if lda == 0 { 34 lda = n 35 } 36 a := make([]float64, m*lda) 37 for i := range a { 38 a[i] = rnd.Float64() - 0.5 39 } 40 work := make([]float64, n) 41 for i := range work { 42 work[i] = rnd.Float64() 43 } 44 aCopy := make([]float64, len(a)) 45 copy(aCopy, a) 46 47 // Test MaxAbs norm. 48 norm := impl.Dlange(lapack.MaxAbs, m, n, a, lda, work) 49 var ans float64 50 for i := 0; i < m; i++ { 51 idx := blas64.Iamax(n, blas64.Vector{Inc: 1, Data: aCopy[i*lda:]}) 52 ans = math.Max(ans, math.Abs(a[i*lda+idx])) 53 } 54 // Should be strictly equal because there is no floating point summation error. 55 if ans != norm { 56 t.Errorf("MaxAbs mismatch. Want %v, got %v.", ans, norm) 57 } 58 59 // Test MaxColumnSum norm. 60 norm = impl.Dlange(lapack.MaxColumnSum, m, n, a, lda, work) 61 ans = 0 62 for i := 0; i < n; i++ { 63 sum := blas64.Asum(m, blas64.Vector{Inc: lda, Data: aCopy[i:]}) 64 ans = math.Max(ans, sum) 65 } 66 if math.Abs(norm-ans) > 1e-14 { 67 t.Errorf("MaxColumnSum mismatch. Want %v, got %v.", ans, norm) 68 } 69 70 // Test MaxRowSum norm. 71 norm = impl.Dlange(lapack.MaxRowSum, m, n, a, lda, work) 72 ans = 0 73 for i := 0; i < m; i++ { 74 sum := blas64.Asum(n, blas64.Vector{Inc: 1, Data: aCopy[i*lda:]}) 75 ans = math.Max(ans, sum) 76 } 77 if math.Abs(norm-ans) > 1e-14 { 78 t.Errorf("MaxRowSum mismatch. Want %v, got %v.", ans, norm) 79 } 80 81 // Test Frobenius norm 82 norm = impl.Dlange(lapack.NormFrob, m, n, a, lda, work) 83 ans = 0 84 for i := 0; i < m; i++ { 85 sum := blas64.Nrm2(n, blas64.Vector{Inc: 1, Data: aCopy[i*lda:]}) 86 ans += sum * sum 87 } 88 ans = math.Sqrt(ans) 89 if math.Abs(norm-ans) > 1e-14 { 90 t.Errorf("NormFrob mismatch. Want %v, got %v.", ans, norm) 91 } 92 } 93 }