github.com/ericlagergren/ctb@v0.0.0-20220810041818-96749d9c394d/lll/big_test.go (about)

     1  package lll
     2  
     3  import (
     4  	"testing"
     5  )
     6  
     7  func TestRound(t *testing.T) {
     8  	for i, tc := range []struct {
     9  		in, out T
    10  	}{
    11  		{F64(21, 2), I64(11)},                              // 10.5
    12  		{F64(-21, 2), I64(-11)},                            // -10.5
    13  		{F64(6283, 2000), I64(3)},                          // 3.1415
    14  		{F64(-6283, 2000), I64(-3)},                        // -3.1415
    15  		{F64(9285714285714286, 10000000000000000), I64(1)}, // 0.9285714285714286
    16  	} {
    17  		got := round(tc.in)
    18  		if tc.out.Cmp(got) != 0 {
    19  			t.Fatalf("#%d: expected %s, got %s", i, tc.out, got)
    20  		}
    21  	}
    22  }
    23  
    24  func TestReduction(t *testing.T) {
    25  	for i, tc := range []struct {
    26  		basis [][]T
    27  		want  [][]T
    28  		delta T
    29  	}{
    30  		{
    31  			basis: [][]T{
    32  				{I64(1), I64(1), I64(1)},
    33  				{I64(-1), I64(0), I64(2)},
    34  				{I64(3), I64(5), I64(6)},
    35  			},
    36  			want: [][]T{
    37  				{I64(0), I64(1), I64(0)},
    38  				{I64(1), I64(0), I64(1)},
    39  				{I64(-1), I64(0), I64(2)},
    40  			},
    41  			delta: F64(3, 4),
    42  		},
    43  		{
    44  			basis: [][]T{
    45  				{I64(105), I64(821), I64(404), I64(328)},
    46  				{I64(881), I64(667), I64(644), I64(927)},
    47  				{I64(181), I64(483), I64(87), I64(500)},
    48  				{I64(893), I64(834), I64(732), I64(441)},
    49  			},
    50  			want: [][]T{
    51  				{I64(76), I64(-338), I64(-317), I64(172)},
    52  				{I64(88), I64(-171), I64(-229), I64(-314)},
    53  				{I64(269), I64(312), I64(-142), I64(186)},
    54  				{I64(519), I64(-299), I64(470), I64(-73)},
    55  			},
    56  			delta: F64(3, 4),
    57  		},
    58  	} {
    59  		got := Reduction(tc.delta, tc.basis)
    60  		if !equal(got, tc.want) {
    61  			t.Fatalf("#%d: wanted %v, got %v", i, tc.want, got)
    62  		}
    63  	}
    64  }
    65  
    66  func TestGramSchmidt(t *testing.T) {
    67  	for i, tc := range []struct {
    68  		v    [][]T
    69  		want [][]T
    70  	}{
    71  		{
    72  			v: [][]T{
    73  				{I64(3), I64(1)},
    74  				{I64(2), I64(2)},
    75  			},
    76  			want: [][]T{
    77  				{I64(3), I64(1)},
    78  				{F64(-2, 5), F64(6, 5)},
    79  			},
    80  		},
    81  		{
    82  			v: [][]T{
    83  				{I64(4), I64(1), I64(2)},
    84  				{I64(4), I64(7), I64(2)},
    85  				{I64(3), I64(1), I64(7)},
    86  			},
    87  			want: [][]T{
    88  				{I64(4), I64(1), I64(2)},
    89  				{F64(-8, 7), F64(40, 7), F64(-4, 7)},
    90  				{F64(-11, 5), I64(0), F64(22, 5)},
    91  			},
    92  		},
    93  	} {
    94  		got := gramSchmidt(nil, tc.v)
    95  		if !equal(got, tc.want) {
    96  			t.Fatalf("#%d: wanted %v, got %v", i, tc.want, got)
    97  		}
    98  	}
    99  }
   100  
   101  func BenchmarkReduction(b *testing.B) {
   102  	data := []struct {
   103  		basis [][]T
   104  		want  [][]T
   105  		delta T
   106  	}{
   107  		{
   108  			basis: [][]T{
   109  				{I64(1), I64(1), I64(1)},
   110  				{I64(-1), I64(0), I64(2)},
   111  				{I64(3), I64(5), I64(6)},
   112  			},
   113  			want: [][]T{
   114  				{I64(0), I64(1), I64(0)},
   115  				{I64(1), I64(0), I64(1)},
   116  				{I64(-1), I64(0), I64(2)},
   117  			},
   118  			delta: F64(3, 4),
   119  		},
   120  		{
   121  			basis: [][]T{
   122  				{I64(105), I64(821), I64(404), I64(328)},
   123  				{I64(881), I64(667), I64(644), I64(927)},
   124  				{I64(181), I64(483), I64(87), I64(500)},
   125  				{I64(893), I64(834), I64(732), I64(441)},
   126  			},
   127  			want: [][]T{
   128  				{I64(76), I64(-338), I64(-317), I64(172)},
   129  				{I64(88), I64(-171), I64(-229), I64(-314)},
   130  				{I64(269), I64(312), I64(-142), I64(186)},
   131  				{I64(519), I64(-299), I64(470), I64(-73)},
   132  			},
   133  			delta: F64(3, 4),
   134  		},
   135  	}
   136  	b.ResetTimer()
   137  	for i := 0; i < b.N; i++ {
   138  		d := data[i%len(data)]
   139  		Sink = Reduction(d.delta, d.basis)
   140  	}
   141  }
   142  
   143  var Sink [][]T
   144  
   145  func equal(a, b [][]T) bool {
   146  	if len(a) != len(b) {
   147  		return false
   148  	}
   149  	for i, ai := range a {
   150  		for j, aj := range ai {
   151  			if aj.Cmp(b[i][j]) != 0 {
   152  				return false
   153  			}
   154  		}
   155  	}
   156  	return true
   157  }