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 }