github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/cmplxs/cmplxs_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 cmplxs 6 7 import ( 8 "fmt" 9 "math" 10 "math/cmplx" 11 "strconv" 12 "testing" 13 14 "golang.org/x/exp/rand" 15 16 "github.com/jingcheng-WU/gonum/cmplxs/cscalar" 17 "github.com/jingcheng-WU/gonum/floats" 18 ) 19 20 const ( 21 EqTolerance = 1e-14 22 Small = 10 23 Medium = 1000 24 Large = 100000 25 Huge = 10000000 26 ) 27 28 func areSlicesEqual(t *testing.T, truth, comp []complex128, str string) { 29 if !EqualApprox(comp, truth, EqTolerance) { 30 t.Errorf(str+". Expected %v, returned %v", truth, comp) 31 } 32 } 33 34 func areSlicesSame(t *testing.T, truth, comp []complex128, str string) { 35 ok := len(truth) == len(comp) 36 if ok { 37 for i, a := range truth { 38 if !cscalar.EqualWithinAbsOrRel(a, comp[i], EqTolerance, EqTolerance) && !cscalar.Same(a, comp[i]) { 39 ok = false 40 break 41 } 42 } 43 } 44 if !ok { 45 t.Errorf(str+". Expected %v, returned %v", truth, comp) 46 } 47 } 48 49 func Panics(fun func()) (b bool) { 50 defer func() { 51 err := recover() 52 if err != nil { 53 b = true 54 } 55 }() 56 fun() 57 return 58 } 59 60 func TestAdd(t *testing.T) { 61 a := []complex128{1 + 1i, 2 + 2i, 3 + 3i} 62 b := []complex128{4 + 4i, 5 + 5i, 6 + 6i} 63 c := []complex128{7 + 7i, 8 + 8i, 9 + 9i} 64 truth := []complex128{12 + 12i, 15 + 15i, 18 + 18i} 65 n := make([]complex128, 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([]complex128, 2), make([]complex128, 3)) }) { 77 t.Errorf("Did not panic with length mismatch") 78 } 79 } 80 81 func TestAddTo(t *testing.T) { 82 a := []complex128{1 + 1i, 2 + 2i, 3 + 3i} 83 b := []complex128{4 + 4i, 5 + 5i, 6 + 6i} 84 truth := []complex128{5 + 5i, 7 + 7i, 9 + 9i} 85 n1 := make([]complex128, len(a)) 86 87 n2 := AddTo(n1, a, b) 88 areSlicesEqual(t, truth, n1, "Bad addition from mutator") 89 areSlicesEqual(t, truth, n2, "Bad addition from returned slice") 90 91 // Test that it panics 92 if !Panics(func() { AddTo(make([]complex128, 2), make([]complex128, 3), make([]complex128, 3)) }) { 93 t.Errorf("Did not panic with length mismatch") 94 } 95 if !Panics(func() { AddTo(make([]complex128, 3), make([]complex128, 3), make([]complex128, 2)) }) { 96 t.Errorf("Did not panic with length mismatch") 97 } 98 } 99 100 func TestAddConst(t *testing.T) { 101 s := []complex128{3 + 1i, 4 + 2i, 1 + 3i, 7 + 4i, 5 + 5i} 102 c := 6 + 1i 103 truth := []complex128{9 + 2i, 10 + 3i, 7 + 4i, 13 + 5i, 11 + 6i} 104 AddConst(c, s) 105 areSlicesEqual(t, truth, s, "Wrong addition of constant") 106 } 107 108 func TestAddScaled(t *testing.T) { 109 s := []complex128{3, 4, 1, 7, 5} 110 alpha := 6 + 1i 111 dst := []complex128{1, 2, 3, 4, 5} 112 ans := []complex128{19 + 3i, 26 + 4i, 9 + 1i, 46 + 7i, 35 + 5i} 113 AddScaled(dst, alpha, s) 114 if !EqualApprox(dst, ans, EqTolerance) { 115 t.Errorf("Adding scaled did not match. Expected %v, returned %v", ans, dst) 116 } 117 short := []complex128{1} 118 if !Panics(func() { AddScaled(dst, alpha, short) }) { 119 t.Errorf("Doesn't panic if s is smaller than dst") 120 } 121 if !Panics(func() { AddScaled(short, alpha, s) }) { 122 t.Errorf("Doesn't panic if dst is smaller than s") 123 } 124 } 125 126 func TestAddScaledTo(t *testing.T) { 127 s := []complex128{3, 4, 1, 7, 5} 128 alpha := 6 + 1i 129 y := []complex128{1, 2, 3, 4, 5} 130 dst1 := make([]complex128, 5) 131 ans := []complex128{19 + 3i, 26 + 4i, 9 + 1i, 46 + 7i, 35 + 5i} 132 dst2 := AddScaledTo(dst1, y, alpha, s) 133 if !EqualApprox(dst1, ans, EqTolerance) { 134 t.Errorf("AddScaledTo did not match for mutator") 135 } 136 if !EqualApprox(dst2, ans, EqTolerance) { 137 t.Errorf("AddScaledTo did not match for returned slice") 138 } 139 AddScaledTo(dst1, y, alpha, s) 140 if !EqualApprox(dst1, ans, EqTolerance) { 141 t.Errorf("Reusing dst did not match") 142 } 143 short := []complex128{1} 144 if !Panics(func() { AddScaledTo(dst1, y, alpha, short) }) { 145 t.Errorf("Doesn't panic if s is smaller than dst") 146 } 147 if !Panics(func() { AddScaledTo(short, y, alpha, s) }) { 148 t.Errorf("Doesn't panic if dst is smaller than s") 149 } 150 if !Panics(func() { AddScaledTo(dst1, short, alpha, s) }) { 151 t.Errorf("Doesn't panic if y is smaller than dst") 152 } 153 } 154 155 func TestCount(t *testing.T) { 156 s := []complex128{3, 4, 1, 7, 5} 157 f := func(v complex128) bool { return cmplx.Abs(v) > 3.5 } 158 truth := 3 159 n := Count(f, s) 160 if n != truth { 161 t.Errorf("Wrong number of elements counted") 162 } 163 } 164 165 func TestCumProd(t *testing.T) { 166 s := []complex128{3 + 1i, 4 + 2i, 1 + 3i, 7 + 4i, 5 + 5i} 167 receiver := make([]complex128, len(s)) 168 result := CumProd(receiver, s) 169 truth := []complex128{3 + 1i, 10 + 10i, -20 + 40i, -300 + 200i, -2500 - 500i} 170 areSlicesEqual(t, truth, receiver, "Wrong cumprod mutated with new receiver") 171 areSlicesEqual(t, truth, result, "Wrong cumprod result with new receiver") 172 CumProd(receiver, s) 173 areSlicesEqual(t, truth, receiver, "Wrong cumprod returned with reused receiver") 174 175 // Test that it panics 176 if !Panics(func() { CumProd(make([]complex128, 2), make([]complex128, 3)) }) { 177 t.Errorf("Did not panic with length mismatch") 178 } 179 180 // Test empty CumProd 181 emptyReceiver := make([]complex128, 0) 182 truth = []complex128{} 183 CumProd(emptyReceiver, emptyReceiver) 184 areSlicesEqual(t, truth, emptyReceiver, "Wrong cumprod returned with empty receiver") 185 } 186 187 func TestComplex(t *testing.T) { 188 for i, test := range []struct { 189 dst []complex128 190 real, imag []float64 191 want []complex128 192 panics bool 193 }{ 194 {}, 195 { 196 dst: make([]complex128, 4), 197 real: []float64{1, 2, 3, 4}, 198 imag: []float64{1, 2, 3, 4}, 199 want: []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i}, 200 }, 201 { 202 dst: make([]complex128, 3), 203 real: []float64{1, 2, 3, 4}, 204 imag: []float64{1, 2, 3, 4}, 205 panics: true, 206 }, 207 { 208 dst: make([]complex128, 4), 209 real: []float64{1, 2, 3}, 210 imag: []float64{1, 2, 3, 4}, 211 panics: true, 212 }, 213 { 214 dst: make([]complex128, 4), 215 real: []float64{1, 2, 3, 4}, 216 imag: []float64{1, 2, 3}, 217 panics: true, 218 }, 219 { 220 dst: make([]complex128, 4), 221 real: []float64{1, 2, 3, 4}, 222 imag: []float64{1, 2, 3, math.NaN()}, 223 want: []complex128{1 + 1i, 2 + 2i, 3 + 3i, cmplx.NaN()}, 224 }, 225 } { 226 var got []complex128 227 panicked := Panics(func() { 228 got = Complex(test.dst, test.real, test.imag) 229 }) 230 if panicked != test.panics { 231 if panicked { 232 t.Errorf("unexpected panic for test %d", i) 233 } else { 234 t.Errorf("expected panic for test %d", i) 235 } 236 } 237 if panicked || test.panics { 238 continue 239 } 240 if !Same(got, test.dst) { 241 t.Errorf("mismatch between dst and return test %d: got:%v want:%v", i, got, test.dst) 242 } 243 if !Same(got, test.want) { 244 t.Errorf("unexpected result for test %d: got:%v want:%v", i, got, test.want) 245 } 246 } 247 248 } 249 250 func TestCumSum(t *testing.T) { 251 s := []complex128{3 + 1i, 4 + 2i, 1 + 3i, 7 + 4i, 5 + 5i} 252 receiver := make([]complex128, len(s)) 253 result := CumSum(receiver, s) 254 truth := []complex128{3 + 1i, 7 + 3i, 8 + 6i, 15 + 10i, 20 + 15i} 255 areSlicesEqual(t, truth, receiver, "Wrong cumsum mutated with new receiver") 256 areSlicesEqual(t, truth, result, "Wrong cumsum returned with new receiver") 257 CumSum(receiver, s) 258 areSlicesEqual(t, truth, receiver, "Wrong cumsum returned with reused receiver") 259 260 // Test that it panics 261 if !Panics(func() { CumSum(make([]complex128, 2), make([]complex128, 3)) }) { 262 t.Errorf("Did not panic with length mismatch") 263 } 264 265 // Test empty CumSum 266 emptyReceiver := make([]complex128, 0) 267 truth = []complex128{} 268 CumSum(emptyReceiver, emptyReceiver) 269 areSlicesEqual(t, truth, emptyReceiver, "Wrong cumsum returned with empty receiver") 270 } 271 272 func TestDistance(t *testing.T) { 273 norms := []float64{1, 2, 4, math.Inf(1)} 274 slices := []struct { 275 s []complex128 276 t []complex128 277 }{ 278 { 279 nil, 280 nil, 281 }, 282 { 283 []complex128{8 + 1i, 9 + 2i, 10 + 3i, -12 + 4i}, 284 []complex128{8 + 1i, 9 + 2i, 10 + 3i, -12 + 4i}, 285 }, 286 { 287 []complex128{1 + 1i, 2 + 2i, 3 + 3i, -4 + 4i, -5 + 5i, 8 + 6i}, 288 []complex128{-9.2 - 1i, -6.8 - 2i, 9 - 3i, -3 - 4i, -2 - 5i, 1 - 6i}, 289 }, 290 } 291 292 for j, test := range slices { 293 tmp := make([]complex128, len(test.s)) 294 for i, L := range norms { 295 dist := Distance(test.s, test.t, L) 296 copy(tmp, test.s) 297 Sub(tmp, test.t) 298 norm := Norm(tmp, L) 299 if dist != norm { // Use equality because they should be identical. 300 t.Errorf("Distance does not match norm for case %v, %v. Expected %v, Found %v.", i, j, norm, dist) 301 } 302 } 303 } 304 305 if !Panics(func() { Distance([]complex128{}, []complex128{1}, 1) }) { 306 t.Errorf("Did not panic with unequal lengths") 307 } 308 } 309 310 func TestDiv(t *testing.T) { 311 s1 := []complex128{5 - 5i, 12 + 2i, 27 - 3i} 312 s2 := []complex128{1 - 1i, 2 + 2i, 3 - 1i} 313 ans := []complex128{5 + 0i, 3.5 - 2.5i, 8.4 + 1.8i} 314 Div(s1, s2) 315 if !EqualApprox(s1, ans, EqTolerance) { 316 t.Errorf("Div doesn't give correct answer. Expected %v, Found %v.", ans, s1) 317 } 318 s1short := []complex128{1} 319 if !Panics(func() { Div(s1short, s2) }) { 320 t.Errorf("Did not panic with unequal lengths") 321 } 322 s2short := []complex128{1} 323 if !Panics(func() { Div(s1, s2short) }) { 324 t.Errorf("Did not panic with unequal lengths") 325 } 326 } 327 328 func TestDivTo(t *testing.T) { 329 s1 := []complex128{5 - 5i, 12 + 2i, 27 - 3i} 330 s1orig := []complex128{5 - 5i, 12 + 2i, 27 - 3i} 331 s2 := []complex128{1 - 1i, 2 + 2i, 3 - 1i} 332 s2orig := []complex128{1 - 1i, 2 + 2i, 3 - 1i} 333 dst1 := make([]complex128, 3) 334 ans := []complex128{5 + 0i, 3.5 - 2.5i, 8.4 + 1.8i} 335 dst2 := DivTo(dst1, s1, s2) 336 if !EqualApprox(dst1, ans, EqTolerance) { 337 t.Errorf("DivTo doesn't give correct answer in mutated slice") 338 } 339 if !EqualApprox(dst2, ans, EqTolerance) { 340 t.Errorf("DivTo doesn't give correct answer in returned slice") 341 } 342 if !EqualApprox(s1, s1orig, EqTolerance) { 343 t.Errorf("S1 changes during multo") 344 } 345 if !EqualApprox(s2, s2orig, EqTolerance) { 346 t.Errorf("s2 changes during multo") 347 } 348 DivTo(dst1, s1, s2) 349 if !EqualApprox(dst1, ans, EqTolerance) { 350 t.Errorf("DivTo doesn't give correct answer reusing dst") 351 } 352 dstShort := []complex128{1} 353 if !Panics(func() { DivTo(dstShort, s1, s2) }) { 354 t.Errorf("Did not panic with s1 wrong length") 355 } 356 s1short := []complex128{1} 357 if !Panics(func() { DivTo(dst1, s1short, s2) }) { 358 t.Errorf("Did not panic with s1 wrong length") 359 } 360 s2short := []complex128{1} 361 if !Panics(func() { DivTo(dst1, s1, s2short) }) { 362 t.Errorf("Did not panic with s2 wrong length") 363 } 364 } 365 366 func TestDot(t *testing.T) { 367 s1 := []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i} 368 s2 := []complex128{-3 + 4i, 4 + 3i, 5 + 2i, -6 + 1i} 369 truth := 16 + 24i 370 ans := Dot(s1, s2) 371 if ans != truth { 372 t.Errorf("Dot product computed incorrectly. Expected %v, Found %v.", truth, ans) 373 } 374 375 // Test that it panics 376 if !Panics(func() { Dot(make([]complex128, 2), make([]complex128, 3)) }) { 377 t.Errorf("Did not panic with length mismatch") 378 } 379 } 380 381 func TestEquals(t *testing.T) { 382 s1 := []complex128{1 + 1i, 2 + 4i, 3 + 8i, 4 + 16i} 383 s2 := []complex128{1 + 1i, 2 + 4i, 3 + 8i, 4 + 16i} 384 if !Equal(s1, s2) { 385 t.Errorf("Equal slices returned as unequal") 386 } 387 s2 = []complex128{1 + 1i, 2 + 4i, 3 + 8i, 4 + 16i + 1e-14} 388 if Equal(s1, s2) { 389 t.Errorf("Unequal slices returned as equal") 390 } 391 if Equal(s1, []complex128{}) { 392 t.Errorf("Unequal slice lengths returned as equal") 393 } 394 } 395 396 func TestEqualApprox(t *testing.T) { 397 s1 := []complex128{1 + 1i, 2 + 4i, 3 + 8i, 4 + 16i} 398 s2 := []complex128{1 + 1i, 2 + 4i, 3 + 8i, 4 + 16i + 1e-10} 399 if EqualApprox(s1, s2, 1e-13) { 400 t.Errorf("Unequal slices returned as equal for absolute") 401 } 402 if !EqualApprox(s1, s2, 1e-5) { 403 t.Errorf("Equal slices returned as unequal for absolute") 404 } 405 s1 = []complex128{1 + 1i, 2 + 4i, 3 + 8i, 1000 + 1000i} 406 s2 = []complex128{1 + 1i, 2 + 4i, 3 + 8i, (1000 + 1000i) * (1 + 1e-7)} 407 if EqualApprox(s1, s2, 1e-8) { 408 t.Errorf("Unequal slices returned as equal for relative") 409 } 410 if !EqualApprox(s1, s2, 1e-5) { 411 t.Errorf("Equal slices returned as unequal for relative") 412 } 413 if EqualApprox(s1, []complex128{}, 1e-5) { 414 t.Errorf("Unequal slice lengths returned as equal") 415 } 416 } 417 418 func TestEqualFunc(t *testing.T) { 419 s1 := []complex128{1 + 1i, 2 + 4i, 3 + 8i, 4 + 16i} 420 s2 := []complex128{1 + 1i, 2 + 4i, 3 + 8i, 4 + 16i} 421 eq := func(x, y complex128) bool { return x == y } 422 if !EqualFunc(s1, s2, eq) { 423 t.Errorf("Equal slices returned as unequal") 424 } 425 s2 = []complex128{1 + 1i, 2 + 4i, 3 + 8i, 4 + 16i + 1e-14} 426 if EqualFunc(s1, s2, eq) { 427 t.Errorf("Unequal slices returned as equal") 428 } 429 if EqualFunc(s1, []complex128{}, eq) { 430 t.Errorf("Unequal slice lengths returned as equal") 431 } 432 } 433 434 func TestEqualLengths(t *testing.T) { 435 s1 := []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i} 436 s2 := []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i} 437 s3 := []complex128{1 + 1i, 2 + 2i, 3 + 3i} 438 if !EqualLengths(s1, s2) { 439 t.Errorf("Equal lengths returned as unequal") 440 } 441 if EqualLengths(s1, s3) { 442 t.Errorf("Unequal lengths returned as equal") 443 } 444 if !EqualLengths(s1) { 445 t.Errorf("Single slice returned as unequal") 446 } 447 if !EqualLengths() { 448 t.Errorf("No slices returned as unequal") 449 } 450 } 451 452 func eqIntSlice(one, two []int) string { 453 if len(one) != len(two) { 454 return "Length mismatch" 455 } 456 for i, val := range one { 457 if val != two[i] { 458 return "Index " + strconv.Itoa(i) + " mismatch" 459 } 460 } 461 return "" 462 } 463 464 func TestFind(t *testing.T) { 465 s := []complex128{3 + 1i, 4 - 1i, 1 + 2i, 7 + 10i, 5 - 100i} 466 f := func(v complex128) bool { return cmplx.Abs(v) > 3.5 } 467 allTrueInds := []int{1, 3, 4} 468 469 // Test finding first two elements 470 inds, err := Find(nil, f, s, 2) 471 if err != nil { 472 t.Errorf("Find first two: Improper error return") 473 } 474 trueInds := allTrueInds[:2] 475 str := eqIntSlice(inds, trueInds) 476 if str != "" { 477 t.Errorf("Find first two: " + str) 478 } 479 480 // Test finding no elements with non nil slice 481 inds = []int{1, 2, 3, 4, 5, 6} 482 inds, err = Find(inds, f, s, 0) 483 if err != nil { 484 t.Errorf("Find no elements: Improper error return") 485 } 486 str = eqIntSlice(inds, []int{}) 487 if str != "" { 488 t.Errorf("Find no non-nil: " + str) 489 } 490 491 // Test finding first two elements with non nil slice 492 inds = []int{1, 2, 3, 4, 5, 6} 493 inds, err = Find(inds, f, s, 2) 494 if err != nil { 495 t.Errorf("Find first two non-nil: Improper error return") 496 } 497 str = eqIntSlice(inds, trueInds) 498 if str != "" { 499 t.Errorf("Find first two non-nil: " + str) 500 } 501 502 // Test finding too many elements 503 inds, err = Find(inds, f, s, 4) 504 if err == nil { 505 t.Errorf("Request too many: No error returned") 506 } 507 str = eqIntSlice(inds, allTrueInds) 508 if str != "" { 509 t.Errorf("Request too many: Does not match all of the inds: " + str) 510 } 511 512 // Test finding all elements 513 inds, err = Find(nil, f, s, -1) 514 if err != nil { 515 t.Errorf("Find all: Improper error returned") 516 } 517 str = eqIntSlice(inds, allTrueInds) 518 if str != "" { 519 t.Errorf("Find all: Does not match all of the inds: " + str) 520 } 521 } 522 523 func TestHasNaN(t *testing.T) { 524 for i, test := range []struct { 525 s []complex128 526 ans bool 527 }{ 528 {}, 529 { 530 s: []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i}, 531 }, 532 { 533 s: []complex128{1 + 1i, cmplx.NaN(), 3 + 3i, 4 + 4i}, 534 ans: true, 535 }, 536 { 537 s: []complex128{1 + 1i, 2 + 2i, 3 + 3i, cmplx.NaN()}, 538 ans: true, 539 }, 540 } { 541 b := HasNaN(test.s) 542 if b != test.ans { 543 t.Errorf("HasNaN mismatch case %d. Expected %v, Found %v", i, test.ans, b) 544 } 545 } 546 } 547 548 func TestImag(t *testing.T) { 549 for i, test := range []struct { 550 dst []float64 551 src []complex128 552 want []float64 553 panics bool 554 }{ 555 {}, 556 { 557 dst: make([]float64, 4), 558 src: []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i}, 559 want: []float64{1, 2, 3, 4}, 560 }, 561 { 562 dst: make([]float64, 3), 563 src: []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i}, 564 panics: true, 565 }, 566 { 567 dst: make([]float64, 4), 568 src: []complex128{1 + 1i, 2 + 2i, 3 + 3i, cmplx.NaN()}, 569 want: []float64{1, 2, 3, math.NaN()}, 570 }, 571 } { 572 var got []float64 573 panicked := Panics(func() { 574 got = Imag(test.dst, test.src) 575 }) 576 if panicked != test.panics { 577 if panicked { 578 t.Errorf("unexpected panic for test %d", i) 579 } else { 580 t.Errorf("expected panic for test %d", i) 581 } 582 } 583 if panicked || test.panics { 584 continue 585 } 586 if !floats.Same(got, test.dst) { 587 t.Errorf("mismatch between dst and return test %d: got:%v want:%v", i, got, test.dst) 588 } 589 if !floats.Same(got, test.want) { 590 t.Errorf("unexpected result for test %d: got:%v want:%v", i, got, test.want) 591 } 592 } 593 594 } 595 596 func TestLogSpan(t *testing.T) { 597 // FIXME(kortschak) 598 receiver1 := make([]complex128, 6) 599 truth := []complex128{0.001, 0.01, 0.1, 1, 10, 100} 600 receiver2 := LogSpan(receiver1, 0.001, 100) 601 tst := make([]complex128, 6) 602 for i := range truth { 603 tst[i] = receiver1[i] / truth[i] 604 } 605 comp := make([]complex128, 6) 606 for i := range comp { 607 comp[i] = 1 608 } 609 areSlicesEqual(t, comp, tst, "Improper logspace from mutator") 610 611 for i := range truth { 612 tst[i] = receiver2[i] / truth[i] 613 } 614 areSlicesEqual(t, comp, tst, "Improper logspace from returned slice") 615 616 if !Panics(func() { LogSpan(nil, 1, 5) }) { 617 t.Errorf("Span accepts nil argument") 618 } 619 if !Panics(func() { LogSpan(make([]complex128, 1), 1, 5) }) { 620 t.Errorf("Span accepts argument of len = 1") 621 } 622 } 623 624 func TestMaxAbsAndIdx(t *testing.T) { 625 for _, test := range []struct { 626 in []complex128 627 wantIdx int 628 wantVal complex128 629 desc string 630 }{ 631 { 632 in: []complex128{3 + 1i, 4 + 1i, 1 + 1i, 7 + 1i, 5 + 1i}, 633 wantIdx: 3, 634 wantVal: 7 + 1i, 635 desc: "with only finite entries", 636 }, 637 { 638 in: []complex128{cmplx.NaN(), 4 + 1i, 1 + 1i, 7 + 1i, 5 + 1i}, 639 wantIdx: 3, 640 wantVal: 7 + 1i, 641 desc: "with leading NaN", 642 }, 643 { 644 in: []complex128{cmplx.NaN(), cmplx.NaN(), cmplx.NaN()}, 645 wantIdx: 0, 646 wantVal: cmplx.NaN(), 647 desc: "when only NaN elements exist", 648 }, 649 { 650 in: []complex128{cmplx.NaN(), cmplx.Inf()}, 651 wantIdx: 1, 652 wantVal: cmplx.Inf(), 653 desc: "leading NaN followed by Inf", 654 }, 655 } { 656 ind := MaxAbsIdx(test.in) 657 if ind != test.wantIdx { 658 t.Errorf("Wrong index "+test.desc+": got:%d want:%d", ind, test.wantIdx) 659 } 660 val := MaxAbs(test.in) 661 if !cscalar.Same(val, test.wantVal) { 662 t.Errorf("Wrong value "+test.desc+": got:%f want:%f", val, test.wantVal) 663 } 664 } 665 } 666 667 func TestMinAbsAndIdx(t *testing.T) { 668 for _, test := range []struct { 669 in []complex128 670 wantIdx int 671 wantVal complex128 672 desc string 673 }{ 674 { 675 in: []complex128{3 + 1i, 4 + 1i, 1 + 1i, 7 + 1i, 5 + 1i}, 676 wantIdx: 2, 677 wantVal: 1 + 1i, 678 desc: "with only finite entries", 679 }, 680 { 681 in: []complex128{cmplx.NaN(), 4 + 1i, 1 + 1i, 7 + 1i, 5 + 1i}, 682 wantIdx: 2, 683 wantVal: 1 + 1i, 684 desc: "with leading NaN", 685 }, 686 { 687 in: []complex128{cmplx.NaN(), cmplx.NaN(), cmplx.NaN()}, 688 wantIdx: 0, 689 wantVal: cmplx.NaN(), 690 desc: "when only NaN elements exist", 691 }, 692 { 693 in: []complex128{cmplx.NaN(), cmplx.Inf()}, 694 wantIdx: 1, 695 wantVal: cmplx.Inf(), 696 desc: "leading NaN followed by Inf", 697 }, 698 } { 699 ind := MinAbsIdx(test.in) 700 if ind != test.wantIdx { 701 t.Errorf("Wrong index "+test.desc+": got:%d want:%d", ind, test.wantIdx) 702 } 703 val := MinAbs(test.in) 704 if !cscalar.Same(val, test.wantVal) { 705 t.Errorf("Wrong value "+test.desc+": got:%f want:%f", val, test.wantVal) 706 } 707 } 708 } 709 710 func TestMul(t *testing.T) { 711 s1 := []complex128{1 + 1i, 2 + 2i, 3 + 3i} 712 s2 := []complex128{1 + 1i, 2 + 2i, 3 + 3i} 713 ans := []complex128{0 + 2i, 0 + 8i, 0 + 18i} 714 Mul(s1, s2) 715 if !EqualApprox(s1, ans, EqTolerance) { 716 t.Errorf("Mul doesn't give correct answer. Expected %v, Found %v", ans, s1) 717 } 718 s1short := []complex128{1} 719 if !Panics(func() { Mul(s1short, s2) }) { 720 t.Errorf("Did not panic with unequal lengths") 721 } 722 s2short := []complex128{1} 723 if !Panics(func() { Mul(s1, s2short) }) { 724 t.Errorf("Did not panic with unequal lengths") 725 } 726 } 727 728 func TestMulTo(t *testing.T) { 729 s1 := []complex128{1 + 1i, 2 + 2i, 3 + 3i} 730 s1orig := []complex128{1 + 1i, 2 + 2i, 3 + 3i} 731 s2 := []complex128{1 + 1i, 2 + 2i, 3 + 3i} 732 s2orig := []complex128{1 + 1i, 2 + 2i, 3 + 3i} 733 dst1 := make([]complex128, 3) 734 ans := []complex128{0 + 2i, 0 + 8i, 0 + 18i} 735 dst2 := MulTo(dst1, s1, s2) 736 if !EqualApprox(dst1, ans, EqTolerance) { 737 t.Errorf("MulTo doesn't give correct answer in mutated slice") 738 } 739 if !EqualApprox(dst2, ans, EqTolerance) { 740 t.Errorf("MulTo doesn't give correct answer in returned slice") 741 } 742 if !EqualApprox(s1, s1orig, EqTolerance) { 743 t.Errorf("S1 changes during multo") 744 } 745 if !EqualApprox(s2, s2orig, EqTolerance) { 746 t.Errorf("s2 changes during multo") 747 } 748 MulTo(dst1, s1, s2) 749 if !EqualApprox(dst1, ans, EqTolerance) { 750 t.Errorf("MulTo doesn't give correct answer reusing dst") 751 } 752 dstShort := []complex128{1} 753 if !Panics(func() { MulTo(dstShort, s1, s2) }) { 754 t.Errorf("Did not panic with s1 wrong length") 755 } 756 s1short := []complex128{1} 757 if !Panics(func() { MulTo(dst1, s1short, s2) }) { 758 t.Errorf("Did not panic with s1 wrong length") 759 } 760 s2short := []complex128{1} 761 if !Panics(func() { MulTo(dst1, s1, s2short) }) { 762 t.Errorf("Did not panic with s2 wrong length") 763 } 764 } 765 766 // Complexify 767 768 func TestNearestIdx(t *testing.T) { 769 for _, test := range []struct { 770 in []complex128 771 query complex128 772 want int 773 desc string 774 }{ 775 { 776 in: []complex128{6.2, 3, 5, 6.2, 8}, 777 query: 2, 778 want: 1, 779 desc: "Wrong index returned when value is less than all of elements", 780 }, 781 { 782 in: []complex128{6.2, 3, 5, 6.2, 8}, 783 query: 9, 784 want: 4, 785 desc: "Wrong index returned when value is greater than all of elements", 786 }, 787 { 788 in: []complex128{6.2, 3, 5, 6.2, 8}, 789 query: 3.1, 790 want: 1, 791 desc: "Wrong index returned when value is greater than closest element", 792 }, 793 { 794 in: []complex128{6.2, 3, 5, 6.2, 8}, 795 query: 2.9, 796 want: 1, 797 desc: "Wrong index returned when value is less than closest element", 798 }, 799 { 800 in: []complex128{6.2, 3, 5, 6.2, 8}, 801 query: 3, 802 want: 1, 803 desc: "Wrong index returned when value is equal to element", 804 }, 805 { 806 in: []complex128{6.2, 3, 5, 6.2, 8}, 807 query: 6.2, 808 want: 0, 809 desc: "Wrong index returned when value is equal to several elements", 810 }, 811 { 812 in: []complex128{6.2, 3, 5, 6.2, 8}, 813 query: 4, 814 want: 1, 815 desc: "Wrong index returned when value is exactly between two closest elements", 816 }, 817 { 818 in: []complex128{cmplx.NaN(), 3, 2, -1}, 819 query: 2, 820 want: 2, 821 desc: "Wrong index returned when initial element is NaN", 822 }, 823 { 824 in: []complex128{0, cmplx.NaN(), -1, 2}, 825 query: cmplx.NaN(), 826 want: 0, 827 desc: "Wrong index returned when query is NaN and a NaN element exists", 828 }, 829 { 830 in: []complex128{0, cmplx.NaN(), -1, 2}, 831 query: cmplx.Inf(), 832 want: 3, 833 desc: "Wrong index returned when query is Inf and no Inf element exists", 834 }, 835 { 836 in: []complex128{cmplx.NaN(), cmplx.NaN(), cmplx.NaN()}, 837 query: 1, 838 want: 0, 839 desc: "Wrong index returned when query is a number and only NaN elements exist", 840 }, 841 { 842 in: []complex128{cmplx.NaN(), cmplx.Inf()}, 843 query: 1, 844 want: 1, 845 desc: "Wrong index returned when query is a number and single NaN precedes Inf", 846 }, 847 } { 848 ind := NearestIdx(test.in, test.query) 849 if ind != test.want { 850 t.Errorf(test.desc+": got:%d want:%d", ind, test.want) 851 } 852 } 853 } 854 855 func TestNorm(t *testing.T) { 856 s := []complex128{-1, -3.4, 5, -6} 857 val := Norm(s, math.Inf(1)) 858 truth := 6.0 859 if math.Abs(val-truth) > EqTolerance { 860 t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val) 861 } 862 // 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 863 val = Norm(s, 2) 864 truth = 8.5767126569566267590651614132751986658027271236078592 865 if math.Abs(val-truth) > EqTolerance { 866 t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val) 867 } 868 // 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 869 val = Norm(s, 3) 870 truth = 7.2514321388020228478109121239004816430071237369356233 871 if math.Abs(val-truth) > EqTolerance { 872 t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val) 873 } 874 875 //http://www.wolframalpha.com/input/?i=%7C-1%7C+%2B+%7C-3.4%7C+%2B+%7C5%7C%2B++%7C6%7C 876 val = Norm(s, 1) 877 truth = 15.4 878 if math.Abs(val-truth) > EqTolerance { 879 t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val) 880 } 881 } 882 883 func TestProd(t *testing.T) { 884 s := []complex128{} 885 val := Prod(s) 886 if val != 1 { 887 t.Errorf("Val not returned as default when slice length is zero") 888 } 889 s = []complex128{3, 4, 1, 7, 5} 890 val = Prod(s) 891 if val != 420 { 892 t.Errorf("Wrong prod returned. Expected %v returned %v", 420, val) 893 } 894 } 895 896 func TestReverse(t *testing.T) { 897 for _, s := range [][]complex128{ 898 {0}, 899 {1, 0}, 900 {2, 1, 0}, 901 {3, 2, 1, 0}, 902 {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, 903 } { 904 Reverse(s) 905 for i, v := range s { 906 if v != complex(float64(i), 0) { 907 t.Errorf("unexpected values for element %d: got:%v want:%v", i, v, i) 908 } 909 } 910 } 911 } 912 913 func TestReal(t *testing.T) { 914 for i, test := range []struct { 915 dst []float64 916 src []complex128 917 want []float64 918 panics bool 919 }{ 920 {}, 921 { 922 dst: make([]float64, 4), 923 src: []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i}, 924 want: []float64{1, 2, 3, 4}, 925 }, 926 { 927 dst: make([]float64, 3), 928 src: []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i}, 929 panics: true, 930 }, 931 { 932 dst: make([]float64, 4), 933 src: []complex128{1 + 1i, 2 + 2i, 3 + 3i, cmplx.NaN()}, 934 want: []float64{1, 2, 3, math.NaN()}, 935 }, 936 } { 937 var got []float64 938 panicked := Panics(func() { 939 got = Real(test.dst, test.src) 940 }) 941 if panicked != test.panics { 942 if panicked { 943 t.Errorf("unexpected panic for test %d", i) 944 } else { 945 t.Errorf("expected panic for test %d", i) 946 } 947 } 948 if panicked || test.panics { 949 continue 950 } 951 if !floats.Same(got, test.dst) { 952 t.Errorf("mismatch between dst and return test %d: got:%v want:%v", i, got, test.dst) 953 } 954 if !floats.Same(got, test.want) { 955 t.Errorf("unexpected result for test %d: got:%v want:%v", i, got, test.want) 956 } 957 } 958 959 } 960 func TestSame(t *testing.T) { 961 s1 := []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i} 962 s2 := []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i} 963 if !Same(s1, s2) { 964 t.Errorf("Equal slices returned as unequal") 965 } 966 s2 = []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i + 1e-14} 967 if Same(s1, s2) { 968 t.Errorf("Unequal slices returned as equal") 969 } 970 if Same(s1, []complex128{}) { 971 t.Errorf("Unequal slice lengths returned as equal") 972 } 973 s1 = []complex128{1 + 1i, 2 + 2i, cmplx.NaN(), 4 + 4i} 974 s2 = []complex128{1 + 1i, 2 + 2i, cmplx.NaN(), 4 + 4i} 975 if !Same(s1, s2) { 976 t.Errorf("Slices with matching NaN values returned as unequal") 977 } 978 s1 = []complex128{1 + 1i, 2 + 2i, cmplx.NaN(), 4 + 4i} 979 s2 = []complex128{1 + 1i, cmplx.NaN(), 3 + 3i, 4 + 4i} 980 if Same(s1, s2) { 981 t.Errorf("Slices with unmatching NaN values returned as equal") 982 } 983 } 984 985 func TestScale(t *testing.T) { 986 s := []complex128{3, 4, 1, 7, 5} 987 c := 5 + 5i 988 truth := []complex128{15 + 15i, 20 + 20i, 5 + 5i, 35 + 35i, 25 + 25i} 989 Scale(c, s) 990 areSlicesEqual(t, truth, s, "Bad scaling") 991 } 992 993 func TestScaleTo(t *testing.T) { 994 s := []complex128{3, 4, 1, 7, 5} 995 sCopy := make([]complex128, len(s)) 996 copy(sCopy, s) 997 c := 5 + 5i 998 truth := []complex128{15 + 15i, 20 + 20i, 5 + 5i, 35 + 35i, 25 + 25i} 999 dst := make([]complex128, len(s)) 1000 ScaleTo(dst, c, s) 1001 if !Same(dst, truth) { 1002 t.Errorf("Scale to does not match. Got %v, want %v", dst, truth) 1003 } 1004 if !Same(s, sCopy) { 1005 t.Errorf("Source modified during call. Got %v, want %v", s, sCopy) 1006 } 1007 } 1008 1009 func TestSpan(t *testing.T) { 1010 receiver1 := make([]complex128, 5) 1011 truth := []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i, 5 + 5i} 1012 receiver2 := Span(receiver1, 1+1i, 5+5i) 1013 areSlicesEqual(t, truth, receiver1, "Improper linspace from mutator") 1014 areSlicesEqual(t, truth, receiver2, "Improper linspace from returned slice") 1015 receiver1 = make([]complex128, 6) 1016 truth = []complex128{0, 0.2 + 0.4i, 0.4 + 0.8i, 0.6 + 1.2i, 0.8 + 1.6i, 1 + 2i} 1017 Span(receiver1, 0, 1+2i) 1018 areSlicesEqual(t, truth, receiver1, "Improper linspace") 1019 if !Panics(func() { Span(nil, 1, 5) }) { 1020 t.Errorf("Span accepts nil argument") 1021 } 1022 if !Panics(func() { Span(make([]complex128, 1), 1, 5) }) { 1023 t.Errorf("Span accepts argument of len = 1") 1024 } 1025 1026 for _, test := range []struct { 1027 n int 1028 l, u complex128 1029 want []complex128 1030 }{ 1031 { 1032 n: 5, l: cmplx.Inf(), u: cmplx.Inf(), 1033 want: []complex128{cmplx.Inf(), cmplx.Inf(), cmplx.Inf(), cmplx.Inf(), cmplx.Inf()}, 1034 }, 1035 { 1036 n: 5, l: cmplx.Inf(), u: cmplx.NaN(), 1037 want: []complex128{cmplx.Inf(), cmplx.NaN(), cmplx.NaN(), cmplx.NaN(), cmplx.NaN()}, 1038 }, 1039 { 1040 n: 5, l: cmplx.NaN(), u: cmplx.Inf(), 1041 want: []complex128{cmplx.NaN(), cmplx.NaN(), cmplx.NaN(), cmplx.NaN(), cmplx.Inf()}, 1042 }, 1043 { 1044 n: 5, l: 42, u: cmplx.Inf(), 1045 want: []complex128{42, cmplx.Inf(), cmplx.Inf(), cmplx.Inf(), cmplx.Inf()}, 1046 }, 1047 { 1048 n: 5, l: 42, u: cmplx.NaN(), 1049 want: []complex128{42, cmplx.NaN(), cmplx.NaN(), cmplx.NaN(), cmplx.NaN()}, 1050 }, 1051 { 1052 n: 5, l: cmplx.Inf(), u: 42, 1053 want: []complex128{cmplx.Inf(), cmplx.Inf(), cmplx.Inf(), cmplx.Inf(), 42}, 1054 }, 1055 { 1056 n: 5, l: cmplx.NaN(), u: 42, 1057 want: []complex128{cmplx.NaN(), cmplx.NaN(), cmplx.NaN(), cmplx.NaN(), 42}, 1058 }, 1059 } { 1060 got := Span(make([]complex128, test.n), test.l, test.u) 1061 areSlicesSame(t, test.want, got, 1062 fmt.Sprintf("Unexpected slice of length %d for %f to %f", test.n, test.l, test.u)) 1063 } 1064 } 1065 1066 func TestSub(t *testing.T) { 1067 s := []complex128{3 + 2i, 4 + 3i, 1 + 7i, 7 + 1i, 5 - 1i} 1068 v := []complex128{1 + 1i, 2 + 4i, 3, 4, 5 - 1i} 1069 truth := []complex128{2 + 1i, 2 - 1i, -2 + 7i, 3 + 1i, 0} 1070 Sub(s, v) 1071 areSlicesEqual(t, truth, s, "Bad subtract") 1072 // Test that it panics 1073 if !Panics(func() { Sub(make([]complex128, 2), make([]complex128, 3)) }) { 1074 t.Errorf("Did not panic with length mismatch") 1075 } 1076 } 1077 1078 func TestSubTo(t *testing.T) { 1079 s := []complex128{3 + 2i, 4 + 3i, 1 + 7i, 7 + 1i, 5 - 1i} 1080 v := []complex128{1 + 1i, 2 + 4i, 3, 4, 5 - 1i} 1081 truth := []complex128{2 + 1i, 2 - 1i, -2 + 7i, 3 + 1i, 0} 1082 dst1 := make([]complex128, len(s)) 1083 dst2 := SubTo(dst1, s, v) 1084 areSlicesEqual(t, truth, dst1, "Bad subtract from mutator") 1085 areSlicesEqual(t, truth, dst2, "Bad subtract from returned slice") 1086 // Test that all mismatch combinations panic 1087 if !Panics(func() { SubTo(make([]complex128, 2), make([]complex128, 3), make([]complex128, 3)) }) { 1088 t.Errorf("Did not panic with dst different length") 1089 } 1090 if !Panics(func() { SubTo(make([]complex128, 3), make([]complex128, 2), make([]complex128, 3)) }) { 1091 t.Errorf("Did not panic with subtractor different length") 1092 } 1093 if !Panics(func() { SubTo(make([]complex128, 3), make([]complex128, 3), make([]complex128, 2)) }) { 1094 t.Errorf("Did not panic with subtractee different length") 1095 } 1096 } 1097 1098 func TestSum(t *testing.T) { 1099 s := []complex128{} 1100 val := Sum(s) 1101 if val != 0 { 1102 t.Errorf("Val not returned as default when slice length is zero") 1103 } 1104 s = []complex128{3 + 1i, 4 + 2i, 1 + 3i, 7 + 4i, 5 + 5i} 1105 val = Sum(s) 1106 if val != 20+15i { 1107 t.Errorf("Wrong sum returned") 1108 } 1109 } 1110 1111 func randomSlice(l int, src rand.Source) []complex128 { 1112 rnd := rand.New(src) 1113 s := make([]complex128, l) 1114 for i := range s { 1115 s[i] = complex(rnd.Float64(), rnd.Float64()) 1116 } 1117 return s 1118 } 1119 1120 func benchmarkAdd(b *testing.B, size int) { 1121 src := rand.NewSource(1) 1122 s1 := randomSlice(size, src) 1123 s2 := randomSlice(size, src) 1124 b.ResetTimer() 1125 for i := 0; i < b.N; i++ { 1126 Add(s1, s2) 1127 } 1128 } 1129 func BenchmarkAddSmall(b *testing.B) { benchmarkAdd(b, Small) } 1130 func BenchmarkAddMed(b *testing.B) { benchmarkAdd(b, Medium) } 1131 func BenchmarkAddLarge(b *testing.B) { benchmarkAdd(b, Large) } 1132 func BenchmarkAddHuge(b *testing.B) { benchmarkAdd(b, Huge) } 1133 1134 func benchmarkAddTo(b *testing.B, size int) { 1135 src := rand.NewSource(1) 1136 s1 := randomSlice(size, src) 1137 s2 := randomSlice(size, src) 1138 dst := randomSlice(size, src) 1139 b.ResetTimer() 1140 for i := 0; i < b.N; i++ { 1141 AddTo(dst, s1, s2) 1142 } 1143 } 1144 func BenchmarkAddToSmall(b *testing.B) { benchmarkAddTo(b, Small) } 1145 func BenchmarkAddToMed(b *testing.B) { benchmarkAddTo(b, Medium) } 1146 func BenchmarkAddToLarge(b *testing.B) { benchmarkAddTo(b, Large) } 1147 func BenchmarkAddToHuge(b *testing.B) { benchmarkAddTo(b, Huge) } 1148 1149 func benchmarkCumProd(b *testing.B, size int) { 1150 src := rand.NewSource(1) 1151 s := randomSlice(size, src) 1152 dst := randomSlice(size, src) 1153 b.ResetTimer() 1154 for i := 0; i < b.N; i++ { 1155 CumProd(dst, s) 1156 } 1157 } 1158 func BenchmarkCumProdSmall(b *testing.B) { benchmarkCumProd(b, Small) } 1159 func BenchmarkCumProdMed(b *testing.B) { benchmarkCumProd(b, Medium) } 1160 func BenchmarkCumProdLarge(b *testing.B) { benchmarkCumProd(b, Large) } 1161 func BenchmarkCumProdHuge(b *testing.B) { benchmarkCumProd(b, Huge) } 1162 1163 func benchmarkCumSum(b *testing.B, size int) { 1164 src := rand.NewSource(1) 1165 s := randomSlice(size, src) 1166 dst := randomSlice(size, src) 1167 b.ResetTimer() 1168 for i := 0; i < b.N; i++ { 1169 CumSum(dst, s) 1170 } 1171 } 1172 func BenchmarkCumSumSmall(b *testing.B) { benchmarkCumSum(b, Small) } 1173 func BenchmarkCumSumMed(b *testing.B) { benchmarkCumSum(b, Medium) } 1174 func BenchmarkCumSumLarge(b *testing.B) { benchmarkCumSum(b, Large) } 1175 func BenchmarkCumSumHuge(b *testing.B) { benchmarkCumSum(b, Huge) } 1176 1177 func benchmarkDiv(b *testing.B, size int) { 1178 src := rand.NewSource(1) 1179 s := randomSlice(size, src) 1180 dst := randomSlice(size, src) 1181 b.ResetTimer() 1182 for i := 0; i < b.N; i++ { 1183 Div(dst, s) 1184 } 1185 } 1186 func BenchmarkDivSmall(b *testing.B) { benchmarkDiv(b, Small) } 1187 func BenchmarkDivMed(b *testing.B) { benchmarkDiv(b, Medium) } 1188 func BenchmarkDivLarge(b *testing.B) { benchmarkDiv(b, Large) } 1189 func BenchmarkDivHuge(b *testing.B) { benchmarkDiv(b, Huge) } 1190 1191 func benchmarkDivTo(b *testing.B, size int) { 1192 src := rand.NewSource(1) 1193 s1 := randomSlice(size, src) 1194 s2 := randomSlice(size, src) 1195 dst := randomSlice(size, src) 1196 b.ResetTimer() 1197 for i := 0; i < b.N; i++ { 1198 DivTo(dst, s1, s2) 1199 } 1200 } 1201 func BenchmarkDivToSmall(b *testing.B) { benchmarkDivTo(b, Small) } 1202 func BenchmarkDivToMed(b *testing.B) { benchmarkDivTo(b, Medium) } 1203 func BenchmarkDivToLarge(b *testing.B) { benchmarkDivTo(b, Large) } 1204 func BenchmarkDivToHuge(b *testing.B) { benchmarkDivTo(b, Huge) } 1205 1206 func benchmarkSub(b *testing.B, size int) { 1207 src := rand.NewSource(1) 1208 s1 := randomSlice(size, src) 1209 s2 := randomSlice(size, src) 1210 b.ResetTimer() 1211 for i := 0; i < b.N; i++ { 1212 Sub(s1, s2) 1213 } 1214 } 1215 func BenchmarkSubSmall(b *testing.B) { benchmarkSub(b, Small) } 1216 func BenchmarkSubMed(b *testing.B) { benchmarkSub(b, Medium) } 1217 func BenchmarkSubLarge(b *testing.B) { benchmarkSub(b, Large) } 1218 func BenchmarkSubHuge(b *testing.B) { benchmarkSub(b, Huge) } 1219 1220 func benchmarkSubTo(b *testing.B, size int) { 1221 src := rand.NewSource(1) 1222 s1 := randomSlice(size, src) 1223 s2 := randomSlice(size, src) 1224 dst := randomSlice(size, src) 1225 b.ResetTimer() 1226 for i := 0; i < b.N; i++ { 1227 SubTo(dst, s1, s2) 1228 } 1229 } 1230 func BenchmarkSubToSmall(b *testing.B) { benchmarkSubTo(b, Small) } 1231 func BenchmarkSubToMed(b *testing.B) { benchmarkSubTo(b, Medium) } 1232 func BenchmarkSubToLarge(b *testing.B) { benchmarkSubTo(b, Large) } 1233 func BenchmarkSubToHuge(b *testing.B) { benchmarkSubTo(b, Huge) } 1234 1235 func benchmarkDot(b *testing.B, size int) { 1236 src := rand.NewSource(1) 1237 s1 := randomSlice(size, src) 1238 s2 := randomSlice(size, src) 1239 b.ResetTimer() 1240 for i := 0; i < b.N; i++ { 1241 Dot(s1, s2) 1242 } 1243 } 1244 func BenchmarkDotSmall(b *testing.B) { benchmarkDot(b, Small) } 1245 func BenchmarkDotMed(b *testing.B) { benchmarkDot(b, Medium) } 1246 func BenchmarkDotLarge(b *testing.B) { benchmarkDot(b, Large) } 1247 func BenchmarkDotHuge(b *testing.B) { benchmarkDot(b, Huge) } 1248 1249 func benchmarkAddScaledTo(b *testing.B, size int) { 1250 src := rand.NewSource(1) 1251 dst := randomSlice(size, src) 1252 y := randomSlice(size, src) 1253 s := randomSlice(size, src) 1254 b.ResetTimer() 1255 for i := 0; i < b.N; i++ { 1256 AddScaledTo(dst, y, 2.3, s) 1257 } 1258 } 1259 func BenchmarkAddScaledToSmall(b *testing.B) { benchmarkAddScaledTo(b, Small) } 1260 func BenchmarkAddScaledToMedium(b *testing.B) { benchmarkAddScaledTo(b, Medium) } 1261 func BenchmarkAddScaledToLarge(b *testing.B) { benchmarkAddScaledTo(b, Large) } 1262 func BenchmarkAddScaledToHuge(b *testing.B) { benchmarkAddScaledTo(b, Huge) } 1263 1264 func benchmarkScale(b *testing.B, size int) { 1265 src := rand.NewSource(1) 1266 dst := randomSlice(size, src) 1267 b.ResetTimer() 1268 for i := 0; i < b.N; i += 2 { 1269 Scale(2.0, dst) 1270 Scale(0.5, dst) 1271 } 1272 } 1273 func BenchmarkScaleSmall(b *testing.B) { benchmarkScale(b, Small) } 1274 func BenchmarkScaleMedium(b *testing.B) { benchmarkScale(b, Medium) } 1275 func BenchmarkScaleLarge(b *testing.B) { benchmarkScale(b, Large) } 1276 func BenchmarkScaleHuge(b *testing.B) { benchmarkScale(b, Huge) } 1277 1278 func benchmarkNorm2(b *testing.B, size int) { 1279 src := rand.NewSource(1) 1280 s := randomSlice(size, src) 1281 b.ResetTimer() 1282 for i := 0; i < b.N; i++ { 1283 Norm(s, 2) 1284 } 1285 } 1286 func BenchmarkNorm2Small(b *testing.B) { benchmarkNorm2(b, Small) } 1287 func BenchmarkNorm2Medium(b *testing.B) { benchmarkNorm2(b, Medium) } 1288 func BenchmarkNorm2Large(b *testing.B) { benchmarkNorm2(b, Large) } 1289 func BenchmarkNorm2Huge(b *testing.B) { benchmarkNorm2(b, Huge) }