OSDN Git Service

test (#52)
[bytom/vapor.git] / vendor / gonum.org / v1 / gonum / floats / floats_test.go
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         "math"
9         "strconv"
10         "testing"
11
12         "golang.org/x/exp/rand"
13 )
14
15 const (
16         EqTolerance = 1E-14
17         Small       = 10
18         Medium      = 1000
19         Large       = 100000
20         Huge        = 10000000
21 )
22
23 func AreSlicesEqual(t *testing.T, truth, comp []float64, str string) {
24         if !EqualApprox(comp, truth, EqTolerance) {
25                 t.Errorf(str+". Expected %v, returned %v", truth, comp)
26         }
27 }
28
29 func Panics(fun func()) (b bool) {
30         defer func() {
31                 err := recover()
32                 if err != nil {
33                         b = true
34                 }
35         }()
36         fun()
37         return
38 }
39
40 func TestAdd(t *testing.T) {
41         a := []float64{1, 2, 3}
42         b := []float64{4, 5, 6}
43         c := []float64{7, 8, 9}
44         truth := []float64{12, 15, 18}
45         n := make([]float64, len(a))
46
47         Add(n, a)
48         Add(n, b)
49         Add(n, c)
50         AreSlicesEqual(t, truth, n, "Wrong addition of slices new receiver")
51         Add(a, b)
52         Add(a, c)
53         AreSlicesEqual(t, truth, n, "Wrong addition of slices for no new receiver")
54
55         // Test that it panics
56         if !Panics(func() { Add(make([]float64, 2), make([]float64, 3)) }) {
57                 t.Errorf("Did not panic with length mismatch")
58         }
59 }
60
61 func TestAddTo(t *testing.T) {
62         a := []float64{1, 2, 3}
63         b := []float64{4, 5, 6}
64         truth := []float64{5, 7, 9}
65         n1 := make([]float64, len(a))
66
67         n2 := AddTo(n1, a, b)
68         AreSlicesEqual(t, truth, n1, "Bad addition from mutator")
69         AreSlicesEqual(t, truth, n2, "Bad addition from returned slice")
70
71         // Test that it panics
72         if !Panics(func() { AddTo(make([]float64, 2), make([]float64, 3), make([]float64, 3)) }) {
73                 t.Errorf("Did not panic with length mismatch")
74         }
75         if !Panics(func() { AddTo(make([]float64, 3), make([]float64, 3), make([]float64, 2)) }) {
76                 t.Errorf("Did not panic with length mismatch")
77         }
78
79 }
80
81 func TestAddConst(t *testing.T) {
82         s := []float64{3, 4, 1, 7, 5}
83         c := 6.0
84         truth := []float64{9, 10, 7, 13, 11}
85         AddConst(c, s)
86         AreSlicesEqual(t, truth, s, "Wrong addition of constant")
87 }
88
89 func TestAddScaled(t *testing.T) {
90         s := []float64{3, 4, 1, 7, 5}
91         alpha := 6.0
92         dst := []float64{1, 2, 3, 4, 5}
93         ans := []float64{19, 26, 9, 46, 35}
94         AddScaled(dst, alpha, s)
95         if !EqualApprox(dst, ans, EqTolerance) {
96                 t.Errorf("Adding scaled did not match")
97         }
98         short := []float64{1}
99         if !Panics(func() { AddScaled(dst, alpha, short) }) {
100                 t.Errorf("Doesn't panic if s is smaller than dst")
101         }
102         if !Panics(func() { AddScaled(short, alpha, s) }) {
103                 t.Errorf("Doesn't panic if dst is smaller than s")
104         }
105 }
106
107 func TestAddScaledTo(t *testing.T) {
108         s := []float64{3, 4, 1, 7, 5}
109         alpha := 6.0
110         y := []float64{1, 2, 3, 4, 5}
111         dst1 := make([]float64, 5)
112         ans := []float64{19, 26, 9, 46, 35}
113         dst2 := AddScaledTo(dst1, y, alpha, s)
114         if !EqualApprox(dst1, ans, EqTolerance) {
115                 t.Errorf("AddScaledTo did not match for mutator")
116         }
117         if !EqualApprox(dst2, ans, EqTolerance) {
118                 t.Errorf("AddScaledTo did not match for returned slice")
119         }
120         AddScaledTo(dst1, y, alpha, s)
121         if !EqualApprox(dst1, ans, EqTolerance) {
122                 t.Errorf("Reusing dst did not match")
123         }
124         short := []float64{1}
125         if !Panics(func() { AddScaledTo(dst1, y, alpha, short) }) {
126                 t.Errorf("Doesn't panic if s is smaller than dst")
127         }
128         if !Panics(func() { AddScaledTo(short, y, alpha, s) }) {
129                 t.Errorf("Doesn't panic if dst is smaller than s")
130         }
131         if !Panics(func() { AddScaledTo(dst1, short, alpha, s) }) {
132                 t.Errorf("Doesn't panic if y is smaller than dst")
133         }
134 }
135
136 func TestArgsort(t *testing.T) {
137         s := []float64{3, 4, 1, 7, 5}
138         inds := make([]int, len(s))
139
140         Argsort(s, inds)
141
142         sortedS := []float64{1, 3, 4, 5, 7}
143         trueInds := []int{2, 0, 1, 4, 3}
144
145         if !Equal(s, sortedS) {
146                 t.Error("elements not sorted correctly")
147         }
148         for i := range trueInds {
149                 if trueInds[i] != inds[i] {
150                         t.Error("inds not correct")
151                 }
152         }
153
154         inds = []int{1, 2}
155         if !Panics(func() { Argsort(s, inds) }) {
156                 t.Error("does not panic if lengths do not match")
157         }
158 }
159
160 func TestCount(t *testing.T) {
161         s := []float64{3, 4, 1, 7, 5}
162         f := func(v float64) bool { return v > 3.5 }
163         truth := 3
164         n := Count(f, s)
165         if n != truth {
166                 t.Errorf("Wrong number of elements counted")
167         }
168 }
169
170 func TestCumProd(t *testing.T) {
171         s := []float64{3, 4, 1, 7, 5}
172         receiver := make([]float64, len(s))
173         result := CumProd(receiver, s)
174         truth := []float64{3, 12, 12, 84, 420}
175         AreSlicesEqual(t, truth, receiver, "Wrong cumprod mutated with new receiver")
176         AreSlicesEqual(t, truth, result, "Wrong cumprod result with new receiver")
177         CumProd(receiver, s)
178         AreSlicesEqual(t, truth, receiver, "Wrong cumprod returned with reused receiver")
179
180         // Test that it panics
181         if !Panics(func() { CumProd(make([]float64, 2), make([]float64, 3)) }) {
182                 t.Errorf("Did not panic with length mismatch")
183         }
184
185         // Test empty CumProd
186         emptyReceiver := make([]float64, 0)
187         truth = []float64{}
188         CumProd(emptyReceiver, emptyReceiver)
189         AreSlicesEqual(t, truth, emptyReceiver, "Wrong cumprod returned with empty receiver")
190
191 }
192
193 func TestCumSum(t *testing.T) {
194         s := []float64{3, 4, 1, 7, 5}
195         receiver := make([]float64, len(s))
196         result := CumSum(receiver, s)
197         truth := []float64{3, 7, 8, 15, 20}
198         AreSlicesEqual(t, truth, receiver, "Wrong cumsum mutated with new receiver")
199         AreSlicesEqual(t, truth, result, "Wrong cumsum returned with new receiver")
200         CumSum(receiver, s)
201         AreSlicesEqual(t, truth, receiver, "Wrong cumsum returned with reused receiver")
202
203         // Test that it panics
204         if !Panics(func() { CumSum(make([]float64, 2), make([]float64, 3)) }) {
205                 t.Errorf("Did not panic with length mismatch")
206         }
207
208         // Test empty CumSum
209         emptyReceiver := make([]float64, 0)
210         truth = []float64{}
211         CumSum(emptyReceiver, emptyReceiver)
212         AreSlicesEqual(t, truth, emptyReceiver, "Wrong cumsum returned with empty receiver")
213
214 }
215
216 func TestDistance(t *testing.T) {
217         norms := []float64{1, 2, 4, math.Inf(1)}
218         slices := []struct {
219                 s []float64
220                 t []float64
221         }{
222                 {
223                         nil,
224                         nil,
225                 },
226                 {
227                         []float64{8, 9, 10, -12},
228                         []float64{8, 9, 10, -12},
229                 },
230                 {
231                         []float64{1, 2, 3, -4, -5, 8},
232                         []float64{-9.2, -6.8, 9, -3, -2, 1},
233                 },
234         }
235
236         for j, test := range slices {
237                 tmp := make([]float64, len(test.s))
238                 for i, L := range norms {
239                         dist := Distance(test.s, test.t, L)
240                         copy(tmp, test.s)
241                         Sub(tmp, test.t)
242                         norm := Norm(tmp, L)
243                         if dist != norm { // Use equality because they should be identical
244                                 t.Errorf("Distance does not match norm for case %v, %v. Expected %v, Found %v.", i, j, norm, dist)
245                         }
246                 }
247         }
248
249         if !Panics(func() { Distance([]float64{}, norms, 1) }) {
250                 t.Errorf("Did not panic with unequal lengths")
251         }
252
253 }
254
255 func TestDiv(t *testing.T) {
256         s1 := []float64{5, 12, 27}
257         s2 := []float64{1, 2, 3}
258         ans := []float64{5, 6, 9}
259         Div(s1, s2)
260         if !EqualApprox(s1, ans, EqTolerance) {
261                 t.Errorf("Mul doesn't give correct answer")
262         }
263         s1short := []float64{1}
264         if !Panics(func() { Div(s1short, s2) }) {
265                 t.Errorf("Did not panic with unequal lengths")
266         }
267         s2short := []float64{1}
268         if !Panics(func() { Div(s1, s2short) }) {
269                 t.Errorf("Did not panic with unequal lengths")
270         }
271 }
272
273 func TestDivTo(t *testing.T) {
274         s1 := []float64{5, 12, 27}
275         s1orig := []float64{5, 12, 27}
276         s2 := []float64{1, 2, 3}
277         s2orig := []float64{1, 2, 3}
278         dst1 := make([]float64, 3)
279         ans := []float64{5, 6, 9}
280         dst2 := DivTo(dst1, s1, s2)
281         if !EqualApprox(dst1, ans, EqTolerance) {
282                 t.Errorf("DivTo doesn't give correct answer in mutated slice")
283         }
284         if !EqualApprox(dst2, ans, EqTolerance) {
285                 t.Errorf("DivTo doesn't give correct answer in returned slice")
286         }
287         if !EqualApprox(s1, s1orig, EqTolerance) {
288                 t.Errorf("S1 changes during multo")
289         }
290         if !EqualApprox(s2, s2orig, EqTolerance) {
291                 t.Errorf("s2 changes during multo")
292         }
293         DivTo(dst1, s1, s2)
294         if !EqualApprox(dst1, ans, EqTolerance) {
295                 t.Errorf("DivTo doesn't give correct answer reusing dst")
296         }
297         dstShort := []float64{1}
298         if !Panics(func() { DivTo(dstShort, s1, s2) }) {
299                 t.Errorf("Did not panic with s1 wrong length")
300         }
301         s1short := []float64{1}
302         if !Panics(func() { DivTo(dst1, s1short, s2) }) {
303                 t.Errorf("Did not panic with s1 wrong length")
304         }
305         s2short := []float64{1}
306         if !Panics(func() { DivTo(dst1, s1, s2short) }) {
307                 t.Errorf("Did not panic with s2 wrong length")
308         }
309 }
310
311 func TestDot(t *testing.T) {
312         s1 := []float64{1, 2, 3, 4}
313         s2 := []float64{-3, 4, 5, -6}
314         truth := -4.0
315         ans := Dot(s1, s2)
316         if ans != truth {
317                 t.Errorf("Dot product computed incorrectly")
318         }
319
320         // Test that it panics
321         if !Panics(func() { Dot(make([]float64, 2), make([]float64, 3)) }) {
322                 t.Errorf("Did not panic with length mismatch")
323         }
324 }
325
326 func TestEquals(t *testing.T) {
327         s1 := []float64{1, 2, 3, 4}
328         s2 := []float64{1, 2, 3, 4}
329         if !Equal(s1, s2) {
330                 t.Errorf("Equal slices returned as unequal")
331         }
332         s2 = []float64{1, 2, 3, 4 + 1e-14}
333         if Equal(s1, s2) {
334                 t.Errorf("Unequal slices returned as equal")
335         }
336         if Equal(s1, []float64{}) {
337                 t.Errorf("Unequal slice lengths returned as equal")
338         }
339 }
340
341 func TestEqualApprox(t *testing.T) {
342         s1 := []float64{1, 2, 3, 4}
343         s2 := []float64{1, 2, 3, 4 + 1e-10}
344         if EqualApprox(s1, s2, 1e-13) {
345                 t.Errorf("Unequal slices returned as equal for absolute")
346         }
347         if !EqualApprox(s1, s2, 1e-5) {
348                 t.Errorf("Equal slices returned as unequal for absolute")
349         }
350         s1 = []float64{1, 2, 3, 1000}
351         s2 = []float64{1, 2, 3, 1000 * (1 + 1e-7)}
352         if EqualApprox(s1, s2, 1e-8) {
353                 t.Errorf("Unequal slices returned as equal for relative")
354         }
355         if !EqualApprox(s1, s2, 1e-5) {
356                 t.Errorf("Equal slices returned as unequal for relative")
357         }
358         if EqualApprox(s1, []float64{}, 1e-5) {
359                 t.Errorf("Unequal slice lengths returned as equal")
360         }
361 }
362
363 func TestEqualFunc(t *testing.T) {
364         s1 := []float64{1, 2, 3, 4}
365         s2 := []float64{1, 2, 3, 4}
366         eq := func(x, y float64) bool { return x == y }
367         if !EqualFunc(s1, s2, eq) {
368                 t.Errorf("Equal slices returned as unequal")
369         }
370         s2 = []float64{1, 2, 3, 4 + 1e-14}
371         if EqualFunc(s1, s2, eq) {
372                 t.Errorf("Unequal slices returned as equal")
373         }
374         if EqualFunc(s1, []float64{}, eq) {
375                 t.Errorf("Unequal slice lengths returned as equal")
376         }
377 }
378
379 func TestEqualsRelative(t *testing.T) {
380         var equalityTests = []struct {
381                 a, b  float64
382                 tol   float64
383                 equal bool
384         }{
385                 {1000000, 1000001, 0, true},
386                 {1000001, 1000000, 0, true},
387                 {10000, 10001, 0, false},
388                 {10001, 10000, 0, false},
389                 {-1000000, -1000001, 0, true},
390                 {-1000001, -1000000, 0, true},
391                 {-10000, -10001, 0, false},
392                 {-10001, -10000, 0, false},
393                 {1.0000001, 1.0000002, 0, true},
394                 {1.0000002, 1.0000001, 0, true},
395                 {1.0002, 1.0001, 0, false},
396                 {1.0001, 1.0002, 0, false},
397                 {-1.000001, -1.000002, 0, true},
398                 {-1.000002, -1.000001, 0, true},
399                 {-1.0001, -1.0002, 0, false},
400                 {-1.0002, -1.0001, 0, false},
401                 {0.000000001000001, 0.000000001000002, 0, true},
402                 {0.000000001000002, 0.000000001000001, 0, true},
403                 {0.000000000001002, 0.000000000001001, 0, false},
404                 {0.000000000001001, 0.000000000001002, 0, false},
405                 {-0.000000001000001, -0.000000001000002, 0, true},
406                 {-0.000000001000002, -0.000000001000001, 0, true},
407                 {-0.000000000001002, -0.000000000001001, 0, false},
408                 {-0.000000000001001, -0.000000000001002, 0, false},
409                 {0, 0, 0, true},
410                 {0, -0, 0, true},
411                 {-0, -0, 0, true},
412                 {0.00000001, 0, 0, false},
413                 {0, 0.00000001, 0, false},
414                 {-0.00000001, 0, 0, false},
415                 {0, -0.00000001, 0, false},
416                 {0, 1e-310, 0.01, true},
417                 {1e-310, 0, 0.01, true},
418                 {1e-310, 0, 0.000001, false},
419                 {0, 1e-310, 0.000001, false},
420                 {0, -1e-310, 0.1, true},
421                 {-1e-310, 0, 0.1, true},
422                 {-1e-310, 0, 0.00000001, false},
423                 {0, -1e-310, 0.00000001, false},
424                 {math.Inf(1), math.Inf(1), 0, true},
425                 {math.Inf(-1), math.Inf(-1), 0, true},
426                 {math.Inf(-1), math.Inf(1), 0, false},
427                 {math.Inf(1), math.MaxFloat64, 0, false},
428                 {math.Inf(-1), -math.MaxFloat64, 0, false},
429                 {math.NaN(), math.NaN(), 0, false},
430                 {math.NaN(), 0, 0, false},
431                 {-0, math.NaN(), 0, false},
432                 {math.NaN(), -0, 0, false},
433                 {0, math.NaN(), 0, false},
434                 {math.NaN(), math.Inf(1), 0, false},
435                 {math.Inf(1), math.NaN(), 0, false},
436                 {math.NaN(), math.Inf(-1), 0, false},
437                 {math.Inf(-1), math.NaN(), 0, false},
438                 {math.NaN(), math.MaxFloat64, 0, false},
439                 {math.MaxFloat64, math.NaN(), 0, false},
440                 {math.NaN(), -math.MaxFloat64, 0, false},
441                 {-math.MaxFloat64, math.NaN(), 0, false},
442                 {math.NaN(), math.SmallestNonzeroFloat64, 0, false},
443                 {math.SmallestNonzeroFloat64, math.NaN(), 0, false},
444                 {math.NaN(), -math.SmallestNonzeroFloat64, 0, false},
445                 {-math.SmallestNonzeroFloat64, math.NaN(), 0, false},
446                 {1.000000001, -1.0, 0, false},
447                 {-1.0, 1.000000001, 0, false},
448                 {-1.000000001, 1.0, 0, false},
449                 {1.0, -1.000000001, 0, false},
450                 {10 * math.SmallestNonzeroFloat64, 10 * -math.SmallestNonzeroFloat64, 0, true},
451                 {1e11 * math.SmallestNonzeroFloat64, 1e11 * -math.SmallestNonzeroFloat64, 0, false},
452                 {math.SmallestNonzeroFloat64, -math.SmallestNonzeroFloat64, 0, true},
453                 {-math.SmallestNonzeroFloat64, math.SmallestNonzeroFloat64, 0, true},
454                 {math.SmallestNonzeroFloat64, 0, 0, true},
455                 {0, math.SmallestNonzeroFloat64, 0, true},
456                 {-math.SmallestNonzeroFloat64, 0, 0, true},
457                 {0, -math.SmallestNonzeroFloat64, 0, true},
458                 {0.000000001, -math.SmallestNonzeroFloat64, 0, false},
459                 {0.000000001, math.SmallestNonzeroFloat64, 0, false},
460                 {math.SmallestNonzeroFloat64, 0.000000001, 0, false},
461                 {-math.SmallestNonzeroFloat64, 0.000000001, 0, false},
462         }
463         for _, ts := range equalityTests {
464                 if ts.tol == 0 {
465                         ts.tol = 1e-5
466                 }
467                 if equal := EqualWithinRel(ts.a, ts.b, ts.tol); equal != ts.equal {
468                         t.Errorf("Relative equality of %g and %g with tolerance %g returned: %v. Expected: %v",
469                                 ts.a, ts.b, ts.tol, equal, ts.equal)
470                 }
471         }
472 }
473
474 func nextAfterN(x, y float64, n int) float64 {
475         for i := 0; i < n; i++ {
476                 x = math.Nextafter(x, y)
477         }
478         return x
479 }
480
481 func TestEqualsULP(t *testing.T) {
482         if f := 67329.242; !EqualWithinULP(f, nextAfterN(f, math.Inf(1), 10), 10) {
483                 t.Errorf("Equal values returned as unequal")
484         }
485         if f := 67329.242; EqualWithinULP(f, nextAfterN(f, math.Inf(1), 5), 1) {
486                 t.Errorf("Unequal values returned as equal")
487         }
488         if f := 67329.242; EqualWithinULP(nextAfterN(f, math.Inf(1), 5), f, 1) {
489                 t.Errorf("Unequal values returned as equal")
490         }
491         if f := nextAfterN(0, math.Inf(1), 2); !EqualWithinULP(f, nextAfterN(f, math.Inf(-1), 5), 10) {
492                 t.Errorf("Equal values returned as unequal")
493         }
494         if !EqualWithinULP(67329.242, 67329.242, 10) {
495                 t.Errorf("Equal float64s not returned as equal")
496         }
497         if EqualWithinULP(1, math.NaN(), 10) {
498                 t.Errorf("NaN returned as equal")
499         }
500
501 }
502
503 func TestEqualLengths(t *testing.T) {
504         s1 := []float64{1, 2, 3, 4}
505         s2 := []float64{1, 2, 3, 4}
506         s3 := []float64{1, 2, 3}
507         if !EqualLengths(s1, s2) {
508                 t.Errorf("Equal lengths returned as unequal")
509         }
510         if EqualLengths(s1, s3) {
511                 t.Errorf("Unequal lengths returned as equal")
512         }
513         if !EqualLengths(s1) {
514                 t.Errorf("Single slice returned as unequal")
515         }
516         if !EqualLengths() {
517                 t.Errorf("No slices returned as unequal")
518         }
519 }
520
521 func eqIntSlice(one, two []int) string {
522         if len(one) != len(two) {
523                 return "Length mismatch"
524         }
525         for i, val := range one {
526                 if val != two[i] {
527                         return "Index " + strconv.Itoa(i) + " mismatch"
528                 }
529         }
530         return ""
531 }
532
533 func TestFind(t *testing.T) {
534         s := []float64{3, 4, 1, 7, 5}
535         f := func(v float64) bool { return v > 3.5 }
536         allTrueInds := []int{1, 3, 4}
537
538         // Test finding first two elements
539         inds, err := Find(nil, f, s, 2)
540         if err != nil {
541                 t.Errorf("Find first two: Improper error return")
542         }
543         trueInds := allTrueInds[:2]
544         str := eqIntSlice(inds, trueInds)
545         if str != "" {
546                 t.Errorf("Find first two: " + str)
547         }
548
549         // Test finding no elements with non nil slice
550         inds = []int{1, 2, 3, 4, 5, 6}
551         inds, err = Find(inds, f, s, 0)
552         if err != nil {
553                 t.Errorf("Find no elements: Improper error return")
554         }
555         str = eqIntSlice(inds, []int{})
556         if str != "" {
557                 t.Errorf("Find no non-nil: " + str)
558         }
559
560         // Test finding first two elements with non nil slice
561         inds = []int{1, 2, 3, 4, 5, 6}
562         inds, err = Find(inds, f, s, 2)
563         if err != nil {
564                 t.Errorf("Find first two non-nil: Improper error return")
565         }
566         str = eqIntSlice(inds, trueInds)
567         if str != "" {
568                 t.Errorf("Find first two non-nil: " + str)
569         }
570
571         // Test finding too many elements
572         inds, err = Find(inds, f, s, 4)
573         if err == nil {
574                 t.Errorf("Request too many: No error returned")
575         }
576         str = eqIntSlice(inds, allTrueInds)
577         if str != "" {
578                 t.Errorf("Request too many: Does not match all of the inds: " + str)
579         }
580
581         // Test finding all elements
582         inds, err = Find(nil, f, s, -1)
583         if err != nil {
584                 t.Errorf("Find all: Improper error returned")
585         }
586         str = eqIntSlice(inds, allTrueInds)
587         if str != "" {
588                 t.Errorf("Find all: Does not match all of the inds: " + str)
589         }
590 }
591
592 func TestHasNaN(t *testing.T) {
593         for i, test := range []struct {
594                 s   []float64
595                 ans bool
596         }{
597                 {},
598                 {
599                         s: []float64{1, 2, 3, 4},
600                 },
601                 {
602                         s:   []float64{1, math.NaN(), 3, 4},
603                         ans: true,
604                 },
605                 {
606                         s:   []float64{1, 2, 3, math.NaN()},
607                         ans: true,
608                 },
609         } {
610                 b := HasNaN(test.s)
611                 if b != test.ans {
612                         t.Errorf("HasNaN mismatch case %d. Expected %v, Found %v", i, test.ans, b)
613                 }
614         }
615 }
616
617 func TestLogSpan(t *testing.T) {
618         receiver1 := make([]float64, 6)
619         truth := []float64{0.001, 0.01, 0.1, 1, 10, 100}
620         receiver2 := LogSpan(receiver1, 0.001, 100)
621         tst := make([]float64, 6)
622         for i := range truth {
623                 tst[i] = receiver1[i] / truth[i]
624         }
625         comp := make([]float64, 6)
626         for i := range comp {
627                 comp[i] = 1
628         }
629         AreSlicesEqual(t, comp, tst, "Improper logspace from mutator")
630
631         for i := range truth {
632                 tst[i] = receiver2[i] / truth[i]
633         }
634         AreSlicesEqual(t, comp, tst, "Improper logspace from returned slice")
635
636         if !Panics(func() { LogSpan(nil, 1, 5) }) {
637                 t.Errorf("Span accepts nil argument")
638         }
639         if !Panics(func() { LogSpan(make([]float64, 1), 1, 5) }) {
640                 t.Errorf("Span accepts argument of len = 1")
641         }
642 }
643
644 func TestLogSumExp(t *testing.T) {
645         s := []float64{1, 2, 3, 4, 5}
646         val := LogSumExp(s)
647         // 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
648         truth := 5.4519143959375933331957225109748087179338972737576824
649         if math.Abs(val-truth) > EqTolerance {
650                 t.Errorf("Wrong logsumexp for many values")
651         }
652         s = []float64{1, 2}
653         // http://www.wolframalpha.com/input/?i=log%28exp%281%29+%2B+exp%282%29%29
654         truth = 2.3132616875182228340489954949678556419152800856703483
655         val = LogSumExp(s)
656         if math.Abs(val-truth) > EqTolerance {
657                 t.Errorf("Wrong logsumexp for two values. %v expected, %v found", truth, val)
658         }
659         // This case would normally underflow
660         s = []float64{-1001, -1002, -1003, -1004, -1005}
661         // 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
662         truth = -1000.54808560406240666680427748902519128206610272624
663         val = LogSumExp(s)
664         if math.Abs(val-truth) > EqTolerance {
665                 t.Errorf("Doesn't match for underflow case. %v expected, %v found", truth, val)
666         }
667         // positive infinite case
668         s = []float64{1, 2, 3, 4, 5, math.Inf(1)}
669         val = LogSumExp(s)
670         truth = math.Inf(1)
671         if val != truth {
672                 t.Errorf("Doesn't match for pos Infinity case. %v expected, %v found", truth, val)
673         }
674         // negative infinite case
675         s = []float64{1, 2, 3, 4, 5, math.Inf(-1)}
676         val = LogSumExp(s)
677         truth = 5.4519143959375933331957225109748087179338972737576824 // same as first case
678         if math.Abs(val-truth) > EqTolerance {
679                 t.Errorf("Wrong logsumexp for values with negative infinity")
680         }
681
682 }
683
684 func TestMaxAndIdx(t *testing.T) {
685         s := []float64{3, 4, 1, 7, 5}
686         ind := MaxIdx(s)
687         val := Max(s)
688         if val != 7 {
689                 t.Errorf("Wrong value returned")
690         }
691         if ind != 3 {
692                 t.Errorf("Wrong index returned")
693         }
694 }
695
696 func TestMinAndIdx(t *testing.T) {
697         s := []float64{3, 4, 1, 7, 5}
698         ind := MinIdx(s)
699         val := Min(s)
700         if val != 1 {
701                 t.Errorf("Wrong value returned")
702         }
703         if ind != 2 {
704                 t.Errorf("Wrong index returned")
705         }
706 }
707
708 func TestMul(t *testing.T) {
709         s1 := []float64{1, 2, 3}
710         s2 := []float64{1, 2, 3}
711         ans := []float64{1, 4, 9}
712         Mul(s1, s2)
713         if !EqualApprox(s1, ans, EqTolerance) {
714                 t.Errorf("Mul doesn't give correct answer")
715         }
716         s1short := []float64{1}
717         if !Panics(func() { Mul(s1short, s2) }) {
718                 t.Errorf("Did not panic with unequal lengths")
719         }
720         s2short := []float64{1}
721         if !Panics(func() { Mul(s1, s2short) }) {
722                 t.Errorf("Did not panic with unequal lengths")
723         }
724 }
725
726 func TestMulTo(t *testing.T) {
727         s1 := []float64{1, 2, 3}
728         s1orig := []float64{1, 2, 3}
729         s2 := []float64{1, 2, 3}
730         s2orig := []float64{1, 2, 3}
731         dst1 := make([]float64, 3)
732         ans := []float64{1, 4, 9}
733         dst2 := MulTo(dst1, s1, s2)
734         if !EqualApprox(dst1, ans, EqTolerance) {
735                 t.Errorf("MulTo doesn't give correct answer in mutated slice")
736         }
737         if !EqualApprox(dst2, ans, EqTolerance) {
738                 t.Errorf("MulTo doesn't give correct answer in returned slice")
739         }
740         if !EqualApprox(s1, s1orig, EqTolerance) {
741                 t.Errorf("S1 changes during multo")
742         }
743         if !EqualApprox(s2, s2orig, EqTolerance) {
744                 t.Errorf("s2 changes during multo")
745         }
746         MulTo(dst1, s1, s2)
747         if !EqualApprox(dst1, ans, EqTolerance) {
748                 t.Errorf("MulTo doesn't give correct answer reusing dst")
749         }
750         dstShort := []float64{1}
751         if !Panics(func() { MulTo(dstShort, s1, s2) }) {
752                 t.Errorf("Did not panic with s1 wrong length")
753         }
754         s1short := []float64{1}
755         if !Panics(func() { MulTo(dst1, s1short, s2) }) {
756                 t.Errorf("Did not panic with s1 wrong length")
757         }
758         s2short := []float64{1}
759         if !Panics(func() { MulTo(dst1, s1, s2short) }) {
760                 t.Errorf("Did not panic with s2 wrong length")
761         }
762 }
763
764 func TestNaNWith(t *testing.T) {
765         tests := []struct {
766                 payload uint64
767                 bits    uint64
768         }{
769                 {0, math.Float64bits(0 / func() float64 { return 0 }())}, // Hide the division by zero from the compiler.
770                 {1, math.Float64bits(math.NaN())},
771                 {1954, 0x7ff80000000007a2}, // R NA.
772         }
773
774         for _, test := range tests {
775                 nan := NaNWith(test.payload)
776                 if !math.IsNaN(nan) {
777                         t.Errorf("expected NaN value, got:%f", nan)
778                 }
779
780                 bits := math.Float64bits(nan)
781
782                 // Strip sign bit.
783                 const sign = 1 << 63
784                 bits &^= sign
785                 test.bits &^= sign
786
787                 if bits != test.bits {
788                         t.Errorf("expected NaN bit representation: got:%x want:%x", bits, test.bits)
789                 }
790         }
791 }
792
793 func TestNaNPayload(t *testing.T) {
794         tests := []struct {
795                 f       float64
796                 payload uint64
797                 ok      bool
798         }{
799                 {0 / func() float64 { return 0 }(), 0, true}, // Hide the division by zero from the compiler.
800
801                 // The following two line are written explicitly to defend against potential changes to math.Copysign.
802                 {math.Float64frombits(math.Float64bits(math.NaN()) | (1 << 63)), 1, true},  // math.Copysign(math.NaN(), -1)
803                 {math.Float64frombits(math.Float64bits(math.NaN()) &^ (1 << 63)), 1, true}, // math.Copysign(math.NaN(), 1)
804
805                 {NaNWith(1954), 1954, true}, // R NA.
806
807                 {math.Copysign(0, -1), 0, false},
808                 {0, 0, false},
809                 {math.Inf(-1), 0, false},
810                 {math.Inf(1), 0, false},
811
812                 {math.Float64frombits(0x7ff0000000000001), 0, false}, // Signalling NaN.
813         }
814
815         for _, test := range tests {
816                 payload, ok := NaNPayload(test.f)
817                 if payload != test.payload {
818                         t.Errorf("expected NaN payload: got:%x want:%x", payload, test.payload)
819                 }
820                 if ok != test.ok {
821                         t.Errorf("expected NaN status: got:%t want:%t", ok, test.ok)
822                 }
823         }
824 }
825
826 func TestNearest(t *testing.T) {
827         s := []float64{6.2, 3, 5, 6.2, 8}
828         ind := Nearest(s, 2.0)
829         if ind != 1 {
830                 t.Errorf("Wrong index returned when value is less than all of elements")
831         }
832         ind = Nearest(s, 9.0)
833         if ind != 4 {
834                 t.Errorf("Wrong index returned when value is greater than all of elements")
835         }
836         ind = Nearest(s, 3.1)
837         if ind != 1 {
838                 t.Errorf("Wrong index returned when value is greater than closest element")
839         }
840         ind = Nearest(s, 3.1)
841         if ind != 1 {
842                 t.Errorf("Wrong index returned when value is greater than closest element")
843         }
844         ind = Nearest(s, 2.9)
845         if ind != 1 {
846                 t.Errorf("Wrong index returned when value is less than closest element")
847         }
848         ind = Nearest(s, 3)
849         if ind != 1 {
850                 t.Errorf("Wrong index returned when value is equal to element")
851         }
852         ind = Nearest(s, 6.2)
853         if ind != 0 {
854                 t.Errorf("Wrong index returned when value is equal to several elements")
855         }
856         ind = Nearest(s, 4)
857         if ind != 1 {
858                 t.Errorf("Wrong index returned when value is exactly between two closest elements")
859         }
860 }
861
862 func TestNearestWithinSpan(t *testing.T) {
863         if !Panics(func() { NearestWithinSpan(10, 8, 2, 4.5) }) {
864                 t.Errorf("Did not panic when upper bound is lower than greater bound")
865         }
866         for i, test := range []struct {
867                 length int
868                 lower  float64
869                 upper  float64
870                 value  float64
871                 idx    int
872         }{
873                 {
874                         length: 13,
875                         lower:  7,
876                         upper:  8.2,
877                         value:  6,
878                         idx:    -1,
879                 },
880                 {
881                         length: 13,
882                         lower:  7,
883                         upper:  8.2,
884                         value:  10,
885                         idx:    -1,
886                 },
887                 {
888                         length: 13,
889                         lower:  7,
890                         upper:  8.2,
891                         value:  7.19,
892                         idx:    2,
893                 },
894                 {
895                         length: 13,
896                         lower:  7,
897                         upper:  8.2,
898                         value:  7.21,
899                         idx:    2,
900                 },
901                 {
902                         length: 13,
903                         lower:  7,
904                         upper:  8.2,
905                         value:  7.2,
906                         idx:    2,
907                 },
908                 {
909                         length: 13,
910                         lower:  7,
911                         upper:  8.2,
912                         value:  7.151,
913                         idx:    2,
914                 },
915                 {
916                         length: 13,
917                         lower:  7,
918                         upper:  8.2,
919                         value:  7.249,
920                         idx:    2,
921                 },
922         } {
923                 if idx := NearestWithinSpan(test.length, test.lower, test.upper, test.value); test.idx != idx {
924                         t.Errorf("Case %v mismatch: Want: %v, Got: %v", i, test.idx, idx)
925                 }
926         }
927 }
928
929 func TestNorm(t *testing.T) {
930         s := []float64{-1, -3.4, 5, -6}
931         val := Norm(s, math.Inf(1))
932         truth := 6.0
933         if math.Abs(val-truth) > EqTolerance {
934                 t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val)
935         }
936         // 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
937         val = Norm(s, 2)
938         truth = 8.5767126569566267590651614132751986658027271236078592
939         if math.Abs(val-truth) > EqTolerance {
940                 t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val)
941         }
942         // 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
943         val = Norm(s, 3)
944         truth = 7.2514321388020228478109121239004816430071237369356233
945         if math.Abs(val-truth) > EqTolerance {
946                 t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val)
947         }
948
949         //http://www.wolframalpha.com/input/?i=%7C-1%7C+%2B+%7C-3.4%7C+%2B+%7C5%7C%2B++%7C6%7C
950         val = Norm(s, 1)
951         truth = 15.4
952         if math.Abs(val-truth) > EqTolerance {
953                 t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val)
954         }
955 }
956
957 func TestProd(t *testing.T) {
958         s := []float64{}
959         val := Prod(s)
960         if val != 1 {
961                 t.Errorf("Val not returned as default when slice length is zero")
962         }
963         s = []float64{3, 4, 1, 7, 5}
964         val = Prod(s)
965         if val != 420 {
966                 t.Errorf("Wrong prod returned. Expected %v returned %v", 420, val)
967         }
968 }
969
970 func TestReverse(t *testing.T) {
971         for _, s := range [][]float64{
972                 {0},
973                 {1, 0},
974                 {2, 1, 0},
975                 {3, 2, 1, 0},
976                 {9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
977         } {
978                 Reverse(s)
979                 for i, v := range s {
980                         if v != float64(i) {
981                                 t.Errorf("unexpected values for element %d: got:%v want:%v", i, v, i)
982                         }
983                 }
984         }
985 }
986
987 func TestRound(t *testing.T) {
988         for _, test := range []struct {
989                 x    float64
990                 prec int
991                 want float64
992         }{
993                 {x: 0, prec: 1, want: 0},
994                 {x: math.Inf(1), prec: 1, want: math.Inf(1)},
995                 {x: math.NaN(), prec: 1, want: math.NaN()},
996                 {x: func() float64 { var f float64; return -f }(), prec: 1, want: 0},
997                 {x: math.MaxFloat64 / 2, prec: 1, want: math.MaxFloat64 / 2},
998                 {x: 1 << 64, prec: 1, want: 1 << 64},
999                 {x: 454.4445, prec: 3, want: 454.445},
1000                 {x: 454.44445, prec: 4, want: 454.4445},
1001                 {x: 0.42499, prec: 4, want: 0.425},
1002                 {x: 0.42599, prec: 4, want: 0.426},
1003                 {x: 0.424999999999993, prec: 2, want: 0.42},
1004                 {x: 0.425, prec: 2, want: 0.43},
1005                 {x: 0.425000000000001, prec: 2, want: 0.43},
1006                 {x: 123.4244999999999, prec: 3, want: 123.424},
1007                 {x: 123.4245, prec: 3, want: 123.425},
1008                 {x: 123.4245000000001, prec: 3, want: 123.425},
1009
1010                 {x: 454.45, prec: 0, want: 454},
1011                 {x: 454.45, prec: 1, want: 454.5},
1012                 {x: 454.45, prec: 2, want: 454.45},
1013                 {x: 454.45, prec: 3, want: 454.45},
1014                 {x: 454.445, prec: 0, want: 454},
1015                 {x: 454.445, prec: 1, want: 454.4},
1016                 {x: 454.445, prec: 2, want: 454.45},
1017                 {x: 454.445, prec: 3, want: 454.445},
1018                 {x: 454.445, prec: 4, want: 454.445},
1019                 {x: 454.55, prec: 0, want: 455},
1020                 {x: 454.55, prec: 1, want: 454.6},
1021                 {x: 454.55, prec: 2, want: 454.55},
1022                 {x: 454.55, prec: 3, want: 454.55},
1023                 {x: 454.455, prec: 0, want: 454},
1024                 {x: 454.455, prec: 1, want: 454.5},
1025                 {x: 454.455, prec: 2, want: 454.46},
1026                 {x: 454.455, prec: 3, want: 454.455},
1027                 {x: 454.455, prec: 4, want: 454.455},
1028
1029                 // Negative precision.
1030                 {x: 454.45, prec: -1, want: 450},
1031                 {x: 454.45, prec: -2, want: 500},
1032                 {x: 500, prec: -3, want: 1000},
1033                 {x: 500, prec: -4, want: 0},
1034                 {x: 1500, prec: -3, want: 2000},
1035                 {x: 1500, prec: -4, want: 0},
1036         } {
1037                 for _, sign := range []float64{1, -1} {
1038                         got := Round(sign*test.x, test.prec)
1039                         want := sign * test.want
1040                         if want == 0 {
1041                                 want = 0
1042                         }
1043                         if (got != want || math.Signbit(got) != math.Signbit(want)) && !(math.IsNaN(got) && math.IsNaN(want)) {
1044                                 t.Errorf("unexpected result for Round(%g, %d): got: %g, want: %g", sign*test.x, test.prec, got, want)
1045                         }
1046                 }
1047         }
1048 }
1049
1050 func TestRoundEven(t *testing.T) {
1051         for _, test := range []struct {
1052                 x    float64
1053                 prec int
1054                 want float64
1055         }{
1056                 {x: 0, prec: 1, want: 0},
1057                 {x: math.Inf(1), prec: 1, want: math.Inf(1)},
1058                 {x: math.NaN(), prec: 1, want: math.NaN()},
1059                 {x: func() float64 { var f float64; return -f }(), prec: 1, want: 0},
1060                 {x: math.MaxFloat64 / 2, prec: 1, want: math.MaxFloat64 / 2},
1061                 {x: 1 << 64, prec: 1, want: 1 << 64},
1062                 {x: 454.4445, prec: 3, want: 454.444},
1063                 {x: 454.44445, prec: 4, want: 454.4444},
1064                 {x: 0.42499, prec: 4, want: 0.425},
1065                 {x: 0.42599, prec: 4, want: 0.426},
1066                 {x: 0.424999999999993, prec: 2, want: 0.42},
1067                 {x: 0.425, prec: 2, want: 0.42},
1068                 {x: 0.425000000000001, prec: 2, want: 0.43},
1069                 {x: 123.4244999999999, prec: 3, want: 123.424},
1070                 {x: 123.4245, prec: 3, want: 123.424},
1071                 {x: 123.4245000000001, prec: 3, want: 123.425},
1072
1073                 {x: 454.45, prec: 0, want: 454},
1074                 {x: 454.45, prec: 1, want: 454.4},
1075                 {x: 454.45, prec: 2, want: 454.45},
1076                 {x: 454.45, prec: 3, want: 454.45},
1077                 {x: 454.445, prec: 0, want: 454},
1078                 {x: 454.445, prec: 1, want: 454.4},
1079                 {x: 454.445, prec: 2, want: 454.44},
1080                 {x: 454.445, prec: 3, want: 454.445},
1081                 {x: 454.445, prec: 4, want: 454.445},
1082                 {x: 454.55, prec: 0, want: 455},
1083                 {x: 454.55, prec: 1, want: 454.6},
1084                 {x: 454.55, prec: 2, want: 454.55},
1085                 {x: 454.55, prec: 3, want: 454.55},
1086                 {x: 454.455, prec: 0, want: 454},
1087                 {x: 454.455, prec: 1, want: 454.5},
1088                 {x: 454.455, prec: 2, want: 454.46},
1089                 {x: 454.455, prec: 3, want: 454.455},
1090                 {x: 454.455, prec: 4, want: 454.455},
1091
1092                 // Negative precision.
1093                 {x: 454.45, prec: -1, want: 450},
1094                 {x: 454.45, prec: -2, want: 500},
1095                 {x: 500, prec: -3, want: 0},
1096                 {x: 500, prec: -4, want: 0},
1097                 {x: 1500, prec: -3, want: 2000},
1098                 {x: 1500, prec: -4, want: 0},
1099         } {
1100                 for _, sign := range []float64{1, -1} {
1101                         got := RoundEven(sign*test.x, test.prec)
1102                         want := sign * test.want
1103                         if want == 0 {
1104                                 want = 0
1105                         }
1106                         if (got != want || math.Signbit(got) != math.Signbit(want)) && !(math.IsNaN(got) && math.IsNaN(want)) {
1107                                 t.Errorf("unexpected result for RoundEven(%g, %d): got: %g, want: %g", sign*test.x, test.prec, got, want)
1108                         }
1109                 }
1110         }
1111 }
1112
1113 func TestSame(t *testing.T) {
1114         s1 := []float64{1, 2, 3, 4}
1115         s2 := []float64{1, 2, 3, 4}
1116         if !Same(s1, s2) {
1117                 t.Errorf("Equal slices returned as unequal")
1118         }
1119         s2 = []float64{1, 2, 3, 4 + 1e-14}
1120         if Same(s1, s2) {
1121                 t.Errorf("Unequal slices returned as equal")
1122         }
1123         if Same(s1, []float64{}) {
1124                 t.Errorf("Unequal slice lengths returned as equal")
1125         }
1126         s1 = []float64{1, 2, math.NaN(), 4}
1127         s2 = []float64{1, 2, math.NaN(), 4}
1128         if !Same(s1, s2) {
1129                 t.Errorf("Slices with matching NaN values returned as unequal")
1130         }
1131         s1 = []float64{1, 2, math.NaN(), 4}
1132         s2 = []float64{1, math.NaN(), 3, 4}
1133         if !Same(s1, s2) {
1134                 t.Errorf("Slices with unmatching NaN values returned as equal")
1135         }
1136 }
1137
1138 func TestScale(t *testing.T) {
1139         s := []float64{3, 4, 1, 7, 5}
1140         c := 5.0
1141         truth := []float64{15, 20, 5, 35, 25}
1142         Scale(c, s)
1143         AreSlicesEqual(t, truth, s, "Bad scaling")
1144 }
1145
1146 func TestSpan(t *testing.T) {
1147         receiver1 := make([]float64, 5)
1148         truth := []float64{1, 2, 3, 4, 5}
1149         receiver2 := Span(receiver1, 1, 5)
1150         AreSlicesEqual(t, truth, receiver1, "Improper linspace from mutator")
1151         AreSlicesEqual(t, truth, receiver2, "Improper linspace from returned slice")
1152         receiver1 = make([]float64, 6)
1153         truth = []float64{0, 0.2, 0.4, 0.6, 0.8, 1.0}
1154         Span(receiver1, 0, 1)
1155         AreSlicesEqual(t, truth, receiver1, "Improper linspace")
1156         if !Panics(func() { Span(nil, 1, 5) }) {
1157                 t.Errorf("Span accepts nil argument")
1158         }
1159         if !Panics(func() { Span(make([]float64, 1), 1, 5) }) {
1160                 t.Errorf("Span accepts argument of len = 1")
1161         }
1162 }
1163
1164 func TestSub(t *testing.T) {
1165         s := []float64{3, 4, 1, 7, 5}
1166         v := []float64{1, 2, 3, 4, 5}
1167         truth := []float64{2, 2, -2, 3, 0}
1168         Sub(s, v)
1169         AreSlicesEqual(t, truth, s, "Bad subtract")
1170         // Test that it panics
1171         if !Panics(func() { Sub(make([]float64, 2), make([]float64, 3)) }) {
1172                 t.Errorf("Did not panic with length mismatch")
1173         }
1174 }
1175
1176 func TestSubTo(t *testing.T) {
1177         s := []float64{3, 4, 1, 7, 5}
1178         v := []float64{1, 2, 3, 4, 5}
1179         truth := []float64{2, 2, -2, 3, 0}
1180         dst1 := make([]float64, len(s))
1181         dst2 := SubTo(dst1, s, v)
1182         AreSlicesEqual(t, truth, dst1, "Bad subtract from mutator")
1183         AreSlicesEqual(t, truth, dst2, "Bad subtract from returned slice")
1184         // Test that all mismatch combinations panic
1185         if !Panics(func() { SubTo(make([]float64, 2), make([]float64, 3), make([]float64, 3)) }) {
1186                 t.Errorf("Did not panic with dst different length")
1187         }
1188         if !Panics(func() { SubTo(make([]float64, 3), make([]float64, 2), make([]float64, 3)) }) {
1189                 t.Errorf("Did not panic with subtractor different length")
1190         }
1191         if !Panics(func() { SubTo(make([]float64, 3), make([]float64, 3), make([]float64, 2)) }) {
1192                 t.Errorf("Did not panic with subtractee different length")
1193         }
1194 }
1195
1196 func TestSum(t *testing.T) {
1197         s := []float64{}
1198         val := Sum(s)
1199         if val != 0 {
1200                 t.Errorf("Val not returned as default when slice length is zero")
1201         }
1202         s = []float64{3, 4, 1, 7, 5}
1203         val = Sum(s)
1204         if val != 20 {
1205                 t.Errorf("Wrong sum returned")
1206         }
1207 }
1208
1209 func TestWithin(t *testing.T) {
1210         for i, test := range []struct {
1211                 s      []float64
1212                 v      float64
1213                 idx    int
1214                 panics bool
1215         }{
1216                 {
1217                         s:   []float64{1, 2, 5, 9},
1218                         v:   1,
1219                         idx: 0,
1220                 },
1221                 {
1222                         s:   []float64{1, 2, 5, 9},
1223                         v:   9,
1224                         idx: -1,
1225                 },
1226                 {
1227                         s:   []float64{1, 2, 5, 9},
1228                         v:   1.5,
1229                         idx: 0,
1230                 },
1231                 {
1232                         s:   []float64{1, 2, 5, 9},
1233                         v:   2,
1234                         idx: 1,
1235                 },
1236                 {
1237                         s:   []float64{1, 2, 5, 9},
1238                         v:   2.5,
1239                         idx: 1,
1240                 },
1241                 {
1242                         s:   []float64{1, 2, 5, 9},
1243                         v:   -3,
1244                         idx: -1,
1245                 },
1246                 {
1247                         s:   []float64{1, 2, 5, 9},
1248                         v:   15,
1249                         idx: -1,
1250                 },
1251                 {
1252                         s:   []float64{1, 2, 5, 9},
1253                         v:   math.NaN(),
1254                         idx: -1,
1255                 },
1256                 {
1257                         s:      []float64{5, 2, 6},
1258                         panics: true,
1259                 },
1260                 {
1261                         panics: true,
1262                 },
1263                 {
1264                         s:      []float64{1},
1265                         panics: true,
1266                 },
1267         } {
1268                 var idx int
1269                 panics := Panics(func() { idx = Within(test.s, test.v) })
1270                 if panics {
1271                         if !test.panics {
1272                                 t.Errorf("Case %v: bad panic", i)
1273                         }
1274                         continue
1275                 }
1276                 if test.panics {
1277                         if !panics {
1278                                 t.Errorf("Case %v: did not panic when it should", i)
1279                         }
1280                         continue
1281                 }
1282                 if idx != test.idx {
1283                         t.Errorf("Case %v: Idx mismatch. Want: %v, got: %v", i, test.idx, idx)
1284                 }
1285         }
1286
1287 }
1288
1289 func randomSlice(l int) []float64 {
1290         s := make([]float64, l)
1291         for i := range s {
1292                 s[i] = rand.Float64()
1293         }
1294         return s
1295 }
1296
1297 func benchmarkMin(b *testing.B, size int) {
1298         s := randomSlice(size)
1299         b.ResetTimer()
1300         for i := 0; i < b.N; i++ {
1301                 Min(s)
1302         }
1303 }
1304 func BenchmarkMinSmall(b *testing.B) { benchmarkMin(b, Small) }
1305 func BenchmarkMinMed(b *testing.B)   { benchmarkMin(b, Medium) }
1306 func BenchmarkMinLarge(b *testing.B) { benchmarkMin(b, Large) }
1307 func BenchmarkMinHuge(b *testing.B)  { benchmarkMin(b, Huge) }
1308
1309 func benchmarkAdd(b *testing.B, size int) {
1310         s1 := randomSlice(size)
1311         s2 := randomSlice(size)
1312         b.ResetTimer()
1313         for i := 0; i < b.N; i++ {
1314                 Add(s1, s2)
1315         }
1316 }
1317 func BenchmarkAddSmall(b *testing.B) { benchmarkAdd(b, Small) }
1318 func BenchmarkAddMed(b *testing.B)   { benchmarkAdd(b, Medium) }
1319 func BenchmarkAddLarge(b *testing.B) { benchmarkAdd(b, Large) }
1320 func BenchmarkAddHuge(b *testing.B)  { benchmarkAdd(b, Huge) }
1321
1322 func benchmarkAddTo(b *testing.B, size int) {
1323         s1 := randomSlice(size)
1324         s2 := randomSlice(size)
1325         dst := randomSlice(size)
1326         b.ResetTimer()
1327         for i := 0; i < b.N; i++ {
1328                 AddTo(dst, s1, s2)
1329         }
1330 }
1331 func BenchmarkAddToSmall(b *testing.B) { benchmarkAddTo(b, Small) }
1332 func BenchmarkAddToMed(b *testing.B)   { benchmarkAddTo(b, Medium) }
1333 func BenchmarkAddToLarge(b *testing.B) { benchmarkAddTo(b, Large) }
1334 func BenchmarkAddToHuge(b *testing.B)  { benchmarkAddTo(b, Huge) }
1335
1336 func benchmarkCumProd(b *testing.B, size int) {
1337         s := randomSlice(size)
1338         dst := randomSlice(size)
1339         b.ResetTimer()
1340         for i := 0; i < b.N; i++ {
1341                 CumProd(dst, s)
1342         }
1343 }
1344 func BenchmarkCumProdSmall(b *testing.B) { benchmarkCumProd(b, Small) }
1345 func BenchmarkCumProdMed(b *testing.B)   { benchmarkCumProd(b, Medium) }
1346 func BenchmarkCumProdLarge(b *testing.B) { benchmarkCumProd(b, Large) }
1347 func BenchmarkCumProdHuge(b *testing.B)  { benchmarkCumProd(b, Huge) }
1348
1349 func benchmarkCumSum(b *testing.B, size int) {
1350         s := randomSlice(size)
1351         dst := randomSlice(size)
1352         b.ResetTimer()
1353         for i := 0; i < b.N; i++ {
1354                 CumSum(dst, s)
1355         }
1356 }
1357 func BenchmarkCumSumSmall(b *testing.B) { benchmarkCumSum(b, Small) }
1358 func BenchmarkCumSumMed(b *testing.B)   { benchmarkCumSum(b, Medium) }
1359 func BenchmarkCumSumLarge(b *testing.B) { benchmarkCumSum(b, Large) }
1360 func BenchmarkCumSumHuge(b *testing.B)  { benchmarkCumSum(b, Huge) }
1361
1362 func benchmarkDiv(b *testing.B, size int) {
1363         s := randomSlice(size)
1364         dst := randomSlice(size)
1365         b.ResetTimer()
1366         for i := 0; i < b.N; i++ {
1367                 Div(dst, s)
1368         }
1369 }
1370 func BenchmarkDivSmall(b *testing.B) { benchmarkDiv(b, Small) }
1371 func BenchmarkDivMed(b *testing.B)   { benchmarkDiv(b, Medium) }
1372 func BenchmarkDivLarge(b *testing.B) { benchmarkDiv(b, Large) }
1373 func BenchmarkDivHuge(b *testing.B)  { benchmarkDiv(b, Huge) }
1374
1375 func benchmarkDivTo(b *testing.B, size int) {
1376         s1 := randomSlice(size)
1377         s2 := randomSlice(size)
1378         dst := randomSlice(size)
1379         b.ResetTimer()
1380         for i := 0; i < b.N; i++ {
1381                 DivTo(dst, s1, s2)
1382         }
1383 }
1384 func BenchmarkDivToSmall(b *testing.B) { benchmarkDivTo(b, Small) }
1385 func BenchmarkDivToMed(b *testing.B)   { benchmarkDivTo(b, Medium) }
1386 func BenchmarkDivToLarge(b *testing.B) { benchmarkDivTo(b, Large) }
1387 func BenchmarkDivToHuge(b *testing.B)  { benchmarkDivTo(b, Huge) }
1388
1389 func benchmarkSub(b *testing.B, size int) {
1390         s1 := randomSlice(size)
1391         s2 := randomSlice(size)
1392         b.ResetTimer()
1393         for i := 0; i < b.N; i++ {
1394                 Sub(s1, s2)
1395         }
1396 }
1397 func BenchmarkSubSmall(b *testing.B) { benchmarkSub(b, Small) }
1398 func BenchmarkSubMed(b *testing.B)   { benchmarkSub(b, Medium) }
1399 func BenchmarkSubLarge(b *testing.B) { benchmarkSub(b, Large) }
1400 func BenchmarkSubHuge(b *testing.B)  { benchmarkSub(b, Huge) }
1401
1402 func benchmarkSubTo(b *testing.B, size int) {
1403         s1 := randomSlice(size)
1404         s2 := randomSlice(size)
1405         dst := randomSlice(size)
1406         b.ResetTimer()
1407         for i := 0; i < b.N; i++ {
1408                 SubTo(dst, s1, s2)
1409         }
1410 }
1411 func BenchmarkSubToSmall(b *testing.B) { benchmarkSubTo(b, Small) }
1412 func BenchmarkSubToMed(b *testing.B)   { benchmarkSubTo(b, Medium) }
1413 func BenchmarkSubToLarge(b *testing.B) { benchmarkSubTo(b, Large) }
1414 func BenchmarkSubToHuge(b *testing.B)  { benchmarkSubTo(b, Huge) }
1415
1416 func benchmarkLogSumExp(b *testing.B, size int) {
1417         s := randomSlice(size)
1418         b.ResetTimer()
1419         for i := 0; i < b.N; i++ {
1420                 LogSumExp(s)
1421         }
1422 }
1423 func BenchmarkLogSumExpSmall(b *testing.B) { benchmarkLogSumExp(b, Small) }
1424 func BenchmarkLogSumExpMed(b *testing.B)   { benchmarkLogSumExp(b, Medium) }
1425 func BenchmarkLogSumExpLarge(b *testing.B) { benchmarkLogSumExp(b, Large) }
1426 func BenchmarkLogSumExpHuge(b *testing.B)  { benchmarkLogSumExp(b, Huge) }
1427
1428 func benchmarkDot(b *testing.B, size int) {
1429         s1 := randomSlice(size)
1430         s2 := randomSlice(size)
1431         b.ResetTimer()
1432         for i := 0; i < b.N; i++ {
1433                 Dot(s1, s2)
1434         }
1435 }
1436 func BenchmarkDotSmall(b *testing.B) { benchmarkDot(b, Small) }
1437 func BenchmarkDotMed(b *testing.B)   { benchmarkDot(b, Medium) }
1438 func BenchmarkDotLarge(b *testing.B) { benchmarkDot(b, Large) }
1439 func BenchmarkDotHuge(b *testing.B)  { benchmarkDot(b, Huge) }
1440
1441 func benchmarkAddScaledTo(b *testing.B, size int) {
1442         dst := randomSlice(size)
1443         y := randomSlice(size)
1444         s := randomSlice(size)
1445         b.ResetTimer()
1446         for i := 0; i < b.N; i++ {
1447                 AddScaledTo(dst, y, 2.3, s)
1448         }
1449 }
1450 func BenchmarkAddScaledToSmall(b *testing.B)  { benchmarkAddScaledTo(b, Small) }
1451 func BenchmarkAddScaledToMedium(b *testing.B) { benchmarkAddScaledTo(b, Medium) }
1452 func BenchmarkAddScaledToLarge(b *testing.B)  { benchmarkAddScaledTo(b, Large) }
1453 func BenchmarkAddScaledToHuge(b *testing.B)   { benchmarkAddScaledTo(b, Huge) }
1454
1455 func benchmarkScale(b *testing.B, size int) {
1456         dst := randomSlice(size)
1457         b.ResetTimer()
1458         for i := 0; i < b.N; i += 2 {
1459                 Scale(2.0, dst)
1460                 Scale(0.5, dst)
1461         }
1462 }
1463 func BenchmarkScaleSmall(b *testing.B)  { benchmarkScale(b, Small) }
1464 func BenchmarkScaleMedium(b *testing.B) { benchmarkScale(b, Medium) }
1465 func BenchmarkScaleLarge(b *testing.B)  { benchmarkScale(b, Large) }
1466 func BenchmarkScaleHuge(b *testing.B)   { benchmarkScale(b, Huge) }