github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/testlapack/dlascl.go (about)

     1  // Copyright ©2016 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  	"fmt"
     9  	"math"
    10  	"math/rand"
    11  	"testing"
    12  
    13  	"github.com/gonum/lapack"
    14  )
    15  
    16  type Dlascler interface {
    17  	Dlascl(kind lapack.MatrixType, kl, ku int, cfrom, cto float64, m, n int, a []float64, lda int)
    18  }
    19  
    20  func DlasclTest(t *testing.T, impl Dlascler) {
    21  	const tol = 1e-16
    22  
    23  	rnd := rand.New(rand.NewSource(1))
    24  	for ti, test := range []struct {
    25  		m, n int
    26  	}{
    27  		{0, 0},
    28  		{1, 1},
    29  		{1, 10},
    30  		{10, 1},
    31  		{2, 2},
    32  		{2, 11},
    33  		{11, 2},
    34  		{3, 3},
    35  		{3, 11},
    36  		{11, 3},
    37  		{11, 11},
    38  		{11, 100},
    39  		{100, 11},
    40  	} {
    41  		m := test.m
    42  		n := test.n
    43  		for _, extra := range []int{0, 11} {
    44  			for _, kind := range []lapack.MatrixType{lapack.General, lapack.UpperTri, lapack.LowerTri} {
    45  				a := randomGeneral(m, n, n+extra, rnd)
    46  				aCopy := cloneGeneral(a)
    47  				cfrom := rnd.NormFloat64()
    48  				cto := rnd.NormFloat64()
    49  				scale := cto / cfrom
    50  
    51  				impl.Dlascl(kind, -1, -1, cfrom, cto, m, n, a.Data, a.Stride)
    52  
    53  				prefix := fmt.Sprintf("Case #%v: kind=%v,m=%v,n=%v,extra=%v", ti, kind, m, n, extra)
    54  				if !generalOutsideAllNaN(a) {
    55  					t.Errorf("%v: out-of-range write to A", prefix)
    56  				}
    57  				switch kind {
    58  				case lapack.General:
    59  					for i := 0; i < m; i++ {
    60  						for j := 0; j < n; j++ {
    61  							want := scale * aCopy.Data[i*aCopy.Stride+j]
    62  							got := a.Data[i*a.Stride+j]
    63  							if math.Abs(want-got) > tol {
    64  								t.Errorf("%v: unexpected A[%v,%v]=%v, want %v", prefix, i, j, got, want)
    65  							}
    66  						}
    67  					}
    68  				case lapack.UpperTri:
    69  					for i := 0; i < m; i++ {
    70  						for j := i; j < n; j++ {
    71  							want := scale * aCopy.Data[i*aCopy.Stride+j]
    72  							got := a.Data[i*a.Stride+j]
    73  							if math.Abs(want-got) > tol {
    74  								t.Errorf("%v: unexpected A[%v,%v]=%v, want %v", prefix, i, j, got, want)
    75  							}
    76  						}
    77  					}
    78  					for i := 0; i < m; i++ {
    79  						for j := 0; j < min(i, n); j++ {
    80  							if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] {
    81  								t.Errorf("%v: unexpected modification in lower triangle of A", prefix)
    82  							}
    83  						}
    84  					}
    85  				case lapack.LowerTri:
    86  					for i := 0; i < m; i++ {
    87  						for j := 0; j <= min(i, n-1); j++ {
    88  							want := scale * aCopy.Data[i*aCopy.Stride+j]
    89  							got := a.Data[i*a.Stride+j]
    90  							if math.Abs(want-got) > tol {
    91  								t.Errorf("%v: unexpected A[%v,%v]=%v, want %v", prefix, i, j, got, want)
    92  							}
    93  						}
    94  					}
    95  					for i := 0; i < m; i++ {
    96  						for j := i + 1; j < n; j++ {
    97  							if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] {
    98  								t.Errorf("%v: unexpected modification in upper triangle of A", prefix)
    99  							}
   100  						}
   101  					}
   102  				}
   103  			}
   104  		}
   105  	}
   106  }