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

     1  package num32
     2  
     3  import (
     4  	"gitee.com/quant1x/gox/num"
     5  	"gitee.com/quant1x/gox/num/internal/functions"
     6  	"github.com/chewxy/math32"
     7  	"golang.org/x/exp/constraints"
     8  	"golang.org/x/exp/slices"
     9  	"unsafe"
    10  )
    11  
    12  // Arithmetic
    13  
    14  // Add returns the result of adding two slices element-wise.
    15  func Add(x, y []float32) []float32 {
    16  	x = slices.Clone(x)
    17  	Add_Inplace(x, y)
    18  	return x
    19  }
    20  
    21  // Add_Inplace adds a slice element-wise to the first slice, inplace.
    22  func Add_Inplace(x, y []float32) {
    23  	checkEqualLength(x, y)
    24  	checkOverlap(x, y)
    25  	if functions.UseAVX2 {
    26  		functions.Add_AVX2_F32(x, y)
    27  	} else {
    28  		functions.Add_Go(x, y)
    29  	}
    30  }
    31  
    32  // Add_Into adds two slices element-wise and stores the result in the destination slice.
    33  func Add_Into(dst, x, y []float32) []float32 {
    34  	dst = checkCapacity(dst, x)
    35  	checkOverlap(dst, x)
    36  	copy(dst, x)
    37  	Add_Inplace(dst, y)
    38  	return dst
    39  }
    40  
    41  // Sub returns the result of subtracting two slices element-wise.
    42  func Sub(x, y []float32) []float32 {
    43  	x = slices.Clone(x)
    44  	Sub_Inplace(x, y)
    45  	return x
    46  }
    47  
    48  // Sub_Inplace subtracts a slice element-wise from the first slice, inplace.
    49  func Sub_Inplace(x, y []float32) {
    50  	checkEqualLength(x, y)
    51  	checkOverlap(x, y)
    52  	if functions.UseAVX2 {
    53  		functions.Sub_AVX2_F32(x, y)
    54  	} else {
    55  		functions.Sub_Go(x, y)
    56  	}
    57  }
    58  
    59  // Sub_Into subtracts two slices element-wise and stores the result in the destination slice.
    60  func Sub_Into(dst, x, y []float32) []float32 {
    61  	dst = checkCapacity(dst, x)
    62  	checkOverlap(dst, x)
    63  	copy(dst, x)
    64  	Sub_Inplace(dst, y)
    65  	return dst
    66  }
    67  
    68  // Mul returns the result of multiplying two slices element-wise.
    69  func Mul(x, y []float32) []float32 {
    70  	x = slices.Clone(x)
    71  	Mul_Inplace(x, y)
    72  	return x
    73  }
    74  
    75  // Mul_Inplace multiplies the first slice element-wise by the second, inplace.
    76  func Mul_Inplace(x, y []float32) {
    77  	checkEqualLength(x, y)
    78  	checkOverlap(x, y)
    79  	if functions.UseAVX2 {
    80  		functions.Mul_AVX2_F32(x, y)
    81  	} else {
    82  		functions.Mul_Go(x, y)
    83  	}
    84  }
    85  
    86  // Mul_Into multiplies two slices element-wise and stores the result in the destination slice.
    87  func Mul_Into(dst, x, y []float32) []float32 {
    88  	dst = checkCapacity(dst, x)
    89  	checkOverlap(dst, x)
    90  	copy(dst, x)
    91  	Mul_Inplace(dst, y)
    92  	return dst
    93  }
    94  
    95  // Div returns the result of dividing two slices element-wise.
    96  func Div(x, y []float32) []float32 {
    97  	x = slices.Clone(x)
    98  	Div_Inplace(x, y)
    99  	return x
   100  }
   101  
   102  // Div_Inplace divides the first slice element-wise by the second, inplace.
   103  func Div_Inplace(x, y []float32) {
   104  	checkEqualLength(x, y)
   105  	checkOverlap(x, y)
   106  	if functions.UseAVX2 {
   107  		functions.Div_AVX2_F32(x, y)
   108  	} else {
   109  		functions.Div_Go(x, y)
   110  	}
   111  }
   112  
   113  // Div_Into divides two slices element-wise and stores the result in the destination slice.
   114  func Div_Into(dst, x, y []float32) []float32 {
   115  	dst = checkCapacity(dst, x)
   116  	checkOverlap(dst, x)
   117  	copy(dst, x)
   118  	Div_Inplace(dst, y)
   119  	return dst
   120  }
   121  
   122  // AddNumber returns the result of adding a number to each slice element.
   123  func AddNumber(x []float32, a float32) []float32 {
   124  	x = slices.Clone(x)
   125  	AddNumber_Inplace(x, a)
   126  	return x
   127  }
   128  
   129  // AddNumber_Inplace adds a number to each slice element, inplace.
   130  func AddNumber_Inplace(x []float32, a float32) {
   131  	if functions.UseAVX2 {
   132  		functions.AddNumber_AVX2_F32(x, a)
   133  	} else {
   134  		functions.AddNumber_Go(x, a)
   135  	}
   136  }
   137  
   138  // AddNumber_Into adds a number to each slice element and stores the result in the
   139  // destination slice.
   140  func AddNumber_Into(dst, x []float32, a float32) []float32 {
   141  	dst = checkCapacity(dst, x)
   142  	checkOverlap(dst, x)
   143  	copy(dst, x)
   144  	AddNumber_Inplace(dst, a)
   145  	return dst
   146  }
   147  
   148  // SubNumber returns the result of subtracting a number from each slice element.
   149  func SubNumber(x []float32, a float32) []float32 {
   150  	x = slices.Clone(x)
   151  	SubNumber_Inplace(x, a)
   152  	return x
   153  }
   154  
   155  // SubNumber_Inplace subtracts a number from each slice element, inplace.
   156  func SubNumber_Inplace(x []float32, a float32) {
   157  	if functions.UseAVX2 {
   158  		functions.SubNumber_AVX2_F32(x, a)
   159  	} else {
   160  		functions.SubNumber_Go(x, a)
   161  	}
   162  }
   163  
   164  // SubNumber_Into subtracts a number from each slice element and stores the result in the
   165  // destination slice.
   166  func SubNumber_Into(dst, x []float32, a float32) []float32 {
   167  	dst = checkCapacity(dst, x)
   168  	checkOverlap(dst, x)
   169  	copy(dst, x)
   170  	SubNumber_Inplace(dst, a)
   171  	return dst
   172  }
   173  
   174  // MulNumber returns the result of multiplying each slice element by a number.
   175  func MulNumber(x []float32, a float32) []float32 {
   176  	x = slices.Clone(x)
   177  	MulNumber_Inplace(x, a)
   178  	return x
   179  }
   180  
   181  // MulNumber_Inplace multiplies each slice element by a number, inplace.
   182  func MulNumber_Inplace(x []float32, a float32) {
   183  	if functions.UseAVX2 {
   184  		functions.MulNumber_AVX2_F32(x, a)
   185  	} else {
   186  		functions.MulNumber_Go(x, a)
   187  	}
   188  }
   189  
   190  // MulNumber_Into multiplies each slice element by a number and stores the result in the
   191  // destination slice.
   192  func MulNumber_Into(dst, x []float32, a float32) []float32 {
   193  	dst = checkCapacity(dst, x)
   194  	checkOverlap(dst, x)
   195  	copy(dst, x)
   196  	MulNumber_Inplace(dst, a)
   197  	return dst
   198  }
   199  
   200  // DivNumber returns the result of dividing each slice element by a number.
   201  func DivNumber(x []float32, a float32) []float32 {
   202  	x = slices.Clone(x)
   203  	DivNumber_Inplace(x, a)
   204  	return x
   205  }
   206  
   207  // DivNumber_Inplace divides each slice element by a number, inplace.
   208  func DivNumber_Inplace(x []float32, a float32) {
   209  	if functions.UseAVX2 {
   210  		functions.DivNumber_AVX2_F32(x, a)
   211  	} else {
   212  		functions.DivNumber_Go(x, a)
   213  	}
   214  }
   215  
   216  // DivNumber_Into divides each slice element by a number and stores the result in the
   217  // destination slice.
   218  func DivNumber_Into(dst, x []float32, a float32) []float32 {
   219  	dst = checkCapacity(dst, x)
   220  	checkOverlap(dst, x)
   221  	copy(dst, x)
   222  	DivNumber_Inplace(dst, a)
   223  	return dst
   224  }
   225  
   226  // Abs returns the absolute value of each slice element.
   227  func Abs(x []float32) []float32 {
   228  	x = slices.Clone(x)
   229  	Abs_Inplace(x)
   230  	return x
   231  }
   232  
   233  // Abs_Inplace computes the absolute value of each slice element, inplace.
   234  func Abs_Inplace(x []float32) {
   235  	if functions.UseAVX2 {
   236  		functions.Abs_AVX2_F32(x)
   237  	} else {
   238  		functions.Abs_Go_F32(x)
   239  	}
   240  }
   241  
   242  // Abs_Into computes the absolute value of each slice element and stores the result in the
   243  // destination slice.
   244  func Abs_Into(dst, x []float32) []float32 {
   245  	dst = checkCapacity(dst, x)
   246  	checkOverlap(dst, x)
   247  	copy(dst, x)
   248  	Abs_Inplace(dst)
   249  	return dst
   250  }
   251  
   252  // Neg returns the additive inverse of each slice element.
   253  func Neg(x []float32) []float32 {
   254  	x = slices.Clone(x)
   255  	Neg_Inplace(x)
   256  	return x
   257  }
   258  
   259  // Neg_Inplace computes the additive inverse of each slice element, inplace.
   260  func Neg_Inplace(x []float32) {
   261  	if functions.UseAVX2 {
   262  		functions.Neg_AVX2_F32(x)
   263  	} else {
   264  		functions.Neg_Go(x)
   265  	}
   266  }
   267  
   268  // Neg_Into computes the additive inverse of each slice element and stores the result in the
   269  // destination slice.
   270  func Neg_Into(dst, x []float32) []float32 {
   271  	dst = checkCapacity(dst, x)
   272  	checkOverlap(dst, x)
   273  	copy(dst, x)
   274  	Neg_Inplace(dst)
   275  	return dst
   276  }
   277  
   278  // Inv returns the multiplicative inverse of each slice element.
   279  func Inv(x []float32) []float32 {
   280  	x = slices.Clone(x)
   281  	Inv_Inplace(x)
   282  	return x
   283  }
   284  
   285  // Inv_Inplace computes the multiplicative inverse of each slice element, inplace.
   286  func Inv_Inplace(x []float32) {
   287  	if functions.UseAVX2 {
   288  		functions.Inv_AVX2_F32(x)
   289  	} else {
   290  		functions.Inv_Go(x)
   291  	}
   292  }
   293  
   294  // Inv_Into computes the multiplicative inverse of each slice element and stores the result
   295  // in the destination slice.
   296  func Inv_Into(dst, x []float32) []float32 {
   297  	dst = checkCapacity(dst, x)
   298  	checkOverlap(dst, x)
   299  	copy(dst, x)
   300  	Inv_Inplace(dst)
   301  	return dst
   302  }
   303  
   304  // Aggregates
   305  
   306  // Sum returns the sum of all elements in a slice.
   307  func Sum(x []float32) float32 {
   308  	if functions.UseAVX2 {
   309  		return functions.Sum_AVX2_F32(x)
   310  	} else {
   311  		return functions.Sum_Go(x)
   312  	}
   313  }
   314  
   315  // CumSum returns the cumulative sum of a slice. The element at index i equals the sum of x[:i+1].
   316  func CumSum(x []float32) []float32 {
   317  	x = slices.Clone(x)
   318  	CumSum_Inplace(x)
   319  	return x
   320  }
   321  
   322  // CumSum_Inplace computes the cumulative sum of a slice, inplace. The new element at index i
   323  // equals the sum of x[:i+1].
   324  func CumSum_Inplace(x []float32) {
   325  	if functions.UseAVX2 {
   326  		functions.CumSum_AVX2_F32(x)
   327  	} else {
   328  		functions.CumSum_Go(x)
   329  	}
   330  }
   331  
   332  // CumSum_Into computes the cumulative sum of a slice and stores the result in the destination
   333  // slice. The element at index i equals the sum of x[:i+1].
   334  func CumSum_Into(dst, x []float32) []float32 {
   335  	dst = checkCapacity(dst, x)
   336  	checkOverlap(dst, x)
   337  	copy(dst, x)
   338  	CumSum_Inplace(dst)
   339  	return dst
   340  }
   341  
   342  // Prod returns the product of all elements in a slice.
   343  func Prod(x []float32) float32 {
   344  	if functions.UseAVX2 {
   345  		return functions.Prod_AVX2_F32(x)
   346  	} else {
   347  		return functions.Prod_Go(x)
   348  	}
   349  }
   350  
   351  // CumProd returns the cumulative product of a slice. The element at index i equals the product
   352  // of x[:i+1].
   353  func CumProd(x []float32) []float32 {
   354  	x = slices.Clone(x)
   355  	CumProd_Inplace(x)
   356  	return x
   357  }
   358  
   359  // CumProd_Inplace computes the cumulative product of a slice, inplace. The new element at index i
   360  // equals the product of x[:i+1].
   361  func CumProd_Inplace(x []float32) {
   362  	if functions.UseAVX2 {
   363  		functions.CumProd_AVX2_F32(x)
   364  	} else {
   365  		functions.CumProd_Go(x)
   366  	}
   367  }
   368  
   369  // CumProd_Into computes the cumulative product of a slice and stores the result in the destination
   370  // slice. The element at index i equals the product of x[:i+1].
   371  func CumProd_Into(dst, x []float32) []float32 {
   372  	dst = checkCapacity(dst, x)
   373  	checkOverlap(dst, x)
   374  	copy(dst, x)
   375  	CumProd_Inplace(dst)
   376  	return dst
   377  }
   378  
   379  // Mean returns the arithmetic average of the slice elements.
   380  func Mean(x []float32) float32 {
   381  	checkNotEmpty(x)
   382  	if functions.UseAVX2 {
   383  		return functions.Mean_AVX2_F32(x)
   384  	} else {
   385  		return functions.Mean_Go(x)
   386  	}
   387  }
   388  
   389  // Median returns the median value of the slice elements.
   390  func Median(x []float32) float32 {
   391  	checkNotEmpty(x)
   392  	if functions.UseAVX2 {
   393  		return functions.Median_AVX2_F32(x)
   394  	} else {
   395  		return functions.Median_Go(x)
   396  	}
   397  }
   398  
   399  // Quantile returns the q-th quantile of the slice elements. The value of q should be between
   400  // 0 and 1 (inclusive).
   401  func Quantile(x []float32, q float32) float32 {
   402  	if q < 0 || q > 1 {
   403  		panic("value of q should be between 0 and 1")
   404  	}
   405  	checkNotEmpty(x)
   406  	if functions.UseAVX2 {
   407  		return functions.Quantile_AVX2_F32(x, q)
   408  	} else {
   409  		return functions.Quantile_Go(x, q)
   410  	}
   411  }
   412  
   413  // Distance
   414  
   415  // Dot returns the dot product of two vectors.
   416  func Dot(x, y []float32) float32 {
   417  	checkNotEmpty(x)
   418  	checkEqualLength(x, y)
   419  	if functions.UseAVX2 {
   420  		return functions.Dot_AVX2_F32(x, y)
   421  	} else {
   422  		return functions.Dot_Go(x, y)
   423  	}
   424  }
   425  
   426  // Norm returns the Euclidean norm of a vector, i.e. its length.
   427  func Norm(x []float32) float32 {
   428  	checkNotEmpty(x)
   429  	if functions.UseAVX2 {
   430  		return functions.Norm_AVX2_F32(x)
   431  	} else {
   432  		return functions.Norm_Go_F32(x)
   433  	}
   434  }
   435  
   436  // Distance returns the Euclidean distance between two vectors.
   437  func Distance(x, y []float32) float32 {
   438  	checkNotEmpty(x)
   439  	checkEqualLength(x, y)
   440  	if functions.UseAVX2 {
   441  		return functions.Distance_AVX2_F32(x, y)
   442  	} else {
   443  		return functions.Distance_Go_F32(x, y)
   444  	}
   445  }
   446  
   447  // ManhattanNorm returns the sum of absolute values of the slice elements.
   448  func ManhattanNorm(x []float32) float32 {
   449  	checkNotEmpty(x)
   450  	if functions.UseAVX2 {
   451  		return functions.ManhattanNorm_AVX2_F32(x)
   452  	} else {
   453  		return functions.ManhattanNorm_Go_F32(x)
   454  	}
   455  }
   456  
   457  // ManhattanDistance returns the sum of element-wise absolute differences between two slices.
   458  func ManhattanDistance(x, y []float32) float32 {
   459  	checkNotEmpty(x)
   460  	checkEqualLength(x, y)
   461  	if functions.UseAVX2 {
   462  		return functions.ManhattanDistance_AVX2_F32(x, y)
   463  	} else {
   464  		return functions.ManhattanDistance_Go_F32(x, y)
   465  	}
   466  }
   467  
   468  // CosineSimilarity returns the cosine similarity of two vectors.
   469  func CosineSimilarity(x, y []float32) float32 {
   470  	checkNotEmpty(x)
   471  	checkEqualLength(x, y)
   472  	if functions.UseAVX2 {
   473  		return functions.CosineSimilarity_AVX2_F32(x, y)
   474  	} else {
   475  		return functions.CosineSimilarity_Go_F32(x, y)
   476  	}
   477  }
   478  
   479  // Matrices
   480  
   481  func checkDimensions[T constraints.Float](x, y []T, n int) (int, int) {
   482  	m := len(x) / n
   483  	p := len(y) / n
   484  	if m*n < len(x) || n*p < len(y) {
   485  		panic("slice lengths must be multiple of n")
   486  	}
   487  	return m, p
   488  }
   489  
   490  // MatMul multiplies an m-by-n and n-by-p matrix and returns the resulting m-by-p matrix.
   491  // The matrices should be in row-major order. To multiply a matrix and a vector pass an
   492  // n-by-1 matrix.
   493  func MatMul(x, y []float32, n int) []float32 {
   494  	m, p := checkDimensions(x, y, n)
   495  	dst := make([]float32, m*p)
   496  	if functions.UseAVX2 {
   497  		functions.MatMul_Parallel_AVX2_F32(dst, x, y, m, n, p)
   498  	} else {
   499  		functions.MatMul_Parallel_Go(dst, x, y, m, n, p)
   500  	}
   501  	return dst
   502  }
   503  
   504  // MatMul_Into multiplies an m-by-n and n-by-p matrix and stores the resulting m-by-p matrix
   505  // in the destination slice. The matrices should be in row-major order. To multiply a matrix
   506  // and a vector pass an n-by-1 matrix.
   507  func MatMul_Into(dst, x, y []float32, n int) []float32 {
   508  	m, p := checkDimensions(x, y, n)
   509  	if cap(dst) < m*p {
   510  		panic("destination slice not large enough to hold result")
   511  	}
   512  	Zeros_Into(dst, m*p)
   513  	if functions.UseAVX2 {
   514  		functions.MatMul_Parallel_AVX2_F32(dst, x, y, m, n, p)
   515  	} else {
   516  		functions.MatMul_Parallel_Go(dst, x, y, m, n, p)
   517  	}
   518  	return dst[:m*p]
   519  }
   520  
   521  // Mat4Mul multiplies two 4-by-4 matrices and returns the resulting 4-by-4 matrix. The matrices
   522  // should be in row-major order. To multiply a matrix and a vector batch them into groups of 4.
   523  func Mat4Mul(x, y []float32) []float32 {
   524  	var dst [16]float32
   525  	return Mat4Mul_Into(dst[:], x, y)
   526  }
   527  
   528  // Mat4Mul_Into multiplies two 4-by-4 matrices and stores the resulting 4-by-4 matrix in the
   529  // destination slice. The matrices should be in row-major order. To multiply a matrix and a vector
   530  // batch them into groups of 4.
   531  func Mat4Mul_Into(dst, x, y []float32) []float32 {
   532  	// Note: skipping overlap check due to overhead
   533  	if cap(dst) < 16 || len(x) != 16 || len(y) != 16 {
   534  		panic("slices must be length 16 (4 by 4)")
   535  	}
   536  	if functions.UseAVX2 {
   537  		functions.Mat4Mul_AVX2_F32(dst, x, y)
   538  	} else {
   539  		functions.Mat4Mul_Go(dst, x, y)
   540  	}
   541  	return dst[:16]
   542  }
   543  
   544  // Special
   545  
   546  // Sqrt returns the square root of each slice element.
   547  func Sqrt(x []float32) []float32 {
   548  	x = slices.Clone(x)
   549  	Sqrt_Inplace(x)
   550  	return x
   551  }
   552  
   553  // Sqrt_Inplace computes the square root of each slice element, inplace.
   554  func Sqrt_Inplace(x []float32) {
   555  	if functions.UseAVX2 {
   556  		functions.Sqrt_AVX2_F32(x)
   557  	} else {
   558  		functions.Sqrt_Go_F32(x)
   559  	}
   560  }
   561  
   562  // Sqrt_Into computes the square root of each slice element and stores the result in the
   563  // destination slice.
   564  func Sqrt_Into(dst, x []float32) []float32 {
   565  	dst = checkCapacity(dst, x)
   566  	checkOverlap(dst, x)
   567  	copy(dst, x)
   568  	Sqrt_Inplace(dst)
   569  	return dst
   570  }
   571  
   572  // Round returns the result of rounding each slice element to the nearest integer value.
   573  func Round(x []float32) []float32 {
   574  	x = slices.Clone(x)
   575  	Round_Inplace(x)
   576  	return x
   577  }
   578  
   579  // Round_Inplace rounds each slice element to the nearest integer value, inplace.
   580  func Round_Inplace(x []float32) {
   581  	if functions.UseAVX2 {
   582  		functions.Round_AVX2_F32(x)
   583  	} else {
   584  		functions.Round_Go_F32(x)
   585  	}
   586  }
   587  
   588  // Round_Into rounds each slice element to the nearest integer value and stores the result
   589  // in the destination slice.
   590  func Round_Into(dst, x []float32) []float32 {
   591  	dst = checkCapacity(dst, x)
   592  	checkOverlap(dst, x)
   593  	copy(dst, x)
   594  	Round_Inplace(dst)
   595  	return dst
   596  }
   597  
   598  // Floor returns the result of rounding each slice element to the nearest lesser integer value.
   599  func Floor(x []float32) []float32 {
   600  	x = slices.Clone(x)
   601  	Floor_Inplace(x)
   602  	return x
   603  }
   604  
   605  // Floor_Inplace rounds each slice element to the nearest lesser integer value, inplace.
   606  func Floor_Inplace(x []float32) {
   607  	if functions.UseAVX2 {
   608  		functions.Floor_AVX2_F32(x)
   609  	} else {
   610  		functions.Floor_Go_F32(x)
   611  	}
   612  }
   613  
   614  // Floor_Into rounds each slice element to the nearest lesser integer value and stores the result
   615  // in the destination slice.
   616  func Floor_Into(dst, x []float32) []float32 {
   617  	dst = checkCapacity(dst, x)
   618  	checkOverlap(dst, x)
   619  	copy(dst, x)
   620  	Floor_Inplace(dst)
   621  	return dst
   622  }
   623  
   624  // Ceil returns the result of rounding each slice element to the nearest greater integer value.
   625  func Ceil(x []float32) []float32 {
   626  	x = slices.Clone(x)
   627  	Ceil_Inplace(x)
   628  	return x
   629  }
   630  
   631  // Ceil_Inplace rounds each slice element to the nearest greater integer value, inplace.
   632  func Ceil_Inplace(x []float32) {
   633  	if functions.UseAVX2 {
   634  		functions.Ceil_AVX2_F32(x)
   635  	} else {
   636  		functions.Ceil_Go_F32(x)
   637  	}
   638  }
   639  
   640  // Ceil_Into rounds each slice element to the nearest greater integer value and stores the result
   641  // in the destination slice.
   642  func Ceil_Into(dst, x []float32) []float32 {
   643  	dst = checkCapacity(dst, x)
   644  	checkOverlap(dst, x)
   645  	copy(dst, x)
   646  	Ceil_Inplace(dst)
   647  	return dst
   648  }
   649  
   650  // Pow returns the elements in the first slice raised to the power in the second.
   651  func Pow(x, y []float32) []float32 {
   652  	x = slices.Clone(x)
   653  	Pow_Inplace(x, y)
   654  	return x
   655  }
   656  
   657  // Pow_Inplace raises the elements in the first slice to the power in the second, inplace.
   658  func Pow_Inplace(x, y []float32) {
   659  	checkEqualLength(x, y)
   660  	checkOverlap(x, y)
   661  	if functions.UseAVX2 {
   662  		functions.Pow_AVX2_F32(x, y)
   663  	} else {
   664  		functions.Pow_Go_F32(x, y)
   665  	}
   666  }
   667  
   668  // Pow_Into raises the elements in the first slice to the power in the second and stores the
   669  // result in the destination slice.
   670  func Pow_Into(dst, x, y []float32) []float32 {
   671  	dst = checkCapacity(dst, x)
   672  	checkOverlap(dst, x)
   673  	copy(dst, x)
   674  	Pow_Inplace(dst, y)
   675  	return dst
   676  }
   677  
   678  // Special (32-bit only)
   679  
   680  // Sin returns the sine of each element.
   681  func Sin(x []float32) []float32 {
   682  	x = slices.Clone(x)
   683  	Sin_Inplace(x)
   684  	return x
   685  }
   686  
   687  // Sin_Inplace computes the sine of each element, inplace.
   688  func Sin_Inplace(x []float32) {
   689  	if functions.UseAVX2 {
   690  		functions.Sin_AVX2_F32(x)
   691  	} else {
   692  		functions.Sin_Go_F32(x)
   693  	}
   694  }
   695  
   696  // Sin_Into stores the sine of each element in the destination slice.
   697  func Sin_Into(dst, x []float32) []float32 {
   698  	dst = checkCapacity(dst, x)
   699  	checkOverlap(dst, x)
   700  	copy(dst, x)
   701  	Sin_Inplace(dst)
   702  	return dst
   703  }
   704  
   705  // Cos returns the cosine of each element.
   706  func Cos(x []float32) []float32 {
   707  	x = slices.Clone(x)
   708  	Cos_Inplace(x)
   709  	return x
   710  }
   711  
   712  // Cos_Inplace computes the cosine of each element, inplace.
   713  func Cos_Inplace(x []float32) {
   714  	if functions.UseAVX2 {
   715  		functions.Cos_AVX2_F32(x)
   716  	} else {
   717  		functions.Cos_Go_F32(x)
   718  	}
   719  }
   720  
   721  // Cos_Into stores the cosine of each element in the destination slice.
   722  func Cos_Into(dst, x []float32) []float32 {
   723  	dst = checkCapacity(dst, x)
   724  	checkOverlap(dst, x)
   725  	copy(dst, x)
   726  	Cos_Inplace(dst)
   727  	return dst
   728  }
   729  
   730  // SinCos_Into stores the sine and cosine of each element in the destination slices. Faster than
   731  // calling Sin_Into and Cos_Into individually if both are needed.
   732  func SinCos_Into(dstSin, dstCos, x []float32) {
   733  	dstSin = checkCapacity(dstSin, x)
   734  	dstCos = checkCapacity(dstCos, x)
   735  	checkOverlap(dstSin, x)
   736  	checkOverlap(dstCos, x)
   737  	if functions.UseAVX2 {
   738  		functions.SinCos_AVX2_F32(dstSin, dstCos, x)
   739  	} else {
   740  		functions.SinCos_Go_F32(dstSin, dstCos, x)
   741  	}
   742  }
   743  
   744  // Exp returns the exponential of each element.
   745  func Exp(x []float32) []float32 {
   746  	x = slices.Clone(x)
   747  	Exp_Inplace(x)
   748  	return x
   749  }
   750  
   751  // Exp_Inplace computes the exponential of each element, inplace.
   752  func Exp_Inplace(x []float32) {
   753  	if functions.UseAVX2 {
   754  		functions.Exp_AVX2_F32(x)
   755  	} else {
   756  		functions.Exp_Go_F32(x)
   757  	}
   758  }
   759  
   760  // Exp_Into stores the exponential of each element in the destination slice.
   761  func Exp_Into(dst, x []float32) []float32 {
   762  	dst = checkCapacity(dst, x)
   763  	checkOverlap(dst, x)
   764  	copy(dst, x)
   765  	Exp_Inplace(dst)
   766  	return dst
   767  }
   768  
   769  // Log returns the natural logarithm of each element.
   770  func Log(x []float32) []float32 {
   771  	x = slices.Clone(x)
   772  	Log_Inplace(x)
   773  	return x
   774  }
   775  
   776  // Log_Inplace computes the natural logarithm of each element, inplace.
   777  func Log_Inplace(x []float32) {
   778  	if functions.UseAVX2 {
   779  		functions.Log_AVX2_F32(x)
   780  	} else {
   781  		functions.Log_Go_F32(x)
   782  	}
   783  }
   784  
   785  // Log_Into stores the natural logarithm of each element in the destination slice.
   786  func Log_Into(dst, x []float32) []float32 {
   787  	dst = checkCapacity(dst, x)
   788  	checkOverlap(dst, x)
   789  	copy(dst, x)
   790  	Log_Inplace(dst)
   791  	return dst
   792  }
   793  
   794  // Log2 returns the base 2 logarithm of each element.
   795  func Log2(x []float32) []float32 {
   796  	x = slices.Clone(x)
   797  	Log2_Inplace(x)
   798  	return x
   799  }
   800  
   801  // Log2_Inplace computes the base 2 logarithm of each element, inplace.
   802  func Log2_Inplace(x []float32) {
   803  	if functions.UseAVX2 {
   804  		functions.Log2_AVX2_F32(x)
   805  	} else {
   806  		functions.Log2_Go_F32(x)
   807  	}
   808  }
   809  
   810  // Log2_Into stores the base 2 logarithm of each element in the destination slice.
   811  func Log2_Into(dst, x []float32) []float32 {
   812  	dst = checkCapacity(dst, x)
   813  	checkOverlap(dst, x)
   814  	copy(dst, x)
   815  	Log2_Inplace(dst)
   816  	return dst
   817  }
   818  
   819  // Log10 returns the base 10 logarithm of each element.
   820  func Log10(x []float32) []float32 {
   821  	x = slices.Clone(x)
   822  	Log10_Inplace(x)
   823  	return x
   824  }
   825  
   826  // Log10_Inplace computes the base 10 logarithm of each element, inplace.
   827  func Log10_Inplace(x []float32) {
   828  	if functions.UseAVX2 {
   829  		functions.Log10_AVX2_F32(x)
   830  	} else {
   831  		functions.Log10_Go_F32(x)
   832  	}
   833  }
   834  
   835  // Log10_Into stores the base 10 logarithm of each element in the destination slice.
   836  func Log10_Into(dst, x []float32) []float32 {
   837  	dst = checkCapacity(dst, x)
   838  	checkOverlap(dst, x)
   839  	copy(dst, x)
   840  	Log10_Inplace(dst)
   841  	return dst
   842  }
   843  
   844  // Comparison
   845  
   846  // Min returns the minimum value of a slice.
   847  func Min(x []float32) float32 {
   848  	checkNotEmpty(x)
   849  	if functions.UseAVX2 {
   850  		return functions.Min_AVX2_F32(x)
   851  	} else {
   852  		return functions.Min_Go(x)
   853  	}
   854  }
   855  
   856  // ArgMin returns the (first) index of the minimum value of a slice.
   857  func ArgMin(x []float32) int {
   858  	checkNotEmpty(x)
   859  	if functions.UseAVX2 {
   860  		return functions.ArgMin_AVX2_F32(x)
   861  	} else {
   862  		return functions.ArgMin_Go(x)
   863  	}
   864  }
   865  
   866  // Minimum returns the element-wise minimum values between two slices.
   867  func Minimum(x, y []float32) []float32 {
   868  	x = slices.Clone(x)
   869  	Minimum_Inplace(x, y)
   870  	return x
   871  }
   872  
   873  // Minimum_Inplace compares two slices element-wise and replaces the values in the first slice
   874  // with the minimum value.
   875  func Minimum_Inplace(x, y []float32) {
   876  	checkEqualLength(x, y)
   877  	checkOverlap(x, y)
   878  	if functions.UseAVX2 {
   879  		functions.Minimum_AVX2_F32(x, y)
   880  	} else {
   881  		functions.Minimum_Go(x, y)
   882  	}
   883  }
   884  
   885  // Minimum_Into compares two slices element-wise and stores the minimum values in the destination
   886  // slice.
   887  func Minimum_Into(dst, x, y []float32) []float32 {
   888  	dst = checkCapacity(dst, x)
   889  	checkOverlap(dst, x)
   890  	copy(dst, x)
   891  	Minimum_Inplace(dst, y)
   892  	return dst
   893  }
   894  
   895  // MinimumNumber returns the minimum of a number and each slice element.
   896  func MinimumNumber(x []float32, a float32) []float32 {
   897  	x = slices.Clone(x)
   898  	MinimumNumber_Inplace(x, a)
   899  	return x
   900  }
   901  
   902  // MinimumNumber_Inplace compares a number to each slice element and replaces the values in the
   903  // slice with the minimum value.
   904  func MinimumNumber_Inplace(x []float32, a float32) {
   905  	if functions.UseAVX2 {
   906  		functions.MinimumNumber_AVX2_F32(x, a)
   907  	} else {
   908  		functions.MinimumNumber_Go(x, a)
   909  	}
   910  }
   911  
   912  // MinimumNumber_Into compares a number to each slice element and stores the minimum values in
   913  // the destination slice.
   914  func MinimumNumber_Into(dst, x []float32, a float32) []float32 {
   915  	dst = checkCapacity(dst, x)
   916  	checkOverlap(dst, x)
   917  	copy(dst, x)
   918  	MinimumNumber_Inplace(dst, a)
   919  	return dst
   920  }
   921  
   922  // Max returns the maximum value of a slice.
   923  func Max(x []float32) float32 {
   924  	checkNotEmpty(x)
   925  	if functions.UseAVX2 {
   926  		return functions.Max_AVX2_F32(x)
   927  	} else {
   928  		return functions.Max_Go(x)
   929  	}
   930  }
   931  
   932  // ArgMax returns the (first) index of the maximum value of a slice.
   933  func ArgMax(x []float32) int {
   934  	checkNotEmpty(x)
   935  	if functions.UseAVX2 {
   936  		return functions.ArgMax_AVX2_F32(x)
   937  	} else {
   938  		return functions.ArgMax_Go(x)
   939  	}
   940  }
   941  
   942  // Maximum returns the element-wise maximum values between two slices.
   943  func Maximum(x, y []float32) []float32 {
   944  	x = slices.Clone(x)
   945  	Maximum_Inplace(x, y)
   946  	return x
   947  }
   948  
   949  // Maximum_Inplace compares two slices element-wise and replaces the values in the first slice
   950  // with the maximum value.
   951  func Maximum_Inplace(x, y []float32) {
   952  	checkEqualLength(x, y)
   953  	checkOverlap(x, y)
   954  	if functions.UseAVX2 {
   955  		functions.Maximum_AVX2_F32(x, y)
   956  	} else {
   957  		functions.Maximum_Go(x, y)
   958  	}
   959  }
   960  
   961  // Maximum_Into compares two slices element-wise and stores the maximum values in the destination
   962  // slice.
   963  func Maximum_Into(dst, x, y []float32) []float32 {
   964  	dst = checkCapacity(dst, x)
   965  	checkOverlap(dst, x)
   966  	copy(dst, x)
   967  	Maximum_Inplace(dst, y)
   968  	return dst
   969  }
   970  
   971  // MaximumNumber returns the maximum of a number and each slice element.
   972  func MaximumNumber(x []float32, a float32) []float32 {
   973  	x = slices.Clone(x)
   974  	MaximumNumber_Inplace(x, a)
   975  	return x
   976  }
   977  
   978  // MaximumNumber_Inplace compares a number to each slice element and replaces the values in the
   979  // slice with the maximum value.
   980  func MaximumNumber_Inplace(x []float32, a float32) {
   981  	if functions.UseAVX2 {
   982  		functions.MaximumNumber_AVX2_F32(x, a)
   983  	} else {
   984  		functions.MaximumNumber_Go(x, a)
   985  	}
   986  }
   987  
   988  // MaximumNumber_Into compares a number to each slice element and stores the maximum values in
   989  // the destination slice.
   990  func MaximumNumber_Into(dst, x []float32, a float32) []float32 {
   991  	dst = checkCapacity(dst, x)
   992  	checkOverlap(dst, x)
   993  	copy(dst, x)
   994  	MaximumNumber_Inplace(dst, a)
   995  	return dst
   996  }
   997  
   998  // Find returns the index of the first slice element equal to the given value, or -1 if not found.
   999  func Find(x []float32, a float32) int {
  1000  	if functions.UseAVX2 {
  1001  		idx := functions.Find_AVX2_F32(x, a)
  1002  		if idx == len(x) {
  1003  			return -1
  1004  		}
  1005  		return idx
  1006  	} else {
  1007  		return functions.Find_Go(x, a)
  1008  	}
  1009  }
  1010  
  1011  // Lt returns an element-wise "less than" comparison between two slices.
  1012  func Lt(x, y []float32) []bool {
  1013  	dst := make([]bool, len(x))
  1014  	return Lt_Into(dst, x, y)
  1015  }
  1016  
  1017  // Lt_Into stores an element-wise "less than" comparison between two slices in the destination
  1018  // slice.
  1019  func Lt_Into(dst []bool, x, y []float32) []bool {
  1020  	checkEqualLength(x, y)
  1021  	dst = checkCapacity(dst, x)
  1022  	if functions.UseAVX2 {
  1023  		functions.Lt_AVX2_F32(dst, x, y)
  1024  	} else {
  1025  		functions.Lt_Go(dst, x, y)
  1026  	}
  1027  	return dst
  1028  }
  1029  
  1030  // LtNumber returns an element-wise "less than" comparison between each slice element and
  1031  // a number.
  1032  func LtNumber(x []float32, a float32) []bool {
  1033  	dst := make([]bool, len(x))
  1034  	return LtNumber_Into(dst, x, a)
  1035  }
  1036  
  1037  // LtNumber_Into stores an element-wise "less than" comparison between each slice element
  1038  // and a number in the destination slice.
  1039  func LtNumber_Into(dst []bool, x []float32, a float32) []bool {
  1040  	dst = checkCapacity(dst, x)
  1041  	if functions.UseAVX2 {
  1042  		functions.LtNumber_AVX2_F32(dst, x, a)
  1043  	} else {
  1044  		functions.LtNumber_Go(dst, x, a)
  1045  	}
  1046  	return dst
  1047  }
  1048  
  1049  // Lte returns an element-wise "less than or equal" comparison between two slices.
  1050  func Lte(x, y []float32) []bool {
  1051  	dst := make([]bool, len(x))
  1052  	return Lte_Into(dst, x, y)
  1053  }
  1054  
  1055  // Lte_Into stores an element-wise "less than or equal" comparison between two slices in the
  1056  // destination slice.
  1057  func Lte_Into(dst []bool, x, y []float32) []bool {
  1058  	checkEqualLength(x, y)
  1059  	dst = checkCapacity(dst, x)
  1060  	if functions.UseAVX2 {
  1061  		functions.Lte_AVX2_F32(dst, x, y)
  1062  	} else {
  1063  		functions.Lte_Go(dst, x, y)
  1064  	}
  1065  	return dst
  1066  }
  1067  
  1068  // LteNumber returns an element-wise "less than or equal" comparison between each slice element
  1069  // and a number.
  1070  func LteNumber(x []float32, a float32) []bool {
  1071  	dst := make([]bool, len(x))
  1072  	return LteNumber_Into(dst, x, a)
  1073  }
  1074  
  1075  // LteNumber_Into stores an element-wise "less than or equal" comparison between each slice
  1076  // element and a number in the destination slice.
  1077  func LteNumber_Into(dst []bool, x []float32, a float32) []bool {
  1078  	dst = checkCapacity(dst, x)
  1079  	if functions.UseAVX2 {
  1080  		functions.LteNumber_AVX2_F32(dst, x, a)
  1081  	} else {
  1082  		functions.LteNumber_Go(dst, x, a)
  1083  	}
  1084  	return dst
  1085  }
  1086  
  1087  // Gt returns an element-wise "greater than" comparison between two slices.
  1088  func Gt(x, y []float32) []bool {
  1089  	dst := make([]bool, len(x))
  1090  	return Gt_Into(dst, x, y)
  1091  }
  1092  
  1093  // Gt_Into stores an element-wise "greater than" comparison between two slices in the destination
  1094  // slice.
  1095  func Gt_Into(dst []bool, x, y []float32) []bool {
  1096  	checkEqualLength(x, y)
  1097  	dst = checkCapacity(dst, x)
  1098  	if functions.UseAVX2 {
  1099  		functions.Gt_AVX2_F32(dst, x, y)
  1100  	} else {
  1101  		functions.Gt_Go(dst, x, y)
  1102  	}
  1103  	return dst
  1104  }
  1105  
  1106  // GtNumber returns an element-wise "greater than" comparison between each slice element and
  1107  // a number.
  1108  func GtNumber(x []float32, a float32) []bool {
  1109  	dst := make([]bool, len(x))
  1110  	return GtNumber_Into(dst, x, a)
  1111  }
  1112  
  1113  // GtNumber_Into stores an element-wise "greater than" comparison between each slice element and
  1114  // a number in the destination slice.
  1115  func GtNumber_Into(dst []bool, x []float32, a float32) []bool {
  1116  	dst = checkCapacity(dst, x)
  1117  	if functions.UseAVX2 {
  1118  		functions.GtNumber_AVX2_F32(dst, x, a)
  1119  	} else {
  1120  		functions.GtNumber_Go(dst, x, a)
  1121  	}
  1122  	return dst
  1123  }
  1124  
  1125  // Gte returns an element-wise "greater than or equal" comparison between two slices.
  1126  func Gte(x, y []float32) []bool {
  1127  	dst := make([]bool, len(x))
  1128  	return Gte_Into(dst, x, y)
  1129  }
  1130  
  1131  // Gte_Into stores an element-wise "greater than or equal" comparison between two slices in the
  1132  // destination slice.
  1133  func Gte_Into(dst []bool, x, y []float32) []bool {
  1134  	checkEqualLength(x, y)
  1135  	dst = checkCapacity(dst, x)
  1136  	if functions.UseAVX2 {
  1137  		functions.Gte_AVX2_F32(dst, x, y)
  1138  	} else {
  1139  		functions.Gte_Go(dst, x, y)
  1140  	}
  1141  	return dst
  1142  }
  1143  
  1144  // GteNumber returns an element-wise "greater than or equal" comparison between each slice element
  1145  // and a number.
  1146  func GteNumber(x []float32, a float32) []bool {
  1147  	dst := make([]bool, len(x))
  1148  	return GteNumber_Into(dst, x, a)
  1149  }
  1150  
  1151  // GteNumber_Into stores an element-wise "greater than or equal" comparison between each slice
  1152  // element and a number in the destination slice.
  1153  func GteNumber_Into(dst []bool, x []float32, a float32) []bool {
  1154  	dst = checkCapacity(dst, x)
  1155  	if functions.UseAVX2 {
  1156  		functions.GteNumber_AVX2_F32(dst, x, a)
  1157  	} else {
  1158  		functions.GteNumber_Go(dst, x, a)
  1159  	}
  1160  	return dst
  1161  }
  1162  
  1163  // Eq returns an element-wise equality comparison between two slices.
  1164  func Eq(x, y []float32) []bool {
  1165  	dst := make([]bool, len(x))
  1166  	return Eq_Into(dst, x, y)
  1167  }
  1168  
  1169  // Eq_Into stores an element-wise equality comparison between two slices in the destination
  1170  // slice.
  1171  func Eq_Into(dst []bool, x, y []float32) []bool {
  1172  	checkEqualLength(x, y)
  1173  	dst = checkCapacity(dst, x)
  1174  	if functions.UseAVX2 {
  1175  		functions.Eq_AVX2_F32(dst, x, y)
  1176  	} else {
  1177  		functions.Eq_Go(dst, x, y)
  1178  	}
  1179  	return dst
  1180  }
  1181  
  1182  // EqNumber returns an element-wise equality comparison between each slice element and a number.
  1183  func EqNumber(x []float32, a float32) []bool {
  1184  	dst := make([]bool, len(x))
  1185  	return EqNumber_Into(dst, x, a)
  1186  }
  1187  
  1188  // EqNumber_Into stores an element-wise equality comparison between each slice element and a
  1189  // number in the destination slice.
  1190  func EqNumber_Into(dst []bool, x []float32, a float32) []bool {
  1191  	dst = checkCapacity(dst, x)
  1192  	if functions.UseAVX2 {
  1193  		functions.EqNumber_AVX2_F32(dst, x, a)
  1194  	} else {
  1195  		functions.EqNumber_Go(dst, x, a)
  1196  	}
  1197  	return dst
  1198  }
  1199  
  1200  // Neq returns an element-wise "not equal" comparison between two slices.
  1201  func Neq(x, y []float32) []bool {
  1202  	dst := make([]bool, len(x))
  1203  	return Neq_Into(dst, x, y)
  1204  }
  1205  
  1206  // Neq_Into stores an element-wise "not equal" comparison between two slices in the destination
  1207  // slice.
  1208  func Neq_Into(dst []bool, x, y []float32) []bool {
  1209  	checkEqualLength(x, y)
  1210  	dst = checkCapacity(dst, x)
  1211  	if functions.UseAVX2 {
  1212  		functions.Neq_AVX2_F32(dst, x, y)
  1213  	} else {
  1214  		functions.Neq_Go(dst, x, y)
  1215  	}
  1216  	return dst
  1217  }
  1218  
  1219  // NeqNumber returns an element-wise "not equal" comparison between each slice element and a number.
  1220  func NeqNumber(x []float32, a float32) []bool {
  1221  	dst := make([]bool, len(x))
  1222  	return NeqNumber_Into(dst, x, a)
  1223  }
  1224  
  1225  // NeqNumber_Into stores an element-wise "not equal" comparison between each slice element and a
  1226  // number in the destination slice.
  1227  func NeqNumber_Into(dst []bool, x []float32, a float32) []bool {
  1228  	dst = checkCapacity(dst, x)
  1229  	if functions.UseAVX2 {
  1230  		functions.NeqNumber_AVX2_F32(dst, x, a)
  1231  	} else {
  1232  		functions.NeqNumber_Go(dst, x, a)
  1233  	}
  1234  	return dst
  1235  }
  1236  
  1237  // Boolean
  1238  
  1239  // Not returns the logical negation of each slice element.
  1240  func Not(x []bool) []bool {
  1241  	x = slices.Clone(x)
  1242  	Not_Inplace(x)
  1243  	return x
  1244  }
  1245  
  1246  // Not_Inplace computes the logical negation of each slice element, inplace.
  1247  func Not_Inplace(x []bool) {
  1248  	if functions.UseAVX2 {
  1249  		functions.Not_AVX2(x)
  1250  	} else {
  1251  		functions.Not_Go(x)
  1252  	}
  1253  }
  1254  
  1255  // Not_Into stores the logical negation of each slice element in the destination slice.
  1256  func Not_Into(dst, x []bool) []bool {
  1257  	dst = checkCapacity(dst, x)
  1258  	checkOverlap(dst, x)
  1259  	copy(dst, x)
  1260  	Not_Inplace(dst)
  1261  	return dst
  1262  }
  1263  
  1264  // And returns the element-wise logical "and" operation between two slices.
  1265  func And(x, y []bool) []bool {
  1266  	x = slices.Clone(x)
  1267  	And_Inplace(x, y)
  1268  	return x
  1269  }
  1270  
  1271  // And_Inplace computes the element-wise logical "and" operation between two slices, inplace.
  1272  func And_Inplace(x, y []bool) {
  1273  	checkEqualLength(x, y)
  1274  	checkOverlap(x, y)
  1275  	if functions.UseAVX2 {
  1276  		functions.And_AVX2(x, y)
  1277  	} else {
  1278  		functions.And_Go(x, y)
  1279  	}
  1280  }
  1281  
  1282  // And_Into stores the element-wise logical "and" operation between two slices in the destination
  1283  // slice.
  1284  func And_Into(dst, x, y []bool) []bool {
  1285  	dst = checkCapacity(dst, x)
  1286  	checkOverlap(dst, x)
  1287  	copy(dst, x)
  1288  	And_Inplace(dst, y)
  1289  	return dst
  1290  }
  1291  
  1292  // Or returns the element-wise logical "or" operation between two slices.
  1293  func Or(x, y []bool) []bool {
  1294  	x = slices.Clone(x)
  1295  	Or_Inplace(x, y)
  1296  	return x
  1297  }
  1298  
  1299  // Or_Inplace computes the element-wise logical "or" operation between two slices, inplace.
  1300  func Or_Inplace(x, y []bool) {
  1301  	checkEqualLength(x, y)
  1302  	checkOverlap(x, y)
  1303  	if functions.UseAVX2 {
  1304  		functions.Or_AVX2(x, y)
  1305  	} else {
  1306  		functions.Or_Go(x, y)
  1307  	}
  1308  }
  1309  
  1310  // Or_Into stores the element-wise logical "or" operation between two slices in the destination
  1311  // slice.
  1312  func Or_Into(dst, x, y []bool) []bool {
  1313  	dst = checkCapacity(dst, x)
  1314  	checkOverlap(dst, x)
  1315  	copy(dst, x)
  1316  	Or_Inplace(dst, y)
  1317  	return dst
  1318  }
  1319  
  1320  // Xor returns the element-wise "exclusive or" operation between two slices.
  1321  func Xor(x, y []bool) []bool {
  1322  	x = slices.Clone(x)
  1323  	Xor_Inplace(x, y)
  1324  	return x
  1325  }
  1326  
  1327  // Xor_Inplace computes the element-wise "exclusive or" operation between two slices, inplace.
  1328  func Xor_Inplace(x, y []bool) {
  1329  	checkEqualLength(x, y)
  1330  	checkOverlap(x, y)
  1331  	if functions.UseAVX2 {
  1332  		functions.Xor_AVX2(x, y)
  1333  	} else {
  1334  		functions.Xor_Go(x, y)
  1335  	}
  1336  }
  1337  
  1338  // Xor_Into stores the element-wise "exclusive or" operation between two slices in the destination
  1339  // slice.
  1340  func Xor_Into(dst, x, y []bool) []bool {
  1341  	dst = checkCapacity(dst, x)
  1342  	checkOverlap(dst, x)
  1343  	copy(dst, x)
  1344  	Xor_Inplace(dst, y)
  1345  	return dst
  1346  }
  1347  
  1348  // Select returns the slice elements for which the corresponding boolean values are true.
  1349  func Select(x []float32, y []bool) []float32 {
  1350  	dst := make([]float32, 0)
  1351  	return Select_Into(dst, x, y)
  1352  }
  1353  
  1354  // Select_Into stores the slice elements for which the corresponding boolean values are true in
  1355  // the destination slice. This function grows the destination slice if the selection yields more
  1356  // values than it has capacity for.
  1357  func Select_Into(dst, x []float32, y []bool) []float32 {
  1358  	checkEqualLength(x, y)
  1359  	//checkOverlap(dst[:cap(dst)], x)
  1360  	return functions.Select_Go(dst, x, y)
  1361  }
  1362  
  1363  // All returns whether all boolean values in the slice are true.
  1364  func All(x []bool) bool {
  1365  	if functions.UseAVX2 {
  1366  		return functions.All_AVX2(x) != 0
  1367  	} else {
  1368  		return functions.All_Go(x)
  1369  	}
  1370  }
  1371  
  1372  // Any returns whether at least one boolean value in the slice is true.
  1373  func Any(x []bool) bool {
  1374  	if functions.UseAVX2 {
  1375  		return functions.Any_AVX2(x) != 0
  1376  	} else {
  1377  		return functions.Any_Go(x)
  1378  	}
  1379  }
  1380  
  1381  // None returns whether none of the boolean values in the slice are true.
  1382  func None(x []bool) bool {
  1383  	if functions.UseAVX2 {
  1384  		return functions.None_AVX2(x) != 0
  1385  	} else {
  1386  		return functions.None_Go(x)
  1387  	}
  1388  }
  1389  
  1390  // Count returns the number of boolean values that are true.
  1391  func Count(x []bool) int {
  1392  	if functions.UseAVX2 {
  1393  		return functions.Count_AVX2(x)
  1394  	} else {
  1395  		return functions.Count_Go(x)
  1396  	}
  1397  }
  1398  
  1399  // Construction
  1400  
  1401  // Zeros returns a new slice of length n filled with zeros.
  1402  func Zeros(n int) []float32 {
  1403  	dst := make([]float32, n)
  1404  	return Repeat_Into(dst, 0, n)
  1405  }
  1406  
  1407  // Zeros_Into sets the first n elements in the destination slice to zero.
  1408  func Zeros_Into(dst []float32, n int) []float32 {
  1409  	return Repeat_Into(dst, 0, n)
  1410  }
  1411  
  1412  // Ones returns a new slice of length n filled with ones.
  1413  func Ones(n int) []float32 {
  1414  	dst := make([]float32, n)
  1415  	return Repeat_Into(dst, 1, n)
  1416  }
  1417  
  1418  // Ones_Into sets the first n elements in the destination slice to one.
  1419  func Ones_Into(dst []float32, n int) []float32 {
  1420  	return Repeat_Into(dst, 1, n)
  1421  }
  1422  
  1423  // Repeat returns a new slice of length n filled with the given value.
  1424  func Repeat(a float32, n int) []float32 {
  1425  	dst := make([]float32, n)
  1426  	return Repeat_Into(dst, a, n)
  1427  }
  1428  
  1429  // Repeat_Into sets the first n elements in the destination slice to the given value.
  1430  func Repeat_Into(dst []float32, a float32, n int) []float32 {
  1431  	if cap(dst) < n {
  1432  		panic("destination slice not large enough to hold result")
  1433  	}
  1434  	if functions.UseAVX2 {
  1435  		functions.Repeat_AVX2_F32(dst, a, n)
  1436  	} else {
  1437  		functions.Repeat_Go(dst, a, n)
  1438  	}
  1439  	return dst[:n]
  1440  }
  1441  
  1442  // Range returns a new slice with values incrementing from a to b (excl.) in steps of 1.
  1443  func Range(a, b float32) []float32 {
  1444  	dst := make([]float32, int(math32.Max(0, math32.Ceil(b-a))))
  1445  	return Range_Into(dst, a, b)
  1446  }
  1447  
  1448  // Range_Into writes values incrementing from a to b (excl.) in steps of 1 to the destination slice.
  1449  func Range_Into(dst []float32, a, b float32) []float32 {
  1450  	n := int(math32.Max(0, math32.Ceil(b-a)))
  1451  	if cap(dst) < n {
  1452  		panic("destination slice not large enough to hold result")
  1453  	}
  1454  	if functions.UseAVX2 {
  1455  		functions.Range_AVX2_F32(dst, a, n)
  1456  	} else {
  1457  		functions.Range_Go(dst, a, n)
  1458  	}
  1459  	return dst[:n]
  1460  }
  1461  
  1462  // Gather returns a new slice containing just the elements at the given indices.
  1463  func Gather(x []float32, idx []int) []float32 {
  1464  	dst := make([]float32, len(idx))
  1465  	return Gather_Into(dst, x, idx)
  1466  }
  1467  
  1468  // Gather_Into stores the slice elements at the given indices in the destination slice.
  1469  func Gather_Into(dst, x []float32, idx []int) []float32 {
  1470  	dst = checkCapacity(dst, idx)
  1471  	checkOverlap(dst, x)
  1472  	functions.Gather_Go(dst, x, idx)
  1473  	return dst
  1474  }
  1475  
  1476  // Scatter returns a slice of size elements where position idx[i] is set to x[i], for all
  1477  // i < len(x) = len(idx). The other elements are set to zero.
  1478  func Scatter(x []float32, idx []int, size int) []float32 {
  1479  	dst := make([]float32, size)
  1480  	return Scatter_Into(dst, x, idx)
  1481  }
  1482  
  1483  // Scatter_Into sets positions idx[i] to x[i] in the destination slice, for all
  1484  // i < len(x) = len(idx). The other elements are not modified.
  1485  func Scatter_Into(dst, x []float32, idx []int) []float32 {
  1486  	checkOverlap(dst, x)
  1487  	functions.Scatter_Go(dst, x, idx)
  1488  	return dst
  1489  }
  1490  
  1491  // FromBool creates a slice of floats from a slice of bools by converting all false values to 0
  1492  // and all true values to 1.
  1493  func FromBool(x []bool) []float32 {
  1494  	dst := make([]float32, len(x))
  1495  	return FromBool_Into(dst, x)
  1496  }
  1497  
  1498  // FromBool_Into creates a slice of floats from a slice of bools by converting all false values
  1499  // to 0 and all true values to 1. The result is stored in the destination slice.
  1500  func FromBool_Into(dst []float32, x []bool) []float32 {
  1501  	dst = checkCapacity(dst, x)
  1502  	if functions.UseAVX2 {
  1503  		functions.FromBool_AVX2_F32(dst, x)
  1504  	} else {
  1505  		functions.FromBool_Go(dst, x)
  1506  	}
  1507  	return dst
  1508  }
  1509  
  1510  // FromInt64 creates a slice of floats from a slice of 64-bit ints. Standard conversion rules
  1511  // apply.
  1512  func FromInt64(x []int64) []float32 {
  1513  	dst := make([]float32, len(x))
  1514  	return FromInt64_Into(dst, x)
  1515  }
  1516  
  1517  // FromInt64_Into creates a slice of floats from a slice of 64-bit ints. Standard conversion
  1518  // rules apply. The result is stored in the destination slice.
  1519  func FromInt64_Into(dst []float32, x []int64) []float32 {
  1520  	dst = checkCapacity(dst, x)
  1521  	if functions.UseAVX2 {
  1522  		functions.FromInt64_AVX2_F32(dst, x)
  1523  	} else {
  1524  		functions.FromNumber_Go(dst, x)
  1525  	}
  1526  	return dst
  1527  }
  1528  
  1529  // FromInt32 creates a slice of floats from a slice of 32-bit ints. Standard conversion rules
  1530  // apply.
  1531  func FromInt32(x []int32) []float32 {
  1532  	dst := make([]float32, len(x))
  1533  	return FromInt32_Into(dst, x)
  1534  }
  1535  
  1536  // FromInt32_Into creates a slice of floats from a slice of 32-bit ints. Standard conversion
  1537  // rules apply. The result is stored in the destination slice.
  1538  func FromInt32_Into(dst []float32, x []int32) []float32 {
  1539  	dst = checkCapacity(dst, x)
  1540  	if functions.UseAVX2 {
  1541  		functions.FromInt32_AVX2_F32(dst, x)
  1542  	} else {
  1543  		functions.FromNumber_Go(dst, x)
  1544  	}
  1545  	return dst
  1546  }
  1547  
  1548  // FromFloat64 creates a slice of floats from a slice of 64-bit floats. Standard conversion
  1549  // rules apply.
  1550  func FromFloat64(x []float64) []float32 {
  1551  	dst := make([]float32, len(x))
  1552  	return FromFloat64_Into(dst, x)
  1553  }
  1554  
  1555  // FromFloat64_Into creates a slice of floats from a slice of 32-bit floats. Standard conversion
  1556  // rules apply. The result is stored in the destination slice.
  1557  func FromFloat64_Into(dst []float32, x []float64) []float32 {
  1558  	dst = checkCapacity(dst, x)
  1559  	if functions.UseAVX2 {
  1560  		functions.FromFloat64_AVX2_F32(dst, x)
  1561  	} else {
  1562  		functions.FromNumber_Go(dst, x)
  1563  	}
  1564  	return dst
  1565  }
  1566  
  1567  // ToBool converts a slice of floats to a slice of bools by setting all zero values to true and
  1568  // all non-zero values to false.
  1569  func ToBool(x []float64) []bool {
  1570  	dst := make([]bool, len(x))
  1571  	return ToBool_Into(dst, x)
  1572  }
  1573  
  1574  // ToBool_Into converts a slice of floats to a slice of bools by setting all zero values to true
  1575  // and all non-zero values to false. The result is stored in the destination slice.
  1576  func ToBool_Into(dst []bool, x []float64) []bool {
  1577  	dst = checkCapacity(dst, x)
  1578  	if functions.UseAVX2 {
  1579  		functions.ToBool_AVX2_F64(dst, x)
  1580  	} else {
  1581  		functions.ToBool_Go(dst, x)
  1582  	}
  1583  	return dst
  1584  }
  1585  
  1586  // ToInt64 converts a slice of floats to a slice of 64-bit ints. Standard conversion rules apply.
  1587  func ToInt64(x []float32) []int64 {
  1588  	dst := make([]int64, len(x))
  1589  	return ToInt64_Into(dst, x)
  1590  }
  1591  
  1592  // ToInt64_Into converts a slice of floats to a slice of 64-bit ints. Standard conversion rules
  1593  // apply. The result is stored in the destination slice.
  1594  func ToInt64_Into(dst []int64, x []float32) []int64 {
  1595  	dst = checkCapacity(dst, x)
  1596  	if functions.UseAVX2 {
  1597  		functions.ToInt64_AVX2_F32(dst, x)
  1598  	} else {
  1599  		functions.ToNumber_Go(dst, x)
  1600  	}
  1601  	return dst
  1602  }
  1603  
  1604  // ToInt32 converts a slice of floats to a slice of 32-bit ints. Standard conversion rules apply.
  1605  func ToInt32(x []float32) []int32 {
  1606  	dst := make([]int32, len(x))
  1607  	return ToInt32_Into(dst, x)
  1608  }
  1609  
  1610  // ToInt32_Into converts a slice of floats to a slice of 32-bit ints. Standard conversion rules
  1611  // apply. The result is stored in the destination slice.
  1612  func ToInt32_Into(dst []int32, x []float32) []int32 {
  1613  	dst = checkCapacity(dst, x)
  1614  	if functions.UseAVX2 {
  1615  		functions.ToInt32_AVX2_F32(dst, x)
  1616  	} else {
  1617  		functions.ToNumber_Go(dst, x)
  1618  	}
  1619  	return dst
  1620  }
  1621  
  1622  // ToFloat64 converts a slice of floats to a slice of 32-bit floats. Standard conversion rules
  1623  // apply.
  1624  func ToFloat64(x []float32) []float64 {
  1625  	dst := make([]float64, len(x))
  1626  	return ToFloat64_Into(dst, x)
  1627  }
  1628  
  1629  // ToFloat64_Into converts a slice of floats to a slice of 64-bit floats. Standard conversion
  1630  // rules apply. The result is stored in the destination slice.
  1631  func ToFloat64_Into(dst []float64, x []float32) []float64 {
  1632  	dst = checkCapacity(dst, x)
  1633  	if functions.UseAVX2 {
  1634  		functions.FromFloat32_AVX2_F64(dst, x)
  1635  	} else {
  1636  		functions.ToNumber_Go(dst, x)
  1637  	}
  1638  	return dst
  1639  }
  1640  
  1641  // Misc
  1642  
  1643  // Info returns information about the current operating environment.
  1644  func Info() num.SystemInfo {
  1645  	return num.Info()
  1646  }
  1647  
  1648  // SetAcceleration toggles simd acceleration. Not thread safe.
  1649  func SetAcceleration(enabled bool) {
  1650  	num.SetAcceleration(enabled)
  1651  }
  1652  
  1653  // Validation
  1654  
  1655  func slicesOverlap[T, F any](x []T, y []F) bool {
  1656  	if len(x) == 0 || len(y) == 0 {
  1657  		return false
  1658  	}
  1659  	xStart := uintptr(unsafe.Pointer(&x[0]))
  1660  	xEnd := uintptr(unsafe.Pointer(&x[len(x)-1]))
  1661  	yStart := uintptr(unsafe.Pointer(&y[0]))
  1662  	yEnd := uintptr(unsafe.Pointer(&y[len(y)-1]))
  1663  	return xStart <= yEnd && yStart <= xEnd
  1664  }
  1665  
  1666  func checkCapacity[T, F any](dst []T, x []F) []T {
  1667  	if cap(dst) < len(x) {
  1668  		panic("destination slice not large enough to hold result")
  1669  	}
  1670  	return dst[:len(x)]
  1671  }
  1672  
  1673  func checkEqualLength[T, F any](x []T, y []F) {
  1674  	if len(x) != len(y) {
  1675  		panic("slices must be of equal length")
  1676  	}
  1677  }
  1678  
  1679  func checkNotEmpty[T any](x []T) {
  1680  	if len(x) == 0 {
  1681  		panic("slice must not be empty")
  1682  	}
  1683  }
  1684  
  1685  func checkOverlap[T, F any](x []T, y []F) {
  1686  	if slicesOverlap(x, y) {
  1687  		panic("destination slice must not overlap input slice")
  1688  	}
  1689  }