github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/lapack/testlapack/dcombssq.go (about)

     1  // Copyright ©2019 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  	"golang.org/x/exp/rand"
    12  )
    13  
    14  type Dcombssqer interface {
    15  	Dcombssq(scale1, ssq1, scale2, ssq2 float64) (scale, ssq float64)
    16  }
    17  
    18  func DcombssqTest(t *testing.T, impl Dcombssqer) {
    19  	const tol = 1e-15
    20  
    21  	rnd := rand.New(rand.NewSource(1))
    22  	for i := 0; i < 100; i++ {
    23  		// Generate random, non-negative input, with an occasional NaN.
    24  		var hasNaN bool
    25  		scale1 := rnd.Float64()
    26  		var ssq1 float64
    27  		if rnd.Float64() < 0.5 {
    28  			ssq1 = math.NaN()
    29  			hasNaN = true
    30  		} else {
    31  			ssq1 = rnd.Float64()
    32  		}
    33  
    34  		scale2 := rnd.Float64()
    35  		var ssq2 float64
    36  		if rnd.Float64() < 0.5 {
    37  			ssq2 = math.NaN()
    38  			hasNaN = true
    39  		} else {
    40  			ssq2 = rnd.Float64()
    41  		}
    42  
    43  		switch rnd.Intn(4) {
    44  		case 0:
    45  			scale1 = 0
    46  		case 1:
    47  			scale2 = 0
    48  		case 2:
    49  			scale1, scale2 = 0, 0
    50  		}
    51  
    52  		// Compute scale and ssq such that
    53  		//  scale^2 * ssq := scale1^2 * ssq1 + scale2^2 * ssq2
    54  		scale, ssq := impl.Dcombssq(scale1, ssq1, scale2, ssq2)
    55  
    56  		if hasNaN {
    57  			if !math.IsNaN(ssq) {
    58  				t.Errorf("Case %v: unexpected ssq; got %v, want NaN", i, ssq)
    59  			}
    60  			continue
    61  		}
    62  
    63  		// Compute the expected result in a non-sophisticated way and
    64  		// compare against the result we got.
    65  		want := scale1*scale1*ssq1 + scale2*scale2*ssq2
    66  		got := scale * scale * ssq
    67  		if math.Abs(want-got) >= tol {
    68  			t.Errorf("Case %v: unexpected result; got %v, want %v", i, got, want)
    69  		}
    70  	}
    71  }