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  }