gitee.com/quant1x/num@v0.3.2/x64/vek_test.go (about)

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