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