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