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.
15 "gonum.org/v1/gonum/blas/blas64"
19 _ encoding.BinaryMarshaler = (*Dense)(nil)
20 _ encoding.BinaryUnmarshaler = (*Dense)(nil)
21 _ encoding.BinaryMarshaler = (*VecDense)(nil)
22 _ encoding.BinaryUnmarshaler = (*VecDense)(nil)
25 var denseData = []struct {
28 eq func(got, want Matrix) bool
31 raw: []byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
32 want: NewDense(0, 0, []float64{}),
36 raw: []byte("\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@"),
37 want: NewDense(2, 2, []float64{1, 2, 3, 4}),
41 raw: []byte("\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@"),
42 want: NewDense(2, 3, []float64{1, 2, 3, 4, 5, 6}),
46 raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@"),
47 want: NewDense(3, 2, []float64{1, 2, 3, 4, 5, 6}),
51 raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00\"@"),
52 want: NewDense(3, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}),
56 raw: []byte("\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@"),
57 want: NewDense(3, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).Slice(0, 2, 0, 2).(*Dense),
61 raw: []byte("\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00\"@"),
62 want: NewDense(3, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).Slice(1, 3, 1, 3).(*Dense),
66 raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00\"@"),
67 want: NewDense(3, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).Slice(0, 3, 1, 3).(*Dense),
71 raw: []byte("\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\x00\x00\x00\x00\x00\x00\xf0\u007f\x01\x00\x00\x00\x00\x00\xf8\u007f"),
72 want: NewDense(1, 4, []float64{0, math.Inf(-1), math.Inf(+1), math.NaN()}),
73 eq: func(got, want Matrix) bool {
74 for _, v := range []bool{
76 math.IsInf(got.At(0, 1), -1),
77 math.IsInf(got.At(0, 2), +1),
78 math.IsNaN(got.At(0, 3)),
89 func TestDenseMarshal(t *testing.T) {
90 for i, test := range denseData {
91 buf, err := test.want.MarshalBinary()
93 t.Errorf("error encoding test-%d: %v\n", i, err)
97 nrows, ncols := test.want.Dims()
98 sz := nrows*ncols*sizeFloat64 + 2*sizeInt64
100 t.Errorf("encoded size test-%d: want=%d got=%d\n", i, sz, len(buf))
103 if !bytes.Equal(buf, test.raw) {
104 t.Errorf("error encoding test-%d: bytes mismatch.\n got=%q\nwant=%q\n",
114 func TestDenseMarshalTo(t *testing.T) {
115 for i, test := range denseData {
116 buf := new(bytes.Buffer)
117 n, err := test.want.MarshalBinaryTo(buf)
119 t.Errorf("error encoding test-%d: %v\n", i, err)
123 nrows, ncols := test.want.Dims()
124 sz := nrows*ncols*sizeFloat64 + 2*sizeInt64
126 t.Errorf("encoded size test-%d: want=%d got=%d\n", i, sz, n)
129 if !bytes.Equal(buf.Bytes(), test.raw) {
130 t.Errorf("error encoding test-%d: bytes mismatch.\n got=%q\nwant=%q\n",
140 func TestDenseUnmarshal(t *testing.T) {
141 for i, test := range denseData {
143 err := v.UnmarshalBinary(test.raw)
145 t.Errorf("error decoding test-%d: %v\n", i, err)
148 if !test.eq(&v, test.want) {
149 t.Errorf("error decoding test-%d: values differ.\n got=%v\nwant=%v\n",
158 func TestDenseUnmarshalFrom(t *testing.T) {
159 for i, test := range denseData {
161 buf := bytes.NewReader(test.raw)
162 n, err := v.UnmarshalBinaryFrom(buf)
164 t.Errorf("error decoding test-%d: %v\n", i, err)
167 if n != len(test.raw) {
168 t.Errorf("error decoding test-%d: lengths differ.\n got=%d\nwant=%d\n",
172 if !test.eq(&v, test.want) {
173 t.Errorf("error decoding test-%d: values differ.\n got=%v\nwant=%v\n",
182 func TestDenseUnmarshalFromError(t *testing.T) {
184 for i, tt := range []struct {
190 end: len(test.raw) - 1,
194 end: len(test.raw) - sizeFloat64,
218 end: 2*sizeInt64 - 1,
226 end: 2*sizeInt64 + 1,
230 end: 2*sizeInt64 + sizeFloat64 - 1,
234 end: 2*sizeInt64 + sizeFloat64,
238 end: 2*sizeInt64 + sizeFloat64 + 1,
241 buf := bytes.NewReader(test.raw[tt.beg:tt.end])
243 _, err := m.UnmarshalBinaryFrom(buf)
244 if err != io.ErrUnexpectedEOF {
245 t.Errorf("test #%d: error decoding. got=%v. want=%v\n", i, err, io.ErrUnexpectedEOF)
250 func TestDenseIORoundTrip(t *testing.T) {
251 for i, test := range denseData {
252 buf, err := test.want.MarshalBinary()
254 t.Errorf("error encoding test #%d: %v\n", i, err)
258 err = got.UnmarshalBinary(buf)
260 t.Errorf("error decoding test #%d: %v\n", i, err)
263 if !test.eq(&got, test.want) {
264 t.Errorf("r/w test #%d failed\n got=%#v\nwant=%#v\n", i, &got, test.want)
267 wbuf := new(bytes.Buffer)
268 _, err = test.want.MarshalBinaryTo(wbuf)
270 t.Errorf("error encoding test #%d: %v\n", i, err)
273 if !bytes.Equal(buf, wbuf.Bytes()) {
274 t.Errorf("r/w test #%d encoding via MarshalBinary and MarshalBinaryTo differ:\nwith-stream: %q\n no-stream: %q\n",
275 i, wbuf.Bytes(), buf,
280 _, err = wgot.UnmarshalBinaryFrom(wbuf)
282 t.Errorf("error decoding test #%d: %v\n", i, err)
285 if !test.eq(&wgot, test.want) {
286 t.Errorf("r/w test #%d failed\n got=%#v\nwant=%#v\n", i, &wgot, test.want)
291 var vectorData = []struct {
294 eq func(got, want Matrix) bool
297 raw: []byte("\x00\x00\x00\x00\x00\x00\x00\x00"),
298 want: NewVecDense(0, []float64{}),
302 raw: []byte("\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@"),
303 want: NewVecDense(4, []float64{1, 2, 3, 4}),
307 raw: []byte("\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@"),
308 want: NewVecDense(6, []float64{1, 2, 3, 4, 5, 6}),
312 raw: []byte("\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00\"@"),
313 want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}),
317 raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@"),
318 want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(0, 3).(*VecDense),
322 raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@"),
323 want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(1, 4).(*VecDense),
327 raw: []byte("\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @"),
328 want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(0, 8).(*VecDense),
332 raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x18@"),
335 Data: []float64{0, 1, 2, 3, 4, 5, 6},
343 raw: []byte("\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\x00\x00\x00\x00\x00\x00\xf0\u007f\x01\x00\x00\x00\x00\x00\xf8\u007f"),
344 want: NewVecDense(4, []float64{0, math.Inf(-1), math.Inf(+1), math.NaN()}),
345 eq: func(got, want Matrix) bool {
346 for _, v := range []bool{
348 math.IsInf(got.At(1, 0), -1),
349 math.IsInf(got.At(2, 0), +1),
350 math.IsNaN(got.At(3, 0)),
361 func TestVecDenseMarshal(t *testing.T) {
362 for i, test := range vectorData {
363 buf, err := test.want.MarshalBinary()
365 t.Errorf("error encoding test-%d: %v\n", i, err)
369 nrows, ncols := test.want.Dims()
370 sz := nrows*ncols*sizeFloat64 + sizeInt64
372 t.Errorf("encoded size test-%d: want=%d got=%d\n", i, sz, len(buf))
375 if !bytes.Equal(buf, test.raw) {
376 t.Errorf("error encoding test-%d: bytes mismatch.\n got=%q\nwant=%q\n",
386 func TestVecDenseMarshalTo(t *testing.T) {
387 for i, test := range vectorData {
388 buf := new(bytes.Buffer)
389 n, err := test.want.MarshalBinaryTo(buf)
391 t.Errorf("error encoding test-%d: %v\n", i, err)
395 nrows, ncols := test.want.Dims()
396 sz := nrows*ncols*sizeFloat64 + sizeInt64
398 t.Errorf("encoded size test-%d: want=%d got=%d\n", i, sz, n)
401 if !bytes.Equal(buf.Bytes(), test.raw) {
402 t.Errorf("error encoding test-%d: bytes mismatch.\n got=%q\nwant=%q\n",
412 func TestVecDenseUnmarshal(t *testing.T) {
413 for i, test := range vectorData {
415 err := v.UnmarshalBinary(test.raw)
417 t.Errorf("error decoding test-%d: %v\n", i, err)
420 if !test.eq(&v, test.want) {
421 t.Errorf("error decoding test-%d: values differ.\n got=%v\nwant=%v\n",
430 func TestVecDenseUnmarshalFrom(t *testing.T) {
431 for i, test := range vectorData {
433 buf := bytes.NewReader(test.raw)
434 n, err := v.UnmarshalBinaryFrom(buf)
436 t.Errorf("error decoding test-%d: %v\n", i, err)
439 if n != len(test.raw) {
440 t.Errorf("error decoding test-%d: lengths differ.\n got=%d\nwant=%d\n",
446 if !test.eq(&v, test.want) {
447 t.Errorf("error decoding test-%d: values differ.\n got=%v\nwant=%v\n",
456 func TestVecDenseUnmarshalFromError(t *testing.T) {
457 test := vectorData[1]
458 for i, tt := range []struct {
464 end: len(test.raw) - 1,
468 end: len(test.raw) - sizeFloat64,
492 end: sizeInt64 + sizeFloat64 - 1,
496 end: sizeInt64 + sizeFloat64,
500 end: sizeInt64 + sizeFloat64 + 1,
503 buf := bytes.NewReader(test.raw[tt.beg:tt.end])
505 _, err := v.UnmarshalBinaryFrom(buf)
506 if err != io.ErrUnexpectedEOF {
507 t.Errorf("test #%d: error decoding. got=%v. want=%v\n", i, err, io.ErrUnexpectedEOF)
512 func TestVecDenseIORoundTrip(t *testing.T) {
513 for i, test := range vectorData {
514 buf, err := test.want.MarshalBinary()
516 t.Errorf("error encoding test #%d: %v\n", i, err)
520 err = got.UnmarshalBinary(buf)
522 t.Errorf("error decoding test #%d: %v\n", i, err)
524 if !test.eq(&got, test.want) {
525 t.Errorf("r/w test #%d failed\n got=%#v\nwant=%#v\n", i, &got, test.want)
528 wbuf := new(bytes.Buffer)
529 _, err = test.want.MarshalBinaryTo(wbuf)
531 t.Errorf("error encoding test #%d: %v\n", i, err)
534 if !bytes.Equal(buf, wbuf.Bytes()) {
535 t.Errorf("test #%d encoding via MarshalBinary and MarshalBinaryTo differ:\nwith-stream: %q\n no-stream: %q\n",
536 i, wbuf.Bytes(), buf,
541 _, err = wgot.UnmarshalBinaryFrom(wbuf)
543 t.Errorf("error decoding test #%d: %v\n", i, err)
546 if !test.eq(&wgot, test.want) {
547 t.Errorf("r/w test #%d failed\n got=%#v\nwant=%#v\n", i, &wgot, test.want)
552 func BenchmarkMarshalDense10(b *testing.B) { marshalBinaryBenchDense(b, 10) }
553 func BenchmarkMarshalDense100(b *testing.B) { marshalBinaryBenchDense(b, 100) }
554 func BenchmarkMarshalDense1000(b *testing.B) { marshalBinaryBenchDense(b, 1000) }
555 func BenchmarkMarshalDense10000(b *testing.B) { marshalBinaryBenchDense(b, 10000) }
557 func marshalBinaryBenchDense(b *testing.B, size int) {
558 data := make([]float64, size)
559 for i := range data {
562 m := NewDense(1, size, data)
565 for n := 0; n < b.N; n++ {
570 func BenchmarkUnmarshalDense10(b *testing.B) { unmarshalBinaryBenchDense(b, 10) }
571 func BenchmarkUnmarshalDense100(b *testing.B) { unmarshalBinaryBenchDense(b, 100) }
572 func BenchmarkUnmarshalDense1000(b *testing.B) { unmarshalBinaryBenchDense(b, 1000) }
573 func BenchmarkUnmarshalDense10000(b *testing.B) { unmarshalBinaryBenchDense(b, 10000) }
575 func unmarshalBinaryBenchDense(b *testing.B, size int) {
576 data := make([]float64, size)
577 for i := range data {
580 buf, err := NewDense(1, size, data).MarshalBinary()
582 b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err)
586 for n := 0; n < b.N; n++ {
588 m.UnmarshalBinary(buf)
592 func BenchmarkMarshalToDense10(b *testing.B) { marshalBinaryToBenchDense(b, 10) }
593 func BenchmarkMarshalToDense100(b *testing.B) { marshalBinaryToBenchDense(b, 100) }
594 func BenchmarkMarshalToDense1000(b *testing.B) { marshalBinaryToBenchDense(b, 1000) }
595 func BenchmarkMarshalToDense10000(b *testing.B) { marshalBinaryToBenchDense(b, 10000) }
597 func marshalBinaryToBenchDense(b *testing.B, size int) {
598 data := make([]float64, size)
599 for i := range data {
602 m := NewDense(1, size, data)
606 for n := 0; n < b.N; n++ {
611 type readerTest struct {
616 func (r *readerTest) Read(data []byte) (int, error) {
617 n := copy(data, r.buf[r.pos:r.pos+len(data)])
622 func (r *readerTest) reset() {
626 func BenchmarkUnmarshalFromDense10(b *testing.B) { unmarshalBinaryFromBenchDense(b, 10) }
627 func BenchmarkUnmarshalFromDense100(b *testing.B) { unmarshalBinaryFromBenchDense(b, 100) }
628 func BenchmarkUnmarshalFromDense1000(b *testing.B) { unmarshalBinaryFromBenchDense(b, 1000) }
629 func BenchmarkUnmarshalFromDense10000(b *testing.B) { unmarshalBinaryFromBenchDense(b, 10000) }
631 func unmarshalBinaryFromBenchDense(b *testing.B, size int) {
632 data := make([]float64, size)
633 for i := range data {
636 buf, err := NewDense(1, size, data).MarshalBinary()
638 b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err)
640 r := &readerTest{buf: buf}
643 for n := 0; n < b.N; n++ {
645 m.UnmarshalBinaryFrom(r)
650 func BenchmarkMarshalVecDense10(b *testing.B) { marshalBinaryBenchVecDense(b, 10) }
651 func BenchmarkMarshalVecDense100(b *testing.B) { marshalBinaryBenchVecDense(b, 100) }
652 func BenchmarkMarshalVecDense1000(b *testing.B) { marshalBinaryBenchVecDense(b, 1000) }
653 func BenchmarkMarshalVecDense10000(b *testing.B) { marshalBinaryBenchVecDense(b, 10000) }
655 func marshalBinaryBenchVecDense(b *testing.B, size int) {
656 data := make([]float64, size)
657 for i := range data {
660 vec := NewVecDense(size, data)
663 for n := 0; n < b.N; n++ {
668 func BenchmarkUnmarshalVecDense10(b *testing.B) { unmarshalBinaryBenchVecDense(b, 10) }
669 func BenchmarkUnmarshalVecDense100(b *testing.B) { unmarshalBinaryBenchVecDense(b, 100) }
670 func BenchmarkUnmarshalVecDense1000(b *testing.B) { unmarshalBinaryBenchVecDense(b, 1000) }
671 func BenchmarkUnmarshalVecDense10000(b *testing.B) { unmarshalBinaryBenchVecDense(b, 10000) }
673 func unmarshalBinaryBenchVecDense(b *testing.B, size int) {
674 data := make([]float64, size)
675 for i := range data {
678 buf, err := NewVecDense(size, data).MarshalBinary()
680 b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err)
684 for n := 0; n < b.N; n++ {
686 vec.UnmarshalBinary(buf)
690 func BenchmarkMarshalToVecDense10(b *testing.B) { marshalBinaryToBenchVecDense(b, 10) }
691 func BenchmarkMarshalToVecDense100(b *testing.B) { marshalBinaryToBenchVecDense(b, 100) }
692 func BenchmarkMarshalToVecDense1000(b *testing.B) { marshalBinaryToBenchVecDense(b, 1000) }
693 func BenchmarkMarshalToVecDense10000(b *testing.B) { marshalBinaryToBenchVecDense(b, 10000) }
695 func marshalBinaryToBenchVecDense(b *testing.B, size int) {
696 data := make([]float64, size)
697 for i := range data {
700 vec := NewVecDense(size, data)
704 for n := 0; n < b.N; n++ {
705 vec.MarshalBinaryTo(w)
709 func BenchmarkUnmarshalFromVecDense10(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 10) }
710 func BenchmarkUnmarshalFromVecDense100(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 100) }
711 func BenchmarkUnmarshalFromVecDense1000(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 1000) }
712 func BenchmarkUnmarshalFromVecDense10000(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 10000) }
714 func unmarshalBinaryFromBenchVecDense(b *testing.B, size int) {
715 data := make([]float64, size)
716 for i := range data {
719 buf, err := NewVecDense(size, data).MarshalBinary()
721 b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err)
723 r := &readerTest{buf: buf}
726 for n := 0; n < b.N; n++ {
728 vec.UnmarshalBinaryFrom(r)