gonum.org/v1/gonum@v0.14.0/mat/vector_test.go (about)

     1  // Copyright ©2015 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 mat
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  
    11  	"golang.org/x/exp/rand"
    12  
    13  	"gonum.org/v1/gonum/blas/blas64"
    14  )
    15  
    16  func TestNewVecDense(t *testing.T) {
    17  	t.Parallel()
    18  	for i, test := range []struct {
    19  		n      int
    20  		data   []float64
    21  		vector *VecDense
    22  	}{
    23  		{
    24  			n:    3,
    25  			data: []float64{4, 5, 6},
    26  			vector: &VecDense{
    27  				mat: blas64.Vector{
    28  					N:    3,
    29  					Data: []float64{4, 5, 6},
    30  					Inc:  1,
    31  				},
    32  			},
    33  		},
    34  		{
    35  			n:    3,
    36  			data: nil,
    37  			vector: &VecDense{
    38  				mat: blas64.Vector{
    39  					N:    3,
    40  					Data: []float64{0, 0, 0},
    41  					Inc:  1,
    42  				},
    43  			},
    44  		},
    45  	} {
    46  		v := NewVecDense(test.n, test.data)
    47  		rows, cols := v.Dims()
    48  		if rows != test.n {
    49  			t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.n)
    50  		}
    51  		if cols != 1 {
    52  			t.Errorf("unexpected number of cols for test %d: got: %d want: 1", i, cols)
    53  		}
    54  		if !reflect.DeepEqual(v, test.vector) {
    55  			t.Errorf("unexpected data slice for test %d: got: %v want: %v", i, v, test.vector)
    56  		}
    57  	}
    58  }
    59  
    60  func TestCap(t *testing.T) {
    61  	t.Parallel()
    62  	for i, test := range []struct {
    63  		vector *VecDense
    64  		want   int
    65  	}{
    66  		{vector: NewVecDense(3, nil), want: 3},
    67  		{
    68  			vector: &VecDense{
    69  				mat: blas64.Vector{
    70  					N:    3,
    71  					Data: make([]float64, 7, 10),
    72  					Inc:  3,
    73  				},
    74  			},
    75  			want: 4,
    76  		},
    77  		{
    78  			vector: &VecDense{
    79  				mat: blas64.Vector{
    80  					N:    4,
    81  					Data: make([]float64, 10),
    82  					Inc:  3,
    83  				},
    84  			},
    85  			want: 4,
    86  		},
    87  		{
    88  			vector: &VecDense{
    89  				mat: blas64.Vector{
    90  					N:    4,
    91  					Data: make([]float64, 11),
    92  					Inc:  3,
    93  				},
    94  			},
    95  			want: 4,
    96  		},
    97  		{
    98  			vector: &VecDense{
    99  				mat: blas64.Vector{
   100  					N:    4,
   101  					Data: make([]float64, 12),
   102  					Inc:  3,
   103  				},
   104  			},
   105  			want: 4,
   106  		},
   107  		{
   108  			vector: &VecDense{
   109  				mat: blas64.Vector{
   110  					N:    4,
   111  					Data: make([]float64, 13),
   112  					Inc:  3,
   113  				},
   114  			},
   115  			want: 5,
   116  		},
   117  	} {
   118  		got := test.vector.Cap()
   119  		if got != test.want {
   120  			t.Errorf("unexpected capacty for test %d: got: %d want: %d", i, got, test.want)
   121  		}
   122  	}
   123  }
   124  
   125  func TestVecDenseAtSet(t *testing.T) {
   126  	t.Parallel()
   127  	for i, test := range []struct {
   128  		vector *VecDense
   129  	}{
   130  		{
   131  			vector: &VecDense{
   132  				mat: blas64.Vector{
   133  					N:    3,
   134  					Data: []float64{0, 1, 2},
   135  					Inc:  1,
   136  				},
   137  			},
   138  		},
   139  		{
   140  			vector: &VecDense{
   141  				mat: blas64.Vector{
   142  					N:    3,
   143  					Data: []float64{0, 10, 10, 1, 10, 10, 2},
   144  					Inc:  3,
   145  				},
   146  			},
   147  		},
   148  	} {
   149  		v := test.vector
   150  		n := test.vector.mat.N
   151  
   152  		for _, row := range []int{-1, n} {
   153  			panicked, message := panics(func() { v.At(row, 0) })
   154  			if !panicked || message != ErrRowAccess.Error() {
   155  				t.Errorf("expected panic for invalid row access for test %d n=%d r=%d", i, n, row)
   156  			}
   157  		}
   158  		for _, col := range []int{-1, 1} {
   159  			panicked, message := panics(func() { v.At(0, col) })
   160  			if !panicked || message != ErrColAccess.Error() {
   161  				t.Errorf("expected panic for invalid column access for test %d n=%d c=%d", i, n, col)
   162  			}
   163  		}
   164  
   165  		for _, row := range []int{0, 1, n - 1} {
   166  			if e := v.At(row, 0); e != float64(row) {
   167  				t.Errorf("unexpected value for At(%d, 0) for test %d : got: %v want: %v", row, i, e, float64(row))
   168  			}
   169  		}
   170  
   171  		for _, row := range []int{-1, n} {
   172  			panicked, message := panics(func() { v.SetVec(row, 100) })
   173  			if !panicked || message != ErrVectorAccess.Error() {
   174  				t.Errorf("expected panic for invalid row access for test %d n=%d r=%d", i, n, row)
   175  			}
   176  		}
   177  
   178  		for inc, row := range []int{0, 2} {
   179  			v.SetVec(row, 100+float64(inc))
   180  			if e := v.At(row, 0); e != 100+float64(inc) {
   181  				t.Errorf("unexpected value for At(%d, 0) after SetVec(%[1]d, %v) for test %d: got: %v want: %[2]v", row, 100+float64(inc), i, e)
   182  			}
   183  		}
   184  	}
   185  }
   186  
   187  func TestVecDenseZero(t *testing.T) {
   188  	t.Parallel()
   189  	// Elements that equal 1 should be set to zero, elements that equal -1
   190  	// should remain unchanged.
   191  	for _, test := range []*VecDense{
   192  		{
   193  			mat: blas64.Vector{
   194  				N:   5,
   195  				Inc: 2,
   196  				Data: []float64{
   197  					1, -1,
   198  					1, -1,
   199  					1, -1,
   200  					1, -1,
   201  					1,
   202  				},
   203  			},
   204  		},
   205  	} {
   206  		dataCopy := make([]float64, len(test.mat.Data))
   207  		copy(dataCopy, test.mat.Data)
   208  		test.Zero()
   209  		for i, v := range test.mat.Data {
   210  			if dataCopy[i] != -1 && v != 0 {
   211  				t.Errorf("Matrix not zeroed in bounds")
   212  			}
   213  			if dataCopy[i] == -1 && v != -1 {
   214  				t.Errorf("Matrix zeroed out of bounds")
   215  			}
   216  		}
   217  	}
   218  }
   219  
   220  func TestVecDenseMul(t *testing.T) {
   221  	t.Parallel()
   222  	method := func(receiver, a, b Matrix) {
   223  		type mulVecer interface {
   224  			MulVec(a Matrix, b Vector)
   225  		}
   226  		rd := receiver.(mulVecer)
   227  		rd.MulVec(a, b.(Vector))
   228  	}
   229  	denseComparison := func(receiver, a, b *Dense) {
   230  		receiver.Mul(a, b)
   231  	}
   232  	legalSizeMulVec := func(ar, ac, br, bc int) bool {
   233  		var legal bool
   234  		if bc != 1 {
   235  			legal = false
   236  		} else {
   237  			legal = ac == br
   238  		}
   239  		return legal
   240  	}
   241  	testTwoInput(t, "MulVec", &VecDense{}, method, denseComparison, legalTypesMatrixVector, legalSizeMulVec, 1e-14)
   242  }
   243  
   244  func TestVecDenseScale(t *testing.T) {
   245  	t.Parallel()
   246  	for i, test := range []struct {
   247  		a     Vector
   248  		alpha float64
   249  		want  *VecDense
   250  	}{
   251  		{
   252  			a:     NewVecDense(3, []float64{0, 1, 2}),
   253  			alpha: 0,
   254  			want:  NewVecDense(3, []float64{0, 0, 0}),
   255  		},
   256  		{
   257  			a:     NewVecDense(3, []float64{0, 1, 2}),
   258  			alpha: 1,
   259  			want:  NewVecDense(3, []float64{0, 1, 2}),
   260  		},
   261  		{
   262  			a:     NewVecDense(3, []float64{0, 1, 2}),
   263  			alpha: -2,
   264  			want:  NewVecDense(3, []float64{0, -2, -4}),
   265  		},
   266  		{
   267  			a:     NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   268  			alpha: 0,
   269  			want:  NewVecDense(3, []float64{0, 0, 0}),
   270  		},
   271  		{
   272  			a:     NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   273  			alpha: 1,
   274  			want:  NewVecDense(3, []float64{0, 1, 2}),
   275  		},
   276  		{
   277  			a:     NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   278  			alpha: -2,
   279  			want:  NewVecDense(3, []float64{0, -2, -4}),
   280  		},
   281  		{
   282  			a: NewDense(3, 3, []float64{
   283  				0, 1, 2,
   284  				3, 4, 5,
   285  				6, 7, 8,
   286  			}).ColView(1),
   287  			alpha: -2,
   288  			want:  NewVecDense(3, []float64{-2, -8, -14}),
   289  		},
   290  	} {
   291  		var v VecDense
   292  		v.ScaleVec(test.alpha, test.a.(*VecDense))
   293  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   294  			t.Errorf("test %d: unexpected result for v = alpha * a: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   295  		}
   296  
   297  		v.CopyVec(test.a.(*VecDense))
   298  		v.ScaleVec(test.alpha, &v)
   299  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   300  			t.Errorf("test %d: unexpected result for v = alpha * v: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   301  		}
   302  	}
   303  
   304  	for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} {
   305  		method := func(receiver, a Matrix) {
   306  			type scaleVecer interface {
   307  				ScaleVec(float64, Vector)
   308  			}
   309  			v := receiver.(scaleVecer)
   310  			v.ScaleVec(alpha, a.(Vector))
   311  		}
   312  		denseComparison := func(receiver, a *Dense) {
   313  			receiver.Scale(alpha, a)
   314  		}
   315  		testOneInput(t, "ScaleVec", &VecDense{}, method, denseComparison, legalTypeVector, isAnyColumnVector, 0)
   316  	}
   317  }
   318  
   319  func TestCopyVec(t *testing.T) {
   320  	t.Parallel()
   321  	for i, test := range []struct {
   322  		src   *VecDense
   323  		dst   *VecDense
   324  		want  *VecDense
   325  		wantN int
   326  	}{
   327  		{src: NewVecDense(1, nil), dst: NewVecDense(1, nil), want: NewVecDense(1, nil), wantN: 1},
   328  		{src: NewVecDense(3, []float64{1, 2, 3}), dst: NewVecDense(2, []float64{-1, -2}), want: NewVecDense(2, []float64{1, 2}), wantN: 2},
   329  		{src: NewVecDense(2, []float64{1, 2}), dst: NewVecDense(3, []float64{-1, -2, -3}), want: NewVecDense(3, []float64{1, 2, -3}), wantN: 2},
   330  	} {
   331  		got := test.dst
   332  		var n int
   333  		panicked, message := panics(func() { n = got.CopyVec(test.src) })
   334  		if panicked {
   335  			t.Errorf("unexpected panic during vector copy for test %d: %s", i, message)
   336  		}
   337  		if !Equal(got, test.want) {
   338  			t.Errorf("test %d: unexpected result CopyVec:\ngot: %v\nwant:%v", i, got, test.want)
   339  		}
   340  		if n != test.wantN {
   341  			t.Errorf("test %d: unexpected result number of elements copied: got:%d want:%d", i, n, test.wantN)
   342  		}
   343  	}
   344  }
   345  
   346  func TestVecDenseAddScaled(t *testing.T) {
   347  	t.Parallel()
   348  	for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} {
   349  		method := func(receiver, a, b Matrix) {
   350  			type addScaledVecer interface {
   351  				AddScaledVec(Vector, float64, Vector)
   352  			}
   353  			v := receiver.(addScaledVecer)
   354  			v.AddScaledVec(a.(Vector), alpha, b.(Vector))
   355  		}
   356  		denseComparison := func(receiver, a, b *Dense) {
   357  			var sb Dense
   358  			sb.Scale(alpha, b)
   359  			receiver.Add(a, &sb)
   360  		}
   361  		testTwoInput(t, "AddScaledVec", &VecDense{}, method, denseComparison, legalTypesVectorVector, legalSizeSameVec, 1e-14)
   362  	}
   363  }
   364  
   365  func TestVecDenseAdd(t *testing.T) {
   366  	t.Parallel()
   367  	for i, test := range []struct {
   368  		a, b Vector
   369  		want *VecDense
   370  	}{
   371  		{
   372  			a:    NewVecDense(3, []float64{0, 1, 2}),
   373  			b:    NewVecDense(3, []float64{0, 2, 3}),
   374  			want: NewVecDense(3, []float64{0, 3, 5}),
   375  		},
   376  		{
   377  			a:    NewVecDense(3, []float64{0, 1, 2}),
   378  			b:    NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
   379  			want: NewVecDense(3, []float64{0, 3, 5}),
   380  		},
   381  		{
   382  			a:    NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   383  			b:    NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
   384  			want: NewVecDense(3, []float64{0, 3, 5}),
   385  		},
   386  	} {
   387  		var v VecDense
   388  		v.AddVec(test.a.(*VecDense), test.b.(*VecDense))
   389  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   390  			t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   391  		}
   392  	}
   393  }
   394  
   395  func TestVecDenseSub(t *testing.T) {
   396  	t.Parallel()
   397  	for i, test := range []struct {
   398  		a, b Vector
   399  		want *VecDense
   400  	}{
   401  		{
   402  			a:    NewVecDense(3, []float64{0, 1, 2}),
   403  			b:    NewVecDense(3, []float64{0, 0.5, 1}),
   404  			want: NewVecDense(3, []float64{0, 0.5, 1}),
   405  		},
   406  		{
   407  			a:    NewVecDense(3, []float64{0, 1, 2}),
   408  			b:    NewDense(3, 1, []float64{0, 0.5, 1}).ColView(0),
   409  			want: NewVecDense(3, []float64{0, 0.5, 1}),
   410  		},
   411  		{
   412  			a:    NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   413  			b:    NewDense(3, 1, []float64{0, 0.5, 1}).ColView(0),
   414  			want: NewVecDense(3, []float64{0, 0.5, 1}),
   415  		},
   416  	} {
   417  		var v VecDense
   418  		v.SubVec(test.a.(*VecDense), test.b.(*VecDense))
   419  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   420  			t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   421  		}
   422  	}
   423  }
   424  
   425  func TestVecDenseMulElem(t *testing.T) {
   426  	t.Parallel()
   427  	for i, test := range []struct {
   428  		a, b Vector
   429  		want *VecDense
   430  	}{
   431  		{
   432  			a:    NewVecDense(3, []float64{0, 1, 2}),
   433  			b:    NewVecDense(3, []float64{0, 2, 3}),
   434  			want: NewVecDense(3, []float64{0, 2, 6}),
   435  		},
   436  		{
   437  			a:    NewVecDense(3, []float64{0, 1, 2}),
   438  			b:    NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
   439  			want: NewVecDense(3, []float64{0, 2, 6}),
   440  		},
   441  		{
   442  			a:    NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   443  			b:    NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
   444  			want: NewVecDense(3, []float64{0, 2, 6}),
   445  		},
   446  	} {
   447  		var v VecDense
   448  		v.MulElemVec(test.a.(*VecDense), test.b.(*VecDense))
   449  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   450  			t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   451  		}
   452  	}
   453  }
   454  
   455  func TestVecDenseDivElem(t *testing.T) {
   456  	t.Parallel()
   457  	for i, test := range []struct {
   458  		a, b Vector
   459  		want *VecDense
   460  	}{
   461  		{
   462  			a:    NewVecDense(3, []float64{0.5, 1, 2}),
   463  			b:    NewVecDense(3, []float64{0.5, 0.5, 1}),
   464  			want: NewVecDense(3, []float64{1, 2, 2}),
   465  		},
   466  		{
   467  			a:    NewVecDense(3, []float64{0.5, 1, 2}),
   468  			b:    NewDense(3, 1, []float64{0.5, 0.5, 1}).ColView(0),
   469  			want: NewVecDense(3, []float64{1, 2, 2}),
   470  		},
   471  		{
   472  			a:    NewDense(3, 1, []float64{0.5, 1, 2}).ColView(0),
   473  			b:    NewDense(3, 1, []float64{0.5, 0.5, 1}).ColView(0),
   474  			want: NewVecDense(3, []float64{1, 2, 2}),
   475  		},
   476  	} {
   477  		var v VecDense
   478  		v.DivElemVec(test.a.(*VecDense), test.b.(*VecDense))
   479  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   480  			t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   481  		}
   482  	}
   483  }
   484  
   485  func BenchmarkAddScaledVec10Inc1(b *testing.B)      { addScaledVecBench(b, 10, 1) }
   486  func BenchmarkAddScaledVec100Inc1(b *testing.B)     { addScaledVecBench(b, 100, 1) }
   487  func BenchmarkAddScaledVec1000Inc1(b *testing.B)    { addScaledVecBench(b, 1000, 1) }
   488  func BenchmarkAddScaledVec10000Inc1(b *testing.B)   { addScaledVecBench(b, 10000, 1) }
   489  func BenchmarkAddScaledVec100000Inc1(b *testing.B)  { addScaledVecBench(b, 100000, 1) }
   490  func BenchmarkAddScaledVec10Inc2(b *testing.B)      { addScaledVecBench(b, 10, 2) }
   491  func BenchmarkAddScaledVec100Inc2(b *testing.B)     { addScaledVecBench(b, 100, 2) }
   492  func BenchmarkAddScaledVec1000Inc2(b *testing.B)    { addScaledVecBench(b, 1000, 2) }
   493  func BenchmarkAddScaledVec10000Inc2(b *testing.B)   { addScaledVecBench(b, 10000, 2) }
   494  func BenchmarkAddScaledVec100000Inc2(b *testing.B)  { addScaledVecBench(b, 100000, 2) }
   495  func BenchmarkAddScaledVec10Inc20(b *testing.B)     { addScaledVecBench(b, 10, 20) }
   496  func BenchmarkAddScaledVec100Inc20(b *testing.B)    { addScaledVecBench(b, 100, 20) }
   497  func BenchmarkAddScaledVec1000Inc20(b *testing.B)   { addScaledVecBench(b, 1000, 20) }
   498  func BenchmarkAddScaledVec10000Inc20(b *testing.B)  { addScaledVecBench(b, 10000, 20) }
   499  func BenchmarkAddScaledVec100000Inc20(b *testing.B) { addScaledVecBench(b, 100000, 20) }
   500  func addScaledVecBench(b *testing.B, size, inc int) {
   501  	src := rand.NewSource(1)
   502  	x := randVecDense(size, inc, 1, src)
   503  	y := randVecDense(size, inc, 1, src)
   504  	b.ResetTimer()
   505  	var v VecDense
   506  	for i := 0; i < b.N; i++ {
   507  		v.AddScaledVec(y, 2, x)
   508  	}
   509  }
   510  
   511  func BenchmarkScaleVec10Inc1(b *testing.B)      { scaleVecBench(b, 10, 1) }
   512  func BenchmarkScaleVec100Inc1(b *testing.B)     { scaleVecBench(b, 100, 1) }
   513  func BenchmarkScaleVec1000Inc1(b *testing.B)    { scaleVecBench(b, 1000, 1) }
   514  func BenchmarkScaleVec10000Inc1(b *testing.B)   { scaleVecBench(b, 10000, 1) }
   515  func BenchmarkScaleVec100000Inc1(b *testing.B)  { scaleVecBench(b, 100000, 1) }
   516  func BenchmarkScaleVec10Inc2(b *testing.B)      { scaleVecBench(b, 10, 2) }
   517  func BenchmarkScaleVec100Inc2(b *testing.B)     { scaleVecBench(b, 100, 2) }
   518  func BenchmarkScaleVec1000Inc2(b *testing.B)    { scaleVecBench(b, 1000, 2) }
   519  func BenchmarkScaleVec10000Inc2(b *testing.B)   { scaleVecBench(b, 10000, 2) }
   520  func BenchmarkScaleVec100000Inc2(b *testing.B)  { scaleVecBench(b, 100000, 2) }
   521  func BenchmarkScaleVec10Inc20(b *testing.B)     { scaleVecBench(b, 10, 20) }
   522  func BenchmarkScaleVec100Inc20(b *testing.B)    { scaleVecBench(b, 100, 20) }
   523  func BenchmarkScaleVec1000Inc20(b *testing.B)   { scaleVecBench(b, 1000, 20) }
   524  func BenchmarkScaleVec10000Inc20(b *testing.B)  { scaleVecBench(b, 10000, 20) }
   525  func BenchmarkScaleVec100000Inc20(b *testing.B) { scaleVecBench(b, 100000, 20) }
   526  func scaleVecBench(b *testing.B, size, inc int) {
   527  	src := rand.NewSource(1)
   528  	x := randVecDense(size, inc, 1, src)
   529  	b.ResetTimer()
   530  	var v VecDense
   531  	for i := 0; i < b.N; i++ {
   532  		v.ScaleVec(2, x)
   533  	}
   534  }
   535  
   536  func BenchmarkAddVec10Inc1(b *testing.B)      { addVecBench(b, 10, 1) }
   537  func BenchmarkAddVec100Inc1(b *testing.B)     { addVecBench(b, 100, 1) }
   538  func BenchmarkAddVec1000Inc1(b *testing.B)    { addVecBench(b, 1000, 1) }
   539  func BenchmarkAddVec10000Inc1(b *testing.B)   { addVecBench(b, 10000, 1) }
   540  func BenchmarkAddVec100000Inc1(b *testing.B)  { addVecBench(b, 100000, 1) }
   541  func BenchmarkAddVec10Inc2(b *testing.B)      { addVecBench(b, 10, 2) }
   542  func BenchmarkAddVec100Inc2(b *testing.B)     { addVecBench(b, 100, 2) }
   543  func BenchmarkAddVec1000Inc2(b *testing.B)    { addVecBench(b, 1000, 2) }
   544  func BenchmarkAddVec10000Inc2(b *testing.B)   { addVecBench(b, 10000, 2) }
   545  func BenchmarkAddVec100000Inc2(b *testing.B)  { addVecBench(b, 100000, 2) }
   546  func BenchmarkAddVec10Inc20(b *testing.B)     { addVecBench(b, 10, 20) }
   547  func BenchmarkAddVec100Inc20(b *testing.B)    { addVecBench(b, 100, 20) }
   548  func BenchmarkAddVec1000Inc20(b *testing.B)   { addVecBench(b, 1000, 20) }
   549  func BenchmarkAddVec10000Inc20(b *testing.B)  { addVecBench(b, 10000, 20) }
   550  func BenchmarkAddVec100000Inc20(b *testing.B) { addVecBench(b, 100000, 20) }
   551  func addVecBench(b *testing.B, size, inc int) {
   552  	src := rand.NewSource(1)
   553  	x := randVecDense(size, inc, 1, src)
   554  	y := randVecDense(size, inc, 1, src)
   555  	b.ResetTimer()
   556  	var v VecDense
   557  	for i := 0; i < b.N; i++ {
   558  		v.AddVec(x, y)
   559  	}
   560  }
   561  
   562  func BenchmarkSubVec10Inc1(b *testing.B)      { subVecBench(b, 10, 1) }
   563  func BenchmarkSubVec100Inc1(b *testing.B)     { subVecBench(b, 100, 1) }
   564  func BenchmarkSubVec1000Inc1(b *testing.B)    { subVecBench(b, 1000, 1) }
   565  func BenchmarkSubVec10000Inc1(b *testing.B)   { subVecBench(b, 10000, 1) }
   566  func BenchmarkSubVec100000Inc1(b *testing.B)  { subVecBench(b, 100000, 1) }
   567  func BenchmarkSubVec10Inc2(b *testing.B)      { subVecBench(b, 10, 2) }
   568  func BenchmarkSubVec100Inc2(b *testing.B)     { subVecBench(b, 100, 2) }
   569  func BenchmarkSubVec1000Inc2(b *testing.B)    { subVecBench(b, 1000, 2) }
   570  func BenchmarkSubVec10000Inc2(b *testing.B)   { subVecBench(b, 10000, 2) }
   571  func BenchmarkSubVec100000Inc2(b *testing.B)  { subVecBench(b, 100000, 2) }
   572  func BenchmarkSubVec10Inc20(b *testing.B)     { subVecBench(b, 10, 20) }
   573  func BenchmarkSubVec100Inc20(b *testing.B)    { subVecBench(b, 100, 20) }
   574  func BenchmarkSubVec1000Inc20(b *testing.B)   { subVecBench(b, 1000, 20) }
   575  func BenchmarkSubVec10000Inc20(b *testing.B)  { subVecBench(b, 10000, 20) }
   576  func BenchmarkSubVec100000Inc20(b *testing.B) { subVecBench(b, 100000, 20) }
   577  func subVecBench(b *testing.B, size, inc int) {
   578  	src := rand.NewSource(1)
   579  	x := randVecDense(size, inc, 1, src)
   580  	y := randVecDense(size, inc, 1, src)
   581  	b.ResetTimer()
   582  	var v VecDense
   583  	for i := 0; i < b.N; i++ {
   584  		v.SubVec(x, y)
   585  	}
   586  }
   587  
   588  func randVecDense(size, inc int, rho float64, src rand.Source) *VecDense {
   589  	if size <= 0 {
   590  		panic("bad vector size")
   591  	}
   592  	rnd := rand.New(src)
   593  	data := make([]float64, size*inc)
   594  	for i := range data {
   595  		if rnd.Float64() < rho {
   596  			data[i] = rnd.NormFloat64()
   597  		}
   598  	}
   599  	return &VecDense{
   600  		mat: blas64.Vector{
   601  			N:    size,
   602  			Inc:  inc,
   603  			Data: data,
   604  		},
   605  	}
   606  }
   607  
   608  func BenchmarkVectorSum100000(b *testing.B) { vectorSumBench(b, 100000) }
   609  
   610  var vectorSumForBench float64
   611  
   612  func vectorSumBench(b *testing.B, size int) {
   613  	src := rand.NewSource(1)
   614  	a := randVecDense(size, 1, 1.0, src)
   615  	b.ResetTimer()
   616  	for i := 0; i < b.N; i++ {
   617  		vectorSumForBench = Sum(a)
   618  	}
   619  }