github.com/gopherd/gonum@v0.0.4/blas/testblas/dgemv.go (about)

     1  // Copyright ©2014 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.
     4  
     5  package testblas
     6  
     7  import (
     8  	"testing"
     9  
    10  	"github.com/gopherd/gonum/blas"
    11  )
    12  
    13  type DgemvCase struct {
    14  	Name string
    15  	m    int
    16  	n    int
    17  	A    [][]float64
    18  	tA   blas.Transpose
    19  	x    []float64
    20  	incX int
    21  	y    []float64
    22  	incY int
    23  
    24  	Subcases []DgemvSubcase
    25  }
    26  
    27  type DgemvSubcase struct {
    28  	mulXNeg1 bool
    29  	mulYNeg1 bool
    30  	alpha    float64
    31  	beta     float64
    32  	ans      []float64
    33  }
    34  
    35  var DgemvCases = []DgemvCase{
    36  	{
    37  		Name: "M_gt_N_Inc1_NoTrans",
    38  		tA:   blas.NoTrans,
    39  		m:    5,
    40  		n:    3,
    41  		A: [][]float64{
    42  			{4.1, 6.2, 8.1},
    43  			{9.6, 3.5, 9.1},
    44  			{10, 7, 3},
    45  			{1, 1, 2},
    46  			{9, 2, 5},
    47  		},
    48  		incX: 1,
    49  		incY: 1,
    50  		x:    []float64{1, 2, 3},
    51  		y:    []float64{7, 8, 9, 10, 11},
    52  
    53  		Subcases: []DgemvSubcase{
    54  			{
    55  				alpha: 0,
    56  				beta:  0,
    57  				ans:   []float64{0, 0, 0, 0, 0},
    58  			},
    59  			{
    60  				alpha: 0,
    61  				beta:  1,
    62  				ans:   []float64{7, 8, 9, 10, 11},
    63  			},
    64  			{
    65  				alpha: 1,
    66  				beta:  0,
    67  				ans:   []float64{40.8, 43.9, 33, 9, 28},
    68  			},
    69  			{
    70  				alpha: 8,
    71  				beta:  -6,
    72  				ans:   []float64{284.4, 303.2, 210, 12, 158},
    73  			},
    74  		},
    75  	},
    76  	{
    77  		Name: "M_gt_N_Inc1_Trans",
    78  		tA:   blas.Trans,
    79  		m:    5,
    80  		n:    3,
    81  		A: [][]float64{
    82  			{4.1, 6.2, 8.1},
    83  			{9.6, 3.5, 9.1},
    84  			{10, 7, 3},
    85  			{1, 1, 2},
    86  			{9, 2, 5},
    87  		},
    88  		incX: 1,
    89  		incY: 1,
    90  		x:    []float64{1, 2, 3, -4, 5},
    91  		y:    []float64{7, 8, 9},
    92  
    93  		Subcases: []DgemvSubcase{
    94  			{
    95  				alpha: 0,
    96  				beta:  0,
    97  				ans:   []float64{0, 0, 0},
    98  			},
    99  			{
   100  				alpha: 0,
   101  				beta:  1,
   102  				ans:   []float64{7, 8, 9},
   103  			},
   104  			{
   105  				alpha: 1,
   106  				beta:  0,
   107  				ans:   []float64{94.3, 40.2, 52.3},
   108  			},
   109  			{
   110  				alpha: 8,
   111  				beta:  -6,
   112  				ans:   []float64{712.4, 273.6, 364.4},
   113  			},
   114  		},
   115  	},
   116  	{
   117  		Name: "M_eq_N_Inc1_NoTrans",
   118  		tA:   blas.NoTrans,
   119  		m:    3,
   120  		n:    3,
   121  		A: [][]float64{
   122  			{4.1, 6.2, 8.1},
   123  			{9.6, 3.5, 9.1},
   124  			{10, 7, 3},
   125  		},
   126  		incX: 1,
   127  		incY: 1,
   128  		x:    []float64{1, 2, 3},
   129  		y:    []float64{7, 2, 2},
   130  
   131  		Subcases: []DgemvSubcase{
   132  			{
   133  				alpha: 0,
   134  				beta:  0,
   135  				ans:   []float64{0, 0, 0},
   136  			},
   137  			{
   138  				alpha: 0,
   139  				beta:  1,
   140  				ans:   []float64{7, 2, 2},
   141  			},
   142  			{
   143  				alpha: 1,
   144  				beta:  0,
   145  				ans:   []float64{40.8, 43.9, 33},
   146  			},
   147  			{
   148  				alpha: 8,
   149  				beta:  -6,
   150  				ans:   []float64{40.8*8 - 6*7, 43.9*8 - 6*2, 33*8 - 6*2},
   151  			},
   152  		},
   153  	},
   154  	{
   155  		Name: "M_eq_N_Inc1_Trans",
   156  		tA:   blas.Trans,
   157  		m:    3,
   158  		n:    3,
   159  		A: [][]float64{
   160  			{4.1, 6.2, 8.1},
   161  			{9.6, 3.5, 9.1},
   162  			{10, 7, 3},
   163  		},
   164  		incX: 1,
   165  		incY: 1,
   166  		x:    []float64{1, 2, 3},
   167  		y:    []float64{7, 2, 2},
   168  
   169  		Subcases: []DgemvSubcase{
   170  			{
   171  				alpha: 8,
   172  				beta:  -6,
   173  				ans:   []float64{384.4, 261.6, 270.4},
   174  			},
   175  		},
   176  	},
   177  	{
   178  		Name: "M_lt_N_Inc1_NoTrans",
   179  		tA:   blas.NoTrans,
   180  		m:    3,
   181  		n:    5,
   182  		A: [][]float64{
   183  			{4.1, 6.2, 8.1, 10, 7},
   184  			{9.6, 3.5, 9.1, -2, 9},
   185  			{10, 7, 3, 1, -5},
   186  		},
   187  		incX: 1,
   188  		incY: 1,
   189  		x:    []float64{1, 2, 3, -7.6, 8.1},
   190  		y:    []float64{7, 2, 2},
   191  
   192  		Subcases: []DgemvSubcase{
   193  			{
   194  				alpha: 0,
   195  				beta:  0,
   196  				ans:   []float64{0, 0, 0},
   197  			},
   198  			{
   199  				alpha: 0,
   200  				beta:  1,
   201  				ans:   []float64{7, 2, 2},
   202  			},
   203  			{
   204  				alpha: 1,
   205  				beta:  0,
   206  				ans:   []float64{21.5, 132, -15.1},
   207  			},
   208  
   209  			{
   210  				alpha: 8,
   211  				beta:  -6,
   212  				ans:   []float64{21.5*8 - 6*7, 132*8 - 6*2, -15.1*8 - 6*2},
   213  			},
   214  		},
   215  	},
   216  	{
   217  		Name: "M_lt_N_Inc1_Trans",
   218  		tA:   blas.Trans,
   219  		m:    3,
   220  		n:    5,
   221  		A: [][]float64{
   222  			{4.1, 6.2, 8.1, 10, 7},
   223  			{9.6, 3.5, 9.1, -2, 9},
   224  			{10, 7, 3, 1, -5},
   225  		},
   226  		incX: 1,
   227  		incY: 1,
   228  		x:    []float64{1, 2, 3},
   229  		y:    []float64{7, 2, 2, -3, 5},
   230  
   231  		Subcases: []DgemvSubcase{
   232  			{
   233  				alpha: 8,
   234  				beta:  -6,
   235  				ans:   []float64{384.4, 261.6, 270.4, 90, 50},
   236  			},
   237  		},
   238  	},
   239  	{
   240  		Name: "M_gt_N_Part1_NoTrans",
   241  		tA:   blas.NoTrans,
   242  		m:    5,
   243  		n:    3,
   244  		A: [][]float64{
   245  			{4.1, 6.2, 8.1},
   246  			{9.6, 3.5, 9.1},
   247  			{10, 7, 3},
   248  			{1, 1, 2},
   249  			{9, 2, 5},
   250  		},
   251  		incX: 1,
   252  		incY: 2,
   253  		x:    []float64{1, 2, 3},
   254  		y:    []float64{7, 100, 8, 101, 9, 102, 10, 103, 11},
   255  
   256  		Subcases: []DgemvSubcase{
   257  			{
   258  				alpha: 0,
   259  				beta:  0,
   260  				ans:   []float64{0, 100, 0, 101, 0, 102, 0, 103, 0},
   261  			},
   262  			{
   263  				alpha: 0,
   264  				beta:  1,
   265  				ans:   []float64{7, 100, 8, 101, 9, 102, 10, 103, 11},
   266  			},
   267  			{
   268  				alpha: 1,
   269  				beta:  0,
   270  				ans:   []float64{40.8, 100, 43.9, 101, 33, 102, 9, 103, 28},
   271  			},
   272  			{
   273  				alpha: 8,
   274  				beta:  -6,
   275  				ans:   []float64{284.4, 100, 303.2, 101, 210, 102, 12, 103, 158},
   276  			},
   277  		},
   278  	},
   279  	{
   280  		Name: "M_gt_N_Part1_Trans",
   281  		tA:   blas.Trans,
   282  		m:    5,
   283  		n:    3,
   284  		A: [][]float64{
   285  			{4.1, 6.2, 8.1},
   286  			{9.6, 3.5, 9.1},
   287  			{10, 7, 3},
   288  			{1, 1, 2},
   289  			{9, 2, 5},
   290  		},
   291  		incX: 1,
   292  		incY: 2,
   293  		x:    []float64{1, 2, 3, -4, 5},
   294  		y:    []float64{7, 100, 8, 101, 9},
   295  
   296  		Subcases: []DgemvSubcase{
   297  			{
   298  				alpha: 0,
   299  				beta:  0,
   300  				ans:   []float64{0, 100, 0, 101, 0},
   301  			},
   302  			{
   303  				alpha: 0,
   304  				beta:  1,
   305  				ans:   []float64{7, 100, 8, 101, 9},
   306  			},
   307  			{
   308  				alpha: 1,
   309  				beta:  0,
   310  				ans:   []float64{94.3, 100, 40.2, 101, 52.3},
   311  			},
   312  			{
   313  				alpha: 8,
   314  				beta:  -6,
   315  				ans:   []float64{712.4, 100, 273.6, 101, 364.4},
   316  			},
   317  		},
   318  	},
   319  	{
   320  		Name: "M_gt_N_IncNot1_NoTrans",
   321  		tA:   blas.NoTrans,
   322  		m:    5,
   323  		n:    3,
   324  
   325  		A: [][]float64{
   326  			{4.1, 6.2, 8.1},
   327  			{9.6, 3.5, 9.1},
   328  			{10, 7, 3},
   329  			{1, 1, 2},
   330  			{9, 2, 5},
   331  		},
   332  		incX: 2,
   333  		incY: 3,
   334  		x:    []float64{1, 15, 2, 150, 3},
   335  		y:    []float64{7, 2, 6, 8, -4, -5, 9, 1, 1, 10, 19, 22, 11},
   336  		Subcases: []DgemvSubcase{
   337  			{
   338  				alpha: 8,
   339  				beta:  -6,
   340  				ans:   []float64{284.4, 2, 6, 303.2, -4, -5, 210, 1, 1, 12, 19, 22, 158},
   341  			},
   342  			{
   343  				mulXNeg1: true,
   344  				alpha:    8,
   345  				beta:     -6,
   346  				ans:      []float64{220.4, 2, 6, 311.2, -4, -5, 322, 1, 1, -4, 19, 22, 222},
   347  			},
   348  			{
   349  				mulYNeg1: true,
   350  				alpha:    8,
   351  				beta:     -6,
   352  				ans:      []float64{182, 2, 6, 24, -4, -5, 210, 1, 1, 291.2, 19, 22, 260.4},
   353  			},
   354  			{
   355  				mulXNeg1: true,
   356  				mulYNeg1: true,
   357  				alpha:    8,
   358  				beta:     -6,
   359  				ans:      []float64{246, 2, 6, 8, -4, -5, 322, 1, 1, 299.2, 19, 22, 196.4},
   360  			},
   361  		},
   362  	},
   363  	{
   364  		Name: "M_gt_N_IncNot1_Trans",
   365  		tA:   blas.Trans,
   366  		m:    5,
   367  		n:    3,
   368  
   369  		A: [][]float64{
   370  			{4.1, 6.2, 8.1},
   371  			{9.6, 3.5, 9.1},
   372  			{10, 7, 3},
   373  			{1, 1, 2},
   374  			{9, 2, 5},
   375  		},
   376  		incX: 2,
   377  		incY: 3,
   378  		x:    []float64{1, 15, 2, 150, 3, 8, -3, 6, 5},
   379  		y:    []float64{7, 2, 6, 8, -4, -5, 9},
   380  		Subcases: []DgemvSubcase{
   381  			{
   382  				alpha: 8,
   383  				beta:  -6,
   384  				ans:   []float64{720.4, 2, 6, 281.6, -4, -5, 380.4},
   385  			},
   386  			{
   387  				mulXNeg1: true,
   388  				alpha:    8,
   389  				beta:     -6,
   390  				ans:      []float64{219.6, 2, 6, 316, -4, -5, 195.6},
   391  			},
   392  			{
   393  				mulYNeg1: true,
   394  				alpha:    8,
   395  				beta:     -6,
   396  				ans:      []float64{392.4, 2, 6, 281.6, -4, -5, 708.4},
   397  			},
   398  			{
   399  				mulXNeg1: true,
   400  				mulYNeg1: true,
   401  				alpha:    8,
   402  				beta:     -6,
   403  				ans:      []float64{207.6, 2, 6, 316, -4, -5, 207.6},
   404  			},
   405  		},
   406  	},
   407  	{
   408  		Name: "M_eq_N_IncNot1_NoTrans",
   409  		tA:   blas.NoTrans,
   410  		m:    3,
   411  		n:    3,
   412  		A: [][]float64{
   413  			{4.1, 6.2, 8.1},
   414  			{9.6, 3.5, 9.1},
   415  			{10, 7, 3},
   416  		},
   417  		incX: 2,
   418  		incY: 3,
   419  		x:    []float64{1, 15, 2, 150, 3},
   420  		y:    []float64{7, 2, 6, 8, -4, -5, 9},
   421  		Subcases: []DgemvSubcase{
   422  			{
   423  				alpha: 8,
   424  				beta:  -6,
   425  				ans:   []float64{284.4, 2, 6, 303.2, -4, -5, 210},
   426  			},
   427  			{
   428  				mulXNeg1: true,
   429  				alpha:    8,
   430  				beta:     -6,
   431  				ans:      []float64{220.4, 2, 6, 311.2, -4, -5, 322},
   432  			},
   433  			{
   434  				mulYNeg1: true,
   435  				alpha:    8,
   436  				beta:     -6,
   437  				ans:      []float64{222, 2, 6, 303.2, -4, -5, 272.4},
   438  			},
   439  			{
   440  				mulXNeg1: true,
   441  				mulYNeg1: true,
   442  				alpha:    8,
   443  				beta:     -6,
   444  				ans:      []float64{334, 2, 6, 311.2, -4, -5, 208.4},
   445  			},
   446  		},
   447  	},
   448  	{
   449  		Name: "M_eq_N_IncNot1_Trans",
   450  		tA:   blas.Trans,
   451  		m:    3,
   452  		n:    3,
   453  		A: [][]float64{
   454  			{4.1, 6.2, 8.1},
   455  			{9.6, 3.5, 9.1},
   456  			{10, 7, 3},
   457  		},
   458  		incX: 2,
   459  		incY: 3,
   460  		x:    []float64{1, 15, 2, 150, 3},
   461  		y:    []float64{7, 2, 6, 8, -4, -5, 9},
   462  
   463  		Subcases: []DgemvSubcase{
   464  			{
   465  				alpha: 8,
   466  				beta:  -6,
   467  				ans:   []float64{384.4, 2, 6, 225.6, -4, -5, 228.4},
   468  			},
   469  			{
   470  				mulXNeg1: true,
   471  				alpha:    8,
   472  				beta:     -6,
   473  				ans:      []float64{290, 2, 6, 212.8, -4, -5, 310},
   474  			},
   475  			{
   476  				mulYNeg1: true,
   477  				alpha:    8,
   478  				beta:     -6,
   479  				ans:      []float64{240.4, 2, 6, 225.6, -4, -5, 372.4},
   480  			},
   481  			{
   482  				mulXNeg1: true,
   483  				mulYNeg1: true,
   484  				alpha:    8,
   485  				beta:     -6,
   486  				ans:      []float64{322, 2, 6, 212.8, -4, -5, 278},
   487  			},
   488  		},
   489  	},
   490  	{
   491  		Name: "M_lt_N_IncNot1_NoTrans",
   492  		tA:   blas.NoTrans,
   493  		m:    3,
   494  		n:    5,
   495  		A: [][]float64{
   496  			{4.1, 6.2, 8.1, 10, 11},
   497  			{9.6, 3.5, 9.1, -3, -2},
   498  			{10, 7, 3, -7, -4},
   499  		},
   500  		incX: 2,
   501  		incY: 3,
   502  		x:    []float64{1, 15, 2, 150, 3, -2, -4, 8, -9},
   503  		y:    []float64{7, 2, 6, 8, -4, -5, 9},
   504  
   505  		Subcases: []DgemvSubcase{
   506  			{
   507  				alpha: 8,
   508  				beta:  -6,
   509  				ans:   []float64{-827.6, 2, 6, 543.2, -4, -5, 722},
   510  			},
   511  			{
   512  				mulXNeg1: true,
   513  				alpha:    8,
   514  				beta:     -6,
   515  				ans:      []float64{-93.2, 2, 6, -696.8, -4, -5, -1070},
   516  			},
   517  			{
   518  				mulYNeg1: true,
   519  				alpha:    8,
   520  				beta:     -6,
   521  				ans:      []float64{734, 2, 6, 543.2, -4, -5, -839.6},
   522  			},
   523  			{
   524  				mulXNeg1: true,
   525  				mulYNeg1: true,
   526  				alpha:    8,
   527  				beta:     -6,
   528  				ans:      []float64{-1058, 2, 6, -696.8, -4, -5, -105.2},
   529  			},
   530  		},
   531  	},
   532  	{
   533  		Name: "M_lt_N_IncNot1_Trans",
   534  		tA:   blas.Trans,
   535  		m:    3,
   536  		n:    5,
   537  		A: [][]float64{
   538  			{4.1, 6.2, 8.1, 10, 11},
   539  			{9.6, 3.5, 9.1, -3, -2},
   540  			{10, 7, 3, -7, -4},
   541  		},
   542  		incX: 2,
   543  		incY: 3,
   544  		x:    []float64{1, 15, 2, 150, 3},
   545  		y:    []float64{7, 2, 6, 8, -4, -5, 9, -4, -1, -9, 1, 1, 2},
   546  
   547  		Subcases: []DgemvSubcase{
   548  			{
   549  				alpha: 8,
   550  				beta:  -6,
   551  				ans:   []float64{384.4, 2, 6, 225.6, -4, -5, 228.4, -4, -1, -82, 1, 1, -52},
   552  			},
   553  			{
   554  				mulXNeg1: true,
   555  				alpha:    8,
   556  				beta:     -6,
   557  				ans:      []float64{290, 2, 6, 212.8, -4, -5, 310, -4, -1, 190, 1, 1, 188},
   558  			},
   559  			{
   560  				mulYNeg1: true,
   561  				alpha:    8,
   562  				beta:     -6,
   563  				ans:      []float64{-82, 2, 6, -184, -4, -5, 228.4, -4, -1, 327.6, 1, 1, 414.4},
   564  			},
   565  			{
   566  				mulXNeg1: true,
   567  				mulYNeg1: true,
   568  				alpha:    8,
   569  				beta:     -6,
   570  				ans:      []float64{158, 2, 6, 88, -4, -5, 310, -4, -1, 314.8, 1, 1, 320},
   571  			},
   572  		},
   573  	},
   574  	{
   575  		Name: "M_eq_N_Lg_IncNot1_Trans",
   576  		tA:   blas.Trans,
   577  		m:    7,
   578  		n:    7,
   579  		A: [][]float64{
   580  			{4.1, 6.2, 8.1, 2.5, 3.3, 7.4, 9.3},
   581  			{9.6, 3.5, 9.1, 1.2, 5.4, 4.8, 8.7},
   582  			{10, 7, 3, 2, 4, 1, 12},
   583  			{9.6, 3.5, 9.1, 1.2, 5.4, 4.8, 8.7},
   584  			{4.1, 6.2, 8.1, 2.5, 3.3, 7.4, 9.3},
   585  			{10, 7, 3, 2, 4, 1, 12},
   586  			{9.6, 3.5, 9.1, 1.2, 5.4, 4.8, 8.7},
   587  		},
   588  		incX: 2,
   589  		incY: 3,
   590  		x:    []float64{1, 105, 2, 150, 3, 200, 4, 300, 5, 600, 6, 700, 7},
   591  		y:    []float64{7, 200, 600, 8, -400, -500, 9, 600, 700, 10, 500, 400, 11, 200, 300, 12, 100, 200, 13, 300, 400, 14},
   592  
   593  		Subcases: []DgemvSubcase{
   594  			{
   595  				alpha: 8,
   596  				beta:  -6,
   597  				ans:   []float64{1873.1999999999998, 200, 600, 1117.6, -400, -500, 1497.1999999999998, 600, 700, 328.8, 500, 400, 942, 200, 300, 854.4000000000001, 100, 200, 2137.2, 300, 400, 14},
   598  			},
   599  			{
   600  				mulXNeg1: true,
   601  				alpha:    8,
   602  				beta:     -6,
   603  				ans:      []float64{1690.8, 200, 600, 1148, -400, -500, 1562.8, 600, 700, 357.6, 500, 400, 897.2, 200, 300, 998.4, 100, 200, 2103.6000000000004, 300, 400, 14},
   604  			},
   605  			{
   606  				mulYNeg1: true,
   607  				alpha:    8,
   608  				beta:     -6,
   609  				ans:      []float64{2173.2, 200, 600, 878.4000000000001, -400, -500, 954, 600, 700, 328.8, 500, 400, 1485.1999999999998, 200, 300, 1093.6, 100, 200, 1837.1999999999998, 300, 400, 14},
   610  			},
   611  			{
   612  				mulXNeg1: true,
   613  				mulYNeg1: true,
   614  				alpha:    8,
   615  				beta:     -6,
   616  				ans:      []float64{2139.6, 200, 600, 1022.4, -400, -500, 909.2, 600, 700, 357.6, 500, 400, 1550.8, 200, 300, 1124, 100, 200, 1654.8, 300, 400, 14},
   617  			},
   618  		},
   619  	},
   620  
   621  	// TODO: A can be longer than mxn. Add cases where it is longer
   622  	// TODO: x and y can also be longer. Add tests for these
   623  	// TODO: Add tests for dimension mismatch
   624  	// TODO: Add places with a "submatrix view", where lda != m
   625  }
   626  
   627  type Dgemver interface {
   628  	Dgemv(tA blas.Transpose, m, n int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int)
   629  }
   630  
   631  func DgemvTest(t *testing.T, blasser Dgemver) {
   632  	for _, test := range DgemvCases {
   633  		for i, cas := range test.Subcases {
   634  			// Test that it passes with row-major
   635  			dgemvcomp(t, test, cas, i, blasser)
   636  
   637  			// Test the bad inputs
   638  			dgemvbad(t, test, cas, i, blasser)
   639  		}
   640  	}
   641  }
   642  
   643  func dgemvcomp(t *testing.T, test DgemvCase, cas DgemvSubcase, i int, blasser Dgemver) {
   644  	x := sliceCopy(test.x)
   645  	y := sliceCopy(test.y)
   646  	a := sliceOfSliceCopy(test.A)
   647  	aFlat := flatten(a)
   648  
   649  	lda := test.n
   650  
   651  	incX := test.incX
   652  	if cas.mulXNeg1 {
   653  		incX *= -1
   654  	}
   655  	incY := test.incY
   656  	if cas.mulYNeg1 {
   657  		incY *= -1
   658  	}
   659  
   660  	f := func() {
   661  		blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlat, lda, x, incX, cas.beta, y, incY)
   662  	}
   663  	if panics(f) {
   664  		t.Errorf("Test %v case %v: unexpected panic", test.Name, i)
   665  		if throwPanic {
   666  			blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlat, lda, x, incX, cas.beta, y, incY)
   667  		}
   668  		return
   669  	}
   670  	// Check that x and a are unchanged
   671  	if !dSliceEqual(x, test.x) {
   672  		t.Errorf("Test %v, case %v: x modified during call", test.Name, i)
   673  	}
   674  	aFlat2 := flatten(sliceOfSliceCopy(test.A))
   675  	if !dSliceEqual(aFlat2, aFlat) {
   676  		t.Errorf("Test %v, case %v: a modified during call", test.Name, i)
   677  	}
   678  
   679  	// Check that the answer matches
   680  	if !dSliceTolEqual(cas.ans, y) {
   681  		t.Errorf("Test %v, case %v: answer mismatch: Expected %v, Found %v", test.Name, i, cas.ans, y)
   682  	}
   683  }
   684  
   685  func dgemvbad(t *testing.T, test DgemvCase, cas DgemvSubcase, i int, blasser Dgemver) {
   686  	x := sliceCopy(test.x)
   687  	y := sliceCopy(test.y)
   688  	a := sliceOfSliceCopy(test.A)
   689  	aFlatRow := flatten(a)
   690  	ldaRow := test.n
   691  
   692  	f := func() {
   693  		blasser.Dgemv('X', test.m, test.n, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, test.incY)
   694  	}
   695  	if !panics(f) {
   696  		t.Errorf("Test %v case %v: no panic for bad transpose", test.Name, i)
   697  	}
   698  	f = func() {
   699  		blasser.Dgemv(test.tA, -2, test.n, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, test.incY)
   700  	}
   701  	if !panics(f) {
   702  		t.Errorf("Test %v case %v: no panic for m negative", test.Name, i)
   703  	}
   704  	f = func() {
   705  		blasser.Dgemv(test.tA, test.m, -4, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, test.incY)
   706  	}
   707  	if !panics(f) {
   708  		t.Errorf("Test %v case %v: no panic for n negative", test.Name, i)
   709  	}
   710  	f = func() {
   711  		blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlatRow, ldaRow, x, 0, cas.beta, y, test.incY)
   712  	}
   713  	if !panics(f) {
   714  		t.Errorf("Test %v case %v: no panic for incX zero", test.Name, i)
   715  	}
   716  	f = func() {
   717  		blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, 0)
   718  	}
   719  	if !panics(f) {
   720  		t.Errorf("Test %v case %v: no panic for incY zero", test.Name, i)
   721  	}
   722  	f = func() {
   723  		blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlatRow, ldaRow-1, x, test.incX, cas.beta, y, test.incY)
   724  	}
   725  	if !panics(f) {
   726  		t.Errorf("Test %v case %v: no panic for lda too small row major", test.Name, i)
   727  	}
   728  }