1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import jdk.internal.vm.annotation.ForceInline;
  28 
  29 import java.nio.ByteBuffer;
  30 import java.nio.ByteOrder;
  31 import java.nio.FloatBuffer;
  32 import java.util.Objects;
  33 import java.util.concurrent.ThreadLocalRandom;
  34 
  35 
  36 /**
  37  * A specialized {@link Vector} representing an ordered immutable sequence of
  38  * {@code float} values.
  39  *
  40  * @param <S> the type of shape of this vector
  41  */
  42 @SuppressWarnings("cast")
  43 public abstract class FloatVector<S extends Vector.Shape> extends Vector<Float,S> {
  44 
  45     FloatVector() {}
  46 
  47     // Unary operator
  48 
  49     interface FUnOp {
  50         float apply(int i, float a);
  51     }
  52 
  53     abstract FloatVector<S> uOp(FUnOp f);
  54 
  55     abstract FloatVector<S> uOp(Mask<Float, S> m, FUnOp f);
  56 
  57     // Binary operator
  58 
  59     interface FBinOp {
  60         float apply(int i, float a, float b);
  61     }
  62 
  63     abstract FloatVector<S> bOp(Vector<Float,S> v, FBinOp f);
  64 
  65     abstract FloatVector<S> bOp(Vector<Float,S> v, Mask<Float, S> m, FBinOp f);
  66 
  67     // Trinary operator
  68 
  69     interface FTriOp {
  70         float apply(int i, float a, float b, float c);
  71     }
  72 
  73     abstract FloatVector<S> tOp(Vector<Float,S> v1, Vector<Float,S> v2, FTriOp f);
  74 
  75     abstract FloatVector<S> tOp(Vector<Float,S> v1, Vector<Float,S> v2, Mask<Float, S> m, FTriOp f);
  76 
  77     // Reduction operator
  78 
  79     abstract float rOp(float v, FBinOp f);
  80 
  81     // Binary test
  82 
  83     interface FBinTest {
  84         boolean apply(int i, float a, float b);
  85     }
  86 
  87     abstract Mask<Float, S> bTest(Vector<Float,S> v, FBinTest f);
  88 
  89     // Foreach
  90 
  91     interface FUnCon {
  92         void apply(int i, float a);
  93     }
  94 
  95     abstract void forEach(FUnCon f);
  96 
  97     abstract void forEach(Mask<Float, S> m, FUnCon f);
  98 
  99     //
 100 
 101     @Override
 102     public abstract FloatVector<S> add(Vector<Float,S> v);
 103 
 104     /**
 105      * Adds this vector to the broadcast of an input scalar.
 106      * <p>
 107      * This is a vector binary operation where the primitive addition operation
 108      * ({@code +}) is applied to lane elements.
 109      *
 110      * @param s the input scalar
 111      * @return the result of adding this vector to the broadcast of an input
 112      * scalar
 113      */
 114     public abstract FloatVector<S> add(float s);
 115 
 116     @Override
 117     public abstract FloatVector<S> add(Vector<Float,S> v, Mask<Float, S> m);
 118 
 119     /**
 120      * Adds this vector to broadcast of an input scalar,
 121      * selecting lane elements controlled by a mask.
 122      * <p>
 123      * This is a vector binary operation where the primitive addition operation
 124      * ({@code +}) is applied to lane elements.
 125      *
 126      * @param s the input scalar
 127      * @param m the mask controlling lane selection
 128      * @return the result of adding this vector to the broadcast of an input
 129      * scalar
 130      */
 131     public abstract FloatVector<S> add(float s, Mask<Float, S> m);
 132 
 133     @Override
 134     public abstract FloatVector<S> sub(Vector<Float,S> v);
 135 
 136     /**
 137      * Subtracts the broadcast of an input scalar from this vector.
 138      * <p>
 139      * This is a vector binary operation where the primitive subtraction
 140      * operation ({@code -}) is applied to lane elements.
 141      *
 142      * @param s the input scalar
 143      * @return the result of subtracting the broadcast of an input
 144      * scalar from this vector
 145      */
 146     public abstract FloatVector<S> sub(float s);
 147 
 148     @Override
 149     public abstract FloatVector<S> sub(Vector<Float,S> v, Mask<Float, S> m);
 150 
 151     /**
 152      * Subtracts the broadcast of an input scalar from this vector, selecting
 153      * lane elements controlled by a mask.
 154      * <p>
 155      * This is a vector binary operation where the primitive subtraction
 156      * operation ({@code -}) is applied to lane elements.
 157      *
 158      * @param s the input scalar
 159      * @param m the mask controlling lane selection
 160      * @return the result of subtracting the broadcast of an input
 161      * scalar from this vector
 162      */
 163     public abstract FloatVector<S> sub(float s, Mask<Float, S> m);
 164 
 165     @Override
 166     public abstract FloatVector<S> mul(Vector<Float,S> v);
 167 
 168     /**
 169      * Multiplies this vector with the broadcast of an input scalar.
 170      * <p>
 171      * This is a vector binary operation where the primitive multiplication
 172      * operation ({@code *}) is applied to lane elements.
 173      *
 174      * @param s the input scalar
 175      * @return the result of multiplying this vector with the broadcast of an
 176      * input scalar
 177      */
 178     public abstract FloatVector<S> mul(float s);
 179 
 180     @Override
 181     public abstract FloatVector<S> mul(Vector<Float,S> v, Mask<Float, S> m);
 182 
 183     /**
 184      * Multiplies this vector with the broadcast of an input scalar, selecting
 185      * lane elements controlled by a mask.
 186      * <p>
 187      * This is a vector binary operation where the primitive multiplication
 188      * operation ({@code *}) is applied to lane elements.
 189      *
 190      * @param s the input scalar
 191      * @param m the mask controlling lane selection
 192      * @return the result of multiplying this vector with the broadcast of an
 193      * input scalar
 194      */
 195     public abstract FloatVector<S> mul(float s, Mask<Float, S> m);
 196 
 197     @Override
 198     public abstract FloatVector<S> neg();
 199 
 200     @Override
 201     public abstract FloatVector<S> neg(Mask<Float, S> m);
 202 
 203     @Override
 204     public abstract FloatVector<S> abs();
 205 
 206     @Override
 207     public abstract FloatVector<S> abs(Mask<Float, S> m);
 208 
 209     @Override
 210     public abstract FloatVector<S> min(Vector<Float,S> v);
 211 
 212     /**
 213      * Returns the minimum of this vector and the broadcast of an input scalar.
 214      * <p>
 215      * This is a vector binary operation where the operation
 216      * {@code (a, b) -> a < b ? a : b}  is applied to lane elements.
 217      *
 218      * @param s the input scalar
 219      * @return the minimum of this vector and the broadcast of an input scalar
 220      */
 221     public abstract FloatVector<S> min(float s);
 222 
 223     @Override
 224     public abstract FloatVector<S> max(Vector<Float,S> v);
 225 
 226     /**
 227      * Returns the maximum of this vector and the broadcast of an input scalar.
 228      * <p>
 229      * This is a vector binary operation where the operation
 230      * {@code (a, b) -> a > b ? a : b}  is applied to lane elements.
 231      *
 232      * @param s the input scalar
 233      * @return the maximum of this vector and the broadcast of an input scalar
 234      */
 235     public abstract FloatVector<S> max(float s);
 236 
 237     @Override
 238     public abstract Mask<Float, S> equal(Vector<Float,S> v);
 239 
 240     /**
 241      * Tests if this vector is equal to the broadcast of an input scalar.
 242      * <p>
 243      * This is a vector binary test operation where the primitive equals
 244      * operation ({@code ==}) is applied to lane elements.
 245      *
 246      * @param s the input scalar
 247      * @return the result mask of testing if this vector is equal to the
 248      * broadcast of an input scalar
 249      */
 250     public abstract Mask<Float, S> equal(float s);
 251 
 252     @Override
 253     public abstract Mask<Float, S> notEqual(Vector<Float,S> v);
 254 
 255     /**
 256      * Tests if this vector is not equal to the broadcast of an input scalar.
 257      * <p>
 258      * This is a vector binary test operation where the primitive not equals
 259      * operation ({@code !=}) is applied to lane elements.
 260      *
 261      * @param s the input scalar
 262      * @return the result mask of testing if this vector is not equal to the
 263      * broadcast of an input scalar
 264      */
 265     public abstract Mask<Float, S> notEqual(float s);
 266 
 267     @Override
 268     public abstract Mask<Float, S> lessThan(Vector<Float,S> v);
 269 
 270     /**
 271      * Tests if this vector is less than the broadcast of an input scalar.
 272      * <p>
 273      * This is a vector binary test operation where the primitive less than
 274      * operation ({@code <}) is applied to lane elements.
 275      *
 276      * @param s the input scalar
 277      * @return the mask result of testing if this vector is less than the
 278      * broadcast of an input scalar
 279      */
 280     public abstract Mask<Float, S> lessThan(float s);
 281 
 282     @Override
 283     public abstract Mask<Float, S> lessThanEq(Vector<Float,S> v);
 284 
 285     /**
 286      * Tests if this vector is less or equal to the broadcast of an input scalar.
 287      * <p>
 288      * This is a vector binary test operation where the primitive less than
 289      * or equal to operation ({@code <=}) is applied to lane elements.
 290      *
 291      * @param s the input scalar
 292      * @return the mask result of testing if this vector is less than or equal
 293      * to the broadcast of an input scalar
 294      */
 295     public abstract Mask<Float, S> lessThanEq(float s);
 296 
 297     @Override
 298     public abstract Mask<Float, S> greaterThan(Vector<Float,S> v);
 299 
 300     /**
 301      * Tests if this vector is greater than the broadcast of an input scalar.
 302      * <p>
 303      * This is a vector binary test operation where the primitive greater than
 304      * operation ({@code >}) is applied to lane elements.
 305      *
 306      * @param s the input scalar
 307      * @return the mask result of testing if this vector is greater than the
 308      * broadcast of an input scalar
 309      */
 310     public abstract Mask<Float, S> greaterThan(float s);
 311 
 312     @Override
 313     public abstract Mask<Float, S> greaterThanEq(Vector<Float,S> v);
 314 
 315     /**
 316      * Tests if this vector is greater than or equal to the broadcast of an
 317      * input scalar.
 318      * <p>
 319      * This is a vector binary test operation where the primitive greater than
 320      * or equal to operation ({@code >=}) is applied to lane elements.
 321      *
 322      * @param s the input scalar
 323      * @return the mask result of testing if this vector is greater than or
 324      * equal to the broadcast of an input scalar
 325      */
 326     public abstract Mask<Float, S> greaterThanEq(float s);
 327 
 328     @Override
 329     public abstract FloatVector<S> blend(Vector<Float,S> v, Mask<Float, S> m);
 330 
 331     /**
 332      * Blends the lane elements of this vector with those of the broadcast of an
 333      * input scalar, selecting lanes controlled by a mask.
 334      * <p>
 335      * For each lane of the mask, at lane index {@code N}, if the mask lane
 336      * is set then the lane element at {@code N} from the input vector is
 337      * selected and placed into the resulting vector at {@code N},
 338      * otherwise the the lane element at {@code N} from this input vector is
 339      * selected and placed into the resulting vector at {@code N}.
 340      *
 341      * @param s the input scalar
 342      * @param m the mask controlling lane selection
 343      * @return the result of blending the lane elements of this vector with
 344      * those of the broadcast of an input scalar
 345      */
 346     public abstract FloatVector<S> blend(float s, Mask<Float, S> m);
 347 
 348     @Override
 349     public abstract FloatVector<S> rearrange(Vector<Float, S> v,
 350                                                       Shuffle<Float, S> s, Mask<Float, S> m);
 351 
 352     @Override
 353     public abstract FloatVector<S> rearrange(Shuffle<Float, S> m);
 354 
 355     @Override
 356     @ForceInline
 357     public <T extends Shape> FloatVector<T> resize(Species<Float, T> species) {
 358         return (FloatVector<T>) species.resize(this);
 359     }
 360 
 361     @Override
 362     public abstract FloatVector<S> rotateEL(int i);
 363 
 364     @Override
 365     public abstract FloatVector<S> rotateER(int i);
 366 
 367     @Override
 368     public abstract FloatVector<S> shiftEL(int i);
 369 
 370     @Override
 371     public abstract FloatVector<S> shiftER(int i);
 372 
 373     /**
 374      * Divides this vector by an input vector.
 375      * <p>
 376      * This is a vector binary operation where the primitive division
 377      * operation ({@code /}) is applied to lane elements.
 378      *
 379      * @param v the input vector
 380      * @return the result of dividing this vector by the input vector
 381      */
 382     public abstract FloatVector<S> div(Vector<Float,S> v);
 383 
 384     /**
 385      * Divides this vector by the broadcast of an input scalar.
 386      * <p>
 387      * This is a vector binary operation where the primitive division
 388      * operation ({@code /}) is applied to lane elements.
 389      *
 390      * @param v the input scalar
 391      * @return the result of dividing this vector by the broadcast of an input
 392      * scalar
 393      */
 394     public abstract FloatVector<S> div(float s);
 395 
 396     /**
 397      * Divides this vector by an input vector, selecting lane elements
 398      * controlled by a mask.
 399      * <p>
 400      * This is a vector binary operation where the primitive division
 401      * operation ({@code /}) is applied to lane elements.
 402      *
 403      * @param v the input vector
 404      * @param m the mask controlling lane selection
 405      * @return the result of dividing this vector by the input vector
 406      */
 407     public abstract FloatVector<S> div(Vector<Float,S> v, Mask<Float, S> m);
 408 
 409     /**
 410      * Divides this vector by the broadcast of an input scalar, selecting lane
 411      * elements controlled by a mask.
 412      * <p>
 413      * This is a vector binary operation where the primitive division
 414      * operation ({@code /}) is applied to lane elements.
 415      *
 416      * @param v the input scalar
 417      * @param m the mask controlling lane selection
 418      * @return the result of dividing this vector by the broadcast of an input
 419      * scalar
 420      */
 421     public abstract FloatVector<S> div(float s, Mask<Float, S> m);
 422 
 423 // @@@ Many methods are refer to Math or StrictMath functions that only accept
 424 //     double values, what should be the behaviour for lane elements of float
 425 //     vectors? down and then upcast? Or will some numeric algorithms differ?
 426 //     The answers might also depend if strict definitions are required
 427 //     to ensure portability.
 428 //     Leveraging the existing defintions in Math/StrictMath is very convenient
 429 //     but its unclear if it is t
 430 
 431     /**
 432      * Calculates the square root of this vector.
 433      * <p>
 434      * This is a vector unary operation where the {@link Math#sqrt} operation
 435      * is applied to lane elements.
 436      *
 437      * @return the square root of this vector
 438      */
 439     public abstract FloatVector<S> sqrt();
 440 
 441     /**
 442      * Calculates the square root of this vector, selecting lane elements
 443      * controlled by a mask.
 444      * <p>
 445      * This is a vector unary operation where the {@link Math#sqrt} operation
 446      * ({@code -}) is applied to lane elements.
 447      *
 448      * @param m the mask controlling lane selection
 449      * @return the square root of this vector
 450      */
 451     public FloatVector<S> sqrt(Mask<Float,S> m) {
 452         return uOp(m, (i, a) -> (float) Math.sqrt((double) a));
 453     }
 454 
 455     /**
 456      * Calculates the trigonometric tangent of this vector.
 457      * <p>
 458      * This is a vector unary operation where the {@link Math#tan} operation
 459      * is applied to lane elements.
 460      *
 461      * @return the tangent of this vector
 462      */
 463     public FloatVector<S> tan() {
 464         return uOp((i, a) -> (float) Math.tan((double) a));
 465     }
 466 
 467     /**
 468      * Calculates the trigonometric tangent of this vector, selecting lane
 469      * elements controlled by a mask.
 470      * <p>
 471      * This is a vector unary operation where the {@link Math#tan} operation
 472      * is applied to lane elements.
 473      *
 474      * @param m the mask controlling lane selection
 475      * @return the tangent of this vector
 476      */
 477     public FloatVector<S> tan(Mask<Float,S> m) {
 478         return uOp(m, (i, a) -> (float) Math.tan((double) a));
 479     }
 480 
 481     /**
 482      * Calculates the hyperbolic tangent of this vector.
 483      * <p>
 484      * This is a vector unary operation where the {@link Math#tanh} operation
 485      * is applied to lane elements.
 486      *
 487      * @return the hyperbolic tangent of this vector
 488      */
 489     public FloatVector<S> tanh() {
 490         return uOp((i, a) -> (float) Math.tanh((double) a));
 491     }
 492 
 493     /**
 494      * Calculates the hyperbolic tangent of this vector, selecting lane elements
 495      * controlled by a mask.
 496      * <p>
 497      * This is a vector unary operation where the {@link Math#tanh} operation
 498      * is applied to lane elements.
 499      *
 500      * @param m the mask controlling lane selection
 501      * @return the hyperbolic tangent of this vector
 502      */
 503     public FloatVector<S> tanh(Mask<Float,S> m) {
 504         return uOp(m, (i, a) -> (float) Math.tanh((double) a));
 505     }
 506 
 507     /**
 508      * Calculates the trigonometric sine of this vector.
 509      * <p>
 510      * This is a vector unary operation where the {@link Math#sin} operation
 511      * is applied to lane elements.
 512      *
 513      * @return the sine of this vector
 514      */
 515     public FloatVector<S> sin() {
 516         return uOp((i, a) -> (float) Math.sin((double) a));
 517     }
 518 
 519     /**
 520      * Calculates the trigonometric sine of this vector, selecting lane elements
 521      * controlled by a mask.
 522      * <p>
 523      * This is a vector unary operation where the {@link Math#sin} operation
 524      * is applied to lane elements.
 525      *
 526      * @param m the mask controlling lane selection
 527      * @return the sine of this vector
 528      */
 529     public FloatVector<S> sin(Mask<Float,S> m) {
 530         return uOp(m, (i, a) -> (float) Math.sin((double) a));
 531     }
 532 
 533     /**
 534      * Calculates the hyperbolic sine of this vector.
 535      * <p>
 536      * This is a vector unary operation where the {@link Math#sinh} operation
 537      * is applied to lane elements.
 538      *
 539      * @return the hyperbolic sine of this vector
 540      */
 541     public FloatVector<S> sinh() {
 542         return uOp((i, a) -> (float) Math.sinh((double) a));
 543     }
 544 
 545     /**
 546      * Calculates the hyperbolic sine of this vector, selecting lane elements
 547      * controlled by a mask.
 548      * <p>
 549      * This is a vector unary operation where the {@link Math#sinh} operation
 550      * is applied to lane elements.
 551      *
 552      * @param m the mask controlling lane selection
 553      * @return the hyperbolic sine of this vector
 554      */
 555     public FloatVector<S> sinh(Mask<Float,S> m) {
 556         return uOp(m, (i, a) -> (float) Math.sinh((double) a));
 557     }
 558 
 559     /**
 560      * Calculates the trigonometric cosine of this vector.
 561      * <p>
 562      * This is a vector unary operation where the {@link Math#cos} operation
 563      * is applied to lane elements.
 564      *
 565      * @return the cosine of this vector
 566      */
 567     public FloatVector<S> cos() {
 568         return uOp((i, a) -> (float) Math.cos((double) a));
 569     }
 570 
 571     /**
 572      * Calculates the trigonometric cosine of this vector, selecting lane
 573      * elements controlled by a mask.
 574      * <p>
 575      * This is a vector unary operation where the {@link Math#cos} operation
 576      * is applied to lane elements.
 577      *
 578      * @param m the mask controlling lane selection
 579      * @return the cosine of this vector
 580      */
 581     public FloatVector<S> cos(Mask<Float,S> m) {
 582         return uOp(m, (i, a) -> (float) Math.cos((double) a));
 583     }
 584 
 585     /**
 586      * Calculates the hyperbolic cosine of this vector.
 587      * <p>
 588      * This is a vector unary operation where the {@link Math#cosh} operation
 589      * is applied to lane elements.
 590      *
 591      * @return the hyperbolic cosine of this vector
 592      */
 593     public FloatVector<S> cosh() {
 594         return uOp((i, a) -> (float) Math.cosh((double) a));
 595     }
 596 
 597     /**
 598      * Calculates the hyperbolic cosine of this vector, selecting lane elements
 599      * controlled by a mask.
 600      * <p>
 601      * This is a vector unary operation where the {@link Math#cosh} operation
 602      * is applied to lane elements.
 603      *
 604      * @param m the mask controlling lane selection
 605      * @return the hyperbolic cosine of this vector
 606      */
 607     public FloatVector<S> cosh(Mask<Float,S> m) {
 608         return uOp(m, (i, a) -> (float) Math.cosh((double) a));
 609     }
 610 
 611     /**
 612      * Calculates the arc sine of this vector.
 613      * <p>
 614      * This is a vector unary operation where the {@link Math#asin} operation
 615      * is applied to lane elements.
 616      *
 617      * @return the arc sine of this vector
 618      */
 619     public FloatVector<S> asin() {
 620         return uOp((i, a) -> (float) Math.asin((double) a));
 621     }
 622 
 623     /**
 624      * Calculates the arc sine of this vector, selecting lane elements
 625      * controlled by a mask.
 626      * <p>
 627      * This is a vector unary operation where the {@link Math#asin} operation
 628      * is applied to lane elements.
 629      *
 630      * @param m the mask controlling lane selection
 631      * @return the arc sine of this vector
 632      */
 633     public FloatVector<S> asin(Mask<Float,S> m) {
 634         return uOp(m, (i, a) -> (float) Math.asin((double) a));
 635     }
 636 
 637     /**
 638      * Calculates the arc cosine of this vector.
 639      * <p>
 640      * This is a vector unary operation where the {@link Math#acos} operation
 641      * is applied to lane elements.
 642      *
 643      * @return the arc cosine of this vector
 644      */
 645     public FloatVector<S> acos() {
 646         return uOp((i, a) -> (float) Math.acos((double) a));
 647     }
 648 
 649     /**
 650      * Calculates the arc cosine of this vector, selecting lane elements
 651      * controlled by a mask.
 652      * <p>
 653      * This is a vector unary operation where the {@link Math#acos} operation
 654      * is applied to lane elements.
 655      *
 656      * @param m the mask controlling lane selection
 657      * @return the arc cosine of this vector
 658      */
 659     public FloatVector<S> acos(Mask<Float,S> m) {
 660         return uOp(m, (i, a) -> (float) Math.acos((double) a));
 661     }
 662 
 663     /**
 664      * Calculates the arc tangent of this vector.
 665      * <p>
 666      * This is a vector unary operation where the {@link Math#atan} operation
 667      * is applied to lane elements.
 668      *
 669      * @return the arc tangent of this vector
 670      */
 671     public FloatVector<S> atan() {
 672         return uOp((i, a) -> (float) Math.atan((double) a));
 673     }
 674 
 675     /**
 676      * Calculates the arc tangent of this vector, selecting lane elements
 677      * controlled by a mask.
 678      * <p>
 679      * This is a vector unary operation where the {@link Math#atan} operation
 680      * is applied to lane elements.
 681      *
 682      * @param m the mask controlling lane selection
 683      * @return the arc tangent of this vector
 684      */
 685     public FloatVector<S> atan(Mask<Float,S> m) {
 686         return uOp(m, (i, a) -> (float) Math.atan((double) a));
 687     }
 688 
 689     /**
 690      * Calculates the arc tangent of this vector divided by an input vector.
 691      * <p>
 692      * This is a vector binary operation where the {@link Math#atan2} operation
 693      * is applied to lane elements.
 694      *
 695      * @param v the input vector
 696      * @return the arc tangent of this vector divided by the input vector
 697      */
 698     public FloatVector<S> atan2(Vector<Float,S> v) {
 699         return bOp(v, (i, a, b) -> (float) Math.atan2((double) a, (double) b));
 700     }
 701 
 702     /**
 703      * Calculates the arc tangent of this vector divided by the broadcast of an
 704      * an input scalar.
 705      * <p>
 706      * This is a vector binary operation where the {@link Math#atan2} operation
 707      * is applied to lane elements.
 708      *
 709      * @param s the input scalar
 710      * @return the arc tangent of this vector over the input vector
 711      */
 712     public abstract FloatVector<S> atan2(float s);
 713 
 714     /**
 715      * Calculates the arc tangent of this vector divided by an input vector,
 716      * selecting lane elements controlled by a mask.
 717      * <p>
 718      * This is a vector binary operation where the {@link Math#atan2} operation
 719      * is applied to lane elements.
 720      *
 721      * @param v the input vector
 722      * @param m the mask controlling lane selection
 723      * @return the arc tangent of this vector divided by the input vector
 724      */
 725     public FloatVector<S> atan2(Vector<Float,S> v, Mask<Float,S> m) {
 726         return bOp(v, m, (i, a, b) -> (float) Math.atan2((double) a, (double) b));
 727     }
 728 
 729     /**
 730      * Calculates the arc tangent of this vector divided by the broadcast of an
 731      * an input scalar, selecting lane elements controlled by a mask.
 732      * <p>
 733      * This is a vector binary operation where the {@link Math#atan2} operation
 734      * is applied to lane elements.
 735      *
 736      * @param s the input scalar
 737      * @param m the mask controlling lane selection
 738      * @return the arc tangent of this vector over the input vector
 739      */
 740     public abstract FloatVector<S> atan2(float s, Mask<Float,S> m);
 741 
 742     /**
 743      * Calculates the cube root of this vector.
 744      * <p>
 745      * This is a vector unary operation where the {@link Math#cbrt} operation
 746      * is applied to lane elements.
 747      *
 748      * @return the cube root of this vector
 749      */
 750     public FloatVector<S> cbrt() {
 751         return uOp((i, a) -> (float) Math.cbrt((double) a));
 752     }
 753 
 754     /**
 755      * Calculates the cube root of this vector, selecting lane elements
 756      * controlled by a mask.
 757      * <p>
 758      * This is a vector unary operation where the {@link Math#cbrt} operation
 759      * is applied to lane elements.
 760      *
 761      * @param m the mask controlling lane selection
 762      * @return the cube root of this vector
 763      */
 764     public FloatVector<S> cbrt(Mask<Float,S> m) {
 765         return uOp(m, (i, a) -> (float) Math.cbrt((double) a));
 766     }
 767 
 768     /**
 769      * Calculates the natural logarithm of this vector.
 770      * <p>
 771      * This is a vector unary operation where the {@link Math#log} operation
 772      * is applied to lane elements.
 773      *
 774      * @return the natural logarithm of this vector
 775      */
 776     public FloatVector<S> log() {
 777         return uOp((i, a) -> (float) Math.log((double) a));
 778     }
 779 
 780     /**
 781      * Calculates the natural logarithm of this vector, selecting lane elements
 782      * controlled by a mask.
 783      * <p>
 784      * This is a vector unary operation where the {@link Math#log} operation
 785      * is applied to lane elements.
 786      *
 787      * @param m the mask controlling lane selection
 788      * @return the natural logarithm of this vector
 789      */
 790     public FloatVector<S> log(Mask<Float,S> m) {
 791         return uOp(m, (i, a) -> (float) Math.log((double) a));
 792     }
 793 
 794     /**
 795      * Calculates the base 10 logarithm of this vector.
 796      * <p>
 797      * This is a vector unary operation where the {@link Math#log10} operation
 798      * is applied to lane elements.
 799      *
 800      * @return the base 10 logarithm of this vector
 801      */
 802     public FloatVector<S> log10() {
 803         return uOp((i, a) -> (float) Math.log10((double) a));
 804     }
 805 
 806     /**
 807      * Calculates the base 10 logarithm of this vector, selecting lane elements
 808      * controlled by a mask.
 809      * <p>
 810      * This is a vector unary operation where the {@link Math#log10} operation
 811      * is applied to lane elements.
 812      *
 813      * @param m the mask controlling lane selection
 814      * @return the base 10 logarithm of this vector
 815      */
 816     public FloatVector<S> log10(Mask<Float,S> m) {
 817         return uOp(m, (i, a) -> (float) Math.log10((double) a));
 818     }
 819 
 820     /**
 821      * Calculates the natural logarithm of the sum of this vector and the
 822      * broadcast of {@code 1}.
 823      * <p>
 824      * This is a vector unary operation where the {@link Math#log1p} operation
 825      * is applied to lane elements.
 826      *
 827      * @return the natural logarithm of the sum of this vector and the broadcast
 828      * of {@code 1}
 829      */
 830     public FloatVector<S> log1p() {
 831         return uOp((i, a) -> (float) Math.log1p((double) a));
 832     }
 833 
 834     /**
 835      * Calculates the natural logarithm of the sum of this vector and the
 836      * broadcast of {@code 1}, selecting lane elements controlled by a mask.
 837      * <p>
 838      * This is a vector unary operation where the {@link Math#log1p} operation
 839      * is applied to lane elements.
 840      *
 841      * @param m the mask controlling lane selection
 842      * @return the natural logarithm of the sum of this vector and the broadcast
 843      * of {@code 1}
 844      */
 845     public FloatVector<S> log1p(Mask<Float,S> m) {
 846         return uOp(m, (i, a) -> (float) Math.log1p((double) a));
 847     }
 848 
 849     /**
 850      * Calculates this vector raised to the power of an input vector.
 851      * <p>
 852      * This is a vector binary operation where the {@link Math#pow} operation
 853      * is applied to lane elements.
 854      *
 855      * @param v the input vector
 856      * @return this vector raised to the power of an input vector
 857      */
 858     public FloatVector<S> pow(Vector<Float,S> v) {
 859         return bOp(v, (i, a, b) -> (float) Math.pow((double) a, (double) b));
 860     }
 861 
 862     /**
 863      * Calculates this vector raised to the power of the broadcast of an input
 864      * scalar.
 865      * <p>
 866      * This is a vector binary operation where the {@link Math#pow} operation
 867      * is applied to lane elements.
 868      *
 869      * @param s the input scalar
 870      * @return this vector raised to the power of the broadcast of an input
 871      * scalar.
 872      */
 873     public abstract FloatVector<S> pow(float s);
 874 
 875     /**
 876      * Calculates this vector raised to the power of an input vector, selecting
 877      * lane elements controlled by a mask.
 878      * <p>
 879      * This is a vector binary operation where the {@link Math#pow} operation
 880      * is applied to lane elements.
 881      *
 882      * @param v the input vector
 883      * @param m the mask controlling lane selection
 884      * @return this vector raised to the power of an input vector
 885      */
 886     public FloatVector<S> pow(Vector<Float,S> v, Mask<Float,S> m) {
 887         return bOp(v, m, (i, a, b) -> (float) Math.pow((double) a, (double) b));
 888     }
 889 
 890     /**
 891      * Calculates this vector raised to the power of the broadcast of an input
 892      * scalar, selecting lane elements controlled by a mask.
 893      * <p>
 894      * This is a vector binary operation where the {@link Math#pow} operation
 895      * is applied to lane elements.
 896      *
 897      * @param s the input scalar
 898      * @param m the mask controlling lane selection
 899      * @return this vector raised to the power of the broadcast of an input
 900      * scalar.
 901      */
 902     public abstract FloatVector<S> pow(float s, Mask<Float,S> m);
 903 
 904     /**
 905      * Calculates the broadcast of Euler's number {@code e} raised to the power
 906      * of this vector.
 907      * <p>
 908      * This is a vector unary operation where the {@link Math#exp} operation
 909      * is applied to lane elements.
 910      *
 911      * @return the broadcast of Euler's number {@code e} raised to the power of
 912      * this vector
 913      */
 914     public FloatVector<S> exp() {
 915         return uOp((i, a) -> (float) Math.exp((double) a));
 916     }
 917 
 918     /**
 919      * Calculates the broadcast of Euler's number {@code e} raised to the power
 920      * of this vector, selecting lane elements controlled by a mask.
 921      * <p>
 922      * This is a vector unary operation where the {@link Math#exp} operation
 923      * is applied to lane elements.
 924      *
 925      * @param m the mask controlling lane selection
 926      * @return the broadcast of Euler's number {@code e} raised to the power of
 927      * this vector
 928      */
 929     public FloatVector<S> exp(Mask<Float,S> m) {
 930         return uOp(m, (i, a) -> (float) Math.exp((double) a));
 931     }
 932 
 933     /**
 934      * Calculates the broadcast of Euler's number {@code e} raised to the power
 935      * of this vector minus the broadcast of {@code -1}.
 936      * More specifically as if the following (ignoring any differences in
 937      * numerical accuracy):
 938      * <pre>{@code
 939      *   this.exp().sub(this.species().broadcast(1))
 940      * }</pre>
 941      * <p>
 942      * This is a vector unary operation where the {@link Math#expm1} operation
 943      * is applied to lane elements.
 944      *
 945      * @return the broadcast of Euler's number {@code e} raised to the power of
 946      * this vector minus the broadcast of {@code -1}
 947      */
 948     public FloatVector<S> expm1() {
 949         return uOp((i, a) -> (float) Math.expm1((double) a));
 950     }
 951 
 952     /**
 953      * Calculates the broadcast of Euler's number {@code e} raised to the power
 954      * of this vector minus the broadcast of {@code -1}, selecting lane elements
 955      * controlled by a mask
 956      * More specifically as if the following (ignoring any differences in
 957      * numerical accuracy):
 958      * <pre>{@code
 959      *   this.exp(m).sub(this.species().broadcast(1), m)
 960      * }</pre>
 961      * <p>
 962      * This is a vector unary operation where the {@link Math#expm1} operation
 963      * is applied to lane elements.
 964      *
 965      * @param m the mask controlling lane selection
 966      * @return the broadcast of Euler's number {@code e} raised to the power of
 967      * this vector minus the broadcast of {@code -1}
 968      */
 969     public FloatVector<S> expm1(Mask<Float,S> m) {
 970         return uOp(m, (i, a) -> (float) Math.expm1((double) a));
 971     }
 972 
 973     /**
 974      * Calculates the product of this vector and a first input vector summed
 975      * with a second input vector.
 976      * More specifically as if the following (ignoring any differences in
 977      * numerical accuracy):
 978      * <pre>{@code
 979      *   this.mul(v1).add(v2)
 980      * }</pre>
 981      * <p>
 982      * This is a vector ternary operation where the {@link Math#fma} operation
 983      * is applied to lane elements.
 984      *
 985      * @param v1 the first input vector
 986      * @param v2 the second input vector
 987      * @return the product of this vector and the first input vector summed with
 988      * the second input vector
 989      */
 990     public abstract FloatVector<S> fma(Vector<Float,S> v1, Vector<Float,S> v2);
 991 
 992     /**
 993      * Calculates the product of this vector and the broadcast of a first input
 994      * scalar summed with the broadcast of a second input scalar.
 995      * More specifically as if the following:
 996      * <pre>{@code
 997      *   this.fma(this.species().broadcast(s1), this.species().broadcast(s2))
 998      * }</pre>
 999      * <p>
1000      * This is a vector ternary operation where the {@link Math#fma} operation
1001      * is applied to lane elements.
1002      *
1003      * @param s1 the first input scalar
1004      * @param s2 the second input scalar
1005      * @return the product of this vector and the broadcast of a first input
1006      * scalar summed with the broadcast of a second input scalar
1007      */
1008     public abstract FloatVector<S> fma(float s1, float s2);
1009 
1010     /**
1011      * Calculates the product of this vector and a first input vector summed
1012      * with a second input vector, selecting lane elements controlled by a mask.
1013      * More specifically as if the following (ignoring any differences in
1014      * numerical accuracy):
1015      * <pre>{@code
1016      *   this.mul(v1, m).add(v2, m)
1017      * }</pre>
1018      * <p>
1019      * This is a vector ternary operation where the {@link Math#fma} operation
1020      * is applied to lane elements.
1021      *
1022      * @param v1 the first input vector
1023      * @param v2 the second input vector
1024      * @param m the mask controlling lane selection
1025      * @return the product of this vector and the first input vector summed with
1026      * the second input vector
1027      */
1028     public FloatVector<S> fma(Vector<Float,S> v1, Vector<Float,S> v2, Mask<Float,S> m) {
1029         return tOp(v1, v2, m, (i, a, b, c) -> Math.fma(a, b, c));
1030     }
1031 
1032     /**
1033      * Calculates the product of this vector and the broadcast of a first input
1034      * scalar summed with the broadcast of a second input scalar, selecting lane
1035      * elements controlled by a mask
1036      * More specifically as if the following:
1037      * <pre>{@code
1038      *   this.fma(this.species().broadcast(s1), this.species().broadcast(s2), m)
1039      * }</pre>
1040      * <p>
1041      * This is a vector ternary operation where the {@link Math#fma} operation
1042      * is applied to lane elements.
1043      *
1044      * @param s1 the first input scalar
1045      * @param s2 the second input scalar
1046      * @param m the mask controlling lane selection
1047      * @return the product of this vector and the broadcast of a first input
1048      * scalar summed with the broadcast of a second input scalar
1049      */
1050     public abstract FloatVector<S> fma(float s1, float s2, Mask<Float,S> m);
1051 
1052 // Computes the square root of the sum of the squares of x and y
1053 
1054     /**
1055      * Calculates square root of the sum of the squares of this vector and an
1056      * input vector.
1057      * More specifically as if the following (ignoring any differences in
1058      * numerical accuracy):
1059      * <pre>{@code
1060      *   this.mul(this).add(v.mul(v)).sqrt()
1061      * }</pre>
1062      * <p>
1063      * This is a vector binary operation where the {@link Math#hypot} operation
1064      * is applied to lane elements.
1065      *
1066      * @param v the input vector
1067      * @return square root of the sum of the squares of this vector and an input
1068      * vector
1069      */
1070     public FloatVector<S> hypot(Vector<Float,S> v) {
1071         return bOp(v, (i, a, b) -> (float) Math.hypot((double) a, (double) b));
1072     }
1073 
1074     /**
1075      * Calculates square root of the sum of the squares of this vector and the
1076      * broadcast of an input scalar.
1077      * More specifically as if the following (ignoring any differences in
1078      * numerical accuracy):
1079      * <pre>{@code
1080      *   this.mul(this).add(this.species().broadcast(v * v)).sqrt()
1081      * }</pre>
1082      * <p>
1083      * This is a vector binary operation where the {@link Math#hypot} operation
1084      * is applied to lane elements.
1085      *
1086      * @param s the input scalar
1087      * @return square root of the sum of the squares of this vector and the
1088      * broadcast of an input scalar
1089      */
1090     public abstract FloatVector<S> hypot(float s);
1091 
1092     /**
1093      * Calculates square root of the sum of the squares of this vector and an
1094      * input vector, selecting lane elements controlled by a mask.
1095      * More specifically as if the following (ignoring any differences in
1096      * numerical accuracy):
1097      * <pre>{@code
1098      *   this.mul(this, m).add(v.mul(v), m).sqrt(m)
1099      * }</pre>
1100      * <p>
1101      * This is a vector binary operation where the {@link Math#hypot} operation
1102      * is applied to lane elements.
1103      *
1104      * @param v the input vector
1105      * @param m the mask controlling lane selection
1106      * @return square root of the sum of the squares of this vector and an input
1107      * vector
1108      */
1109     public FloatVector<S> hypot(Vector<Float,S> v, Mask<Float,S> m) {
1110         return bOp(v, m, (i, a, b) -> (float) Math.hypot((double) a, (double) b));
1111     }
1112 
1113     /**
1114      * Calculates square root of the sum of the squares of this vector and the
1115      * broadcast of an input scalar, selecting lane elements controlled by a
1116      * mask.
1117      * More specifically as if the following (ignoring any differences in
1118      * numerical accuracy):
1119      * <pre>{@code
1120      *   this.mul(this, m).add(this.species().broadcast(v * v), m).sqrt(m)
1121      * }</pre>
1122      * <p>
1123      * This is a vector binary operation where the {@link Math#hypot} operation
1124      * is applied to lane elements.
1125      *
1126      * @param s the input scalar
1127      * @param m the mask controlling lane selection
1128      * @return square root of the sum of the squares of this vector and the
1129      * broadcast of an input scalar
1130      */
1131     public abstract FloatVector<S> hypot(float s, Mask<Float,S> m);
1132 
1133 
1134     @Override
1135     public abstract void intoByteArray(byte[] a, int ix);
1136 
1137     @Override
1138     public abstract void intoByteArray(byte[] a, int ix, Mask<Float, S> m);
1139 
1140     @Override
1141     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1142 
1143     @Override
1144     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Float, S> m);
1145 
1146 
1147     // Type specific horizontal reductions
1148 
1149 // @@@ For floating point vectors order matters for reproducibility
1150 //     with equivalent sequential reduction. Some order needs to be specified
1151 //     by default. If that default is sequential encounter order then there
1152 //     could be a "go faster" option that is unspecified, essentially giving
1153 //     implementation flexibility at the expense of reproducibility and/or
1154 //     accuracy.
1155 // @@@ Mask versions?
1156 
1157     /**
1158      * Adds all lane elements of this vector.
1159      * <p>
1160      * This is an associative vector reduction operation where the addition
1161      * operation ({@code +}) is applied to lane elements,
1162      * and the identity value is {@code 0}.
1163      *
1164      * @return the addition of all the lane elements of this vector
1165      */
1166     public abstract float addAll();
1167 
1168     /**
1169      * Adds all lane elements of this vector, selecting lane elements
1170      * controlled by a mask.
1171      * <p>
1172      * This is an associative vector reduction operation where the addition
1173      * operation ({@code +}) is applied to lane elements,
1174      * and the identity value is {@code 0}.
1175      *
1176      * @param m the mask controlling lane selection
1177      * @return the addition of all the lane elements of this vector
1178      */
1179     public abstract float addAll(Mask<Float, S> m);
1180 
1181     /**
1182      * Subtracts all lane elements of this vector.
1183      * <p>
1184      * This is an associative vector reduction operation where the subtraction
1185      * operation ({@code -}) is applied to lane elements,
1186      * and the identity value is {@code 0}.
1187      *
1188      * @return the subtraction of all the lane elements of this vector
1189      */
1190     public abstract float subAll();
1191 
1192     /**
1193      * Subtracts all lane elements of this vector, selecting lane elements
1194      * controlled by a mask.
1195      * <p>
1196      * This is an associative vector reduction operation where the subtraction
1197      * operation ({@code -}) is applied to lane elements,
1198      * and the identity value is {@code 0}.
1199      *
1200      * @param m the mask controlling lane selection
1201      * @return the subtraction of all the lane elements of this vector
1202      */
1203     public abstract float subAll(Mask<Float, S> m);
1204 
1205     /**
1206      * Multiplies all lane elements of this vector.
1207      * <p>
1208      * This is an associative vector reduction operation where the
1209      * multiplication operation ({@code *}) is applied to lane elements,
1210      * and the identity value is {@code 1}.
1211      *
1212      * @return the multiplication of all the lane elements of this vector
1213      */
1214     public abstract float mulAll();
1215 
1216     /**
1217      * Multiplies all lane elements of this vector, selecting lane elements
1218      * controlled by a mask.
1219      * <p>
1220      * This is an associative vector reduction operation where the
1221      * multiplication operation ({@code *}) is applied to lane elements,
1222      * and the identity value is {@code 1}.
1223      *
1224      * @param m the mask controlling lane selection
1225      * @return the multiplication of all the lane elements of this vector
1226      */
1227     public abstract float mulAll(Mask<Float, S> m);
1228 
1229     /**
1230      * Returns the minimum lane element of this vector.
1231      * <p>
1232      * This is an associative vector reduction operation where the operation
1233      * {@code (a, b) -> a > b ? b : a} is applied to lane elements,
1234      * and the identity value is {@link Float.MAX_VALUE}.
1235      *
1236      * @return the minimum lane element of this vector
1237      */
1238     public abstract float minAll();
1239 
1240     /**
1241      * Returns the minimum lane element of this vector, selecting lane elements
1242      * controlled by a mask.
1243      * <p>
1244      * This is an associative vector reduction operation where the operation
1245      * {@code (a, b) -> a > b ? b : a} is applied to lane elements,
1246      * and the identity value is {@link Float.MAX_VALUE}.
1247      *
1248      * @param m the mask controlling lane selection
1249      * @return the minimum lane element of this vector
1250      */
1251     public abstract float minAll(Mask<Float, S> m);
1252 
1253     /**
1254      * Returns the maximum lane element of this vector.
1255      * <p>
1256      * This is an associative vector reduction operation where the operation
1257      * {@code (a, b) -> a < b ? b : a} is applied to lane elements,
1258      * and the identity value is {@link Float.MIN_VALUE}.
1259      *
1260      * @return the maximum lane element of this vector
1261      */
1262     public abstract float maxAll();
1263 
1264     /**
1265      * Returns the maximum lane element of this vector, selecting lane elements
1266      * controlled by a mask.
1267      * <p>
1268      * This is an associative vector reduction operation where the operation
1269      * {@code (a, b) -> a < b ? b : a} is applied to lane elements,
1270      * and the identity value is {@link Float.MIN_VALUE}.
1271      *
1272      * @param m the mask controlling lane selection
1273      * @return the maximum lane element of this vector
1274      */
1275     public abstract float maxAll(Mask<Float, S> m);
1276 
1277 
1278     // Type specific accessors
1279 
1280     /**
1281      * Gets the lane element at lane index {@code i}
1282      *
1283      * @param i the lane index
1284      * @return the lane element at lane index {@code i}
1285      * @throws IllegalArgumentException if the index is is out of range
1286      * ({@code < 0 || >= length()})
1287      */
1288     public abstract float get(int i);
1289 
1290     /**
1291      * Replaces the lane element of this vector at lane index {@code i} with
1292      * value {@code e}.
1293      * <p>
1294      * This is a cross-lane operation and behaves as if it returns the result
1295      * of blending this vector with an input vector that is the result of
1296      * broadcasting {@code e} and a mask that has only one lane set at lane
1297      * index {@code i}.
1298      *
1299      * @param i the lane index of the lane element to be replaced
1300      * @param e the value to be placed
1301      * @return the result of replacing the lane element of this vector at lane
1302      * index {@code i} with value {@code e}.
1303      * @throws IllegalArgumentException if the index is is out of range
1304      * ({@code < 0 || >= length()})
1305      */
1306     public abstract FloatVector<S> with(int i, float e);
1307 
1308     // Type specific extractors
1309 
1310     /**
1311      * Returns an array containing the lane elements of this vector.
1312      * <p>
1313      * This method behaves as if it {@link #intoArray(float[], int)} stores}
1314      * this vector into an allocated array and returns the array as follows:
1315      * <pre>{@code
1316      *   float[] a = new float[this.length()];
1317      *   this.intoArray(a, 0);
1318      *   return a;
1319      * }</pre>
1320      *
1321      * @return an array containing the the lane elements of this vector
1322      */
1323     @ForceInline
1324     public final float[] toArray() {
1325         // @@@ could allocate without zeroing, see Unsafe.allocateUninitializedArray
1326         float[] a = new float[species().length()];
1327         intoArray(a, 0);
1328         return a;
1329     }
1330 
1331     /**
1332      * Stores this vector into an array starting at offset.
1333      * <p>
1334      * For each vector lane, where {@code N} is the vector lane index,
1335      * the lane element at index {@code N} is stored into the array at index
1336      * {@code i + N}.
1337      *
1338      * @param a the array
1339      * @param i the offset into the array
1340      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1341      * {@code i > a.length - this.length()}
1342      */
1343     public abstract void intoArray(float[] a, int i);
1344 
1345     /**
1346      * Stores this vector into an array starting at offset and using a mask.
1347      * <p>
1348      * For each vector lane, where {@code N} is the vector lane index,
1349      * if the mask lane at index {@code N} is set then the lane element at
1350      * index {@code N} is stored into the array index {@code i + N}.
1351      *
1352      * @param a the array
1353      * @param i the offset into the array
1354      * @param m the mask
1355      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1356      * for any vector lane index {@code N} where the mask at lane {@code N}
1357      * is set {@code i >= a.length - N}
1358      */
1359     public abstract void intoArray(float[] a, int i, Mask<Float, S> m);
1360 
1361     /**
1362      * Stores this vector into an array using indexes obtained from an index
1363      * map.
1364      * <p>
1365      * For each vector lane, where {@code N} is the vector lane index, the
1366      * lane element at index {@code N} is stored into the array at index
1367      * {@code i + indexMap[j + N]}.
1368      *
1369      * @param a the array
1370      * @param i the offset into the array, may be negative if relative
1371      * indexes in the index map compensate to produce a value within the
1372      * array bounds
1373      * @param indexMap the index map
1374      * @param j the offset into the index map
1375      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1376      * {@code j > indexMap.length - this.length()},
1377      * or for any vector lane index {@code N} the result of
1378      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1379      */
1380     public void intoArray(float[] a, int i, int[] indexMap, int j) {
1381         forEach((n, e) -> a[i + indexMap[j + n]] = e);
1382     }
1383 
1384     /**
1385      * Stores this vector into an array using indexes obtained from an index
1386      * map and using a mask.
1387      * <p>
1388      * For each vector lane, where {@code N} is the vector lane index,
1389      * if the mask lane at index {@code N} is set then the lane element at
1390      * index {@code N} is stored into the array at index
1391      * {@code i + indexMap[j + N]}.
1392      *
1393      * @param a the array
1394      * @param i the offset into the array, may be negative if relative
1395      * indexes in the index map compensate to produce a value within the
1396      * array bounds
1397      * @param m the mask
1398      * @param indexMap the index map
1399      * @param j the offset into the index map
1400      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1401      * {@code j > indexMap.length - this.length()},
1402      * or for any vector lane index {@code N} where the mask at lane
1403      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1404      * {@code < 0} or {@code >= a.length}
1405      */
1406     public void intoArray(float[] a, int i, Mask<Float, S> m, int[] indexMap, int j) {
1407         forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
1408     }
1409 
1410     // Species
1411 
1412     @Override
1413     public abstract FloatSpecies<S> species();
1414 
1415     /**
1416      * A specialized factory for creating {@link FloatVector} value of the same
1417      * shape, and a {@link Mask} and {@link Shuffle} values of the same shape
1418      * and {@code int} element type.
1419      *
1420      * @param <S> the type of shape of this species
1421      */
1422     public static abstract class FloatSpecies<S extends Vector.Shape> extends Vector.Species<Float, S> {
1423         interface FOp {
1424             float apply(int i);
1425         }
1426 
1427         abstract FloatVector<S> op(FOp f);
1428 
1429         abstract FloatVector<S> op(Mask<Float, S> m, FOp f);
1430 
1431         // Factories
1432 
1433         @Override
1434         public abstract FloatVector<S> zero();
1435 
1436         /**
1437          * Returns a vector where all lane elements are set to the primitive
1438          * value {@code e}.
1439          *
1440          * @param e the value
1441          * @return a vector of vector where all lane elements are set to
1442          * the primitive value {@code e}
1443          */
1444         public abstract FloatVector<S> broadcast(float e);
1445 
1446         /**
1447          * Returns a vector where the first lane element is set to the primtive
1448          * value {@code e}, all other lane elements are set to the default
1449          * value.
1450          *
1451          * @param e the value
1452          * @return a vector where the first lane element is set to the primitive
1453          * value {@code e}
1454          */
1455         @ForceInline
1456         public final FloatVector<S> single(float e) {
1457             return zero().with(0, e);
1458         }
1459 
1460         /**
1461          * Returns a vector where each lane element is set to a randomly
1462          * generated primitive value.
1463          * @@@ what are the properties of the random number generator?
1464          *
1465          * @return a vector where each lane elements is set to a randomly
1466          * generated primitive value
1467          */
1468         public FloatVector<S> random() {
1469             ThreadLocalRandom r = ThreadLocalRandom.current();
1470             return op(i -> r.nextFloat());
1471         }
1472 
1473         /**
1474          * Returns a vector where each lane element is set to a given
1475          * primitive value.
1476          * <p>
1477          * For each vector lane, where {@code N} is the vector lane index, the
1478          * the primitive value at index {@code N} is placed into the resulting
1479          * vector at lane index {@code N}.
1480          *
1481          * @@@ What should happen if es.length < this.length() ? use the default
1482          * value or throw IndexOutOfBoundsException
1483          *
1484          * @param es the given primitive values
1485          * @return a vector where each lane element is set to a given primitive
1486          * value
1487          */
1488         public abstract FloatVector<S> scalars(float... es);
1489 
1490         /**
1491          * Loads a vector from an array starting at offset.
1492          * <p>
1493          * For each vector lane, where {@code N} is the vector lane index, the
1494          * array element at index {@code i + N} is placed into the
1495          * resulting vector at lane index {@code N}.
1496          *
1497          * @param a the array
1498          * @param i the offset into the array
1499          * @return the vector loaded from an array
1500          * @throws IndexOutOfBoundsException if {@code i < 0}, or
1501          * {@code i > a.length - this.length()}
1502          */
1503         public abstract FloatVector<S> fromArray(float[] a, int i);
1504 
1505         /**
1506          * Loads a vector from an array starting at offset and using a mask.
1507          * <p>
1508          * For each vector lane, where {@code N} is the vector lane index,
1509          * if the mask lane at index {@code N} is set then the array element at
1510          * index {@code i + N} is placed into the resulting vector at lane index
1511          * {@code N}, otherwise the default element value is placed into the
1512          * resulting vector at lane index {@code N}.
1513          *
1514          * @param a the array
1515          * @param i the offset into the array
1516          * @param m the mask
1517          * @return the vector loaded from an array
1518          * @throws IndexOutOfBoundsException if {@code i < 0}, or
1519          * for any vector lane index {@code N} where the mask at lane {@code N}
1520          * is set {@code i > a.length - N}
1521          */
1522         public abstract FloatVector<S> fromArray(float[] a, int i, Mask<Float, S> m);
1523 
1524         /**
1525          * Loads a vector from an array using indexes obtained from an index
1526          * map.
1527          * <p>
1528          * For each vector lane, where {@code N} is the vector lane index, the
1529          * array element at index {@code i + indexMap[j + N]} is placed into the
1530          * resulting vector at lane index {@code N}.
1531          *
1532          * @param a the array
1533          * @param i the offset into the array, may be negative if relative
1534          * indexes in the index map compensate to produce a value within the
1535          * array bounds
1536          * @param indexMap the index map
1537          * @param j the offset into the index map
1538          * @return the vector loaded from an array
1539          * @throws IndexOutOfBoundsException if {@code j < 0}, or
1540          * {@code j > indexMap.length - this.length()},
1541          * or for any vector lane index {@code N} the result of
1542          * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1543          */
1544         public FloatVector<S> fromArray(float[] a, int i, int[] indexMap, int j) {
1545             return op(n -> a[i + indexMap[j + n]]);
1546         }
1547 
1548         /**
1549          * Loads a vector from an array using indexes obtained from an index
1550          * map and using a mask.
1551          * <p>
1552          * For each vector lane, where {@code N} is the vector lane index,
1553          * if the mask lane at index {@code N} is set then the array element at
1554          * index {@code i + indexMap[j + N]} is placed into the resulting vector
1555          * at lane index {@code N}.
1556          *
1557          * @param a the array
1558          * @param i the offset into the array, may be negative if relative
1559          * indexes in the index map compensate to produce a value within the
1560          * array bounds
1561          * @param indexMap the index map
1562          * @param j the offset into the index map
1563          * @return the vector loaded from an array
1564          * @throws IndexOutOfBoundsException if {@code j < 0}, or
1565          * {@code j > indexMap.length - this.length()},
1566          * or for any vector lane index {@code N} where the mask at lane
1567          * {@code N} is set the result of {@code i + indexMap[j + N]} is
1568          * {@code < 0} or {@code >= a.length}
1569          */
1570         public FloatVector<S> fromArray(float[] a, int i, Mask<Float, S> m, int[] indexMap, int j) {
1571             return op(m, n -> a[i + indexMap[j + n]]);
1572         }
1573 
1574         @Override
1575         public abstract FloatVector<S> fromByteArray(byte[] a, int ix);
1576 
1577         @Override
1578         public abstract FloatVector<S> fromByteArray(byte[] a, int ix, Mask<Float, S> m);
1579 
1580         @Override
1581         public abstract FloatVector<S> fromByteBuffer(ByteBuffer bb, int ix);
1582 
1583         @Override
1584         public abstract FloatVector<S> fromByteBuffer(ByteBuffer bb, int ix, Mask<Float, S> m);
1585 
1586         @Override
1587         public <F, T extends Shape> FloatVector<S> reshape(Vector<F, T> o) {
1588             int blen = Math.max(o.species().bitSize(), bitSize()) / Byte.SIZE;
1589             ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
1590             o.intoByteBuffer(bb, 0);
1591             return fromByteBuffer(bb, 0);
1592         }
1593 
1594         @Override
1595         public abstract <F> FloatVector<S> rebracket(Vector<F, S> o);
1596 
1597         @Override
1598         public abstract <T extends Shape> FloatVector<S> resize(Vector<Float, T> o);
1599 
1600         @Override
1601         public abstract <F, T extends Shape> FloatVector<S> cast(Vector<F, T> v);
1602 
1603     }
1604 
1605     /**
1606      * Finds the preferred species for an element type of {@code float}.
1607      * <p>
1608      * A preferred species is a species chosen by the platform that has a
1609      * shape of maximal bit size.  A preferred species for different element
1610      * types will have the same shape, and therefore vectors, masks, and
1611      * shuffles created from such species will be shape compatible.
1612      *
1613      * @return the preferred species for an element type of {@code float}
1614      */
1615     @SuppressWarnings("unchecked")
1616     public static FloatSpecies<?> preferredSpecies() {
1617         return (FloatSpecies<?>) Vector.preferredSpecies(float.class);
1618     }
1619 
1620     /**
1621      * Finds a species for an element type of {@code float} and shape.
1622      *
1623      * @param s the shape
1624      * @param <S> the type of shape
1625      * @return a species for an element type of {@code float} and shape
1626      * @throws IllegalArgumentException if no such species exists for the shape
1627      */
1628     @SuppressWarnings("unchecked")
1629     public static <S extends Shape> FloatSpecies<S> species(S s) {
1630         Objects.requireNonNull(s);
1631         if (s == Shapes.S_64_BIT) {
1632             return (FloatSpecies<S>) Float64Vector.SPECIES;
1633         } else if (s == Shapes.S_128_BIT) {
1634             return (FloatSpecies<S>) Float128Vector.SPECIES;
1635         } else if (s == Shapes.S_256_BIT) {
1636             return (FloatSpecies<S>) Float256Vector.SPECIES;
1637         } else if (s == Shapes.S_512_BIT) {
1638             return (FloatSpecies<S>) Float512Vector.SPECIES;
1639         } else {
1640             throw new IllegalArgumentException("Bad shape: " + s);
1641         }
1642     }
1643 }