gitee.com/quant1x/gox@v1.7.6/num/vek_test.go (about)

     1  package num
     2  
     3  import (
     4  	"github.com/stretchr/testify/require"
     5  	"golang.org/x/exp/slices"
     6  	"math"
     7  	"testing"
     8  )
     9  
    10  // Edge cases. See internal/functions for random float tests.
    11  
    12  const d = 0.001
    13  
    14  var empty []float64 = []float64{}
    15  var one []float64 = []float64{1}
    16  var two []float64 = []float64{1, 2}
    17  var three []float64 = []float64{1, 2, 3}
    18  var four []float64 = []float64{1, 2, 3, 4} // AVX register
    19  var five []float64 = []float64{1, 2, 3, 4, 5}
    20  var negOne []float64 = []float64{-1}
    21  var negTwo []float64 = []float64{-1, -2}
    22  var negThree []float64 = []float64{-1, -2, -3}
    23  var negFour []float64 = []float64{-1, -2, -3, -4} // AVX register
    24  var negFive []float64 = []float64{-1, -2, -3, -4, -5}
    25  var accel []bool = []bool{false, Info().Acceleration}
    26  
    27  func TestArithmetic(t *testing.T) {
    28  	for _, accel := range accel {
    29  		SetAcceleration(accel)
    30  
    31  		dst := make([]float64, 4)
    32  
    33  		require.Panics(t, func() { Add(one, two) })
    34  		require.Empty(t, Add(nil, nil))
    35  		require.Empty(t, Add(empty, nil))
    36  		require.Empty(t, Add(empty, empty))
    37  		require.Equal(t, []float64{2}, Add(one, one))
    38  		require.Equal(t, []float64{2, 4, 6, 8}, Add(four, four))
    39  		require.Equal(t, []float64{2, 4, 6, 8, 10}, Add(five, five))
    40  		dst = Add_Into(dst, three, three)
    41  		require.Equal(t, []float64{2, 4, 6}, dst)
    42  		require.Panics(t, func() { Add_Into(dst, five, five) })
    43  		require.Panics(t, func() { Add_Inplace(five, five) })
    44  
    45  		require.Empty(t, AddNumber(nil, 2))
    46  		require.Empty(t, AddNumber(empty, 2))
    47  		require.Empty(t, AddNumber(empty, 2))
    48  		require.Equal(t, []float64{3}, AddNumber(one, 2))
    49  		require.Equal(t, []float64{3, 4, 5, 6}, AddNumber(four, 2))
    50  		require.Equal(t, []float64{3, 4, 5, 6, 7}, AddNumber(five, 2))
    51  		dst = AddNumber_Into(dst, three, 2)
    52  		require.Equal(t, []float64{3, 4, 5}, dst)
    53  		require.Panics(t, func() { AddNumber_Into(dst, five, 2) })
    54  
    55  		require.Panics(t, func() { Sub(one, two) })
    56  		require.Empty(t, Sub(nil, nil))
    57  		require.Empty(t, Sub(empty, nil))
    58  		require.Empty(t, Sub(empty, empty))
    59  		require.Equal(t, []float64{0}, Sub(one, one))
    60  		require.Equal(t, []float64{0, 0, 0, 0}, Sub(four, four))
    61  		require.Equal(t, []float64{0, 0, 0, 0, 0}, Sub(five, five))
    62  		dst = Sub_Into(dst, three, three)
    63  		require.Equal(t, []float64{0, 0, 0}, dst)
    64  		require.Panics(t, func() { Sub_Into(dst, five, five) })
    65  
    66  		require.Empty(t, SubNumber(nil, 2))
    67  		require.Empty(t, SubNumber(empty, 2))
    68  		require.Empty(t, SubNumber(empty, 2))
    69  		require.Equal(t, []float64{-1}, SubNumber(one, 2))
    70  		require.Equal(t, []float64{-1, 0, 1, 2}, SubNumber(four, 2))
    71  		require.Equal(t, []float64{-1, 0, 1, 2, 3}, SubNumber(five, 2))
    72  		dst = SubNumber_Into(dst, three, 2)
    73  		require.Equal(t, []float64{-1, 0, 1}, dst)
    74  		require.Panics(t, func() { SubNumber_Into(dst, five, 2) })
    75  
    76  		require.Panics(t, func() { Mul(one, two) })
    77  		require.Empty(t, Mul(nil, nil))
    78  		require.Empty(t, Mul(empty, nil))
    79  		require.Empty(t, Mul(empty, empty))
    80  		require.Equal(t, []float64{1}, Mul(one, one))
    81  		require.Equal(t, []float64{1, 4, 9, 16}, Mul(four, four))
    82  		require.Equal(t, []float64{1, 4, 9, 16, 25}, Mul(five, five))
    83  		dst = Mul_Into(dst, three, three)
    84  		require.Equal(t, []float64{1, 4, 9}, dst)
    85  		require.Panics(t, func() { Mul_Into(dst, five, five) })
    86  
    87  		require.Empty(t, MulNumber(nil, 2))
    88  		require.Empty(t, MulNumber(empty, 2))
    89  		require.Empty(t, MulNumber(empty, 2))
    90  		require.Equal(t, []float64{2}, MulNumber(one, 2))
    91  		require.Equal(t, []float64{2, 4, 6, 8}, MulNumber(four, 2))
    92  		require.Equal(t, []float64{2, 4, 6, 8, 10}, MulNumber(five, 2))
    93  		dst = MulNumber_Into(dst, three, 2)
    94  		require.Equal(t, []float64{2, 4, 6}, dst)
    95  		require.Panics(t, func() { MulNumber_Into(dst, five, 2) })
    96  
    97  		require.Panics(t, func() { Div(one, two) })
    98  		require.Empty(t, Div(nil, nil))
    99  		require.Empty(t, Div(empty, nil))
   100  		require.Empty(t, Div(empty, empty))
   101  		require.Equal(t, []float64{1}, Div(one, one))
   102  		require.Equal(t, []float64{1, 1, 1, 1}, Div(four, four))
   103  		require.Equal(t, []float64{1, 1, 1, 1, 1}, Div(five, five))
   104  		dst = Div_Into(dst, three, three)
   105  		require.Equal(t, []float64{1, 1, 1}, dst)
   106  		require.Panics(t, func() { Div_Into(dst, five, five) })
   107  
   108  		require.Empty(t, DivNumber(nil, 2))
   109  		require.Empty(t, DivNumber(empty, 2))
   110  		require.Empty(t, DivNumber(empty, 2))
   111  		require.InDeltaSlice(t, []float64{1. / 2}, DivNumber(one, 2), d)
   112  		require.InDeltaSlice(t, []float64{1. / 2, 2. / 2, 3. / 2, 4. / 2}, DivNumber(four, 2), d)
   113  		require.InDeltaSlice(t, []float64{1. / 2, 2. / 2, 3. / 2, 4. / 2, 5. / 2}, DivNumber(five, 2), d)
   114  		dst = DivNumber_Into(dst, three, 2)
   115  		require.InDeltaSlice(t, []float64{1. / 2, 2. / 2, 3. / 2}, dst, d)
   116  		require.Panics(t, func() { DivNumber_Into(dst, five, 2) })
   117  
   118  		require.Empty(t, Abs(empty))
   119  		require.Empty(t, Abs(nil))
   120  		require.Equal(t, one, Abs(negOne))
   121  		require.Equal(t, four, Abs(negFour))
   122  		require.Equal(t, five, Abs(negFive))
   123  		dst = Abs_Into(dst, negThree)
   124  		require.Equal(t, three, dst)
   125  		require.Panics(t, func() { Abs_Into(dst, five) })
   126  
   127  		require.Empty(t, Neg(empty))
   128  		require.Empty(t, Neg(nil))
   129  		require.Equal(t, negOne, Neg(one))
   130  		require.Equal(t, negFour, Neg(four))
   131  		require.Equal(t, negFive, Neg(five))
   132  		dst = Neg_Into(dst, three)
   133  		require.Equal(t, negThree, dst)
   134  		require.Panics(t, func() { Neg_Into(dst, five) })
   135  
   136  		require.Empty(t, Inv(empty))
   137  		require.Empty(t, Inv(nil))
   138  		require.Equal(t, one, Inv(one))
   139  		require.InDeltaSlice(t, []float64{1, 1. / 2, 1. / 3, 1. / 4}, Inv(four), d)
   140  		require.InDeltaSlice(t, []float64{1, 1. / 2, 1. / 3, 1. / 4, 1. / 5}, Inv(five), d)
   141  		dst = Inv_Into(dst, three)
   142  		require.InDeltaSlice(t, []float64{1, 1. / 2, 1. / 3}, dst, d)
   143  		require.Panics(t, func() { Inv_Into(dst, five) })
   144  	}
   145  }
   146  
   147  func TestAggregates(t *testing.T) {
   148  	for _, accel := range accel {
   149  		SetAcceleration(accel)
   150  
   151  		dst := slices.Clone(four)
   152  		_ = dst
   153  
   154  		require.Equal(t, 0., Sum(empty))
   155  		require.Equal(t, 0., Sum(nil))
   156  		require.Equal(t, 1., Sum(one))
   157  		require.Equal(t, 1.+2+3+4, Sum(four))
   158  		require.Equal(t, 1.+2+3+4+5, Sum(five))
   159  
   160  		require.Empty(t, CumSum(nil))
   161  		require.Empty(t, CumSum(empty))
   162  		require.Equal(t, []float64{1}, CumSum(one))
   163  		require.Equal(t, []float64{1, 3, 6, 10}, CumSum(four))
   164  		require.Equal(t, []float64{1, 3, 6, 10, 15}, CumSum(five))
   165  		dst = CumSum_Into(dst, three)
   166  		require.Equal(t, []float64{1, 3, 6}, dst)
   167  		require.Panics(t, func() { CumSum_Into(dst, five) })
   168  
   169  		require.Equal(t, 1., Prod(empty))
   170  		require.Equal(t, 1., Prod(nil))
   171  		require.Equal(t, 1., Prod(one))
   172  		require.Equal(t, 1.*2*3*4, Prod(four))
   173  		require.Equal(t, 1.*2*3*4*5, Prod(five))
   174  
   175  		require.Empty(t, CumProd(nil))
   176  		require.Empty(t, CumProd(empty))
   177  		require.Equal(t, []float64{1}, CumProd(one))
   178  		require.Equal(t, []float64{1, 2, 6, 24}, CumProd(four))
   179  		require.Equal(t, []float64{1, 2, 6, 24, 120}, CumProd(five))
   180  		dst = CumProd_Into(dst, three)
   181  		require.Equal(t, []float64{1, 2, 6}, dst)
   182  		require.Panics(t, func() { CumProd_Into(dst, five) })
   183  
   184  		require.Panics(t, func() { Mean(nil) })
   185  		require.Panics(t, func() { Mean(empty) })
   186  		require.InDelta(t, 1., Mean(one), d)
   187  		require.InDelta(t, (1.+2+3+4)/4, Mean(four), d)
   188  		require.InDelta(t, (1.+2+3+4+5)/5, Mean(five), d)
   189  
   190  		require.Panics(t, func() { Median(nil) })
   191  		require.Panics(t, func() { Median(empty) })
   192  		require.InDelta(t, 1., Median(one), d)
   193  		require.InDelta(t, 2.5, Median(four), d)
   194  		require.InDelta(t, 3., Median(five), d)
   195  
   196  		require.Panics(t, func() { Quantile(nil, 0.3) })
   197  		require.Panics(t, func() { Quantile(empty, 0.3) })
   198  		require.InDelta(t, 1., Quantile(one, 0.), d)
   199  		require.InDelta(t, 1., Quantile(one, 0.4), d)
   200  		require.InDelta(t, 1., Quantile(one, 1.), d)
   201  		require.InDelta(t, 1., Quantile(four, 0.), d)
   202  		require.InDelta(t, 2.2, Quantile(four, 0.4), d)
   203  		require.InDelta(t, 4., Quantile(four, 1.), d)
   204  		require.InDelta(t, 2.6, Quantile(five, 0.4), d)
   205  	}
   206  }
   207  
   208  func TestDistance(t *testing.T) {
   209  	for _, accel := range accel {
   210  		SetAcceleration(accel)
   211  
   212  		require.Panics(t, func() { Dot(nil, empty) })
   213  		require.Panics(t, func() { Dot(one, two) })
   214  		require.Equal(t, 1., Dot(one, one))
   215  		require.Equal(t, 1.*1+2*2+3*3+4*4, Dot(four, four))
   216  		require.Equal(t, 1.*1+2*2+3*3+4*4+5*5, Dot(five, five))
   217  
   218  		require.Panics(t, func() { Norm(nil) })
   219  		require.InDelta(t, 1., Norm(one), d)
   220  		require.InDelta(t, math.Sqrt(Dot(four, four)), Norm(four), d)
   221  		require.InDelta(t, math.Sqrt(Dot(five, five)), Norm(five), d)
   222  
   223  		require.Panics(t, func() { Distance(nil, nil) })
   224  		require.Panics(t, func() { Distance(one, two) })
   225  		require.InDelta(t, 0., Distance(one, one), d)
   226  		require.InDelta(t, Norm(Sub(one, negOne)), Distance(one, negOne), d)
   227  		require.InDelta(t, 0., Distance(four, four), d)
   228  		require.InDelta(t, Norm(Sub(four, negFour)), Distance(four, negFour), d)
   229  		require.InDelta(t, 0., Distance(five, five), d)
   230  		require.InDelta(t, Norm(Sub(five, negFive)), Distance(five, negFive), d)
   231  
   232  		require.Panics(t, func() { ManhattanNorm(nil) })
   233  		require.InDelta(t, 1., ManhattanNorm(one), d)
   234  		require.InDelta(t, Sum(Abs(four)), ManhattanNorm(four), d)
   235  		require.InDelta(t, Sum(Abs(five)), ManhattanNorm(five), d)
   236  
   237  		require.Panics(t, func() { ManhattanDistance(nil, nil) })
   238  		require.Panics(t, func() { ManhattanDistance(one, two) })
   239  		require.InDelta(t, 0., ManhattanDistance(one, one), d)
   240  		require.InDelta(t, Sum(Abs(Sub(one, negOne))), ManhattanDistance(one, negOne), d)
   241  		require.InDelta(t, 0., ManhattanDistance(four, four), d)
   242  		require.InDelta(t, Sum(Abs(Sub(four, negFour))), ManhattanDistance(four, negFour), d)
   243  		require.InDelta(t, 0., ManhattanDistance(five, five), d)
   244  		require.InDelta(t, Sum(Abs(Sub(five, negFive))), ManhattanDistance(five, negFive), d)
   245  
   246  		require.Panics(t, func() { CosineSimilarity(nil, nil) })
   247  		require.Panics(t, func() { CosineSimilarity(one, two) })
   248  		require.InDelta(t, 1., CosineSimilarity(one, one), d)
   249  		require.InDelta(t, -1., CosineSimilarity(one, negOne), d)
   250  		require.InDelta(t, 1., CosineSimilarity(four, four), d)
   251  		require.InDelta(t, -1., CosineSimilarity(four, negFour), d)
   252  		require.InDelta(t, 0.6666, CosineSimilarity(four, []float64{4, 3, 2, 1}), d)
   253  		require.InDelta(t, 0.6363, CosineSimilarity(five, []float64{5, 4, 3, 2, 1}), d)
   254  	}
   255  }
   256  
   257  func TestMatrices(t *testing.T) {
   258  	for _, accel := range accel {
   259  		SetAcceleration(accel)
   260  
   261  		dst := make([]float64, 4)
   262  
   263  		require.Panics(t, func() { MatMul(empty, empty, 1) })
   264  		require.Panics(t, func() { MatMul(one, one, 0) })
   265  		require.Panics(t, func() { MatMul(two, four, 3) })
   266  		require.InDeltaSlice(t, []float64{1}, MatMul(one, one, 1), d)
   267  		require.InDeltaSlice(t, []float64{7, 10}, MatMul(two, four, 2), d)
   268  		require.InDeltaSlice(t, []float64{1, 2, 2, 4}, MatMul(two, two, 1), d)
   269  		require.InDeltaSlice(t, []float64{30}, MatMul(four, four, 4), d)
   270  		require.InDeltaSlice(t, []float64{55}, MatMul(five, five, 5), d)
   271  		dst = MatMul_Into(dst, two, two, 1)
   272  		require.InDeltaSlice(t, []float64{1, 2, 2, 4}, dst, d)
   273  		require.Panics(t, func() { MatMul_Into(dst, five, five, 1) })
   274  
   275  		dst = make([]float64, 16)
   276  		sixteen := Range(1, 17)
   277  		expected := []float64{90, 100, 110, 120, 202, 228, 254, 280, 314, 356, 398, 440, 426, 484, 542, 600}
   278  
   279  		require.Panics(t, func() { Mat4Mul(empty, empty) })
   280  		require.Panics(t, func() { Mat4Mul(one, one) })
   281  		require.Panics(t, func() { Mat4Mul(two, four) })
   282  		require.InDeltaSlice(t, expected, Mat4Mul(sixteen, sixteen), d)
   283  		dst = Mat4Mul_Into(dst, sixteen, sixteen)
   284  		require.InDeltaSlice(t, expected, dst, d)
   285  		require.Panics(t, func() { Mat4Mul_Into(dst[:4:4], sixteen, sixteen) })
   286  	}
   287  }
   288  
   289  func TestSpecial(t *testing.T) {
   290  	for _, accel := range accel {
   291  		SetAcceleration(accel)
   292  
   293  		dst := make([]float64, 4)
   294  
   295  		require.Empty(t, Sqrt(empty))
   296  		require.InDeltaSlice(t, one, Sqrt(one), d)
   297  		require.InDeltaSlice(t, []float64{1., 1.4142, 1.7321, 2.}, Sqrt(four), d)
   298  		require.InDeltaSlice(t, []float64{1., 1.4142, 1.7321, 2., 2.2361}, Sqrt(five), d)
   299  		require.Panics(t, func() { Sqrt_Into(dst, five) })
   300  
   301  		require.Empty(t, Round(empty))
   302  		require.InDeltaSlice(t, one, Round(one), d)
   303  		require.InDeltaSlice(t, four, Round(AddNumber(four, 0.2)), d)
   304  		require.InDeltaSlice(t, AddNumber(four, 1), Round(AddNumber(four, 0.5)), d)
   305  		require.InDeltaSlice(t, AddNumber(four, 1), Round(AddNumber(four, 0.8)), d)
   306  		require.InDeltaSlice(t, five, Round(AddNumber(five, 0.2)), d)
   307  		require.InDeltaSlice(t, AddNumber(five, 1), Round(AddNumber(five, 0.5)), d)
   308  		require.InDeltaSlice(t, AddNumber(five, 1), Round(AddNumber(five, 0.8)), d)
   309  		dst = Round_Into(dst, four)
   310  		require.InDeltaSlice(t, four, dst, d)
   311  		require.Panics(t, func() { Round_Into(dst, five) })
   312  
   313  		require.Empty(t, Floor(empty))
   314  		require.InDeltaSlice(t, one, Floor(one), d)
   315  		require.InDeltaSlice(t, four, Floor(AddNumber(four, 0.2)), d)
   316  		require.InDeltaSlice(t, four, Floor(AddNumber(four, 0.5)), d)
   317  		require.InDeltaSlice(t, four, Floor(AddNumber(four, 0.8)), d)
   318  		require.InDeltaSlice(t, five, Floor(AddNumber(five, 0.2)), d)
   319  		require.InDeltaSlice(t, five, Floor(AddNumber(five, 0.5)), d)
   320  		require.InDeltaSlice(t, five, Floor(AddNumber(five, 0.8)), d)
   321  		dst = Floor_Into(dst, four)
   322  		require.InDeltaSlice(t, four, dst, d)
   323  		require.Panics(t, func() { Floor_Into(dst, five) })
   324  
   325  		require.Empty(t, Ceil(empty))
   326  		require.InDeltaSlice(t, one, Ceil(one), d)
   327  		require.InDeltaSlice(t, AddNumber(four, 1), Ceil(AddNumber(four, 0.2)), d)
   328  		require.InDeltaSlice(t, AddNumber(four, 1), Ceil(AddNumber(four, 0.5)), d)
   329  		require.InDeltaSlice(t, AddNumber(four, 1), Ceil(AddNumber(four, 0.8)), d)
   330  		require.InDeltaSlice(t, AddNumber(five, 1), Ceil(AddNumber(five, 0.2)), d)
   331  		require.InDeltaSlice(t, AddNumber(five, 1), Ceil(AddNumber(five, 0.5)), d)
   332  		require.InDeltaSlice(t, AddNumber(five, 1), Ceil(AddNumber(five, 0.8)), d)
   333  		dst = Ceil_Into(dst, four)
   334  		require.InDeltaSlice(t, four, dst, d)
   335  		require.Panics(t, func() { Ceil_Into(dst, five) })
   336  
   337  		require.Panics(t, func() { Pow(one, two) })
   338  		require.Empty(t, Pow(empty, nil))
   339  		require.Equal(t, []float64{1}, Pow(one, one))
   340  		require.InDeltaSlice(t, []float64{11.1803}, Pow([]float64{0.2}, []float64{-1.5}), d)
   341  		require.Equal(t, []float64{1, 4, 27, 256}, Pow(four, four))
   342  		require.Equal(t, []float64{1, 4, 27, 256, 3125}, Pow(five, five))
   343  		dst = Pow_Into(dst, three, three)
   344  		require.Equal(t, []float64{1, 4, 27}, dst)
   345  		require.Panics(t, func() { Pow_Into(dst, five, five) })
   346  	}
   347  }
   348  
   349  func TestComparison(t *testing.T) {
   350  	for _, accel := range accel {
   351  		SetAcceleration(accel)
   352  
   353  		dst := make([]float64, 4)
   354  
   355  		require.Panics(t, func() { Min(empty) })
   356  		require.Equal(t, 1., Min(one))
   357  		require.Equal(t, 1., Min(four))
   358  		require.Equal(t, 1., Min(five))
   359  
   360  		require.Panics(t, func() { ArgMin(empty) })
   361  		require.Equal(t, 0, ArgMin(one))
   362  		require.Equal(t, 0, ArgMin(four))
   363  		require.Equal(t, 0, ArgMin(five))
   364  
   365  		require.Panics(t, func() { Minimum(one, two) })
   366  		require.Equal(t, empty, Minimum(empty, nil))
   367  		require.Equal(t, one, Minimum(one, one))
   368  		require.Equal(t, four, Minimum(four, four))
   369  		require.Equal(t, negFour, Minimum(four, negFour))
   370  		require.Equal(t, five, Minimum(five, five))
   371  		require.Equal(t, negFive, Minimum(five, negFive))
   372  		require.Panics(t, func() { Minimum_Into(dst, five, five) })
   373  
   374  		require.Equal(t, empty, MinimumNumber(empty, 2.5))
   375  		require.Equal(t, one, MinimumNumber(one, 2.5))
   376  		require.Equal(t, []float64{1, 2, 2.5, 2.5}, MinimumNumber(four, 2.5))
   377  		require.Equal(t, []float64{1, 2, 2.5, 2.5, 2.5}, MinimumNumber(five, 2.5))
   378  		require.Panics(t, func() { MinimumNumber_Into(dst, five, 2.5) })
   379  
   380  		require.Panics(t, func() { Max(empty) })
   381  		require.Equal(t, 1., Max(one))
   382  		require.Equal(t, 4., Max(four))
   383  		require.Equal(t, 5., Max(five))
   384  
   385  		require.Panics(t, func() { ArgMax(empty) })
   386  		require.Equal(t, 0, ArgMax(one))
   387  		require.Equal(t, 3, ArgMax(four))
   388  		require.Equal(t, 4, ArgMax(five))
   389  
   390  		require.Panics(t, func() { Maximum(one, two) })
   391  		require.Equal(t, empty, Maximum(empty, nil))
   392  		require.Equal(t, one, Maximum(one, one))
   393  		require.Equal(t, four, Maximum(four, four))
   394  		require.Equal(t, four, Maximum(four, negFour))
   395  		require.Equal(t, five, Maximum(five, five))
   396  		require.Equal(t, five, Maximum(five, negFive))
   397  		require.Panics(t, func() { Maximum_Into(dst, five, five) })
   398  
   399  		require.Equal(t, empty, MaximumNumber(empty, 2.5))
   400  		require.Equal(t, []float64{2.5}, MaximumNumber(one, 2.5))
   401  		require.Equal(t, []float64{2.5, 2.5, 3, 4}, MaximumNumber(four, 2.5))
   402  		require.Equal(t, []float64{2.5, 2.5, 3, 4, 5}, MaximumNumber(five, 2.5))
   403  		require.Panics(t, func() { MaximumNumber_Into(dst, five, 2.5) })
   404  
   405  		require.Equal(t, -1, Find(empty, 1))
   406  		require.Equal(t, 0, Find(one, 1))
   407  		require.Equal(t, -1, Find(one, 2))
   408  		require.Equal(t, 3, Find(four, 4))
   409  		require.Equal(t, 4, Find(AddNumber(five, 0.5), 5.5))
   410  
   411  		dstBool := make([]bool, 4)
   412  
   413  		require.Equal(t, []bool{}, Lt(empty, empty))
   414  		require.Equal(t, []bool{false}, Lt(one, one))
   415  		require.Equal(t, []bool{true}, Lt(negOne, one))
   416  		require.Equal(t, []bool{false, false, false, false}, Lt(four, four))
   417  		require.Equal(t, []bool{true, true, true, true}, Lt(negFour, four))
   418  		require.Equal(t, []bool{false, false, false, false, false}, Lt(five, five))
   419  		require.Equal(t, []bool{true, true, true, true, true}, Lt(negFive, five))
   420  		dstBool = Lt_Into(dstBool, negFour, four)
   421  		require.Equal(t, []bool{true, true, true, true}, dstBool)
   422  		require.Panics(t, func() { Lt_Into(dstBool, five, five) })
   423  
   424  		require.Equal(t, []bool{}, LtNumber(empty, 2.5))
   425  		require.Equal(t, []bool{true}, LtNumber(one, 2.5))
   426  		require.Equal(t, []bool{true, true, false, false}, LtNumber(four, 2.5))
   427  		require.Equal(t, []bool{true, true, false, false, false}, LtNumber(five, 2.5))
   428  		require.Panics(t, func() { LtNumber_Into(dstBool, five, 2.5) })
   429  
   430  		require.Equal(t, []bool{}, Lte(empty, empty))
   431  		require.Equal(t, []bool{true}, Lte(one, one))
   432  		require.Equal(t, []bool{false}, Lte(AddNumber(one, 1), one))
   433  		require.Equal(t, []bool{true, true, true, true}, Lte(four, four))
   434  		require.Equal(t, []bool{false, false, false, false}, Lte(AddNumber(four, 1), four))
   435  		require.Equal(t, []bool{true, true, true, true, true}, Lte(five, five))
   436  		require.Equal(t, []bool{false, false, false, false, false}, Lte(AddNumber(five, 1), five))
   437  		require.Panics(t, func() { Lte_Into(dstBool, five, five) })
   438  
   439  		require.Equal(t, []bool{}, LteNumber(empty, 2.5))
   440  		require.Equal(t, []bool{true}, LteNumber(one, 2.5))
   441  		require.Equal(t, []bool{true, true, true, false}, LteNumber(four, 3.0))
   442  		require.Equal(t, []bool{true, true, true, false, false}, LteNumber(five, 3.0))
   443  		require.Panics(t, func() { LteNumber_Into(dstBool, five, 2.5) })
   444  
   445  		require.Equal(t, []bool{}, Gt(empty, empty))
   446  		require.Equal(t, []bool{false}, Gt(one, one))
   447  		require.Equal(t, []bool{true}, Gt(one, negOne))
   448  		require.Equal(t, []bool{false, false, false, false}, Gt(four, four))
   449  		require.Equal(t, []bool{true, true, true, true}, Gt(four, negFour))
   450  		require.Equal(t, []bool{false, false, false, false, false}, Gt(five, five))
   451  		require.Equal(t, []bool{true, true, true, true, true}, Gt(five, negFive))
   452  		require.Panics(t, func() { Gt_Into(dstBool, five, five) })
   453  
   454  		require.Equal(t, []bool{}, GtNumber(empty, 2.5))
   455  		require.Equal(t, []bool{false}, GtNumber(one, 2.5))
   456  		require.Equal(t, []bool{false, false, true, true}, GtNumber(four, 2.5))
   457  		require.Equal(t, []bool{false, false, true, true, true}, GtNumber(five, 2.5))
   458  		require.Panics(t, func() { GtNumber_Into(dstBool, five, 2.5) })
   459  
   460  		require.Equal(t, []bool{}, Gte(empty, empty))
   461  		require.Equal(t, []bool{true}, Gte(one, one))
   462  		require.Equal(t, []bool{false}, Gte(one, AddNumber(one, 1)))
   463  		require.Equal(t, []bool{true, true, true, true}, Gte(four, four))
   464  		require.Equal(t, []bool{false, false, false, false}, Gte(four, AddNumber(four, 1)))
   465  		require.Equal(t, []bool{true, true, true, true, true}, Gte(five, five))
   466  		require.Equal(t, []bool{false, false, false, false, false}, Gte(five, AddNumber(five, 1)))
   467  		require.Panics(t, func() { Gte_Into(dstBool, five, five) })
   468  
   469  		require.Equal(t, []bool{}, GteNumber(empty, 2.5))
   470  		require.Equal(t, []bool{true}, GteNumber(one, 1.0))
   471  		require.Equal(t, []bool{false}, GteNumber(one, 2.5))
   472  		require.Equal(t, []bool{false, false, true, true}, GteNumber(four, 3.0))
   473  		require.Equal(t, []bool{false, false, true, true, true}, GteNumber(five, 3.0))
   474  		require.Panics(t, func() { GteNumber_Into(dstBool, five, 2.5) })
   475  
   476  		require.Equal(t, []bool{}, Eq(empty, empty))
   477  		require.Equal(t, []bool{true}, Eq(one, one))
   478  		require.Equal(t, []bool{false}, Eq(negOne, one))
   479  		require.Equal(t, []bool{true, true, true, true}, Eq(four, four))
   480  		require.Equal(t, []bool{false, false, false, false}, Eq(negFour, four))
   481  		require.Equal(t, []bool{true, true, true, true, true}, Eq(five, five))
   482  		require.Equal(t, []bool{false, false, false, false, false}, Eq(negFive, five))
   483  		require.Panics(t, func() { Eq_Into(dstBool, five, five) })
   484  
   485  		require.Equal(t, []bool{}, EqNumber(empty, 2.5))
   486  		require.Equal(t, []bool{true}, EqNumber(one, 1.0))
   487  		require.Equal(t, []bool{false}, EqNumber(one, 2.5))
   488  		require.Equal(t, []bool{false, false, true, false}, EqNumber(four, 3.0))
   489  		require.Equal(t, []bool{false, false, true, false, false}, EqNumber(five, 3.0))
   490  		require.Panics(t, func() { EqNumber_Into(dstBool, five, 2.5) })
   491  
   492  		require.Equal(t, []bool{}, Neq(empty, empty))
   493  		require.Equal(t, []bool{false}, Neq(one, one))
   494  		require.Equal(t, []bool{true}, Neq(negOne, one))
   495  		require.Equal(t, []bool{false, false, false, false}, Neq(four, four))
   496  		require.Equal(t, []bool{true, true, true, true}, Neq(negFour, four))
   497  		require.Equal(t, []bool{false, false, false, false, false}, Neq(five, five))
   498  		require.Equal(t, []bool{true, true, true, true, true}, Neq(negFive, five))
   499  		require.Panics(t, func() { Neq_Into(dstBool, five, five) })
   500  
   501  		require.Equal(t, []bool{}, NeqNumber(empty, 2.5))
   502  		require.Equal(t, []bool{true}, NeqNumber(one, 2.5))
   503  		require.Equal(t, []bool{false}, NeqNumber(one, 1.0))
   504  		require.Equal(t, []bool{true, true, false, true}, NeqNumber(four, 3.0))
   505  		require.Equal(t, []bool{true, true, false, true, true}, NeqNumber(five, 3.0))
   506  		require.Panics(t, func() { NeqNumber_Into(dstBool, five, 2.5) })
   507  	}
   508  }
   509  
   510  func TestBool(t *testing.T) {
   511  	var emptyBool []bool = []bool{}
   512  	var oneBool []bool = []bool{true}
   513  	var twoBool []bool = []bool{true, false}
   514  	var thirtyTwoBool []bool = append(ToBool(Ones(16)), ToBool(Zeros(16))...) // AVX register
   515  	var negThirtyTwoBool []bool = append(ToBool(Zeros(16)), ToBool(Ones(16))...)
   516  	var thirtyThreeBool []bool = append(ToBool(Ones(16)), ToBool(Zeros(17))...)
   517  	var negThirtyThreeBool []bool = append(ToBool(Zeros(16)), ToBool(Ones(17))...)
   518  
   519  	dstBool := make([]bool, 4)
   520  
   521  	for _, accel := range accel {
   522  		SetAcceleration(accel)
   523  
   524  		require.Equal(t, []bool{}, Not(emptyBool))
   525  		require.Equal(t, []bool{false}, Not(oneBool))
   526  		require.Equal(t, []bool{false, true}, Not(twoBool))
   527  		require.Equal(t, negThirtyTwoBool, Not(thirtyTwoBool))
   528  		require.Equal(t, negThirtyThreeBool, Not(thirtyThreeBool))
   529  		require.Panics(t, func() { Not_Into(dstBool, thirtyTwoBool) })
   530  
   531  		require.Panics(t, func() { And(oneBool, twoBool) })
   532  		require.Equal(t, []bool{}, And(emptyBool, nil))
   533  		require.Equal(t, []bool{true}, And(oneBool, oneBool))
   534  		require.Equal(t, []bool{true, false}, And(twoBool, twoBool))
   535  		require.Equal(t, thirtyTwoBool, And(thirtyTwoBool, thirtyTwoBool))
   536  		require.Equal(t, ToBool(Zeros(32)), And(thirtyTwoBool, negThirtyTwoBool))
   537  		require.Equal(t, thirtyThreeBool, And(thirtyThreeBool, thirtyThreeBool))
   538  		require.Equal(t, ToBool(Zeros(33)), And(thirtyThreeBool, negThirtyThreeBool))
   539  		require.Panics(t, func() { And_Into(dstBool, thirtyTwoBool, thirtyTwoBool) })
   540  
   541  		require.Panics(t, func() { Or(oneBool, twoBool) })
   542  		require.Equal(t, []bool{}, Or(emptyBool, nil))
   543  		require.Equal(t, []bool{true}, Or(oneBool, oneBool))
   544  		require.Equal(t, []bool{true, false}, Or(twoBool, twoBool))
   545  		require.Equal(t, thirtyTwoBool, Or(thirtyTwoBool, thirtyTwoBool))
   546  		require.Equal(t, ToBool(Ones(32)), Or(thirtyTwoBool, negThirtyTwoBool))
   547  		require.Equal(t, thirtyThreeBool, Or(thirtyThreeBool, thirtyThreeBool))
   548  		require.Equal(t, ToBool(Ones(33)), Or(thirtyThreeBool, negThirtyThreeBool))
   549  		require.Panics(t, func() { Or_Into(dstBool, thirtyTwoBool, thirtyTwoBool) })
   550  
   551  		require.Panics(t, func() { Xor(oneBool, twoBool) })
   552  		require.Equal(t, []bool{}, Xor(emptyBool, nil))
   553  		require.Equal(t, []bool{false}, Xor(oneBool, oneBool))
   554  		require.Equal(t, []bool{false, false}, Xor(twoBool, twoBool))
   555  		require.Equal(t, ToBool(Zeros(32)), Xor(thirtyTwoBool, thirtyTwoBool))
   556  		require.Equal(t, ToBool(Ones(32)), Xor(thirtyTwoBool, negThirtyTwoBool))
   557  		require.Equal(t, ToBool(Zeros(33)), Xor(thirtyThreeBool, thirtyThreeBool))
   558  		require.Equal(t, ToBool(Ones(33)), Xor(thirtyThreeBool, negThirtyThreeBool))
   559  		require.Panics(t, func() { Xor_Into(dstBool, thirtyTwoBool, thirtyTwoBool) })
   560  
   561  		dst := make([]float64, 4)
   562  
   563  		require.Panics(t, func() { Select(one, twoBool) })
   564  		require.Equal(t, empty, Select(empty, emptyBool))
   565  		require.Equal(t, one, Select(one, []bool{true}))
   566  		require.Equal(t, empty, Select(one, []bool{false}))
   567  		require.Equal(t, Range(1, 17), Select(Range(1, 33), thirtyTwoBool))
   568  		require.Equal(t, Range(17, 34), Select(Range(1, 34), negThirtyThreeBool))
   569  		dst = Select_Into(dst, Range(1, 34), negThirtyThreeBool) // no capacity check as result size is unknown
   570  		require.Equal(t, Range(17, 34), dst)
   571  
   572  		require.Equal(t, true, All(emptyBool))
   573  		require.Equal(t, true, All(oneBool))
   574  		require.Equal(t, false, All(thirtyTwoBool))
   575  		require.Equal(t, true, All(ToBool(Ones(32))))
   576  		require.Equal(t, false, All(thirtyThreeBool))
   577  		require.Equal(t, true, All(ToBool(Ones(33))))
   578  
   579  		require.Equal(t, false, Any(emptyBool))
   580  		require.Equal(t, true, Any(oneBool))
   581  		require.Equal(t, true, Any(thirtyTwoBool))
   582  		require.Equal(t, false, Any(ToBool(Zeros(32))))
   583  		require.Equal(t, true, Any(thirtyThreeBool))
   584  		require.Equal(t, false, Any(ToBool(Zeros(33))))
   585  
   586  		require.Equal(t, true, None(emptyBool))
   587  		require.Equal(t, false, None(oneBool))
   588  		require.Equal(t, false, None(thirtyTwoBool))
   589  		require.Equal(t, true, None(ToBool(Zeros(32))))
   590  		require.Equal(t, false, None(thirtyThreeBool))
   591  		require.Equal(t, true, None(ToBool(Zeros(33))))
   592  
   593  		require.Equal(t, 0, Count(emptyBool))
   594  		require.Equal(t, 1, Count(oneBool))
   595  		require.Equal(t, 16, Count(thirtyTwoBool))
   596  		require.Equal(t, 0, Count(ToBool(Zeros(32))))
   597  		require.Equal(t, 32, Count(ToBool(Ones(32))))
   598  		require.Equal(t, 16, Count(thirtyThreeBool))
   599  		require.Equal(t, 0, Count(ToBool(Zeros(33))))
   600  		require.Equal(t, 33, Count(ToBool(Ones(33))))
   601  	}
   602  }
   603  
   604  func TestConstruction(t *testing.T) {
   605  	for _, accel := range accel {
   606  		SetAcceleration(accel)
   607  
   608  		dst := make([]float64, 4)
   609  
   610  		require.Equal(t, empty, Zeros(0))
   611  		require.Equal(t, []float64{0}, Zeros(1))
   612  		require.Equal(t, []float64{0, 0, 0, 0}, Zeros(4))
   613  		require.Equal(t, []float64{0, 0, 0, 0, 0}, Zeros(5))
   614  		require.Panics(t, func() { Zeros_Into(dst, 5) })
   615  
   616  		require.Equal(t, empty, Ones(0))
   617  		require.Equal(t, []float64{1}, Ones(1))
   618  		require.Equal(t, []float64{1, 1, 1, 1}, Ones(4))
   619  		require.Equal(t, []float64{1, 1, 1, 1, 1}, Ones(5))
   620  		require.Panics(t, func() { Ones_Into(dst, 5) })
   621  
   622  		require.Panics(t, func() { Repeat(3, -1) })
   623  		require.Equal(t, empty, Repeat(3, 0))
   624  		require.Equal(t, []float64{3}, Repeat(3, 1))
   625  		require.Equal(t, []float64{3, 3, 3, 3}, Repeat(3, 4))
   626  		require.Equal(t, []float64{3, 3, 3, 3, 3}, Repeat(3, 5))
   627  		require.Panics(t, func() { Repeat_Into(dst, 3, 5) })
   628  
   629  		require.Equal(t, empty, Range(0, 0))
   630  		require.Equal(t, empty, Range(1, 0))
   631  		require.Equal(t, []float64{0}, Range(0, 0.1))
   632  		require.Equal(t, []float64{0}, Range(0, 1))
   633  		require.Equal(t, []float64{-0.3, 0.7, 1.7}, Range(-0.3, 1.8))
   634  		require.Equal(t, []float64{0, 1, 2, 3}, Range(0, 4))
   635  		require.Equal(t, []float64{0, 1, 2, 3, 4}, Range(0, 5))
   636  		require.Panics(t, func() { Range_Into(dst, 0, 5) })
   637  
   638  		require.Panics(t, func() { Gather(one, []int{-1}) })
   639  		require.Equal(t, empty, Gather(empty, []int{}))
   640  		require.Equal(t, []float64{1}, Gather(one, []int{0}))
   641  		require.Equal(t, []float64{1, 1}, Gather(one, []int{0, 0}))
   642  		require.Equal(t, []float64{4, 2}, Gather(four, []int{3, 1}))
   643  		require.Equal(t, []float64{5, 2, 5}, Gather(five, []int{4, 1, 4}))
   644  		require.Panics(t, func() { Gather_Into(dst, five, []int{0, 0, 0, 0, 0}) })
   645  
   646  		require.Panics(t, func() { Scatter(one, []int{}, -1) })
   647  		require.Panics(t, func() { Scatter(one, []int{0, 0}, 1) })
   648  		require.Equal(t, empty, Scatter(empty, []int{}, 0))
   649  		require.Equal(t, []float64{0}, Scatter(empty, []int{}, 1))
   650  		require.Equal(t, []float64{1}, Scatter(one, []int{0}, 1))
   651  		require.Equal(t, []float64{2, 0, 1}, Scatter(two, []int{2, 0}, 3))
   652  		require.Equal(t, []float64{3, 4}, Scatter(four, []int{1, 0, 0, 1}, 2))
   653  		require.Equal(t, []float64{5, 4, 3, 2, 1, 0}, Scatter(five, []int{4, 3, 2, 1, 0}, 6))
   654  
   655  		require.Equal(t, empty, FromBool([]bool{}))
   656  		require.Equal(t, []float64{1}, FromBool([]bool{true}))
   657  		require.Equal(t, []float64{0, 1}, FromBool([]bool{false, true}))
   658  		require.Equal(t, []float64{0, 1, 0, 1}, FromBool([]bool{false, true, false, true}))
   659  		require.Equal(t, []float64{0, 1, 0, 1, 1}, FromBool([]bool{false, true, false, true, true}))
   660  		require.Panics(t, func() { FromBool_Into(dst, []bool{false, false, false, false, false}) })
   661  
   662  		require.Equal(t, empty, FromInt32([]int32{}))
   663  		require.Equal(t, []float64{5}, FromInt32([]int32{5}))
   664  		require.Equal(t, []float64{5, -5}, FromInt32([]int32{5, -5}))
   665  		require.Equal(t, []float64{5, -5, 5, 1}, FromInt32([]int32{5, -5, 5, 1}))
   666  		require.Equal(t, []float64{5, -5, 5, 1, 0}, FromInt32([]int32{5, -5, 5, 1, 0}))
   667  		require.Panics(t, func() { FromInt32_Into(dst, []int32{1, 2, 3, 4, 5}) })
   668  	}
   669  }