// 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 ( "fmt" "math" "testing" "golang.org/x/exp/rand" "gonum.org/v1/gonum/floats" ) type Dlassqer interface { Dlassq(n int, x []float64, incx int, scale, ssq float64) (float64, float64) } func DlassqTest(t *testing.T, impl Dlassqer) { const tol = 1e-14 rnd := rand.New(rand.NewSource(1)) for _, n := range []int{0, 1, 2, 3, 4, 5, 10} { for _, incx := range []int{1, 3} { name := fmt.Sprintf("n=%v,incx=%v", n, incx) // Allocate a slice of minimum length and fill it with // random numbers. x := make([]float64, max(0, 1+(n-1)*incx)) for i := range x { x[i] = rnd.Float64() } // Fill the referenced elements of x and compute the // expected result in a non-sophisticated way. scale := rnd.Float64() ssq := rnd.Float64() want := scale * scale * ssq for i := 0; i < n; i++ { xi := rnd.NormFloat64() x[i*incx] = xi want += xi * xi } xCopy := make([]float64, len(x)) copy(xCopy, x) // Update scale and ssq so that // scale_out^2 * ssq_out = x[0]^2 + ... + x[n-1]^2 + scale_in^2*ssq_in scale, ssq = impl.Dlassq(n, x, incx, scale, ssq) if !floats.Equal(x, xCopy) { t.Fatalf("%v: unexpected modification of x", name) } // Check the result. got := scale * scale * ssq if math.Abs(got-want) >= tol { t.Errorf("%v: unexpected result; got %v, want %v", name, got, want) } } } }