1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// Copyright ©2015 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 f32_test
import (
"math"
"testing"
"gonum.org/v1/gonum/floats/scalar"
)
const (
msgRes = "%v: unexpected result Got: %v Expected: %v"
msgVal = "%v: unexpected value at %v Got: %v Expected: %v"
msgGuard = "%v: guard violated in %s vector %v %v"
msgReadOnly = "%v: modified read-only %v argument"
)
var (
nan = float32(math.NaN())
inf = float32(math.Inf(1))
)
// sameApprox tests for nan-aware equality within tolerance.
func sameApprox(x, y, tol float32) bool {
a, b := float64(x), float64(y)
return same(x, y) || scalar.EqualWithinAbsOrRel(a, b, float64(tol), float64(tol))
}
func same(x, y float32) bool {
return scalar.Same(float64(x), float64(y))
}
// sameStrided returns true if the strided vector x contains elements of the
// dense vector ref at indices i*inc, false otherwise.
func sameStrided(ref, x []float32, inc int) bool {
if inc < 0 {
inc = -inc
}
for i, v := range ref {
if !same(x[i*inc], v) {
return false
}
}
return true
}
func guardVector(v []float32, g float32, gdLn int) (guarded []float32) {
guarded = make([]float32, len(v)+gdLn*2)
copy(guarded[gdLn:], v)
for i := 0; i < gdLn; i++ {
guarded[i] = g
guarded[len(guarded)-1-i] = g
}
return guarded
}
func isValidGuard(v []float32, g float32, gdLn int) bool {
for i := 0; i < gdLn; i++ {
if !same(v[i], g) || !same(v[len(v)-1-i], g) {
return false
}
}
return true
}
func guardIncVector(vec []float32, gdVal float32, inc, gdLen int) (guarded []float32) {
if inc < 0 {
inc = -inc
}
inrLen := len(vec) * inc
guarded = make([]float32, inrLen+gdLen*2)
for i := range guarded {
guarded[i] = gdVal
}
for i, v := range vec {
guarded[gdLen+i*inc] = v
}
return guarded
}
func checkValidIncGuard(t *testing.T, v []float32, g float32, inc, gdLn int) {
srcLn := len(v) - 2*gdLn
for i := range v {
switch {
case same(v[i], g):
// Correct value
case i < gdLn:
t.Error("Front guard violated at", i, v[:gdLn])
case i > gdLn+srcLn:
t.Error("Back guard violated at", i-gdLn-srcLn, v[gdLn+srcLn:])
case (i-gdLn)%inc == 0 && (i-gdLn)/inc < len(v):
default:
t.Error("Internal guard violated at", i-gdLn, v[gdLn:gdLn+srcLn])
}
}
}
var ( // Offset sets for testing alignment handling in Unitary assembly functions.
align2 = newIncSet(0, 1, 2, 3)
align3 = newIncToSet(0, 1, 2, 3)
)
type incSet struct {
x, y int
}
// genInc will generate all (x,y) combinations of the input increment set.
func newIncSet(inc ...int) []incSet {
n := len(inc)
is := make([]incSet, n*n)
for x := range inc {
for y := range inc {
is[x*n+y] = incSet{inc[x], inc[y]}
}
}
return is
}
type incToSet struct {
dst, x, y int
}
// genIncTo will generate all (dst,x,y) combinations of the input increment set.
func newIncToSet(inc ...int) []incToSet {
n := len(inc)
is := make([]incToSet, n*n*n)
for i, dst := range inc {
for x := range inc {
for y := range inc {
is[i*n*n+x*n+y] = incToSet{dst, inc[x], inc[y]}
}
}
}
return is
}
|