gonum.org/v1/gonum@v0.14.0/blas/testblas/dger.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  	"math"
     9  	"testing"
    10  )
    11  
    12  type Dgerer interface {
    13  	Dger(m, n int, alpha float64, x []float64, incX int, y []float64, incY int, a []float64, lda int)
    14  }
    15  
    16  func DgerTest(t *testing.T, blasser Dgerer) {
    17  	for _, test := range []struct {
    18  		name string
    19  		a    [][]float64
    20  		m    int
    21  		n    int
    22  		x    []float64
    23  		y    []float64
    24  		incX int
    25  		incY int
    26  
    27  		want [][]float64
    28  	}{
    29  		{
    30  			name: "M gt N inc 1",
    31  			m:    5,
    32  			n:    3,
    33  			a: [][]float64{
    34  				{1.3, 2.4, 3.5},
    35  				{2.6, 2.8, 3.3},
    36  				{-1.3, -4.3, -9.7},
    37  				{8, 9, -10},
    38  				{-12, -14, -6},
    39  			},
    40  			x:    []float64{-2, -3, 0, 1, 2},
    41  			y:    []float64{-1.1, 5, 0},
    42  			incX: 1,
    43  			incY: 1,
    44  			want: [][]float64{{3.5, -7.6, 3.5}, {5.9, -12.2, 3.3}, {-1.3, -4.3, -9.7}, {6.9, 14, -10}, {-14.2, -4, -6}},
    45  		},
    46  		{
    47  			name: "M eq N inc 1",
    48  			m:    3,
    49  			n:    3,
    50  			a: [][]float64{
    51  				{1.3, 2.4, 3.5},
    52  				{2.6, 2.8, 3.3},
    53  				{-1.3, -4.3, -9.7},
    54  			},
    55  			x:    []float64{-2, -3, 0},
    56  			y:    []float64{-1.1, 5, 0},
    57  			incX: 1,
    58  			incY: 1,
    59  			want: [][]float64{{3.5, -7.6, 3.5}, {5.9, -12.2, 3.3}, {-1.3, -4.3, -9.7}},
    60  		},
    61  
    62  		{
    63  			name: "M lt N inc 1",
    64  			m:    3,
    65  			n:    6,
    66  			a: [][]float64{
    67  				{1.3, 2.4, 3.5, 4.8, 1.11, -9},
    68  				{2.6, 2.8, 3.3, -3.4, 6.2, -8.7},
    69  				{-1.3, -4.3, -9.7, -3.1, 8.9, 8.9},
    70  			},
    71  			x:    []float64{-2, -3, 0},
    72  			y:    []float64{-1.1, 5, 0, 9, 19, 22},
    73  			incX: 1,
    74  			incY: 1,
    75  			want: [][]float64{{3.5, -7.6, 3.5, -13.2, -36.89, -53}, {5.9, -12.2, 3.3, -30.4, -50.8, -74.7}, {-1.3, -4.3, -9.7, -3.1, 8.9, 8.9}},
    76  		},
    77  		{
    78  			name: "M gt N inc not 1",
    79  			m:    5,
    80  			n:    3,
    81  			a: [][]float64{
    82  				{1.3, 2.4, 3.5},
    83  				{2.6, 2.8, 3.3},
    84  				{-1.3, -4.3, -9.7},
    85  				{8, 9, -10},
    86  				{-12, -14, -6},
    87  			},
    88  			x:    []float64{-2, -3, 0, 1, 2, 6, 0, 9, 7},
    89  			y:    []float64{-1.1, 5, 0, 8, 7, -5, 7},
    90  			incX: 2,
    91  			incY: 3,
    92  			want: [][]float64{{3.5, -13.6, -10.5}, {2.6, 2.8, 3.3}, {-3.5, 11.7, 4.3}, {8, 9, -10}, {-19.700000000000003, 42, 43}},
    93  		},
    94  		{
    95  			name: "M eq N inc not 1",
    96  			m:    3,
    97  			n:    3,
    98  			a: [][]float64{
    99  				{1.3, 2.4, 3.5},
   100  				{2.6, 2.8, 3.3},
   101  				{-1.3, -4.3, -9.7},
   102  			},
   103  			x:    []float64{-2, -3, 0, 8, 7, -9, 7, -6, 12, 6, 6, 6, -11},
   104  			y:    []float64{-1.1, 5, 0, 0, 9, 8, 6},
   105  			incX: 4,
   106  			incY: 3,
   107  			want: [][]float64{{3.5, 2.4, -8.5}, {-5.1, 2.8, 45.3}, {-14.5, -4.3, 62.3}},
   108  		},
   109  		{
   110  			name: "M lt N inc not 1",
   111  			m:    3,
   112  			n:    6,
   113  			a: [][]float64{
   114  				{1.3, 2.4, 3.5, 4.8, 1.11, -9},
   115  				{2.6, 2.8, 3.3, -3.4, 6.2, -8.7},
   116  				{-1.3, -4.3, -9.7, -3.1, 8.9, 8.9},
   117  			},
   118  			x:    []float64{-2, -3, 0, 0, 8, 0, 9, -3},
   119  			y:    []float64{-1.1, 5, 0, 9, 19, 22, 11, -8.11, -9.22, 9.87, 7},
   120  			incX: 3,
   121  			incY: 2,
   122  			want: [][]float64{{3.5, 2.4, -34.5, -17.2, 19.55, -23}, {2.6, 2.8, 3.3, -3.4, 6.2, -8.7}, {-11.2, -4.3, 161.3, 95.9, -74.08, 71.9}},
   123  		},
   124  		{
   125  			name: "Y NaN element",
   126  			m:    1,
   127  			n:    1,
   128  			a:    [][]float64{{1.3}},
   129  			x:    []float64{1.3},
   130  			y:    []float64{math.NaN()},
   131  			incX: 1,
   132  			incY: 1,
   133  			want: [][]float64{{math.NaN()}},
   134  		},
   135  		{
   136  			name: "M eq N large inc 1",
   137  			m:    7,
   138  			n:    7,
   139  			x:    []float64{6.2, -5, 88.68, 43.4, -30.5, -40.2, 19.9},
   140  			y:    []float64{1.5, 21.7, -28.7, -11.9, 18.1, 3.1, 21},
   141  			a: [][]float64{
   142  				{-20.5, 17.1, -8.4, -23.8, 3.9, 7.7, 6.25},
   143  				{2.9, -0.29, 25.6, -9.4, 36.5, 9.7, 2.3},
   144  				{4.1, -34.1, 10.3, 4.5, -42.05, 9.4, 4},
   145  				{19.2, 9.8, -32.7, 4.1, 4.4, -22.5, -7.8},
   146  				{3.6, -24.5, 21.7, 8.6, -13.82, 38.05, -2.29},
   147  				{39.4, -40.5, 7.9, -2.5, -7.7, 18.1, -25.5},
   148  				{-18.5, 43.2, 2.1, 30.1, 3.02, -31.1, -7.6},
   149  			},
   150  			incX: 1,
   151  			incY: 1,
   152  			want: [][]float64{
   153  				{-11.2, 151.64, -186.34, -97.58, 116.12, 26.92, 136.45},
   154  				{-4.6, -108.79, 169.1, 50.1, -54, -5.8, -102.7},
   155  				{137.12, 1890.256, -2534.816, -1050.792, 1563.058, 284.308, 1866.28},
   156  				{84.3, 951.58, -1278.28, -512.36, 789.94, 112.04, 903.6},
   157  				{-42.15, -686.35, 897.05, 371.55, -565.87, -56.5, -642.79},
   158  				{-20.9, -912.84, 1161.64, 475.88, -735.32, -106.52, -869.7},
   159  				{11.35, 475.03, -569.03, -206.71, 363.21, 30.59, 410.3},
   160  			},
   161  		},
   162  		{
   163  			name: "M eq N large inc not 1",
   164  			m:    7,
   165  			n:    7,
   166  			x:    []float64{6.2, 100, 200, -5, 300, 400, 88.68, 100, 200, 43.4, 300, 400, -30.5, 100, 200, -40.2, 300, 400, 19.9},
   167  			y:    []float64{1.5, 100, 200, 300, 21.7, 100, 200, 300, -28.7, 100, 200, 300, -11.9, 100, 200, 300, 18.1, 100, 200, 300, 3.1, 100, 200, 300, 21},
   168  			a: [][]float64{
   169  				{-20.5, 17.1, -8.4, -23.8, 3.9, 7.7, 6.25},
   170  				{2.9, -0.29, 25.6, -9.4, 36.5, 9.7, 2.3},
   171  				{4.1, -34.1, 10.3, 4.5, -42.05, 9.4, 4},
   172  				{19.2, 9.8, -32.7, 4.1, 4.4, -22.5, -7.8},
   173  				{3.6, -24.5, 21.7, 8.6, -13.82, 38.05, -2.29},
   174  				{39.4, -40.5, 7.9, -2.5, -7.7, 18.1, -25.5},
   175  				{-18.5, 43.2, 2.1, 30.1, 3.02, -31.1, -7.6},
   176  			},
   177  			incX: 3,
   178  			incY: 4,
   179  			want: [][]float64{
   180  				{-11.2, 151.64, -186.34, -97.58, 116.12, 26.92, 136.45},
   181  				{-4.6, -108.79, 169.1, 50.1, -54, -5.8, -102.7},
   182  				{137.12, 1890.256, -2534.816, -1050.792, 1563.058, 284.308, 1866.28},
   183  				{84.3, 951.58, -1278.28, -512.36, 789.94, 112.04, 903.6},
   184  				{-42.15, -686.35, 897.05, 371.55, -565.87, -56.5, -642.79},
   185  				{-20.9, -912.84, 1161.64, 475.88, -735.32, -106.52, -869.7},
   186  				{11.35, 475.03, -569.03, -206.71, 363.21, 30.59, 410.3},
   187  			},
   188  		},
   189  	} {
   190  		// TODO: Add tests where a is longer
   191  		// TODO: Add panic tests
   192  		// TODO: Add negative increment tests
   193  
   194  		x := sliceCopy(test.x)
   195  		y := sliceCopy(test.y)
   196  
   197  		a := sliceOfSliceCopy(test.a)
   198  
   199  		// Test with row major
   200  		alpha := 1.0
   201  		aFlat := flatten(a)
   202  		blasser.Dger(test.m, test.n, alpha, x, test.incX, y, test.incY, aFlat, test.n)
   203  		ans := unflatten(aFlat, test.m, test.n)
   204  		dgercomp(t, x, test.x, y, test.y, ans, test.want, test.name+" row maj")
   205  
   206  		// Test with different alpha
   207  		alpha = 4.0
   208  		aFlat = flatten(a)
   209  		blasser.Dger(test.m, test.n, alpha, x, test.incX, y, test.incY, aFlat, test.n)
   210  		ans = unflatten(aFlat, test.m, test.n)
   211  		trueCopy := sliceOfSliceCopy(test.want)
   212  		for i := range trueCopy {
   213  			for j := range trueCopy[i] {
   214  				trueCopy[i][j] = alpha*(trueCopy[i][j]-a[i][j]) + a[i][j]
   215  			}
   216  		}
   217  		dgercomp(t, x, test.x, y, test.y, ans, trueCopy, test.name+" row maj alpha")
   218  	}
   219  }
   220  
   221  func dgercomp(t *testing.T, x, xCopy, y, yCopy []float64, ans [][]float64, trueAns [][]float64, name string) {
   222  	if !dSliceEqual(x, xCopy) {
   223  		t.Errorf("case %v: x modified during call to dger\n%v\n%v", name, x, xCopy)
   224  	}
   225  	if !dSliceEqual(y, yCopy) {
   226  		t.Errorf("case %v: y modified during call to dger\n%v\n%v", name, y, yCopy)
   227  	}
   228  
   229  	for i := range ans {
   230  		if !dSliceTolEqual(ans[i], trueAns[i]) {
   231  			t.Errorf("case %v: answer mismatch at %v.\nExpected %v,\nFound %v", name, i, trueAns, ans)
   232  			break
   233  		}
   234  	}
   235  }