1 // Copyright ©2016 The Gonum Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
9 func TestL1Norm(t *testing.T) {
10 var src_gd float64 = 1
11 for j, v := range []struct {
15 {want: 0, x: []float64{}},
16 {want: 2, x: []float64{2}},
17 {want: 6, x: []float64{1, 2, 3}},
18 {want: 6, x: []float64{-1, -2, -3}},
19 {want: nan, x: []float64{nan}},
20 {want: 40, x: []float64{8, -8, 8, -8, 8}},
21 {want: 5, x: []float64{0, 1, 0, -1, 0, 1, 0, -1, 0, 1}},
24 v.x = guardVector(v.x, src_gd, g_ln)
25 src := v.x[g_ln : len(v.x)-g_ln]
27 if !same(ret, v.want) {
28 t.Errorf("Test %d L1Norm error Got: %f Expected: %f", j, ret, v.want)
30 if !isValidGuard(v.x, src_gd, g_ln) {
31 t.Errorf("Test %d Guard violated in src vector %v %v", j, v.x[:g_ln], v.x[len(v.x)-g_ln:])
36 func TestL1NormInc(t *testing.T) {
37 var src_gd float64 = 1
38 for j, v := range []struct {
43 {inc: 2, want: 0, x: []float64{}},
44 {inc: 3, want: 2, x: []float64{2}},
45 {inc: 10, want: 6, x: []float64{1, 2, 3}},
46 {inc: 5, want: 6, x: []float64{-1, -2, -3}},
47 {inc: 3, want: nan, x: []float64{nan}},
48 {inc: 15, want: 40, x: []float64{8, -8, 8, -8, 8}},
49 {inc: 1, want: 5, x: []float64{0, 1, 0, -1, 0, 1, 0, -1, 0, 1}},
51 g_ln, ln := 4+j%2, len(v.x)
52 v.x = guardIncVector(v.x, src_gd, v.inc, g_ln)
53 src := v.x[g_ln : len(v.x)-g_ln]
54 ret := L1NormInc(src, ln, v.inc)
55 if !same(ret, v.want) {
56 t.Errorf("Test %d L1NormInc error Got: %f Expected: %f", j, ret, v.want)
58 checkValidIncGuard(t, v.x, src_gd, v.inc, g_ln)
62 func TestAdd(t *testing.T) {
63 var src_gd, dst_gd float64 = 1, 0
64 for j, v := range []struct {
65 dst, src, expect []float64
73 dst: []float64{1, 2, 3},
75 expect: []float64{2, 2, 3},
85 expect: []float64{nan},
88 dst: []float64{8, 8, 8, 8, 8},
89 src: []float64{2, 4, nan, 8, 9},
90 expect: []float64{10, 12, nan, 16, 17},
93 dst: []float64{0, 1, 2, 3, 4},
94 src: []float64{-inf, 4, nan, 8, 9},
95 expect: []float64{-inf, 5, nan, 11, 13},
98 dst: make([]float64, 50)[1:49],
99 src: make([]float64, 50)[1:49],
100 expect: make([]float64, 50)[1:49],
103 sg_ln, dg_ln := 4+j%2, 4+j%3
104 v.src, v.dst = guardVector(v.src, src_gd, sg_ln), guardVector(v.dst, dst_gd, dg_ln)
105 src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln]
107 for i := range v.expect {
108 if !same(dst[i], v.expect[i]) {
109 t.Errorf("Test %d Add error at %d Got: %v Expected: %v", j, i, dst[i], v.expect[i])
112 if !isValidGuard(v.src, src_gd, sg_ln) {
113 t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:sg_ln], v.src[len(v.src)-sg_ln:])
115 if !isValidGuard(v.dst, dst_gd, dg_ln) {
116 t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:dg_ln], v.dst[len(v.dst)-dg_ln:])
121 func TestAddConst(t *testing.T) {
122 var src_gd float64 = 0
123 for j, v := range []struct {
125 src, expect []float64
130 expect: []float64{1},
140 expect: []float64{nan},
144 src: []float64{2, 4, nan, 8, 9},
145 expect: []float64{10, 12, nan, 16, 17},
149 src: []float64{-inf, 4, nan, 8, 9},
150 expect: []float64{nan, inf, nan, inf, inf},
154 v.src = guardVector(v.src, src_gd, g_ln)
155 src := v.src[g_ln : len(v.src)-g_ln]
156 AddConst(v.alpha, src)
157 for i := range v.expect {
158 if !same(src[i], v.expect[i]) {
159 t.Errorf("Test %d AddConst error at %d Got: %v Expected: %v", j, i, src[i], v.expect[i])
162 if !isValidGuard(v.src, src_gd, g_ln) {
163 t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:g_ln], v.src[len(v.src)-g_ln:])
168 func TestCumSum(t *testing.T) {
169 var src_gd, dst_gd float64 = -1, 0
170 for j, v := range []struct {
171 dst, src, expect []float64
181 expect: []float64{1},
186 expect: []float64{nan},
189 dst: []float64{0, 0, 0},
190 src: []float64{1, 2, 3},
191 expect: []float64{1, 3, 6},
194 dst: []float64{0, 0, 0, 0},
195 src: []float64{1, 2, 3},
196 expect: []float64{1, 3, 6},
199 dst: []float64{0, 0, 0, 0},
200 src: []float64{1, 2, 3, 4},
201 expect: []float64{1, 3, 6, 10},
204 dst: []float64{1, nan, nan, 1, 1},
205 src: []float64{1, 1, nan, 1, 1},
206 expect: []float64{1, 2, nan, nan, nan},
209 dst: []float64{nan, 4, inf, -inf, 9},
210 src: []float64{inf, 4, nan, -inf, 9},
211 expect: []float64{inf, inf, nan, nan, nan},
214 dst: make([]float64, 16),
215 src: []float64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
216 expect: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
220 v.src, v.dst = guardVector(v.src, src_gd, g_ln), guardVector(v.dst, dst_gd, g_ln)
221 src, dst := v.src[g_ln:len(v.src)-g_ln], v.dst[g_ln:len(v.dst)-g_ln]
222 ret := CumSum(dst, src)
223 for i := range v.expect {
224 if !same(ret[i], v.expect[i]) {
225 t.Errorf("Test %d CumSum error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i])
227 if !same(ret[i], dst[i]) {
228 t.Errorf("Test %d CumSum ret/dst mismatch %d Ret: %v Dst: %v", j, i, ret[i], dst[i])
231 if !isValidGuard(v.src, src_gd, g_ln) {
232 t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:g_ln], v.src[len(v.src)-g_ln:])
234 if !isValidGuard(v.dst, dst_gd, g_ln) {
235 t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:g_ln], v.dst[len(v.dst)-g_ln:])
240 func TestCumProd(t *testing.T) {
241 var src_gd, dst_gd float64 = -1, 1
242 for j, v := range []struct {
243 dst, src, expect []float64
253 expect: []float64{1},
258 expect: []float64{nan},
261 dst: []float64{0, 0, 0, 0},
262 src: []float64{1, 2, 3, 4},
263 expect: []float64{1, 2, 6, 24},
266 dst: []float64{0, 0, 0},
267 src: []float64{1, 2, 3},
268 expect: []float64{1, 2, 6},
271 dst: []float64{0, 0, 0, 0},
272 src: []float64{1, 2, 3},
273 expect: []float64{1, 2, 6},
276 dst: []float64{nan, 1, nan, 1, 0},
277 src: []float64{1, 1, nan, 1, 1},
278 expect: []float64{1, 1, nan, nan, nan},
281 dst: []float64{nan, 4, nan, -inf, 9},
282 src: []float64{inf, 4, nan, -inf, 9},
283 expect: []float64{inf, inf, nan, nan, nan},
286 dst: make([]float64, 18),
287 src: []float64{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
288 expect: []float64{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536},
291 sg_ln, dg_ln := 4+j%2, 4+j%3
292 v.src, v.dst = guardVector(v.src, src_gd, sg_ln), guardVector(v.dst, dst_gd, dg_ln)
293 src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln]
294 ret := CumProd(dst, src)
295 for i := range v.expect {
296 if !same(ret[i], v.expect[i]) {
297 t.Errorf("Test %d CumProd error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i])
299 if !same(ret[i], dst[i]) {
300 t.Errorf("Test %d CumProd ret/dst mismatch %d Ret: %v Dst: %v", j, i, ret[i], dst[i])
303 if !isValidGuard(v.src, src_gd, sg_ln) {
304 t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:sg_ln], v.src[len(v.src)-sg_ln:])
306 if !isValidGuard(v.dst, dst_gd, dg_ln) {
307 t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:dg_ln], v.dst[len(v.dst)-dg_ln:])
312 func TestDiv(t *testing.T) {
313 var src_gd, dst_gd float64 = -1, 0.5
314 for j, v := range []struct {
315 dst, src, expect []float64
320 expect: []float64{1},
325 expect: []float64{nan},
328 dst: []float64{1, 2, 3, 4},
329 src: []float64{1, 2, 3, 4},
330 expect: []float64{1, 1, 1, 1},
333 dst: []float64{1, 2, 3, 4, 2, 4, 6, 8},
334 src: []float64{1, 2, 3, 4, 1, 2, 3, 4},
335 expect: []float64{1, 1, 1, 1, 2, 2, 2, 2},
338 dst: []float64{2, 4, 6},
339 src: []float64{1, 2, 3},
340 expect: []float64{2, 2, 2},
343 dst: []float64{0, 0, 0, 0},
344 src: []float64{1, 2, 3},
345 expect: []float64{0, 0, 0},
348 dst: []float64{nan, 1, nan, 1, 0, nan, 1, nan, 1, 0},
349 src: []float64{1, 1, nan, 1, 1, 1, 1, nan, 1, 1},
350 expect: []float64{nan, 1, nan, 1, 0, nan, 1, nan, 1, 0},
353 dst: []float64{inf, 4, nan, -inf, 9, inf, 4, nan, -inf, 9},
354 src: []float64{inf, 4, nan, -inf, 3, inf, 4, nan, -inf, 3},
355 expect: []float64{nan, 1, nan, nan, 3, nan, 1, nan, nan, 3},
358 sg_ln, dg_ln := 4+j%2, 4+j%3
359 v.src, v.dst = guardVector(v.src, src_gd, sg_ln), guardVector(v.dst, dst_gd, dg_ln)
360 src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln]
362 for i := range v.expect {
363 if !same(dst[i], v.expect[i]) {
364 t.Errorf("Test %d Div error at %d Got: %v Expected: %v", j, i, dst[i], v.expect[i])
367 if !isValidGuard(v.src, src_gd, sg_ln) {
368 t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:sg_ln], v.src[len(v.src)-sg_ln:])
370 if !isValidGuard(v.dst, dst_gd, dg_ln) {
371 t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:dg_ln], v.dst[len(v.dst)-dg_ln:])
376 func TestDivTo(t *testing.T) {
377 var dst_gd, x_gd, y_gd float64 = -1, 0.5, 0.25
378 for j, v := range []struct {
379 dst, x, y, expect []float64
385 expect: []float64{1},
391 expect: []float64{nan},
394 dst: []float64{-2, -2, -2},
395 x: []float64{1, 2, 3},
396 y: []float64{1, 2, 3},
397 expect: []float64{1, 1, 1},
400 dst: []float64{0, 0, 0},
401 x: []float64{2, 4, 6},
402 y: []float64{1, 2, 3, 4},
403 expect: []float64{2, 2, 2},
406 dst: []float64{-1, -1, -1},
407 x: []float64{0, 0, 0},
408 y: []float64{1, 2, 3},
409 expect: []float64{0, 0, 0},
412 dst: []float64{inf, inf, inf, inf, inf, inf, inf, inf, inf, inf},
413 x: []float64{nan, 1, nan, 1, 0, nan, 1, nan, 1, 0},
414 y: []float64{1, 1, nan, 1, 1, 1, 1, nan, 1, 1},
415 expect: []float64{nan, 1, nan, 1, 0, nan, 1, nan, 1, 0},
418 dst: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
419 x: []float64{inf, 4, nan, -inf, 9, inf, 4, nan, -inf, 9},
420 y: []float64{inf, 4, nan, -inf, 3, inf, 4, nan, -inf, 3},
421 expect: []float64{nan, 1, nan, nan, 3, nan, 1, nan, nan, 3},
424 xg_ln, yg_ln := 4+j%2, 4+j%3
425 v.y, v.x = guardVector(v.y, y_gd, yg_ln), guardVector(v.x, x_gd, xg_ln)
426 y, x := v.y[yg_ln:len(v.y)-yg_ln], v.x[xg_ln:len(v.x)-xg_ln]
427 v.dst = guardVector(v.dst, dst_gd, xg_ln)
428 dst := v.dst[xg_ln : len(v.dst)-xg_ln]
429 ret := DivTo(dst, x, y)
430 for i := range v.expect {
431 if !same(ret[i], v.expect[i]) {
432 t.Errorf("Test %d DivTo error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i])
434 if !same(ret[i], dst[i]) {
435 t.Errorf("Test %d DivTo ret/dst mismatch %d Ret: %v Dst: %v", j, i, ret[i], dst[i])
438 if !isValidGuard(v.y, y_gd, yg_ln) {
439 t.Errorf("Test %d Guard violated in y vector %v %v", j, v.y[:yg_ln], v.y[len(v.y)-yg_ln:])
441 if !isValidGuard(v.x, x_gd, xg_ln) {
442 t.Errorf("Test %d Guard violated in x vector %v %v", j, v.x[:xg_ln], v.x[len(v.x)-xg_ln:])
444 if !isValidGuard(v.dst, dst_gd, xg_ln) {
445 t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:xg_ln], v.dst[len(v.dst)-xg_ln:])
450 func TestL1Dist(t *testing.T) {
451 var t_gd, s_gd float64 = -inf, inf
452 for j, v := range []struct {
467 s: []float64{1, 2, 3, 4},
468 t: []float64{1, 2, 3, 4},
472 s: []float64{2, 4, 6},
473 t: []float64{1, 2, 3, 4},
477 s: []float64{0, 0, 0},
478 t: []float64{1, 2, 3},
482 s: []float64{0, -4, -10},
483 t: []float64{1, 2, 3},
487 s: []float64{0, 1, 0, 1, 0},
488 t: []float64{1, 1, inf, 1, 1},
492 s: []float64{inf, 4, nan, -inf, 9},
493 t: []float64{inf, 4, nan, -inf, 3},
497 sg_ln, tg_ln := 4+j%2, 4+j%3
498 v.s, v.t = guardVector(v.s, s_gd, sg_ln), guardVector(v.t, t_gd, tg_ln)
499 s_lc, t_lc := v.s[sg_ln:len(v.s)-sg_ln], v.t[tg_ln:len(v.t)-tg_ln]
500 ret := L1Dist(s_lc, t_lc)
501 if !same(ret, v.expect) {
502 t.Errorf("Test %d L1Dist error Got: %f Expected: %f", j, ret, v.expect)
504 if !isValidGuard(v.s, s_gd, sg_ln) {
505 t.Errorf("Test %d Guard violated in s vector %v %v", j, v.s[:sg_ln], v.s[len(v.s)-sg_ln:])
507 if !isValidGuard(v.t, t_gd, tg_ln) {
508 t.Errorf("Test %d Guard violated in t vector %v %v", j, v.t[:tg_ln], v.t[len(v.t)-tg_ln:])
513 func TestLinfDist(t *testing.T) {
514 var t_gd, s_gd float64 = 0, inf
515 for j, v := range []struct {
535 s: []float64{1, 2, 3, 4},
536 t: []float64{1, 2, 3, 4},
540 s: []float64{2, 4, 6},
541 t: []float64{1, 2, 3, 4},
545 s: []float64{0, 0, 0},
546 t: []float64{1, 2, 3},
550 s: []float64{0, 1, 0, 1, 0},
551 t: []float64{1, 1, inf, 1, 1},
555 s: []float64{inf, 4, nan, -inf, 9},
556 t: []float64{inf, 4, nan, -inf, 3},
560 sg_ln, tg_ln := 4+j%2, 4+j%3
561 v.s, v.t = guardVector(v.s, s_gd, sg_ln), guardVector(v.t, t_gd, tg_ln)
562 s_lc, t_lc := v.s[sg_ln:len(v.s)-sg_ln], v.t[tg_ln:len(v.t)-tg_ln]
563 ret := LinfDist(s_lc, t_lc)
564 if !same(ret, v.expect) {
565 t.Errorf("Test %d LinfDist error Got: %f Expected: %f", j, ret, v.expect)
567 if !isValidGuard(v.s, s_gd, sg_ln) {
568 t.Errorf("Test %d Guard violated in s vector %v %v", j, v.s[:sg_ln], v.s[len(v.s)-sg_ln:])
570 if !isValidGuard(v.t, t_gd, tg_ln) {
571 t.Errorf("Test %d Guard violated in t vector %v %v", j, v.t[:tg_ln], v.t[len(v.t)-tg_ln:])