github.com/gonum/matrix@v0.0.0-20181209220409-c518dec07be9/mat64/vector_test.go (about)

     1  package mat64
     2  
     3  import (
     4  	"math/rand"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/gonum/blas/blas64"
     9  	"github.com/gonum/matrix"
    10  )
    11  
    12  func TestNewVector(t *testing.T) {
    13  	for i, test := range []struct {
    14  		n      int
    15  		data   []float64
    16  		vector *Vector
    17  	}{
    18  		{
    19  			n:    3,
    20  			data: []float64{4, 5, 6},
    21  			vector: &Vector{
    22  				mat: blas64.Vector{
    23  					Data: []float64{4, 5, 6},
    24  					Inc:  1,
    25  				},
    26  				n: 3,
    27  			},
    28  		},
    29  		{
    30  			n:    3,
    31  			data: nil,
    32  			vector: &Vector{
    33  				mat: blas64.Vector{
    34  					Data: []float64{0, 0, 0},
    35  					Inc:  1,
    36  				},
    37  				n: 3,
    38  			},
    39  		},
    40  	} {
    41  		v := NewVector(test.n, test.data)
    42  		rows, cols := v.Dims()
    43  		if rows != test.n {
    44  			t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.n)
    45  		}
    46  		if cols != 1 {
    47  			t.Errorf("unexpected number of cols for test %d: got: %d want: 1", i, cols)
    48  		}
    49  		if !reflect.DeepEqual(v, test.vector) {
    50  			t.Errorf("unexpected data slice for test %d: got: %v want: %v", i, v, test.vector)
    51  		}
    52  	}
    53  }
    54  
    55  func TestVectorAtSet(t *testing.T) {
    56  	for i, test := range []struct {
    57  		vector *Vector
    58  	}{
    59  		{
    60  			vector: &Vector{
    61  				mat: blas64.Vector{
    62  					Data: []float64{0, 1, 2},
    63  					Inc:  1,
    64  				},
    65  				n: 3,
    66  			},
    67  		},
    68  		{
    69  			vector: &Vector{
    70  				mat: blas64.Vector{
    71  					Data: []float64{0, 10, 10, 1, 10, 10, 2},
    72  					Inc:  3,
    73  				},
    74  				n: 3,
    75  			},
    76  		},
    77  	} {
    78  		v := test.vector
    79  		n := test.vector.n
    80  
    81  		for _, row := range []int{-1, n} {
    82  			panicked, message := panics(func() { v.At(row, 0) })
    83  			if !panicked || message != matrix.ErrRowAccess.Error() {
    84  				t.Errorf("expected panic for invalid row access for test %d n=%d r=%d", i, n, row)
    85  			}
    86  		}
    87  		for _, col := range []int{-1, 1} {
    88  			panicked, message := panics(func() { v.At(0, col) })
    89  			if !panicked || message != matrix.ErrColAccess.Error() {
    90  				t.Errorf("expected panic for invalid column access for test %d n=%d c=%d", i, n, col)
    91  			}
    92  		}
    93  
    94  		for _, row := range []int{0, 1, n - 1} {
    95  			if e := v.At(row, 0); e != float64(row) {
    96  				t.Errorf("unexpected value for At(%d, 0) for test %d : got: %v want: %v", row, i, e, float64(row))
    97  			}
    98  		}
    99  
   100  		for _, row := range []int{-1, n} {
   101  			panicked, message := panics(func() { v.SetVec(row, 100) })
   102  			if !panicked || message != matrix.ErrVectorAccess.Error() {
   103  				t.Errorf("expected panic for invalid row access for test %d n=%d r=%d", i, n, row)
   104  			}
   105  		}
   106  
   107  		for inc, row := range []int{0, 2} {
   108  			v.SetVec(row, 100+float64(inc))
   109  			if e := v.At(row, 0); e != 100+float64(inc) {
   110  				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)
   111  			}
   112  		}
   113  	}
   114  }
   115  
   116  func TestVectorMul(t *testing.T) {
   117  	method := func(receiver, a, b Matrix) {
   118  		type mulVecer interface {
   119  			MulVec(a Matrix, b *Vector)
   120  		}
   121  		rd := receiver.(mulVecer)
   122  		rd.MulVec(a, b.(*Vector))
   123  	}
   124  	denseComparison := func(receiver, a, b *Dense) {
   125  		receiver.Mul(a, b)
   126  	}
   127  	legalSizeMulVec := func(ar, ac, br, bc int) bool {
   128  		var legal bool
   129  		if bc != 1 {
   130  			legal = false
   131  		} else {
   132  			legal = ac == br
   133  		}
   134  		return legal
   135  	}
   136  	testTwoInput(t, "MulVec", &Vector{}, method, denseComparison, legalTypesNotVecVec, legalSizeMulVec, 1e-14)
   137  }
   138  
   139  func TestVectorScale(t *testing.T) {
   140  	for i, test := range []struct {
   141  		a     *Vector
   142  		alpha float64
   143  		want  *Vector
   144  	}{
   145  		{
   146  			a:     NewVector(3, []float64{0, 1, 2}),
   147  			alpha: 0,
   148  			want:  NewVector(3, []float64{0, 0, 0}),
   149  		},
   150  		{
   151  			a:     NewVector(3, []float64{0, 1, 2}),
   152  			alpha: 1,
   153  			want:  NewVector(3, []float64{0, 1, 2}),
   154  		},
   155  		{
   156  			a:     NewVector(3, []float64{0, 1, 2}),
   157  			alpha: -2,
   158  			want:  NewVector(3, []float64{0, -2, -4}),
   159  		},
   160  		{
   161  			a:     NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   162  			alpha: 0,
   163  			want:  NewVector(3, []float64{0, 0, 0}),
   164  		},
   165  		{
   166  			a:     NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   167  			alpha: 1,
   168  			want:  NewVector(3, []float64{0, 1, 2}),
   169  		},
   170  		{
   171  			a:     NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   172  			alpha: -2,
   173  			want:  NewVector(3, []float64{0, -2, -4}),
   174  		},
   175  		{
   176  			a: NewDense(3, 3, []float64{
   177  				0, 1, 2,
   178  				3, 4, 5,
   179  				6, 7, 8,
   180  			}).ColView(1),
   181  			alpha: -2,
   182  			want:  NewVector(3, []float64{-2, -8, -14}),
   183  		},
   184  	} {
   185  		var v Vector
   186  		v.ScaleVec(test.alpha, test.a)
   187  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   188  			t.Errorf("test %d: unexpected result for v = alpha * a: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   189  		}
   190  
   191  		v.CopyVec(test.a)
   192  		v.ScaleVec(test.alpha, &v)
   193  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   194  			t.Errorf("test %d: unexpected result for v = alpha * v: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   195  		}
   196  	}
   197  
   198  	for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} {
   199  		method := func(receiver, a Matrix) {
   200  			type scaleVecer interface {
   201  				ScaleVec(float64, *Vector)
   202  			}
   203  			v := receiver.(scaleVecer)
   204  			v.ScaleVec(alpha, a.(*Vector))
   205  		}
   206  		denseComparison := func(receiver, a *Dense) {
   207  			receiver.Scale(alpha, a)
   208  		}
   209  		testOneInput(t, "ScaleVec", &Vector{}, method, denseComparison, legalTypeVec, isAnyVector, 0)
   210  	}
   211  }
   212  
   213  func TestVectorAddScaled(t *testing.T) {
   214  	for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} {
   215  		method := func(receiver, a, b Matrix) {
   216  			type addScaledVecer interface {
   217  				AddScaledVec(*Vector, float64, *Vector)
   218  			}
   219  			v := receiver.(addScaledVecer)
   220  			v.AddScaledVec(a.(*Vector), alpha, b.(*Vector))
   221  		}
   222  		denseComparison := func(receiver, a, b *Dense) {
   223  			var sb Dense
   224  			sb.Scale(alpha, b)
   225  			receiver.Add(a, &sb)
   226  		}
   227  		testTwoInput(t, "AddScaledVec", &Vector{}, method, denseComparison, legalTypesVecVec, legalSizeSameVec, 1e-14)
   228  	}
   229  }
   230  
   231  func TestVectorAdd(t *testing.T) {
   232  	for i, test := range []struct {
   233  		a, b *Vector
   234  		want *Vector
   235  	}{
   236  		{
   237  			a:    NewVector(3, []float64{0, 1, 2}),
   238  			b:    NewVector(3, []float64{0, 2, 3}),
   239  			want: NewVector(3, []float64{0, 3, 5}),
   240  		},
   241  		{
   242  			a:    NewVector(3, []float64{0, 1, 2}),
   243  			b:    NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
   244  			want: NewVector(3, []float64{0, 3, 5}),
   245  		},
   246  		{
   247  			a:    NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   248  			b:    NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
   249  			want: NewVector(3, []float64{0, 3, 5}),
   250  		},
   251  	} {
   252  		var v Vector
   253  		v.AddVec(test.a, test.b)
   254  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   255  			t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   256  		}
   257  	}
   258  }
   259  
   260  func TestVectorSub(t *testing.T) {
   261  	for i, test := range []struct {
   262  		a, b *Vector
   263  		want *Vector
   264  	}{
   265  		{
   266  			a:    NewVector(3, []float64{0, 1, 2}),
   267  			b:    NewVector(3, []float64{0, 0.5, 1}),
   268  			want: NewVector(3, []float64{0, 0.5, 1}),
   269  		},
   270  		{
   271  			a:    NewVector(3, []float64{0, 1, 2}),
   272  			b:    NewDense(3, 1, []float64{0, 0.5, 1}).ColView(0),
   273  			want: NewVector(3, []float64{0, 0.5, 1}),
   274  		},
   275  		{
   276  			a:    NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   277  			b:    NewDense(3, 1, []float64{0, 0.5, 1}).ColView(0),
   278  			want: NewVector(3, []float64{0, 0.5, 1}),
   279  		},
   280  	} {
   281  		var v Vector
   282  		v.SubVec(test.a, test.b)
   283  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   284  			t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   285  		}
   286  	}
   287  }
   288  
   289  func TestVectorMulElem(t *testing.T) {
   290  	for i, test := range []struct {
   291  		a, b *Vector
   292  		want *Vector
   293  	}{
   294  		{
   295  			a:    NewVector(3, []float64{0, 1, 2}),
   296  			b:    NewVector(3, []float64{0, 2, 3}),
   297  			want: NewVector(3, []float64{0, 2, 6}),
   298  		},
   299  		{
   300  			a:    NewVector(3, []float64{0, 1, 2}),
   301  			b:    NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
   302  			want: NewVector(3, []float64{0, 2, 6}),
   303  		},
   304  		{
   305  			a:    NewDense(3, 1, []float64{0, 1, 2}).ColView(0),
   306  			b:    NewDense(3, 1, []float64{0, 2, 3}).ColView(0),
   307  			want: NewVector(3, []float64{0, 2, 6}),
   308  		},
   309  	} {
   310  		var v Vector
   311  		v.MulElemVec(test.a, test.b)
   312  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   313  			t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   314  		}
   315  	}
   316  }
   317  
   318  func TestVectorDivElem(t *testing.T) {
   319  	for i, test := range []struct {
   320  		a, b *Vector
   321  		want *Vector
   322  	}{
   323  		{
   324  			a:    NewVector(3, []float64{0.5, 1, 2}),
   325  			b:    NewVector(3, []float64{0.5, 0.5, 1}),
   326  			want: NewVector(3, []float64{1, 2, 2}),
   327  		},
   328  		{
   329  			a:    NewVector(3, []float64{0.5, 1, 2}),
   330  			b:    NewDense(3, 1, []float64{0.5, 0.5, 1}).ColView(0),
   331  			want: NewVector(3, []float64{1, 2, 2}),
   332  		},
   333  		{
   334  			a:    NewDense(3, 1, []float64{0.5, 1, 2}).ColView(0),
   335  			b:    NewDense(3, 1, []float64{0.5, 0.5, 1}).ColView(0),
   336  			want: NewVector(3, []float64{1, 2, 2}),
   337  		},
   338  	} {
   339  		var v Vector
   340  		v.DivElemVec(test.a, test.b)
   341  		if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) {
   342  			t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector())
   343  		}
   344  	}
   345  }
   346  
   347  func BenchmarkAddScaledVec10Inc1(b *testing.B)      { addScaledVecBench(b, 10, 1) }
   348  func BenchmarkAddScaledVec100Inc1(b *testing.B)     { addScaledVecBench(b, 100, 1) }
   349  func BenchmarkAddScaledVec1000Inc1(b *testing.B)    { addScaledVecBench(b, 1000, 1) }
   350  func BenchmarkAddScaledVec10000Inc1(b *testing.B)   { addScaledVecBench(b, 10000, 1) }
   351  func BenchmarkAddScaledVec100000Inc1(b *testing.B)  { addScaledVecBench(b, 100000, 1) }
   352  func BenchmarkAddScaledVec10Inc2(b *testing.B)      { addScaledVecBench(b, 10, 2) }
   353  func BenchmarkAddScaledVec100Inc2(b *testing.B)     { addScaledVecBench(b, 100, 2) }
   354  func BenchmarkAddScaledVec1000Inc2(b *testing.B)    { addScaledVecBench(b, 1000, 2) }
   355  func BenchmarkAddScaledVec10000Inc2(b *testing.B)   { addScaledVecBench(b, 10000, 2) }
   356  func BenchmarkAddScaledVec100000Inc2(b *testing.B)  { addScaledVecBench(b, 100000, 2) }
   357  func BenchmarkAddScaledVec10Inc20(b *testing.B)     { addScaledVecBench(b, 10, 20) }
   358  func BenchmarkAddScaledVec100Inc20(b *testing.B)    { addScaledVecBench(b, 100, 20) }
   359  func BenchmarkAddScaledVec1000Inc20(b *testing.B)   { addScaledVecBench(b, 1000, 20) }
   360  func BenchmarkAddScaledVec10000Inc20(b *testing.B)  { addScaledVecBench(b, 10000, 20) }
   361  func BenchmarkAddScaledVec100000Inc20(b *testing.B) { addScaledVecBench(b, 100000, 20) }
   362  func addScaledVecBench(b *testing.B, size, inc int) {
   363  	x := randVector(size, inc, 1, rand.NormFloat64)
   364  	y := randVector(size, inc, 1, rand.NormFloat64)
   365  	b.ResetTimer()
   366  	var v Vector
   367  	for i := 0; i < b.N; i++ {
   368  		v.AddScaledVec(y, 2, x)
   369  	}
   370  }
   371  
   372  func BenchmarkScaleVec10Inc1(b *testing.B)      { scaleVecBench(b, 10, 1) }
   373  func BenchmarkScaleVec100Inc1(b *testing.B)     { scaleVecBench(b, 100, 1) }
   374  func BenchmarkScaleVec1000Inc1(b *testing.B)    { scaleVecBench(b, 1000, 1) }
   375  func BenchmarkScaleVec10000Inc1(b *testing.B)   { scaleVecBench(b, 10000, 1) }
   376  func BenchmarkScaleVec100000Inc1(b *testing.B)  { scaleVecBench(b, 100000, 1) }
   377  func BenchmarkScaleVec10Inc2(b *testing.B)      { scaleVecBench(b, 10, 2) }
   378  func BenchmarkScaleVec100Inc2(b *testing.B)     { scaleVecBench(b, 100, 2) }
   379  func BenchmarkScaleVec1000Inc2(b *testing.B)    { scaleVecBench(b, 1000, 2) }
   380  func BenchmarkScaleVec10000Inc2(b *testing.B)   { scaleVecBench(b, 10000, 2) }
   381  func BenchmarkScaleVec100000Inc2(b *testing.B)  { scaleVecBench(b, 100000, 2) }
   382  func BenchmarkScaleVec10Inc20(b *testing.B)     { scaleVecBench(b, 10, 20) }
   383  func BenchmarkScaleVec100Inc20(b *testing.B)    { scaleVecBench(b, 100, 20) }
   384  func BenchmarkScaleVec1000Inc20(b *testing.B)   { scaleVecBench(b, 1000, 20) }
   385  func BenchmarkScaleVec10000Inc20(b *testing.B)  { scaleVecBench(b, 10000, 20) }
   386  func BenchmarkScaleVec100000Inc20(b *testing.B) { scaleVecBench(b, 100000, 20) }
   387  func scaleVecBench(b *testing.B, size, inc int) {
   388  	x := randVector(size, inc, 1, rand.NormFloat64)
   389  	b.ResetTimer()
   390  	var v Vector
   391  	for i := 0; i < b.N; i++ {
   392  		v.ScaleVec(2, x)
   393  	}
   394  }
   395  
   396  func BenchmarkAddVec10Inc1(b *testing.B)      { addVecBench(b, 10, 1) }
   397  func BenchmarkAddVec100Inc1(b *testing.B)     { addVecBench(b, 100, 1) }
   398  func BenchmarkAddVec1000Inc1(b *testing.B)    { addVecBench(b, 1000, 1) }
   399  func BenchmarkAddVec10000Inc1(b *testing.B)   { addVecBench(b, 10000, 1) }
   400  func BenchmarkAddVec100000Inc1(b *testing.B)  { addVecBench(b, 100000, 1) }
   401  func BenchmarkAddVec10Inc2(b *testing.B)      { addVecBench(b, 10, 2) }
   402  func BenchmarkAddVec100Inc2(b *testing.B)     { addVecBench(b, 100, 2) }
   403  func BenchmarkAddVec1000Inc2(b *testing.B)    { addVecBench(b, 1000, 2) }
   404  func BenchmarkAddVec10000Inc2(b *testing.B)   { addVecBench(b, 10000, 2) }
   405  func BenchmarkAddVec100000Inc2(b *testing.B)  { addVecBench(b, 100000, 2) }
   406  func BenchmarkAddVec10Inc20(b *testing.B)     { addVecBench(b, 10, 20) }
   407  func BenchmarkAddVec100Inc20(b *testing.B)    { addVecBench(b, 100, 20) }
   408  func BenchmarkAddVec1000Inc20(b *testing.B)   { addVecBench(b, 1000, 20) }
   409  func BenchmarkAddVec10000Inc20(b *testing.B)  { addVecBench(b, 10000, 20) }
   410  func BenchmarkAddVec100000Inc20(b *testing.B) { addVecBench(b, 100000, 20) }
   411  func addVecBench(b *testing.B, size, inc int) {
   412  	x := randVector(size, inc, 1, rand.NormFloat64)
   413  	y := randVector(size, inc, 1, rand.NormFloat64)
   414  	b.ResetTimer()
   415  	var v Vector
   416  	for i := 0; i < b.N; i++ {
   417  		v.AddVec(x, y)
   418  	}
   419  }
   420  
   421  func BenchmarkSubVec10Inc1(b *testing.B)      { subVecBench(b, 10, 1) }
   422  func BenchmarkSubVec100Inc1(b *testing.B)     { subVecBench(b, 100, 1) }
   423  func BenchmarkSubVec1000Inc1(b *testing.B)    { subVecBench(b, 1000, 1) }
   424  func BenchmarkSubVec10000Inc1(b *testing.B)   { subVecBench(b, 10000, 1) }
   425  func BenchmarkSubVec100000Inc1(b *testing.B)  { subVecBench(b, 100000, 1) }
   426  func BenchmarkSubVec10Inc2(b *testing.B)      { subVecBench(b, 10, 2) }
   427  func BenchmarkSubVec100Inc2(b *testing.B)     { subVecBench(b, 100, 2) }
   428  func BenchmarkSubVec1000Inc2(b *testing.B)    { subVecBench(b, 1000, 2) }
   429  func BenchmarkSubVec10000Inc2(b *testing.B)   { subVecBench(b, 10000, 2) }
   430  func BenchmarkSubVec100000Inc2(b *testing.B)  { subVecBench(b, 100000, 2) }
   431  func BenchmarkSubVec10Inc20(b *testing.B)     { subVecBench(b, 10, 20) }
   432  func BenchmarkSubVec100Inc20(b *testing.B)    { subVecBench(b, 100, 20) }
   433  func BenchmarkSubVec1000Inc20(b *testing.B)   { subVecBench(b, 1000, 20) }
   434  func BenchmarkSubVec10000Inc20(b *testing.B)  { subVecBench(b, 10000, 20) }
   435  func BenchmarkSubVec100000Inc20(b *testing.B) { subVecBench(b, 100000, 20) }
   436  func subVecBench(b *testing.B, size, inc int) {
   437  	x := randVector(size, inc, 1, rand.NormFloat64)
   438  	y := randVector(size, inc, 1, rand.NormFloat64)
   439  	b.ResetTimer()
   440  	var v Vector
   441  	for i := 0; i < b.N; i++ {
   442  		v.SubVec(x, y)
   443  	}
   444  }
   445  
   446  func randVector(size, inc int, rho float64, rnd func() float64) *Vector {
   447  	if size <= 0 {
   448  		panic("bad vector size")
   449  	}
   450  	data := make([]float64, size*inc)
   451  	for i := range data {
   452  		if rand.Float64() < rho {
   453  			data[i] = rnd()
   454  		}
   455  	}
   456  	return &Vector{
   457  		mat: blas64.Vector{
   458  			Inc:  inc,
   459  			Data: data,
   460  		},
   461  		n: size,
   462  	}
   463  }