gonum.org/v1/gonum@v0.14.0/internal/asm/f32/util_test.go (about)

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