github.com/gopherd/gonum@v0.0.4/lapack/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 "testing" 10 11 "math/rand" 12 13 "github.com/gopherd/gonum/blas/blas64" 14 "github.com/gopherd/gonum/lapack" 15 ) 16 17 type Dlanger interface { 18 Dlange(norm lapack.MatrixNorm, m, n int, a []float64, lda int, work []float64) float64 19 } 20 21 func DlangeTest(t *testing.T, impl Dlanger) { 22 rnd := rand.New(rand.NewSource(1)) 23 for _, test := range []struct { 24 m, n, lda int 25 }{ 26 {4, 3, 0}, 27 {3, 4, 0}, 28 {4, 3, 100}, 29 {3, 4, 100}, 30 } { 31 m := test.m 32 n := test.n 33 lda := test.lda 34 if lda == 0 { 35 lda = n 36 } 37 // Allocate m×n matrix A and fill it with random numbers from [-0.5, 0.5). 38 a := make([]float64, m*lda) 39 for i := range a { 40 a[i] = rnd.Float64() - 0.5 41 } 42 // Store a copy of A for later comparison. 43 aCopy := make([]float64, len(a)) 44 copy(aCopy, a) 45 46 // Allocate workspace slice. 47 work := make([]float64, n) 48 for i := range work { 49 work[i] = rnd.Float64() 50 } 51 52 // Test various norms by comparing the result from Dlange with 53 // explicit calculation. 54 55 // Test MaxAbs norm. 56 norm := impl.Dlange(lapack.MaxAbs, m, n, a, lda, work) 57 var ans float64 58 for i := 0; i < m; i++ { 59 idx := blas64.Iamax(blas64.Vector{N: n, Inc: 1, Data: aCopy[i*lda:]}) 60 ans = math.Max(ans, math.Abs(a[i*lda+idx])) 61 } 62 // Should be strictly equal because there is no floating point summation error. 63 if ans != norm { 64 t.Errorf("MaxAbs mismatch. Want %v, got %v.", ans, norm) 65 } 66 67 // Test MaxColumnSum norm. 68 norm = impl.Dlange(lapack.MaxColumnSum, m, n, a, lda, work) 69 ans = 0 70 for i := 0; i < n; i++ { 71 sum := blas64.Asum(blas64.Vector{N: m, Inc: lda, Data: aCopy[i:]}) 72 ans = math.Max(ans, sum) 73 } 74 if math.Abs(norm-ans) > 1e-14 { 75 t.Errorf("MaxColumnSum mismatch. Want %v, got %v.", ans, norm) 76 } 77 78 // Test MaxRowSum norm. 79 norm = impl.Dlange(lapack.MaxRowSum, m, n, a, lda, work) 80 ans = 0 81 for i := 0; i < m; i++ { 82 sum := blas64.Asum(blas64.Vector{N: n, Inc: 1, Data: aCopy[i*lda:]}) 83 ans = math.Max(ans, sum) 84 } 85 if math.Abs(norm-ans) > 1e-14 { 86 t.Errorf("MaxRowSum mismatch. Want %v, got %v.", ans, norm) 87 } 88 89 // Test Frobenius norm. 90 norm = impl.Dlange(lapack.Frobenius, m, n, a, lda, work) 91 ans = 0 92 for i := 0; i < m; i++ { 93 sum := blas64.Nrm2(blas64.Vector{N: n, Inc: 1, Data: aCopy[i*lda:]}) 94 ans += sum * sum 95 } 96 ans = math.Sqrt(ans) 97 if math.Abs(norm-ans) > 1e-14 { 98 t.Errorf("Frobenius norm mismatch. Want %v, got %v.", ans, norm) 99 } 100 } 101 }