github.com/gopherd/gonum@v0.0.4/floats/floats_test.go (about)

     1  // Copyright ©2013 The Gonum Authors. All rights reserved.
     2  // Use of this code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package floats
     6  
     7  import (
     8  	"fmt"
     9  	"math"
    10  	"sort"
    11  	"strconv"
    12  	"testing"
    13  
    14  	"math/rand"
    15  
    16  	"github.com/gopherd/gonum/floats/scalar"
    17  )
    18  
    19  const (
    20  	EqTolerance = 1e-14
    21  	Small       = 10
    22  	Medium      = 1000
    23  	Large       = 100000
    24  	Huge        = 10000000
    25  )
    26  
    27  func areSlicesEqual(t *testing.T, truth, comp []float64, str string) {
    28  	if !EqualApprox(comp, truth, EqTolerance) {
    29  		t.Errorf(str+". Expected %v, returned %v", truth, comp)
    30  	}
    31  }
    32  
    33  func areSlicesSame(t *testing.T, truth, comp []float64, str string) {
    34  	ok := len(truth) == len(comp)
    35  	if ok {
    36  		for i, a := range truth {
    37  			if !scalar.EqualWithinAbsOrRel(a, comp[i], EqTolerance, EqTolerance) && !scalar.Same(a, comp[i]) {
    38  				ok = false
    39  				break
    40  			}
    41  		}
    42  	}
    43  	if !ok {
    44  		t.Errorf(str+". Expected %v, returned %v", truth, comp)
    45  	}
    46  }
    47  
    48  func Panics(fun func()) (b bool) {
    49  	defer func() {
    50  		err := recover()
    51  		if err != nil {
    52  			b = true
    53  		}
    54  	}()
    55  	fun()
    56  	return
    57  }
    58  
    59  func TestAdd(t *testing.T) {
    60  	t.Parallel()
    61  	a := []float64{1, 2, 3}
    62  	b := []float64{4, 5, 6}
    63  	c := []float64{7, 8, 9}
    64  	truth := []float64{12, 15, 18}
    65  	n := make([]float64, len(a))
    66  
    67  	Add(n, a)
    68  	Add(n, b)
    69  	Add(n, c)
    70  	areSlicesEqual(t, truth, n, "Wrong addition of slices new receiver")
    71  	Add(a, b)
    72  	Add(a, c)
    73  	areSlicesEqual(t, truth, n, "Wrong addition of slices for no new receiver")
    74  
    75  	// Test that it panics
    76  	if !Panics(func() { Add(make([]float64, 2), make([]float64, 3)) }) {
    77  		t.Errorf("Did not panic with length mismatch")
    78  	}
    79  }
    80  
    81  func TestAddTo(t *testing.T) {
    82  	t.Parallel()
    83  	a := []float64{1, 2, 3}
    84  	b := []float64{4, 5, 6}
    85  	truth := []float64{5, 7, 9}
    86  	n1 := make([]float64, len(a))
    87  
    88  	n2 := AddTo(n1, a, b)
    89  	areSlicesEqual(t, truth, n1, "Bad addition from mutator")
    90  	areSlicesEqual(t, truth, n2, "Bad addition from returned slice")
    91  
    92  	// Test that it panics
    93  	if !Panics(func() { AddTo(make([]float64, 2), make([]float64, 3), make([]float64, 3)) }) {
    94  		t.Errorf("Did not panic with length mismatch")
    95  	}
    96  	if !Panics(func() { AddTo(make([]float64, 3), make([]float64, 3), make([]float64, 2)) }) {
    97  		t.Errorf("Did not panic with length mismatch")
    98  	}
    99  }
   100  
   101  func TestAddConst(t *testing.T) {
   102  	t.Parallel()
   103  	s := []float64{3, 4, 1, 7, 5}
   104  	c := 6.0
   105  	truth := []float64{9, 10, 7, 13, 11}
   106  	AddConst(c, s)
   107  	areSlicesEqual(t, truth, s, "Wrong addition of constant")
   108  }
   109  
   110  func TestAddScaled(t *testing.T) {
   111  	t.Parallel()
   112  	s := []float64{3, 4, 1, 7, 5}
   113  	alpha := 6.0
   114  	dst := []float64{1, 2, 3, 4, 5}
   115  	ans := []float64{19, 26, 9, 46, 35}
   116  	AddScaled(dst, alpha, s)
   117  	if !EqualApprox(dst, ans, EqTolerance) {
   118  		t.Errorf("Adding scaled did not match")
   119  	}
   120  	short := []float64{1}
   121  	if !Panics(func() { AddScaled(dst, alpha, short) }) {
   122  		t.Errorf("Doesn't panic if s is smaller than dst")
   123  	}
   124  	if !Panics(func() { AddScaled(short, alpha, s) }) {
   125  		t.Errorf("Doesn't panic if dst is smaller than s")
   126  	}
   127  }
   128  
   129  func TestAddScaledTo(t *testing.T) {
   130  	t.Parallel()
   131  	s := []float64{3, 4, 1, 7, 5}
   132  	alpha := 6.0
   133  	y := []float64{1, 2, 3, 4, 5}
   134  	dst1 := make([]float64, 5)
   135  	ans := []float64{19, 26, 9, 46, 35}
   136  	dst2 := AddScaledTo(dst1, y, alpha, s)
   137  	if !EqualApprox(dst1, ans, EqTolerance) {
   138  		t.Errorf("AddScaledTo did not match for mutator")
   139  	}
   140  	if !EqualApprox(dst2, ans, EqTolerance) {
   141  		t.Errorf("AddScaledTo did not match for returned slice")
   142  	}
   143  	AddScaledTo(dst1, y, alpha, s)
   144  	if !EqualApprox(dst1, ans, EqTolerance) {
   145  		t.Errorf("Reusing dst did not match")
   146  	}
   147  	short := []float64{1}
   148  	if !Panics(func() { AddScaledTo(dst1, y, alpha, short) }) {
   149  		t.Errorf("Doesn't panic if s is smaller than dst")
   150  	}
   151  	if !Panics(func() { AddScaledTo(short, y, alpha, s) }) {
   152  		t.Errorf("Doesn't panic if dst is smaller than s")
   153  	}
   154  	if !Panics(func() { AddScaledTo(dst1, short, alpha, s) }) {
   155  		t.Errorf("Doesn't panic if y is smaller than dst")
   156  	}
   157  }
   158  
   159  func TestArgsort(t *testing.T) {
   160  	t.Parallel()
   161  	s := []float64{3, 4, 1, 7, 5}
   162  	inds := make([]int, len(s))
   163  
   164  	Argsort(s, inds)
   165  
   166  	sortedS := []float64{1, 3, 4, 5, 7}
   167  	trueInds := []int{2, 0, 1, 4, 3}
   168  
   169  	if !Equal(s, sortedS) {
   170  		t.Error("elements not sorted correctly")
   171  	}
   172  	for i := range trueInds {
   173  		if trueInds[i] != inds[i] {
   174  			t.Error("inds not correct")
   175  		}
   176  	}
   177  
   178  	inds = []int{1, 2}
   179  	if !Panics(func() { Argsort(s, inds) }) {
   180  		t.Error("does not panic if lengths do not match")
   181  	}
   182  }
   183  
   184  func TestArgsortStable(t *testing.T) {
   185  	for i := 1; i <= 100; i++ {
   186  		data := make([]float64, i+2)
   187  		data[0] = 2
   188  		data[len(data)-1] = 2
   189  		for j := 1; j <= i; j++ {
   190  			data[j] = 1
   191  		}
   192  		idx := make([]int, len(data))
   193  		ArgsortStable(data, idx)
   194  		if !sort.Float64sAreSorted(data) {
   195  			t.Errorf("unexpected data sort order for case %d", i)
   196  		}
   197  		if !sort.IntsAreSorted(idx[:i]) {
   198  			t.Errorf("unexpected index sort order for case %d", i)
   199  		}
   200  	}
   201  
   202  	if !Panics(func() { ArgsortStable([]float64{1, 2, 3}, []int{0, 0}) }) {
   203  		t.Error("does not panic if lengths do not match")
   204  	}
   205  }
   206  
   207  func TestCount(t *testing.T) {
   208  	t.Parallel()
   209  	s := []float64{3, 4, 1, 7, 5}
   210  	f := func(v float64) bool { return v > 3.5 }
   211  	truth := 3
   212  	n := Count(f, s)
   213  	if n != truth {
   214  		t.Errorf("Wrong number of elements counted")
   215  	}
   216  }
   217  
   218  func TestCumProd(t *testing.T) {
   219  	t.Parallel()
   220  	s := []float64{3, 4, 1, 7, 5}
   221  	receiver := make([]float64, len(s))
   222  	result := CumProd(receiver, s)
   223  	truth := []float64{3, 12, 12, 84, 420}
   224  	areSlicesEqual(t, truth, receiver, "Wrong cumprod mutated with new receiver")
   225  	areSlicesEqual(t, truth, result, "Wrong cumprod result with new receiver")
   226  	CumProd(receiver, s)
   227  	areSlicesEqual(t, truth, receiver, "Wrong cumprod returned with reused receiver")
   228  
   229  	// Test that it panics
   230  	if !Panics(func() { CumProd(make([]float64, 2), make([]float64, 3)) }) {
   231  		t.Errorf("Did not panic with length mismatch")
   232  	}
   233  
   234  	// Test empty CumProd
   235  	emptyReceiver := make([]float64, 0)
   236  	truth = []float64{}
   237  	CumProd(emptyReceiver, emptyReceiver)
   238  	areSlicesEqual(t, truth, emptyReceiver, "Wrong cumprod returned with empty receiver")
   239  }
   240  
   241  func TestCumSum(t *testing.T) {
   242  	t.Parallel()
   243  	s := []float64{3, 4, 1, 7, 5}
   244  	receiver := make([]float64, len(s))
   245  	result := CumSum(receiver, s)
   246  	truth := []float64{3, 7, 8, 15, 20}
   247  	areSlicesEqual(t, truth, receiver, "Wrong cumsum mutated with new receiver")
   248  	areSlicesEqual(t, truth, result, "Wrong cumsum returned with new receiver")
   249  	CumSum(receiver, s)
   250  	areSlicesEqual(t, truth, receiver, "Wrong cumsum returned with reused receiver")
   251  
   252  	// Test that it panics
   253  	if !Panics(func() { CumSum(make([]float64, 2), make([]float64, 3)) }) {
   254  		t.Errorf("Did not panic with length mismatch")
   255  	}
   256  
   257  	// Test empty CumSum
   258  	emptyReceiver := make([]float64, 0)
   259  	truth = []float64{}
   260  	CumSum(emptyReceiver, emptyReceiver)
   261  	areSlicesEqual(t, truth, emptyReceiver, "Wrong cumsum returned with empty receiver")
   262  }
   263  
   264  func TestDistance(t *testing.T) {
   265  	t.Parallel()
   266  	norms := []float64{1, 2, 4, math.Inf(1)}
   267  	slices := []struct {
   268  		s []float64
   269  		t []float64
   270  	}{
   271  		{
   272  			nil,
   273  			nil,
   274  		},
   275  		{
   276  			[]float64{8, 9, 10, -12},
   277  			[]float64{8, 9, 10, -12},
   278  		},
   279  		{
   280  			[]float64{1, 2, 3, -4, -5, 8},
   281  			[]float64{-9.2, -6.8, 9, -3, -2, 1},
   282  		},
   283  	}
   284  
   285  	for j, test := range slices {
   286  		tmp := make([]float64, len(test.s))
   287  		for i, L := range norms {
   288  			dist := Distance(test.s, test.t, L)
   289  			copy(tmp, test.s)
   290  			Sub(tmp, test.t)
   291  			norm := Norm(tmp, L)
   292  			if dist != norm { // Use equality because they should be identical.
   293  				t.Errorf("Distance does not match norm for case %v, %v. Expected %v, Found %v.", i, j, norm, dist)
   294  			}
   295  		}
   296  	}
   297  
   298  	if !Panics(func() { Distance([]float64{}, norms, 1) }) {
   299  		t.Errorf("Did not panic with unequal lengths")
   300  	}
   301  }
   302  
   303  func TestDiv(t *testing.T) {
   304  	t.Parallel()
   305  	s1 := []float64{5, 12, 27}
   306  	s2 := []float64{1, 2, 3}
   307  	ans := []float64{5, 6, 9}
   308  	Div(s1, s2)
   309  	if !EqualApprox(s1, ans, EqTolerance) {
   310  		t.Errorf("Div doesn't give correct answer")
   311  	}
   312  	s1short := []float64{1}
   313  	if !Panics(func() { Div(s1short, s2) }) {
   314  		t.Errorf("Did not panic with unequal lengths")
   315  	}
   316  	s2short := []float64{1}
   317  	if !Panics(func() { Div(s1, s2short) }) {
   318  		t.Errorf("Did not panic with unequal lengths")
   319  	}
   320  }
   321  
   322  func TestDivTo(t *testing.T) {
   323  	t.Parallel()
   324  	s1 := []float64{5, 12, 27}
   325  	s1orig := []float64{5, 12, 27}
   326  	s2 := []float64{1, 2, 3}
   327  	s2orig := []float64{1, 2, 3}
   328  	dst1 := make([]float64, 3)
   329  	ans := []float64{5, 6, 9}
   330  	dst2 := DivTo(dst1, s1, s2)
   331  	if !EqualApprox(dst1, ans, EqTolerance) {
   332  		t.Errorf("DivTo doesn't give correct answer in mutated slice")
   333  	}
   334  	if !EqualApprox(dst2, ans, EqTolerance) {
   335  		t.Errorf("DivTo doesn't give correct answer in returned slice")
   336  	}
   337  	if !EqualApprox(s1, s1orig, EqTolerance) {
   338  		t.Errorf("S1 changes during multo")
   339  	}
   340  	if !EqualApprox(s2, s2orig, EqTolerance) {
   341  		t.Errorf("s2 changes during multo")
   342  	}
   343  	DivTo(dst1, s1, s2)
   344  	if !EqualApprox(dst1, ans, EqTolerance) {
   345  		t.Errorf("DivTo doesn't give correct answer reusing dst")
   346  	}
   347  	dstShort := []float64{1}
   348  	if !Panics(func() { DivTo(dstShort, s1, s2) }) {
   349  		t.Errorf("Did not panic with s1 wrong length")
   350  	}
   351  	s1short := []float64{1}
   352  	if !Panics(func() { DivTo(dst1, s1short, s2) }) {
   353  		t.Errorf("Did not panic with s1 wrong length")
   354  	}
   355  	s2short := []float64{1}
   356  	if !Panics(func() { DivTo(dst1, s1, s2short) }) {
   357  		t.Errorf("Did not panic with s2 wrong length")
   358  	}
   359  }
   360  
   361  func TestDot(t *testing.T) {
   362  	t.Parallel()
   363  	s1 := []float64{1, 2, 3, 4}
   364  	s2 := []float64{-3, 4, 5, -6}
   365  	truth := -4.0
   366  	ans := Dot(s1, s2)
   367  	if ans != truth {
   368  		t.Errorf("Dot product computed incorrectly")
   369  	}
   370  
   371  	// Test that it panics
   372  	if !Panics(func() { Dot(make([]float64, 2), make([]float64, 3)) }) {
   373  		t.Errorf("Did not panic with length mismatch")
   374  	}
   375  }
   376  
   377  func TestEquals(t *testing.T) {
   378  	t.Parallel()
   379  	s1 := []float64{1, 2, 3, 4}
   380  	s2 := []float64{1, 2, 3, 4}
   381  	if !Equal(s1, s2) {
   382  		t.Errorf("Equal slices returned as unequal")
   383  	}
   384  	s2 = []float64{1, 2, 3, 4 + 1e-14}
   385  	if Equal(s1, s2) {
   386  		t.Errorf("Unequal slices returned as equal")
   387  	}
   388  	if Equal(s1, []float64{}) {
   389  		t.Errorf("Unequal slice lengths returned as equal")
   390  	}
   391  }
   392  
   393  func TestEqualApprox(t *testing.T) {
   394  	t.Parallel()
   395  	s1 := []float64{1, 2, 3, 4}
   396  	s2 := []float64{1, 2, 3, 4 + 1e-10}
   397  	if EqualApprox(s1, s2, 1e-13) {
   398  		t.Errorf("Unequal slices returned as equal for absolute")
   399  	}
   400  	if !EqualApprox(s1, s2, 1e-5) {
   401  		t.Errorf("Equal slices returned as unequal for absolute")
   402  	}
   403  	s1 = []float64{1, 2, 3, 1000}
   404  	s2 = []float64{1, 2, 3, 1000 * (1 + 1e-7)}
   405  	if EqualApprox(s1, s2, 1e-8) {
   406  		t.Errorf("Unequal slices returned as equal for relative")
   407  	}
   408  	if !EqualApprox(s1, s2, 1e-5) {
   409  		t.Errorf("Equal slices returned as unequal for relative")
   410  	}
   411  	if EqualApprox(s1, []float64{}, 1e-5) {
   412  		t.Errorf("Unequal slice lengths returned as equal")
   413  	}
   414  }
   415  
   416  func TestEqualFunc(t *testing.T) {
   417  	t.Parallel()
   418  	s1 := []float64{1, 2, 3, 4}
   419  	s2 := []float64{1, 2, 3, 4}
   420  	eq := func(x, y float64) bool { return x == y }
   421  	if !EqualFunc(s1, s2, eq) {
   422  		t.Errorf("Equal slices returned as unequal")
   423  	}
   424  	s2 = []float64{1, 2, 3, 4 + 1e-14}
   425  	if EqualFunc(s1, s2, eq) {
   426  		t.Errorf("Unequal slices returned as equal")
   427  	}
   428  	if EqualFunc(s1, []float64{}, eq) {
   429  		t.Errorf("Unequal slice lengths returned as equal")
   430  	}
   431  }
   432  
   433  func TestEqualsRelative(t *testing.T) {
   434  	t.Parallel()
   435  	equalityTests := []struct {
   436  		a, b  float64
   437  		tol   float64
   438  		equal bool
   439  	}{
   440  		{1000000, 1000001, 0, true},
   441  		{1000001, 1000000, 0, true},
   442  		{10000, 10001, 0, false},
   443  		{10001, 10000, 0, false},
   444  		{-1000000, -1000001, 0, true},
   445  		{-1000001, -1000000, 0, true},
   446  		{-10000, -10001, 0, false},
   447  		{-10001, -10000, 0, false},
   448  		{1.0000001, 1.0000002, 0, true},
   449  		{1.0000002, 1.0000001, 0, true},
   450  		{1.0002, 1.0001, 0, false},
   451  		{1.0001, 1.0002, 0, false},
   452  		{-1.000001, -1.000002, 0, true},
   453  		{-1.000002, -1.000001, 0, true},
   454  		{-1.0001, -1.0002, 0, false},
   455  		{-1.0002, -1.0001, 0, false},
   456  		{0.000000001000001, 0.000000001000002, 0, true},
   457  		{0.000000001000002, 0.000000001000001, 0, true},
   458  		{0.000000000001002, 0.000000000001001, 0, false},
   459  		{0.000000000001001, 0.000000000001002, 0, false},
   460  		{-0.000000001000001, -0.000000001000002, 0, true},
   461  		{-0.000000001000002, -0.000000001000001, 0, true},
   462  		{-0.000000000001002, -0.000000000001001, 0, false},
   463  		{-0.000000000001001, -0.000000000001002, 0, false},
   464  		{0, 0, 0, true},
   465  		{0, -0, 0, true},
   466  		{-0, -0, 0, true},
   467  		{0.00000001, 0, 0, false},
   468  		{0, 0.00000001, 0, false},
   469  		{-0.00000001, 0, 0, false},
   470  		{0, -0.00000001, 0, false},
   471  		{0, 1e-310, 0.01, true},
   472  		{1e-310, 0, 0.01, true},
   473  		{1e-310, 0, 0.000001, false},
   474  		{0, 1e-310, 0.000001, false},
   475  		{0, -1e-310, 0.1, true},
   476  		{-1e-310, 0, 0.1, true},
   477  		{-1e-310, 0, 0.00000001, false},
   478  		{0, -1e-310, 0.00000001, false},
   479  		{math.Inf(1), math.Inf(1), 0, true},
   480  		{math.Inf(-1), math.Inf(-1), 0, true},
   481  		{math.Inf(-1), math.Inf(1), 0, false},
   482  		{math.Inf(1), math.MaxFloat64, 0, false},
   483  		{math.Inf(-1), -math.MaxFloat64, 0, false},
   484  		{math.NaN(), math.NaN(), 0, false},
   485  		{math.NaN(), 0, 0, false},
   486  		{-0, math.NaN(), 0, false},
   487  		{math.NaN(), -0, 0, false},
   488  		{0, math.NaN(), 0, false},
   489  		{math.NaN(), math.Inf(1), 0, false},
   490  		{math.Inf(1), math.NaN(), 0, false},
   491  		{math.NaN(), math.Inf(-1), 0, false},
   492  		{math.Inf(-1), math.NaN(), 0, false},
   493  		{math.NaN(), math.MaxFloat64, 0, false},
   494  		{math.MaxFloat64, math.NaN(), 0, false},
   495  		{math.NaN(), -math.MaxFloat64, 0, false},
   496  		{-math.MaxFloat64, math.NaN(), 0, false},
   497  		{math.NaN(), math.SmallestNonzeroFloat64, 0, false},
   498  		{math.SmallestNonzeroFloat64, math.NaN(), 0, false},
   499  		{math.NaN(), -math.SmallestNonzeroFloat64, 0, false},
   500  		{-math.SmallestNonzeroFloat64, math.NaN(), 0, false},
   501  		{1.000000001, -1.0, 0, false},
   502  		{-1.0, 1.000000001, 0, false},
   503  		{-1.000000001, 1.0, 0, false},
   504  		{1.0, -1.000000001, 0, false},
   505  		{10 * math.SmallestNonzeroFloat64, 10 * -math.SmallestNonzeroFloat64, 0, true},
   506  		{1e11 * math.SmallestNonzeroFloat64, 1e11 * -math.SmallestNonzeroFloat64, 0, false},
   507  		{math.SmallestNonzeroFloat64, -math.SmallestNonzeroFloat64, 0, true},
   508  		{-math.SmallestNonzeroFloat64, math.SmallestNonzeroFloat64, 0, true},
   509  		{math.SmallestNonzeroFloat64, 0, 0, true},
   510  		{0, math.SmallestNonzeroFloat64, 0, true},
   511  		{-math.SmallestNonzeroFloat64, 0, 0, true},
   512  		{0, -math.SmallestNonzeroFloat64, 0, true},
   513  		{0.000000001, -math.SmallestNonzeroFloat64, 0, false},
   514  		{0.000000001, math.SmallestNonzeroFloat64, 0, false},
   515  		{math.SmallestNonzeroFloat64, 0.000000001, 0, false},
   516  		{-math.SmallestNonzeroFloat64, 0.000000001, 0, false},
   517  	}
   518  	for _, ts := range equalityTests {
   519  		if ts.tol == 0 {
   520  			ts.tol = 1e-5
   521  		}
   522  		if equal := scalar.EqualWithinRel(ts.a, ts.b, ts.tol); equal != ts.equal {
   523  			t.Errorf("Relative equality of %g and %g with tolerance %g returned: %v. Expected: %v",
   524  				ts.a, ts.b, ts.tol, equal, ts.equal)
   525  		}
   526  	}
   527  }
   528  
   529  func TestEqualLengths(t *testing.T) {
   530  	t.Parallel()
   531  	s1 := []float64{1, 2, 3, 4}
   532  	s2 := []float64{1, 2, 3, 4}
   533  	s3 := []float64{1, 2, 3}
   534  	if !EqualLengths(s1, s2) {
   535  		t.Errorf("Equal lengths returned as unequal")
   536  	}
   537  	if EqualLengths(s1, s3) {
   538  		t.Errorf("Unequal lengths returned as equal")
   539  	}
   540  	if !EqualLengths(s1) {
   541  		t.Errorf("Single slice returned as unequal")
   542  	}
   543  	if !EqualLengths() {
   544  		t.Errorf("No slices returned as unequal")
   545  	}
   546  }
   547  
   548  func eqIntSlice(one, two []int) string {
   549  	if len(one) != len(two) {
   550  		return "Length mismatch"
   551  	}
   552  	for i, val := range one {
   553  		if val != two[i] {
   554  			return "Index " + strconv.Itoa(i) + " mismatch"
   555  		}
   556  	}
   557  	return ""
   558  }
   559  
   560  func TestFind(t *testing.T) {
   561  	t.Parallel()
   562  	s := []float64{3, 4, 1, 7, 5}
   563  	f := func(v float64) bool { return v > 3.5 }
   564  	allTrueInds := []int{1, 3, 4}
   565  
   566  	// Test finding first two elements
   567  	inds, err := Find(nil, f, s, 2)
   568  	if err != nil {
   569  		t.Errorf("Find first two: Improper error return")
   570  	}
   571  	trueInds := allTrueInds[:2]
   572  	str := eqIntSlice(inds, trueInds)
   573  	if str != "" {
   574  		t.Errorf("Find first two: " + str)
   575  	}
   576  
   577  	// Test finding no elements with non nil slice
   578  	inds = []int{1, 2, 3, 4, 5, 6}
   579  	inds, err = Find(inds, f, s, 0)
   580  	if err != nil {
   581  		t.Errorf("Find no elements: Improper error return")
   582  	}
   583  	str = eqIntSlice(inds, []int{})
   584  	if str != "" {
   585  		t.Errorf("Find no non-nil: " + str)
   586  	}
   587  
   588  	// Test finding first two elements with non nil slice
   589  	inds = []int{1, 2, 3, 4, 5, 6}
   590  	inds, err = Find(inds, f, s, 2)
   591  	if err != nil {
   592  		t.Errorf("Find first two non-nil: Improper error return")
   593  	}
   594  	str = eqIntSlice(inds, trueInds)
   595  	if str != "" {
   596  		t.Errorf("Find first two non-nil: " + str)
   597  	}
   598  
   599  	// Test finding too many elements
   600  	inds, err = Find(inds, f, s, 4)
   601  	if err == nil {
   602  		t.Errorf("Request too many: No error returned")
   603  	}
   604  	str = eqIntSlice(inds, allTrueInds)
   605  	if str != "" {
   606  		t.Errorf("Request too many: Does not match all of the inds: " + str)
   607  	}
   608  
   609  	// Test finding all elements
   610  	inds, err = Find(nil, f, s, -1)
   611  	if err != nil {
   612  		t.Errorf("Find all: Improper error returned")
   613  	}
   614  	str = eqIntSlice(inds, allTrueInds)
   615  	if str != "" {
   616  		t.Errorf("Find all: Does not match all of the inds: " + str)
   617  	}
   618  }
   619  
   620  func TestHasNaN(t *testing.T) {
   621  	t.Parallel()
   622  	for i, test := range []struct {
   623  		s   []float64
   624  		ans bool
   625  	}{
   626  		{},
   627  		{
   628  			s: []float64{1, 2, 3, 4},
   629  		},
   630  		{
   631  			s:   []float64{1, math.NaN(), 3, 4},
   632  			ans: true,
   633  		},
   634  		{
   635  			s:   []float64{1, 2, 3, math.NaN()},
   636  			ans: true,
   637  		},
   638  	} {
   639  		b := HasNaN(test.s)
   640  		if b != test.ans {
   641  			t.Errorf("HasNaN mismatch case %d. Expected %v, Found %v", i, test.ans, b)
   642  		}
   643  	}
   644  }
   645  
   646  func TestLogSpan(t *testing.T) {
   647  	t.Parallel()
   648  	receiver1 := make([]float64, 6)
   649  	truth := []float64{0.001, 0.01, 0.1, 1, 10, 100}
   650  	receiver2 := LogSpan(receiver1, 0.001, 100)
   651  	tst := make([]float64, 6)
   652  	for i := range truth {
   653  		tst[i] = receiver1[i] / truth[i]
   654  	}
   655  	comp := make([]float64, 6)
   656  	for i := range comp {
   657  		comp[i] = 1
   658  	}
   659  	areSlicesEqual(t, comp, tst, "Improper logspace from mutator")
   660  
   661  	for i := range truth {
   662  		tst[i] = receiver2[i] / truth[i]
   663  	}
   664  	areSlicesEqual(t, comp, tst, "Improper logspace from returned slice")
   665  
   666  	if !Panics(func() { LogSpan(nil, 1, 5) }) {
   667  		t.Errorf("Span accepts nil argument")
   668  	}
   669  	if !Panics(func() { LogSpan(make([]float64, 1), 1, 5) }) {
   670  		t.Errorf("Span accepts argument of len = 1")
   671  	}
   672  }
   673  
   674  func TestLogSumExp(t *testing.T) {
   675  	t.Parallel()
   676  	s := []float64{1, 2, 3, 4, 5}
   677  	val := LogSumExp(s)
   678  	// http://www.wolframalpha.com/input/?i=log%28exp%281%29+%2B+exp%282%29+%2B+exp%283%29+%2B+exp%284%29+%2B+exp%285%29%29
   679  	truth := 5.4519143959375933331957225109748087179338972737576824
   680  	if math.Abs(val-truth) > EqTolerance {
   681  		t.Errorf("Wrong logsumexp for many values")
   682  	}
   683  	s = []float64{1, 2}
   684  	// http://www.wolframalpha.com/input/?i=log%28exp%281%29+%2B+exp%282%29%29
   685  	truth = 2.3132616875182228340489954949678556419152800856703483
   686  	val = LogSumExp(s)
   687  	if math.Abs(val-truth) > EqTolerance {
   688  		t.Errorf("Wrong logsumexp for two values. %v expected, %v found", truth, val)
   689  	}
   690  	// This case would normally underflow
   691  	s = []float64{-1001, -1002, -1003, -1004, -1005}
   692  	// http://www.wolframalpha.com/input/?i=log%28exp%28-1001%29%2Bexp%28-1002%29%2Bexp%28-1003%29%2Bexp%28-1004%29%2Bexp%28-1005%29%29
   693  	truth = -1000.54808560406240666680427748902519128206610272624
   694  	val = LogSumExp(s)
   695  	if math.Abs(val-truth) > EqTolerance {
   696  		t.Errorf("Doesn't match for underflow case. %v expected, %v found", truth, val)
   697  	}
   698  	// positive infinite case
   699  	s = []float64{1, 2, 3, 4, 5, math.Inf(1)}
   700  	val = LogSumExp(s)
   701  	truth = math.Inf(1)
   702  	if val != truth {
   703  		t.Errorf("Doesn't match for pos Infinity case. %v expected, %v found", truth, val)
   704  	}
   705  	// negative infinite case
   706  	s = []float64{1, 2, 3, 4, 5, math.Inf(-1)}
   707  	val = LogSumExp(s)
   708  	truth = 5.4519143959375933331957225109748087179338972737576824 // same as first case
   709  	if math.Abs(val-truth) > EqTolerance {
   710  		t.Errorf("Wrong logsumexp for values with negative infinity")
   711  	}
   712  }
   713  
   714  func TestMaxAndIdx(t *testing.T) {
   715  	t.Parallel()
   716  	for _, test := range []struct {
   717  		in      []float64
   718  		wantIdx int
   719  		wantVal float64
   720  		desc    string
   721  	}{
   722  		{
   723  			in:      []float64{3, 4, 1, 7, 5},
   724  			wantIdx: 3,
   725  			wantVal: 7,
   726  			desc:    "with only finite entries",
   727  		},
   728  		{
   729  			in:      []float64{math.NaN(), 4, 1, 7, 5},
   730  			wantIdx: 3,
   731  			wantVal: 7,
   732  			desc:    "with leading NaN",
   733  		},
   734  		{
   735  			in:      []float64{math.NaN(), math.NaN(), math.NaN()},
   736  			wantIdx: 0,
   737  			wantVal: math.NaN(),
   738  			desc:    "when only NaN elements exist",
   739  		},
   740  		{
   741  			in:      []float64{math.NaN(), math.Inf(-1)},
   742  			wantIdx: 1,
   743  			wantVal: math.Inf(-1),
   744  			desc:    "leading NaN followed by -Inf",
   745  		},
   746  		{
   747  			in:      []float64{math.NaN(), math.Inf(1)},
   748  			wantIdx: 1,
   749  			wantVal: math.Inf(1),
   750  			desc:    "leading NaN followed by +Inf",
   751  		},
   752  	} {
   753  		ind := MaxIdx(test.in)
   754  		if ind != test.wantIdx {
   755  			t.Errorf("Wrong index "+test.desc+": got:%d want:%d", ind, test.wantIdx)
   756  		}
   757  		val := Max(test.in)
   758  		if !scalar.Same(val, test.wantVal) {
   759  			t.Errorf("Wrong value "+test.desc+": got:%f want:%f", val, test.wantVal)
   760  		}
   761  	}
   762  	if !Panics(func() { MaxIdx([]float64{}) }) {
   763  		t.Errorf("Expected panic with zero length")
   764  	}
   765  }
   766  
   767  func TestMinAndIdx(t *testing.T) {
   768  	t.Parallel()
   769  	for _, test := range []struct {
   770  		in      []float64
   771  		wantIdx int
   772  		wantVal float64
   773  		desc    string
   774  	}{
   775  		{
   776  			in:      []float64{3, 4, 1, 7, 5},
   777  			wantIdx: 2,
   778  			wantVal: 1,
   779  			desc:    "with only finite entries",
   780  		},
   781  		{
   782  			in:      []float64{math.NaN(), 4, 1, 7, 5},
   783  			wantIdx: 2,
   784  			wantVal: 1,
   785  			desc:    "with leading NaN",
   786  		},
   787  		{
   788  			in:      []float64{math.NaN(), math.NaN(), math.NaN()},
   789  			wantIdx: 0,
   790  			wantVal: math.NaN(),
   791  			desc:    "when only NaN elements exist",
   792  		},
   793  		{
   794  			in:      []float64{math.NaN(), math.Inf(-1)},
   795  			wantIdx: 1,
   796  			wantVal: math.Inf(-1),
   797  			desc:    "leading NaN followed by -Inf",
   798  		},
   799  		{
   800  			in:      []float64{math.NaN(), math.Inf(1)},
   801  			wantIdx: 1,
   802  			wantVal: math.Inf(1),
   803  			desc:    "leading NaN followed by +Inf",
   804  		},
   805  	} {
   806  		ind := MinIdx(test.in)
   807  		if ind != test.wantIdx {
   808  			t.Errorf("Wrong index "+test.desc+": got:%d want:%d", ind, test.wantIdx)
   809  		}
   810  		val := Min(test.in)
   811  		if !scalar.Same(val, test.wantVal) {
   812  			t.Errorf("Wrong value "+test.desc+": got:%f want:%f", val, test.wantVal)
   813  		}
   814  	}
   815  	if !Panics(func() { MinIdx([]float64{}) }) {
   816  		t.Errorf("Expected panic with zero length")
   817  	}
   818  }
   819  
   820  func TestMul(t *testing.T) {
   821  	t.Parallel()
   822  	s1 := []float64{1, 2, 3}
   823  	s2 := []float64{1, 2, 3}
   824  	ans := []float64{1, 4, 9}
   825  	Mul(s1, s2)
   826  	if !EqualApprox(s1, ans, EqTolerance) {
   827  		t.Errorf("Mul doesn't give correct answer")
   828  	}
   829  	s1short := []float64{1}
   830  	if !Panics(func() { Mul(s1short, s2) }) {
   831  		t.Errorf("Did not panic with unequal lengths")
   832  	}
   833  	s2short := []float64{1}
   834  	if !Panics(func() { Mul(s1, s2short) }) {
   835  		t.Errorf("Did not panic with unequal lengths")
   836  	}
   837  }
   838  
   839  func TestMulTo(t *testing.T) {
   840  	t.Parallel()
   841  	s1 := []float64{1, 2, 3}
   842  	s1orig := []float64{1, 2, 3}
   843  	s2 := []float64{1, 2, 3}
   844  	s2orig := []float64{1, 2, 3}
   845  	dst1 := make([]float64, 3)
   846  	ans := []float64{1, 4, 9}
   847  	dst2 := MulTo(dst1, s1, s2)
   848  	if !EqualApprox(dst1, ans, EqTolerance) {
   849  		t.Errorf("MulTo doesn't give correct answer in mutated slice")
   850  	}
   851  	if !EqualApprox(dst2, ans, EqTolerance) {
   852  		t.Errorf("MulTo doesn't give correct answer in returned slice")
   853  	}
   854  	if !EqualApprox(s1, s1orig, EqTolerance) {
   855  		t.Errorf("S1 changes during multo")
   856  	}
   857  	if !EqualApprox(s2, s2orig, EqTolerance) {
   858  		t.Errorf("s2 changes during multo")
   859  	}
   860  	MulTo(dst1, s1, s2)
   861  	if !EqualApprox(dst1, ans, EqTolerance) {
   862  		t.Errorf("MulTo doesn't give correct answer reusing dst")
   863  	}
   864  	dstShort := []float64{1}
   865  	if !Panics(func() { MulTo(dstShort, s1, s2) }) {
   866  		t.Errorf("Did not panic with s1 wrong length")
   867  	}
   868  	s1short := []float64{1}
   869  	if !Panics(func() { MulTo(dst1, s1short, s2) }) {
   870  		t.Errorf("Did not panic with s1 wrong length")
   871  	}
   872  	s2short := []float64{1}
   873  	if !Panics(func() { MulTo(dst1, s1, s2short) }) {
   874  		t.Errorf("Did not panic with s2 wrong length")
   875  	}
   876  }
   877  
   878  func TestNearestIdx(t *testing.T) {
   879  	t.Parallel()
   880  	for _, test := range []struct {
   881  		in    []float64
   882  		query float64
   883  		want  int
   884  		desc  string
   885  	}{
   886  		{
   887  			in:    []float64{6.2, 3, 5, 6.2, 8},
   888  			query: 2,
   889  			want:  1,
   890  			desc:  "Wrong index returned when value is less than all of elements",
   891  		},
   892  		{
   893  			in:    []float64{6.2, 3, 5, 6.2, 8},
   894  			query: 9,
   895  			want:  4,
   896  			desc:  "Wrong index returned when value is greater than all of elements",
   897  		},
   898  		{
   899  			in:    []float64{6.2, 3, 5, 6.2, 8},
   900  			query: 3.1,
   901  			want:  1,
   902  			desc:  "Wrong index returned when value is greater than closest element",
   903  		},
   904  		{
   905  			in:    []float64{6.2, 3, 5, 6.2, 8},
   906  			query: 2.9,
   907  			want:  1,
   908  			desc:  "Wrong index returned when value is less than closest element",
   909  		},
   910  		{
   911  			in:    []float64{6.2, 3, 5, 6.2, 8},
   912  			query: 3,
   913  			want:  1,
   914  			desc:  "Wrong index returned when value is equal to element",
   915  		},
   916  		{
   917  			in:    []float64{6.2, 3, 5, 6.2, 8},
   918  			query: 6.2,
   919  			want:  0,
   920  			desc:  "Wrong index returned when value is equal to several elements",
   921  		},
   922  		{
   923  			in:    []float64{6.2, 3, 5, 6.2, 8},
   924  			query: 4,
   925  			want:  1,
   926  			desc:  "Wrong index returned when value is exactly between two closest elements",
   927  		},
   928  		{
   929  			in:    []float64{math.NaN(), 3, 2, -1},
   930  			query: 2,
   931  			want:  2,
   932  			desc:  "Wrong index returned when initial element is NaN",
   933  		},
   934  		{
   935  			in:    []float64{0, math.NaN(), -1, 2},
   936  			query: math.NaN(),
   937  			want:  0,
   938  			desc:  "Wrong index returned when query is NaN and a NaN element exists",
   939  		},
   940  		{
   941  			in:    []float64{0, math.NaN(), -1, 2},
   942  			query: math.Inf(1),
   943  			want:  3,
   944  			desc:  "Wrong index returned when query is +Inf and no +Inf element exists",
   945  		},
   946  		{
   947  			in:    []float64{0, math.NaN(), -1, 2},
   948  			query: math.Inf(-1),
   949  			want:  2,
   950  			desc:  "Wrong index returned when query is -Inf and no -Inf element exists",
   951  		},
   952  		{
   953  			in:    []float64{math.NaN(), math.NaN(), math.NaN()},
   954  			query: 1,
   955  			want:  0,
   956  			desc:  "Wrong index returned when query is a number and only NaN elements exist",
   957  		},
   958  		{
   959  			in:    []float64{math.NaN(), math.Inf(-1)},
   960  			query: 1,
   961  			want:  1,
   962  			desc:  "Wrong index returned when query is a number and single NaN precedes -Inf",
   963  		},
   964  	} {
   965  		ind := NearestIdx(test.in, test.query)
   966  		if ind != test.want {
   967  			t.Errorf(test.desc+": got:%d want:%d", ind, test.want)
   968  		}
   969  	}
   970  	if !Panics(func() { NearestIdx([]float64{}, 0) }) {
   971  		t.Errorf("Expected panic with zero length")
   972  	}
   973  }
   974  
   975  func TestNearestIdxForSpan(t *testing.T) {
   976  	t.Parallel()
   977  	for i, test := range []struct {
   978  		length int
   979  		lower  float64
   980  		upper  float64
   981  		value  float64
   982  		idx    int
   983  	}{
   984  		{
   985  			length: 13,
   986  			lower:  7,
   987  			upper:  8.2,
   988  			value:  6,
   989  			idx:    0,
   990  		},
   991  		{
   992  			length: 13,
   993  			lower:  7,
   994  			upper:  8.2,
   995  			value:  10,
   996  			idx:    12,
   997  		},
   998  		{
   999  			length: 13,
  1000  			lower:  7,
  1001  			upper:  8.2,
  1002  			value:  7.19,
  1003  			idx:    2,
  1004  		},
  1005  		{
  1006  			length: 13,
  1007  			lower:  7,
  1008  			upper:  8.2,
  1009  			value:  7.21,
  1010  			idx:    2,
  1011  		},
  1012  		{
  1013  			length: 13,
  1014  			lower:  7,
  1015  			upper:  8.2,
  1016  			value:  7.2,
  1017  			idx:    2,
  1018  		},
  1019  		{
  1020  			length: 13,
  1021  			lower:  7,
  1022  			upper:  8.2,
  1023  			value:  7.151,
  1024  			idx:    2,
  1025  		},
  1026  		{
  1027  			length: 13,
  1028  			lower:  7,
  1029  			upper:  8.2,
  1030  			value:  7.249,
  1031  			idx:    2,
  1032  		},
  1033  		{
  1034  			length: 4,
  1035  			lower:  math.Inf(-1),
  1036  			upper:  math.Inf(1),
  1037  			value:  math.Copysign(0, -1),
  1038  			idx:    0,
  1039  		},
  1040  		{
  1041  			length: 5,
  1042  			lower:  math.Inf(-1),
  1043  			upper:  math.Inf(1),
  1044  			value:  0,
  1045  			idx:    2,
  1046  		},
  1047  		{
  1048  			length: 5,
  1049  			lower:  math.Inf(-1),
  1050  			upper:  math.Inf(1),
  1051  			value:  math.Inf(-1),
  1052  			idx:    0,
  1053  		},
  1054  		{
  1055  			length: 5,
  1056  			lower:  math.Inf(-1),
  1057  			upper:  math.Inf(1),
  1058  			value:  math.Inf(1),
  1059  			idx:    3,
  1060  		},
  1061  		{
  1062  			length: 4,
  1063  			lower:  math.Inf(-1),
  1064  			upper:  math.Inf(1),
  1065  			value:  0,
  1066  			idx:    2,
  1067  		},
  1068  		{
  1069  			length: 4,
  1070  			lower:  math.Inf(-1),
  1071  			upper:  math.Inf(1),
  1072  			value:  math.Inf(1),
  1073  			idx:    2,
  1074  		},
  1075  		{
  1076  			length: 4,
  1077  			lower:  math.Inf(-1),
  1078  			upper:  math.Inf(1),
  1079  			value:  math.Inf(-1),
  1080  			idx:    0,
  1081  		},
  1082  		{
  1083  			length: 5,
  1084  			lower:  math.Inf(1),
  1085  			upper:  math.Inf(1),
  1086  			value:  1,
  1087  			idx:    0,
  1088  		},
  1089  		{
  1090  			length: 5,
  1091  			lower:  math.NaN(),
  1092  			upper:  math.NaN(),
  1093  			value:  1,
  1094  			idx:    0,
  1095  		},
  1096  		{
  1097  			length: 5,
  1098  			lower:  0,
  1099  			upper:  1,
  1100  			value:  math.NaN(),
  1101  			idx:    0,
  1102  		},
  1103  		{
  1104  			length: 5,
  1105  			lower:  math.NaN(),
  1106  			upper:  1,
  1107  			value:  0,
  1108  			idx:    4,
  1109  		},
  1110  		{
  1111  			length: 5,
  1112  			lower:  math.Inf(-1),
  1113  			upper:  1,
  1114  			value:  math.Inf(-1),
  1115  			idx:    0,
  1116  		},
  1117  		{
  1118  			length: 5,
  1119  			lower:  math.Inf(-1),
  1120  			upper:  1,
  1121  			value:  0,
  1122  			idx:    4,
  1123  		},
  1124  		{
  1125  			length: 5,
  1126  			lower:  math.Inf(1),
  1127  			upper:  1,
  1128  			value:  math.Inf(1),
  1129  			idx:    0,
  1130  		},
  1131  		{
  1132  			length: 5,
  1133  			lower:  math.Inf(1),
  1134  			upper:  1,
  1135  			value:  0,
  1136  			idx:    4,
  1137  		},
  1138  		{
  1139  			length: 5,
  1140  			lower:  100,
  1141  			upper:  math.Inf(-1),
  1142  			value:  math.Inf(-1),
  1143  			idx:    4,
  1144  		},
  1145  		{
  1146  			length: 5,
  1147  			lower:  100,
  1148  			upper:  math.Inf(-1),
  1149  			value:  200,
  1150  			idx:    0,
  1151  		},
  1152  		{
  1153  			length: 5,
  1154  			lower:  100,
  1155  			upper:  math.Inf(1),
  1156  			value:  math.Inf(1),
  1157  			idx:    4,
  1158  		},
  1159  		{
  1160  			length: 5,
  1161  			lower:  100,
  1162  			upper:  math.Inf(1),
  1163  			value:  200,
  1164  			idx:    0,
  1165  		},
  1166  		{
  1167  			length: 5,
  1168  			lower:  -1,
  1169  			upper:  2,
  1170  			value:  math.Inf(-1),
  1171  			idx:    0,
  1172  		},
  1173  		{
  1174  			length: 5,
  1175  			lower:  -1,
  1176  			upper:  2,
  1177  			value:  math.Inf(1),
  1178  			idx:    4,
  1179  		},
  1180  		{
  1181  			length: 5,
  1182  			lower:  1,
  1183  			upper:  -2,
  1184  			value:  math.Inf(-1),
  1185  			idx:    4,
  1186  		},
  1187  		{
  1188  			length: 5,
  1189  			lower:  1,
  1190  			upper:  -2,
  1191  			value:  math.Inf(1),
  1192  			idx:    0,
  1193  		},
  1194  		{
  1195  			length: 5,
  1196  			lower:  2,
  1197  			upper:  0,
  1198  			value:  3,
  1199  			idx:    0,
  1200  		},
  1201  		{
  1202  			length: 5,
  1203  			lower:  2,
  1204  			upper:  0,
  1205  			value:  -1,
  1206  			idx:    4,
  1207  		},
  1208  	} {
  1209  		if idx := NearestIdxForSpan(test.length, test.lower, test.upper, test.value); test.idx != idx {
  1210  			t.Errorf("Case %v mismatch: Want: %v, Got: %v", i, test.idx, idx)
  1211  		}
  1212  	}
  1213  	if !Panics(func() { NearestIdxForSpan(1, 0, 1, 0.5) }) {
  1214  		t.Errorf("Expected panic for short span length")
  1215  	}
  1216  }
  1217  
  1218  func TestNorm(t *testing.T) {
  1219  	t.Parallel()
  1220  	s := []float64{-1, -3.4, 5, -6}
  1221  	val := Norm(s, math.Inf(1))
  1222  	truth := 6.0
  1223  	if math.Abs(val-truth) > EqTolerance {
  1224  		t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val)
  1225  	}
  1226  	// http://www.wolframalpha.com/input/?i=%28%28-1%29%5E2+%2B++%28-3.4%29%5E2+%2B+5%5E2%2B++6%5E2%29%5E%281%2F2%29
  1227  	val = Norm(s, 2)
  1228  	truth = 8.5767126569566267590651614132751986658027271236078592
  1229  	if math.Abs(val-truth) > EqTolerance {
  1230  		t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val)
  1231  	}
  1232  	// http://www.wolframalpha.com/input/?i=%28%28%7C-1%7C%29%5E3+%2B++%28%7C-3.4%7C%29%5E3+%2B+%7C5%7C%5E3%2B++%7C6%7C%5E3%29%5E%281%2F3%29
  1233  	val = Norm(s, 3)
  1234  	truth = 7.2514321388020228478109121239004816430071237369356233
  1235  	if math.Abs(val-truth) > EqTolerance {
  1236  		t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val)
  1237  	}
  1238  
  1239  	//http://www.wolframalpha.com/input/?i=%7C-1%7C+%2B+%7C-3.4%7C+%2B+%7C5%7C%2B++%7C6%7C
  1240  	val = Norm(s, 1)
  1241  	truth = 15.4
  1242  	if math.Abs(val-truth) > EqTolerance {
  1243  		t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val)
  1244  	}
  1245  }
  1246  
  1247  func TestProd(t *testing.T) {
  1248  	t.Parallel()
  1249  	s := []float64{}
  1250  	val := Prod(s)
  1251  	if val != 1 {
  1252  		t.Errorf("Val not returned as default when slice length is zero")
  1253  	}
  1254  	s = []float64{3, 4, 1, 7, 5}
  1255  	val = Prod(s)
  1256  	if val != 420 {
  1257  		t.Errorf("Wrong prod returned. Expected %v returned %v", 420, val)
  1258  	}
  1259  }
  1260  
  1261  func TestReverse(t *testing.T) {
  1262  	t.Parallel()
  1263  	for _, s := range [][]float64{
  1264  		{0},
  1265  		{1, 0},
  1266  		{2, 1, 0},
  1267  		{3, 2, 1, 0},
  1268  		{9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
  1269  	} {
  1270  		Reverse(s)
  1271  		for i, v := range s {
  1272  			if v != float64(i) {
  1273  				t.Errorf("unexpected values for element %d: got:%v want:%v", i, v, i)
  1274  			}
  1275  		}
  1276  	}
  1277  }
  1278  
  1279  func TestSame(t *testing.T) {
  1280  	t.Parallel()
  1281  	s1 := []float64{1, 2, 3, 4}
  1282  	s2 := []float64{1, 2, 3, 4}
  1283  	if !Same(s1, s2) {
  1284  		t.Errorf("Equal slices returned as unequal")
  1285  	}
  1286  	s2 = []float64{1, 2, 3, 4 + 1e-14}
  1287  	if Same(s1, s2) {
  1288  		t.Errorf("Unequal slices returned as equal")
  1289  	}
  1290  	if Same(s1, []float64{}) {
  1291  		t.Errorf("Unequal slice lengths returned as equal")
  1292  	}
  1293  	s1 = []float64{1, 2, math.NaN(), 4}
  1294  	s2 = []float64{1, 2, math.NaN(), 4}
  1295  	if !Same(s1, s2) {
  1296  		t.Errorf("Slices with matching NaN values returned as unequal")
  1297  	}
  1298  	s1 = []float64{1, 2, math.NaN(), 4}
  1299  	s2 = []float64{1, math.NaN(), 3, 4}
  1300  	if Same(s1, s2) {
  1301  		t.Errorf("Slices with unmatching NaN values returned as equal")
  1302  	}
  1303  }
  1304  
  1305  func TestScale(t *testing.T) {
  1306  	t.Parallel()
  1307  	s := []float64{3, 4, 1, 7, 5}
  1308  	c := 5.0
  1309  	truth := []float64{15, 20, 5, 35, 25}
  1310  	Scale(c, s)
  1311  	areSlicesEqual(t, truth, s, "Bad scaling")
  1312  }
  1313  
  1314  func TestScaleTo(t *testing.T) {
  1315  	t.Parallel()
  1316  	s := []float64{3, 4, 1, 7, 5}
  1317  	sCopy := make([]float64, len(s))
  1318  	copy(sCopy, s)
  1319  	c := 5.0
  1320  	truth := []float64{15, 20, 5, 35, 25}
  1321  	dst := make([]float64, len(s))
  1322  	ScaleTo(dst, c, s)
  1323  	if !Same(dst, truth) {
  1324  		t.Errorf("Scale to does not match. Got %v, want %v", dst, truth)
  1325  	}
  1326  	if !Same(s, sCopy) {
  1327  		t.Errorf("Source modified during call. Got %v, want %v", s, sCopy)
  1328  	}
  1329  	if !Panics(func() { ScaleTo(dst, 0, []float64{1}) }) {
  1330  		t.Errorf("Expected panic with different slice lengths")
  1331  	}
  1332  }
  1333  
  1334  func TestSpan(t *testing.T) {
  1335  	t.Parallel()
  1336  	receiver1 := make([]float64, 5)
  1337  	truth := []float64{1, 2, 3, 4, 5}
  1338  	receiver2 := Span(receiver1, 1, 5)
  1339  	areSlicesEqual(t, truth, receiver1, "Improper linspace from mutator")
  1340  	areSlicesEqual(t, truth, receiver2, "Improper linspace from returned slice")
  1341  	receiver1 = make([]float64, 6)
  1342  	truth = []float64{0, 0.2, 0.4, 0.6, 0.8, 1.0}
  1343  	Span(receiver1, 0, 1)
  1344  	areSlicesEqual(t, truth, receiver1, "Improper linspace")
  1345  	if !Panics(func() { Span(nil, 1, 5) }) {
  1346  		t.Errorf("Span accepts nil argument")
  1347  	}
  1348  	if !Panics(func() { Span(make([]float64, 1), 1, 5) }) {
  1349  		t.Errorf("Span accepts argument of len = 1")
  1350  	}
  1351  
  1352  	for _, test := range []struct {
  1353  		n    int
  1354  		l, u float64
  1355  		want []float64
  1356  	}{
  1357  		{
  1358  			n: 4, l: math.Inf(-1), u: math.Inf(1),
  1359  			want: []float64{math.Inf(-1), math.Inf(-1), math.Inf(1), math.Inf(1)},
  1360  		},
  1361  		{
  1362  			n: 4, l: math.Inf(1), u: math.Inf(-1),
  1363  			want: []float64{math.Inf(1), math.Inf(1), math.Inf(-1), math.Inf(-1)},
  1364  		},
  1365  		{
  1366  			n: 5, l: math.Inf(-1), u: math.Inf(1),
  1367  			want: []float64{math.Inf(-1), math.Inf(-1), 0, math.Inf(1), math.Inf(1)},
  1368  		},
  1369  		{
  1370  			n: 5, l: math.Inf(1), u: math.Inf(-1),
  1371  			want: []float64{math.Inf(1), math.Inf(1), 0, math.Inf(-1), math.Inf(-1)},
  1372  		},
  1373  		{
  1374  			n: 5, l: math.Inf(1), u: math.Inf(1),
  1375  			want: []float64{math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1)},
  1376  		},
  1377  		{
  1378  			n: 5, l: math.Inf(-1), u: math.Inf(-1),
  1379  			want: []float64{math.Inf(-1), math.Inf(-1), math.Inf(-1), math.Inf(-1), math.Inf(-1)},
  1380  		},
  1381  		{
  1382  			n: 5, l: math.Inf(-1), u: math.NaN(),
  1383  			want: []float64{math.Inf(-1), math.NaN(), math.NaN(), math.NaN(), math.NaN()},
  1384  		},
  1385  		{
  1386  			n: 5, l: math.Inf(1), u: math.NaN(),
  1387  			want: []float64{math.Inf(1), math.NaN(), math.NaN(), math.NaN(), math.NaN()},
  1388  		},
  1389  		{
  1390  			n: 5, l: math.NaN(), u: math.Inf(-1),
  1391  			want: []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.Inf(-1)},
  1392  		},
  1393  		{
  1394  			n: 5, l: math.NaN(), u: math.Inf(1),
  1395  			want: []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.Inf(1)},
  1396  		},
  1397  		{
  1398  			n: 5, l: 42, u: math.Inf(-1),
  1399  			want: []float64{42, math.Inf(-1), math.Inf(-1), math.Inf(-1), math.Inf(-1)},
  1400  		},
  1401  		{
  1402  			n: 5, l: 42, u: math.Inf(1),
  1403  			want: []float64{42, math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1)},
  1404  		},
  1405  		{
  1406  			n: 5, l: 42, u: math.NaN(),
  1407  			want: []float64{42, math.NaN(), math.NaN(), math.NaN(), math.NaN()},
  1408  		},
  1409  		{
  1410  			n: 5, l: math.Inf(-1), u: 42,
  1411  			want: []float64{math.Inf(-1), math.Inf(-1), math.Inf(-1), math.Inf(-1), 42},
  1412  		},
  1413  		{
  1414  			n: 5, l: math.Inf(1), u: 42,
  1415  			want: []float64{math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1), 42},
  1416  		},
  1417  		{
  1418  			n: 5, l: math.NaN(), u: 42,
  1419  			want: []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), 42},
  1420  		},
  1421  	} {
  1422  		got := Span(make([]float64, test.n), test.l, test.u)
  1423  		areSlicesSame(t, test.want, got,
  1424  			fmt.Sprintf("Unexpected slice of length %d for %f to %f", test.n, test.l, test.u))
  1425  	}
  1426  }
  1427  
  1428  func TestSub(t *testing.T) {
  1429  	t.Parallel()
  1430  	s := []float64{3, 4, 1, 7, 5}
  1431  	v := []float64{1, 2, 3, 4, 5}
  1432  	truth := []float64{2, 2, -2, 3, 0}
  1433  	Sub(s, v)
  1434  	areSlicesEqual(t, truth, s, "Bad subtract")
  1435  	// Test that it panics
  1436  	if !Panics(func() { Sub(make([]float64, 2), make([]float64, 3)) }) {
  1437  		t.Errorf("Did not panic with length mismatch")
  1438  	}
  1439  }
  1440  
  1441  func TestSubTo(t *testing.T) {
  1442  	t.Parallel()
  1443  	s := []float64{3, 4, 1, 7, 5}
  1444  	v := []float64{1, 2, 3, 4, 5}
  1445  	truth := []float64{2, 2, -2, 3, 0}
  1446  	dst1 := make([]float64, len(s))
  1447  	dst2 := SubTo(dst1, s, v)
  1448  	areSlicesEqual(t, truth, dst1, "Bad subtract from mutator")
  1449  	areSlicesEqual(t, truth, dst2, "Bad subtract from returned slice")
  1450  	// Test that all mismatch combinations panic
  1451  	if !Panics(func() { SubTo(make([]float64, 2), make([]float64, 3), make([]float64, 3)) }) {
  1452  		t.Errorf("Did not panic with dst different length")
  1453  	}
  1454  	if !Panics(func() { SubTo(make([]float64, 3), make([]float64, 2), make([]float64, 3)) }) {
  1455  		t.Errorf("Did not panic with subtractor different length")
  1456  	}
  1457  	if !Panics(func() { SubTo(make([]float64, 3), make([]float64, 3), make([]float64, 2)) }) {
  1458  		t.Errorf("Did not panic with subtractee different length")
  1459  	}
  1460  }
  1461  
  1462  func TestSum(t *testing.T) {
  1463  	t.Parallel()
  1464  	s := []float64{}
  1465  	val := Sum(s)
  1466  	if val != 0 {
  1467  		t.Errorf("Val not returned as default when slice length is zero")
  1468  	}
  1469  	s = []float64{3, 4, 1, 7, 5}
  1470  	val = Sum(s)
  1471  	if val != 20 {
  1472  		t.Errorf("Wrong sum returned")
  1473  	}
  1474  }
  1475  
  1476  func TestWithin(t *testing.T) {
  1477  	t.Parallel()
  1478  	for i, test := range []struct {
  1479  		s      []float64
  1480  		v      float64
  1481  		idx    int
  1482  		panics bool
  1483  	}{
  1484  		{
  1485  			s:   []float64{1, 2, 5, 9},
  1486  			v:   1,
  1487  			idx: 0,
  1488  		},
  1489  		{
  1490  			s:   []float64{1, 2, 5, 9},
  1491  			v:   9,
  1492  			idx: -1,
  1493  		},
  1494  		{
  1495  			s:   []float64{1, 2, 5, 9},
  1496  			v:   1.5,
  1497  			idx: 0,
  1498  		},
  1499  		{
  1500  			s:   []float64{1, 2, 5, 9},
  1501  			v:   2,
  1502  			idx: 1,
  1503  		},
  1504  		{
  1505  			s:   []float64{1, 2, 5, 9},
  1506  			v:   2.5,
  1507  			idx: 1,
  1508  		},
  1509  		{
  1510  			s:   []float64{1, 2, 5, 9},
  1511  			v:   -3,
  1512  			idx: -1,
  1513  		},
  1514  		{
  1515  			s:   []float64{1, 2, 5, 9},
  1516  			v:   15,
  1517  			idx: -1,
  1518  		},
  1519  		{
  1520  			s:   []float64{1, 2, 5, 9},
  1521  			v:   math.NaN(),
  1522  			idx: -1,
  1523  		},
  1524  		{
  1525  			s:      []float64{5, 2, 6},
  1526  			panics: true,
  1527  		},
  1528  		{
  1529  			panics: true,
  1530  		},
  1531  		{
  1532  			s:      []float64{1},
  1533  			panics: true,
  1534  		},
  1535  	} {
  1536  		var idx int
  1537  		panics := Panics(func() { idx = Within(test.s, test.v) })
  1538  		if panics {
  1539  			if !test.panics {
  1540  				t.Errorf("Case %v: bad panic", i)
  1541  			}
  1542  			continue
  1543  		}
  1544  		if test.panics {
  1545  			if !panics {
  1546  				t.Errorf("Case %v: did not panic when it should", i)
  1547  			}
  1548  			continue
  1549  		}
  1550  		if idx != test.idx {
  1551  			t.Errorf("Case %v: Idx mismatch. Want: %v, got: %v", i, test.idx, idx)
  1552  		}
  1553  	}
  1554  }
  1555  
  1556  func TestSumCompensated(t *testing.T) {
  1557  	t.Parallel()
  1558  	k := 100000
  1559  	s1 := make([]float64, 2*k+1)
  1560  	for i := -k; i <= k; i++ {
  1561  		s1[i+k] = 0.2 * float64(i)
  1562  	}
  1563  	s2 := make([]float64, k+1)
  1564  	for i := 0; i < k; i++ {
  1565  		s2[i] = 10. / float64(k)
  1566  	}
  1567  	s2[k] = -10
  1568  
  1569  	for i, test := range []struct {
  1570  		s    []float64
  1571  		want float64
  1572  	}{
  1573  		{
  1574  			// Fails if we use simple Sum.
  1575  			s:    s1,
  1576  			want: 0,
  1577  		},
  1578  		{
  1579  			// Fails if we use simple Sum.
  1580  			s:    s2,
  1581  			want: 0,
  1582  		},
  1583  		{
  1584  			s:    []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
  1585  			want: 55,
  1586  		},
  1587  		{
  1588  			s:    []float64{1.2e20, 0.1, -2.4e20, -0.1, 1.2e20, 0.2, 0.2},
  1589  			want: 0.4,
  1590  		},
  1591  		{
  1592  			s:    []float64{1, 1e100, 1, -1e100},
  1593  			want: 2,
  1594  		},
  1595  	} {
  1596  		got := SumCompensated(test.s)
  1597  		if math.Abs(got-test.want) > EqTolerance {
  1598  			t.Errorf("Wrong sum returned in test case %d. Want: %g, got: %g", i, test.want, got)
  1599  		}
  1600  	}
  1601  }
  1602  
  1603  func randomSlice(l int, src rand.Source) []float64 {
  1604  	rnd := rand.New(src)
  1605  	s := make([]float64, l)
  1606  	for i := range s {
  1607  		s[i] = rnd.Float64()
  1608  	}
  1609  	return s
  1610  }
  1611  
  1612  func benchmarkMin(b *testing.B, size int) {
  1613  	src := rand.NewSource(1)
  1614  	s := randomSlice(size, src)
  1615  	b.ResetTimer()
  1616  	for i := 0; i < b.N; i++ {
  1617  		Min(s)
  1618  	}
  1619  }
  1620  func BenchmarkMinSmall(b *testing.B) { benchmarkMin(b, Small) }
  1621  func BenchmarkMinMed(b *testing.B)   { benchmarkMin(b, Medium) }
  1622  func BenchmarkMinLarge(b *testing.B) { benchmarkMin(b, Large) }
  1623  func BenchmarkMinHuge(b *testing.B)  { benchmarkMin(b, Huge) }
  1624  
  1625  func benchmarkAdd(b *testing.B, size int) {
  1626  	src := rand.NewSource(1)
  1627  	s1 := randomSlice(size, src)
  1628  	s2 := randomSlice(size, src)
  1629  	b.ResetTimer()
  1630  	for i := 0; i < b.N; i++ {
  1631  		Add(s1, s2)
  1632  	}
  1633  }
  1634  func BenchmarkAddSmall(b *testing.B) { benchmarkAdd(b, Small) }
  1635  func BenchmarkAddMed(b *testing.B)   { benchmarkAdd(b, Medium) }
  1636  func BenchmarkAddLarge(b *testing.B) { benchmarkAdd(b, Large) }
  1637  func BenchmarkAddHuge(b *testing.B)  { benchmarkAdd(b, Huge) }
  1638  
  1639  func benchmarkAddTo(b *testing.B, size int) {
  1640  	src := rand.NewSource(1)
  1641  	s1 := randomSlice(size, src)
  1642  	s2 := randomSlice(size, src)
  1643  	dst := randomSlice(size, src)
  1644  	b.ResetTimer()
  1645  	for i := 0; i < b.N; i++ {
  1646  		AddTo(dst, s1, s2)
  1647  	}
  1648  }
  1649  func BenchmarkAddToSmall(b *testing.B) { benchmarkAddTo(b, Small) }
  1650  func BenchmarkAddToMed(b *testing.B)   { benchmarkAddTo(b, Medium) }
  1651  func BenchmarkAddToLarge(b *testing.B) { benchmarkAddTo(b, Large) }
  1652  func BenchmarkAddToHuge(b *testing.B)  { benchmarkAddTo(b, Huge) }
  1653  
  1654  func benchmarkCumProd(b *testing.B, size int) {
  1655  	src := rand.NewSource(1)
  1656  	s := randomSlice(size, src)
  1657  	dst := randomSlice(size, src)
  1658  	b.ResetTimer()
  1659  	for i := 0; i < b.N; i++ {
  1660  		CumProd(dst, s)
  1661  	}
  1662  }
  1663  func BenchmarkCumProdSmall(b *testing.B) { benchmarkCumProd(b, Small) }
  1664  func BenchmarkCumProdMed(b *testing.B)   { benchmarkCumProd(b, Medium) }
  1665  func BenchmarkCumProdLarge(b *testing.B) { benchmarkCumProd(b, Large) }
  1666  func BenchmarkCumProdHuge(b *testing.B)  { benchmarkCumProd(b, Huge) }
  1667  
  1668  func benchmarkCumSum(b *testing.B, size int) {
  1669  	src := rand.NewSource(1)
  1670  	s := randomSlice(size, src)
  1671  	dst := randomSlice(size, src)
  1672  	b.ResetTimer()
  1673  	for i := 0; i < b.N; i++ {
  1674  		CumSum(dst, s)
  1675  	}
  1676  }
  1677  func BenchmarkCumSumSmall(b *testing.B) { benchmarkCumSum(b, Small) }
  1678  func BenchmarkCumSumMed(b *testing.B)   { benchmarkCumSum(b, Medium) }
  1679  func BenchmarkCumSumLarge(b *testing.B) { benchmarkCumSum(b, Large) }
  1680  func BenchmarkCumSumHuge(b *testing.B)  { benchmarkCumSum(b, Huge) }
  1681  
  1682  func benchmarkDiv(b *testing.B, size int) {
  1683  	src := rand.NewSource(1)
  1684  	s := randomSlice(size, src)
  1685  	dst := randomSlice(size, src)
  1686  	b.ResetTimer()
  1687  	for i := 0; i < b.N; i++ {
  1688  		Div(dst, s)
  1689  	}
  1690  }
  1691  func BenchmarkDivSmall(b *testing.B) { benchmarkDiv(b, Small) }
  1692  func BenchmarkDivMed(b *testing.B)   { benchmarkDiv(b, Medium) }
  1693  func BenchmarkDivLarge(b *testing.B) { benchmarkDiv(b, Large) }
  1694  func BenchmarkDivHuge(b *testing.B)  { benchmarkDiv(b, Huge) }
  1695  
  1696  func benchmarkDivTo(b *testing.B, size int) {
  1697  	src := rand.NewSource(1)
  1698  	s1 := randomSlice(size, src)
  1699  	s2 := randomSlice(size, src)
  1700  	dst := randomSlice(size, src)
  1701  	b.ResetTimer()
  1702  	for i := 0; i < b.N; i++ {
  1703  		DivTo(dst, s1, s2)
  1704  	}
  1705  }
  1706  func BenchmarkDivToSmall(b *testing.B) { benchmarkDivTo(b, Small) }
  1707  func BenchmarkDivToMed(b *testing.B)   { benchmarkDivTo(b, Medium) }
  1708  func BenchmarkDivToLarge(b *testing.B) { benchmarkDivTo(b, Large) }
  1709  func BenchmarkDivToHuge(b *testing.B)  { benchmarkDivTo(b, Huge) }
  1710  
  1711  func benchmarkSub(b *testing.B, size int) {
  1712  	src := rand.NewSource(1)
  1713  	s1 := randomSlice(size, src)
  1714  	s2 := randomSlice(size, src)
  1715  	b.ResetTimer()
  1716  	for i := 0; i < b.N; i++ {
  1717  		Sub(s1, s2)
  1718  	}
  1719  }
  1720  func BenchmarkSubSmall(b *testing.B) { benchmarkSub(b, Small) }
  1721  func BenchmarkSubMed(b *testing.B)   { benchmarkSub(b, Medium) }
  1722  func BenchmarkSubLarge(b *testing.B) { benchmarkSub(b, Large) }
  1723  func BenchmarkSubHuge(b *testing.B)  { benchmarkSub(b, Huge) }
  1724  
  1725  func benchmarkSubTo(b *testing.B, size int) {
  1726  	src := rand.NewSource(1)
  1727  	s1 := randomSlice(size, src)
  1728  	s2 := randomSlice(size, src)
  1729  	dst := randomSlice(size, src)
  1730  	b.ResetTimer()
  1731  	for i := 0; i < b.N; i++ {
  1732  		SubTo(dst, s1, s2)
  1733  	}
  1734  }
  1735  func BenchmarkSubToSmall(b *testing.B) { benchmarkSubTo(b, Small) }
  1736  func BenchmarkSubToMed(b *testing.B)   { benchmarkSubTo(b, Medium) }
  1737  func BenchmarkSubToLarge(b *testing.B) { benchmarkSubTo(b, Large) }
  1738  func BenchmarkSubToHuge(b *testing.B)  { benchmarkSubTo(b, Huge) }
  1739  
  1740  func benchmarkLogSumExp(b *testing.B, size int) {
  1741  	src := rand.NewSource(1)
  1742  	s := randomSlice(size, src)
  1743  	b.ResetTimer()
  1744  	for i := 0; i < b.N; i++ {
  1745  		LogSumExp(s)
  1746  	}
  1747  }
  1748  func BenchmarkLogSumExpSmall(b *testing.B) { benchmarkLogSumExp(b, Small) }
  1749  func BenchmarkLogSumExpMed(b *testing.B)   { benchmarkLogSumExp(b, Medium) }
  1750  func BenchmarkLogSumExpLarge(b *testing.B) { benchmarkLogSumExp(b, Large) }
  1751  func BenchmarkLogSumExpHuge(b *testing.B)  { benchmarkLogSumExp(b, Huge) }
  1752  
  1753  func benchmarkDot(b *testing.B, size int) {
  1754  	src := rand.NewSource(1)
  1755  	s1 := randomSlice(size, src)
  1756  	s2 := randomSlice(size, src)
  1757  	b.ResetTimer()
  1758  	for i := 0; i < b.N; i++ {
  1759  		Dot(s1, s2)
  1760  	}
  1761  }
  1762  func BenchmarkDotSmall(b *testing.B) { benchmarkDot(b, Small) }
  1763  func BenchmarkDotMed(b *testing.B)   { benchmarkDot(b, Medium) }
  1764  func BenchmarkDotLarge(b *testing.B) { benchmarkDot(b, Large) }
  1765  func BenchmarkDotHuge(b *testing.B)  { benchmarkDot(b, Huge) }
  1766  
  1767  func benchmarkAddScaledTo(b *testing.B, size int) {
  1768  	src := rand.NewSource(1)
  1769  	dst := randomSlice(size, src)
  1770  	y := randomSlice(size, src)
  1771  	s := randomSlice(size, src)
  1772  	b.ResetTimer()
  1773  	for i := 0; i < b.N; i++ {
  1774  		AddScaledTo(dst, y, 2.3, s)
  1775  	}
  1776  }
  1777  func BenchmarkAddScaledToSmall(b *testing.B)  { benchmarkAddScaledTo(b, Small) }
  1778  func BenchmarkAddScaledToMedium(b *testing.B) { benchmarkAddScaledTo(b, Medium) }
  1779  func BenchmarkAddScaledToLarge(b *testing.B)  { benchmarkAddScaledTo(b, Large) }
  1780  func BenchmarkAddScaledToHuge(b *testing.B)   { benchmarkAddScaledTo(b, Huge) }
  1781  
  1782  func benchmarkScale(b *testing.B, size int) {
  1783  	src := rand.NewSource(1)
  1784  	dst := randomSlice(size, src)
  1785  	b.ResetTimer()
  1786  	for i := 0; i < b.N; i += 2 {
  1787  		Scale(2.0, dst)
  1788  		Scale(0.5, dst)
  1789  	}
  1790  }
  1791  func BenchmarkScaleSmall(b *testing.B)  { benchmarkScale(b, Small) }
  1792  func BenchmarkScaleMedium(b *testing.B) { benchmarkScale(b, Medium) }
  1793  func BenchmarkScaleLarge(b *testing.B)  { benchmarkScale(b, Large) }
  1794  func BenchmarkScaleHuge(b *testing.B)   { benchmarkScale(b, Huge) }
  1795  
  1796  func benchmarkNorm2(b *testing.B, size int) {
  1797  	src := rand.NewSource(1)
  1798  	s := randomSlice(size, src)
  1799  	b.ResetTimer()
  1800  	for i := 0; i < b.N; i++ {
  1801  		Norm(s, 2)
  1802  	}
  1803  }
  1804  func BenchmarkNorm2Small(b *testing.B)  { benchmarkNorm2(b, Small) }
  1805  func BenchmarkNorm2Medium(b *testing.B) { benchmarkNorm2(b, Medium) }
  1806  func BenchmarkNorm2Large(b *testing.B)  { benchmarkNorm2(b, Large) }
  1807  func BenchmarkNorm2Huge(b *testing.B)   { benchmarkNorm2(b, Huge) }
  1808  
  1809  func benchmarkSumCompensated(b *testing.B, size int) {
  1810  	src := rand.NewSource(1)
  1811  	s := randomSlice(size, src)
  1812  	b.ResetTimer()
  1813  	for i := 0; i < b.N; i++ {
  1814  		SumCompensated(s)
  1815  	}
  1816  }
  1817  
  1818  func BenchmarkSumCompensatedSmall(b *testing.B)  { benchmarkSumCompensated(b, Small) }
  1819  func BenchmarkSumCompensatedMedium(b *testing.B) { benchmarkSumCompensated(b, Medium) }
  1820  func BenchmarkSumCompensatedLarge(b *testing.B)  { benchmarkSumCompensated(b, Large) }
  1821  func BenchmarkSumCompensatedHuge(b *testing.B)   { benchmarkSumCompensated(b, Huge) }
  1822  
  1823  func benchmarkSum(b *testing.B, size int) {
  1824  	src := rand.NewSource(1)
  1825  	s := randomSlice(size, src)
  1826  	b.ResetTimer()
  1827  	for i := 0; i < b.N; i++ {
  1828  		Sum(s)
  1829  	}
  1830  }
  1831  
  1832  func BenchmarkSumSmall(b *testing.B)  { benchmarkSum(b, Small) }
  1833  func BenchmarkSumMedium(b *testing.B) { benchmarkSum(b, Medium) }
  1834  func BenchmarkSumLarge(b *testing.B)  { benchmarkSum(b, Large) }
  1835  func BenchmarkSumHuge(b *testing.B)   { benchmarkSum(b, Huge) }