6 "gonum.org/v1/gonum/blas"
9 type DgemvCase struct {
20 Subcases []DgemvSubcase
23 type DgemvSubcase struct {
31 var DgemvCases = []DgemvCase{
33 Name: "M_gt_N_Inc1_NoTrans",
46 x: []float64{1, 2, 3},
47 y: []float64{7, 8, 9, 10, 11},
49 Subcases: []DgemvSubcase{
53 ans: []float64{0, 0, 0, 0, 0},
58 ans: []float64{7, 8, 9, 10, 11},
63 ans: []float64{40.8, 43.9, 33, 9, 28},
68 ans: []float64{284.4, 303.2, 210, 12, 158},
73 Name: "M_gt_N_Inc1_Trans",
86 x: []float64{1, 2, 3, -4, 5},
87 y: []float64{7, 8, 9},
89 Subcases: []DgemvSubcase{
93 ans: []float64{0, 0, 0},
98 ans: []float64{7, 8, 9},
103 ans: []float64{94.3, 40.2, 52.3},
108 ans: []float64{712.4, 273.6, 364.4},
113 Name: "M_eq_N_Inc1_NoTrans",
124 x: []float64{1, 2, 3},
125 y: []float64{7, 2, 2},
127 Subcases: []DgemvSubcase{
131 ans: []float64{0, 0, 0},
136 ans: []float64{7, 2, 2},
141 ans: []float64{40.8, 43.9, 33},
146 ans: []float64{40.8*8 - 6*7, 43.9*8 - 6*2, 33*8 - 6*2},
151 Name: "M_eq_N_Inc1_Trans",
162 x: []float64{1, 2, 3},
163 y: []float64{7, 2, 2},
165 Subcases: []DgemvSubcase{
169 ans: []float64{384.4, 261.6, 270.4},
174 Name: "M_lt_N_Inc1_NoTrans",
179 {4.1, 6.2, 8.1, 10, 7},
180 {9.6, 3.5, 9.1, -2, 9},
185 x: []float64{1, 2, 3, -7.6, 8.1},
186 y: []float64{7, 2, 2},
188 Subcases: []DgemvSubcase{
192 ans: []float64{0, 0, 0},
197 ans: []float64{7, 2, 2},
202 ans: []float64{21.5, 132, -15.1},
208 ans: []float64{21.5*8 - 6*7, 132*8 - 6*2, -15.1*8 - 6*2},
213 Name: "M_lt_N_Inc1_Trans",
218 {4.1, 6.2, 8.1, 10, 7},
219 {9.6, 3.5, 9.1, -2, 9},
224 x: []float64{1, 2, 3},
225 y: []float64{7, 2, 2, -3, 5},
227 Subcases: []DgemvSubcase{
231 ans: []float64{384.4, 261.6, 270.4, 90, 50},
236 Name: "M_gt_N_Part1_NoTrans",
249 x: []float64{1, 2, 3},
250 y: []float64{7, 100, 8, 101, 9, 102, 10, 103, 11},
252 Subcases: []DgemvSubcase{
256 ans: []float64{0, 100, 0, 101, 0, 102, 0, 103, 0},
261 ans: []float64{7, 100, 8, 101, 9, 102, 10, 103, 11},
266 ans: []float64{40.8, 100, 43.9, 101, 33, 102, 9, 103, 28},
271 ans: []float64{284.4, 100, 303.2, 101, 210, 102, 12, 103, 158},
276 Name: "M_gt_N_Part1_Trans",
289 x: []float64{1, 2, 3, -4, 5},
290 y: []float64{7, 100, 8, 101, 9},
292 Subcases: []DgemvSubcase{
296 ans: []float64{0, 100, 0, 101, 0},
301 ans: []float64{7, 100, 8, 101, 9},
306 ans: []float64{94.3, 100, 40.2, 101, 52.3},
311 ans: []float64{712.4, 100, 273.6, 101, 364.4},
316 Name: "M_gt_N_IncNot1_NoTrans",
330 x: []float64{1, 15, 2, 150, 3},
331 y: []float64{7, 2, 6, 8, -4, -5, 9, 1, 1, 10, 19, 22, 11},
332 Subcases: []DgemvSubcase{
336 ans: []float64{284.4, 2, 6, 303.2, -4, -5, 210, 1, 1, 12, 19, 22, 158},
342 ans: []float64{220.4, 2, 6, 311.2, -4, -5, 322, 1, 1, -4, 19, 22, 222},
348 ans: []float64{182, 2, 6, 24, -4, -5, 210, 1, 1, 291.2, 19, 22, 260.4},
355 ans: []float64{246, 2, 6, 8, -4, -5, 322, 1, 1, 299.2, 19, 22, 196.4},
360 Name: "M_gt_N_IncNot1_Trans",
374 x: []float64{1, 15, 2, 150, 3, 8, -3, 6, 5},
375 y: []float64{7, 2, 6, 8, -4, -5, 9},
376 Subcases: []DgemvSubcase{
380 ans: []float64{720.4, 2, 6, 281.6, -4, -5, 380.4},
386 ans: []float64{219.6, 2, 6, 316, -4, -5, 195.6},
392 ans: []float64{392.4, 2, 6, 281.6, -4, -5, 708.4},
399 ans: []float64{207.6, 2, 6, 316, -4, -5, 207.6},
404 Name: "M_eq_N_IncNot1_NoTrans",
415 x: []float64{1, 15, 2, 150, 3},
416 y: []float64{7, 2, 6, 8, -4, -5, 9},
417 Subcases: []DgemvSubcase{
421 ans: []float64{284.4, 2, 6, 303.2, -4, -5, 210},
427 ans: []float64{220.4, 2, 6, 311.2, -4, -5, 322},
433 ans: []float64{222, 2, 6, 303.2, -4, -5, 272.4},
440 ans: []float64{334, 2, 6, 311.2, -4, -5, 208.4},
445 Name: "M_eq_N_IncNot1_Trans",
456 x: []float64{1, 15, 2, 150, 3},
457 y: []float64{7, 2, 6, 8, -4, -5, 9},
459 Subcases: []DgemvSubcase{
463 ans: []float64{384.4, 2, 6, 225.6, -4, -5, 228.4},
469 ans: []float64{290, 2, 6, 212.8, -4, -5, 310},
475 ans: []float64{240.4, 2, 6, 225.6, -4, -5, 372.4},
482 ans: []float64{322, 2, 6, 212.8, -4, -5, 278},
487 Name: "M_lt_N_IncNot1_NoTrans",
492 {4.1, 6.2, 8.1, 10, 11},
493 {9.6, 3.5, 9.1, -3, -2},
498 x: []float64{1, 15, 2, 150, 3, -2, -4, 8, -9},
499 y: []float64{7, 2, 6, 8, -4, -5, 9},
501 Subcases: []DgemvSubcase{
505 ans: []float64{-827.6, 2, 6, 543.2, -4, -5, 722},
511 ans: []float64{-93.2, 2, 6, -696.8, -4, -5, -1070},
517 ans: []float64{734, 2, 6, 543.2, -4, -5, -839.6},
524 ans: []float64{-1058, 2, 6, -696.8, -4, -5, -105.2},
529 Name: "M_lt_N_IncNot1_Trans",
534 {4.1, 6.2, 8.1, 10, 11},
535 {9.6, 3.5, 9.1, -3, -2},
540 x: []float64{1, 15, 2, 150, 3},
541 y: []float64{7, 2, 6, 8, -4, -5, 9, -4, -1, -9, 1, 1, 2},
543 Subcases: []DgemvSubcase{
547 ans: []float64{384.4, 2, 6, 225.6, -4, -5, 228.4, -4, -1, -82, 1, 1, -52},
553 ans: []float64{290, 2, 6, 212.8, -4, -5, 310, -4, -1, 190, 1, 1, 188},
559 ans: []float64{-82, 2, 6, -184, -4, -5, 228.4, -4, -1, 327.6, 1, 1, 414.4},
566 ans: []float64{158, 2, 6, 88, -4, -5, 310, -4, -1, 314.8, 1, 1, 320},
571 // TODO: A can be longer than mxn. Add cases where it is longer
572 // TODO: x and y can also be longer. Add tests for these
573 // TODO: Add tests for dimension mismatch
574 // TODO: Add places with a "submatrix view", where lda != m
577 type Dgemver interface {
578 Dgemv(tA blas.Transpose, m, n int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int)
581 func DgemvTest(t *testing.T, blasser Dgemver) {
582 for _, test := range DgemvCases {
583 for i, cas := range test.Subcases {
584 // Test that it passes with row-major
585 dgemvcomp(t, test, cas, i, blasser)
587 // Test the bad inputs
588 dgemvbad(t, test, cas, i, blasser)
593 func dgemvcomp(t *testing.T, test DgemvCase, cas DgemvSubcase, i int, blasser Dgemver) {
594 x := sliceCopy(test.x)
595 y := sliceCopy(test.y)
596 a := sliceOfSliceCopy(test.A)
611 blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlat, lda, x, incX, cas.beta, y, incY)
614 t.Errorf("Test %v case %v: unexpected panic", test.Name, i)
616 blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlat, lda, x, incX, cas.beta, y, incY)
620 // Check that x and a are unchanged
621 if !dSliceEqual(x, test.x) {
622 t.Errorf("Test %v, case %v: x modified during call", test.Name, i)
624 aFlat2 := flatten(sliceOfSliceCopy(test.A))
625 if !dSliceEqual(aFlat2, aFlat) {
626 t.Errorf("Test %v, case %v: a modified during call", test.Name, i)
629 // Check that the answer matches
630 if !dSliceTolEqual(cas.ans, y) {
631 t.Errorf("Test %v, case %v: answer mismatch: Expected %v, Found %v", test.Name, i, cas.ans, y)
635 func dgemvbad(t *testing.T, test DgemvCase, cas DgemvSubcase, i int, blasser Dgemver) {
636 x := sliceCopy(test.x)
637 y := sliceCopy(test.y)
638 a := sliceOfSliceCopy(test.A)
639 aFlatRow := flatten(a)
643 blasser.Dgemv(312, test.m, test.n, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, test.incY)
646 t.Errorf("Test %v case %v: no panic for bad transpose", test.Name, i)
649 blasser.Dgemv(test.tA, -2, test.n, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, test.incY)
652 t.Errorf("Test %v case %v: no panic for m negative", test.Name, i)
655 blasser.Dgemv(test.tA, test.m, -4, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, test.incY)
658 t.Errorf("Test %v case %v: no panic for n negative", test.Name, i)
661 blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlatRow, ldaRow, x, 0, cas.beta, y, test.incY)
664 t.Errorf("Test %v case %v: no panic for incX zero", test.Name, i)
667 blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, 0)
670 t.Errorf("Test %v case %v: no panic for incY zero", test.Name, i)
673 blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlatRow, ldaRow-1, x, test.incX, cas.beta, y, test.incY)
676 t.Errorf("Test %v case %v: no panic for lda too small row major", test.Name, i)