github.com/alan-christopher/bb84/go@v0.0.0-20210906214457-a5cfb8afc89d/bb84/toeplitz_test.go (about)

     1  package bb84
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"math/rand"
     7  	"testing"
     8  
     9  	"github.com/alan-christopher/bb84/go/bb84/bitmap"
    10  )
    11  
    12  func TestToeplitzMul(t *testing.T) {
    13  	tcs := []struct {
    14  		mat  toeplitz
    15  		vec  bitmap.Dense
    16  		eout bitmap.Dense
    17  	}{
    18  		{
    19  			// (0 1 0)
    20  			// (0 0 1)
    21  			// (1 0 0)
    22  			mat: toeplitz{
    23  				diags: bitmap.NewDense([]byte{0b01001}, 5),
    24  				m:     3,
    25  				n:     3,
    26  			},
    27  			// (0 1 1)^T
    28  			vec: bitmap.NewDense([]byte{0b110}, 3),
    29  			// (1 1 0)^T
    30  			eout: bitmap.NewDense([]byte{0b011}, 3),
    31  		}, {
    32  			// (0 0)
    33  			// (1 0)
    34  			// (0 1)
    35  			// (1 0)
    36  			mat: toeplitz{
    37  				diags: bitmap.NewDense([]byte{0b00101}, 5),
    38  				m:     4,
    39  				n:     2,
    40  			},
    41  			// (1 0)^T
    42  			vec: bitmap.NewDense([]byte{0b01}, 2),
    43  			// (0 1 0 1)^T
    44  			eout: bitmap.NewDense([]byte{0b1010}, 4),
    45  		}, {
    46  			// (1 1 1 0)
    47  			// (0 1 1 1)
    48  			mat: toeplitz{
    49  				diags: bitmap.NewDense([]byte{0b01110}, 5),
    50  				m:     2,
    51  				n:     4,
    52  			},
    53  			// (0 1 0 1)^T
    54  			vec: bitmap.NewDense([]byte{0b01}, 4),
    55  			// (1 0)^T
    56  			eout: bitmap.NewDense([]byte{0b01}, 2),
    57  		},
    58  	}
    59  
    60  	for _, tc := range tcs {
    61  		t.Run(fmt.Sprintf("%dx%d", tc.mat.m, tc.mat.n), func(t *testing.T) {
    62  			out, err := tc.mat.Mul(tc.vec)
    63  			if err != nil {
    64  				t.Fatalf("unexpected error: %v", err)
    65  			}
    66  			if out.Size() != tc.eout.Size() {
    67  				t.Errorf("got bitmap of len %d, want %d", out.Size(), tc.eout.Size())
    68  			}
    69  			outArr := out.Data()
    70  			eoutArr := tc.eout.Data()
    71  			if !bytes.Equal(outArr, eoutArr) {
    72  				t.Errorf("T*v == %v, want %v", outArr, eoutArr)
    73  			}
    74  		})
    75  	}
    76  }
    77  
    78  func TestToeplitzShape(t *testing.T) {
    79  	tcs := []struct {
    80  		name string
    81  		mat  toeplitz
    82  		vec  bitmap.Dense
    83  		eErr bool
    84  	}{
    85  		{
    86  			name: "mismatched dims",
    87  			mat: toeplitz{
    88  				diags: bitmap.NewDense(nil, 5),
    89  				m:     3,
    90  				n:     3,
    91  			},
    92  			vec:  bitmap.NewDense(nil, 2),
    93  			eErr: true,
    94  		}, {
    95  			name: "insufficient diags",
    96  			mat: toeplitz{
    97  				diags: bitmap.NewDense(nil, 2),
    98  				m:     3,
    99  				n:     3,
   100  			},
   101  			vec:  bitmap.NewDense(nil, 3),
   102  			eErr: true,
   103  		}, {
   104  			name: "extra diags",
   105  			mat: toeplitz{
   106  				diags: bitmap.NewDense(nil, 1024),
   107  				m:     3,
   108  				n:     3,
   109  			},
   110  			vec:  bitmap.NewDense(nil, 3),
   111  			eErr: false,
   112  		},
   113  	}
   114  
   115  	for _, tc := range tcs {
   116  		t.Run(tc.name, func(t *testing.T) {
   117  			_, err := tc.mat.Mul(tc.vec)
   118  			if !tc.eErr && err != nil {
   119  				t.Errorf("unexpected error: %v", err)
   120  			}
   121  			if tc.eErr && err == nil {
   122  				t.Errorf("expected error: got nil")
   123  			}
   124  		})
   125  	}
   126  }
   127  
   128  func BenchmarkToeplitzMul(b *testing.B) {
   129  	m := 40
   130  	n := 655360
   131  	bd := make([]byte, (m+n)/8+1)
   132  	rand.Read(bd)
   133  	t := toeplitz{
   134  		diags: bitmap.NewDense(bd, m+n),
   135  		m:     m,
   136  		n:     n,
   137  	}
   138  	bx := make([]byte, n/8+1)
   139  	rand.Read(bx)
   140  	x := bitmap.NewDense(bx, n)
   141  	b.ResetTimer()
   142  	if _, err := t.Mul(x); err != nil {
   143  		b.Errorf("fuck: %v", err)
   144  	}
   145  }