| // Copyright ©2019 The Gonum Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package testlapack |
| |
| import ( |
| "math" |
| "testing" |
| |
| "golang.org/x/exp/rand" |
| ) |
| |
| type Dcombssqer interface { |
| Dcombssq(scale1, ssq1, scale2, ssq2 float64) (scale, ssq float64) |
| } |
| |
| func DcombssqTest(t *testing.T, impl Dcombssqer) { |
| const tol = 1e-15 |
| |
| rnd := rand.New(rand.NewSource(1)) |
| for i := 0; i < 100; i++ { |
| // Generate random, non-negative input, with an occasional NaN. |
| var hasNaN bool |
| scale1 := rnd.Float64() |
| var ssq1 float64 |
| if rnd.Float64() < 0.5 { |
| ssq1 = math.NaN() |
| hasNaN = true |
| } else { |
| ssq1 = rnd.Float64() |
| } |
| |
| scale2 := rnd.Float64() |
| var ssq2 float64 |
| if rnd.Float64() < 0.5 { |
| ssq2 = math.NaN() |
| hasNaN = true |
| } else { |
| ssq2 = rnd.Float64() |
| } |
| |
| switch rnd.Intn(4) { |
| case 0: |
| scale1 = 0 |
| case 1: |
| scale2 = 0 |
| case 2: |
| scale1, scale2 = 0, 0 |
| } |
| |
| // Compute scale and ssq such that |
| // scale^2 * ssq := scale1^2 * ssq1 + scale2^2 * ssq2 |
| scale, ssq := impl.Dcombssq(scale1, ssq1, scale2, ssq2) |
| |
| if hasNaN { |
| if !math.IsNaN(ssq) { |
| t.Errorf("Case %v: unexpected ssq; got %v, want NaN", i, ssq) |
| } |
| continue |
| } |
| |
| // Compute the expected result in a non-sophisticated way and |
| // compare against the result we got. |
| want := scale1*scale1*ssq1 + scale2*scale2*ssq2 |
| got := scale * scale * ssq |
| if math.Abs(want-got) >= tol { |
| t.Errorf("Case %v: unexpected result; got %v, want %v", i, got, want) |
| } |
| } |
| } |