< prev index next >

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java

Print this page
rev 54658 : refactored mask and shuffle creation methods, moved classes to top-level


  39 
  40 /**
  41  * A specialized {@link Vector} representing an ordered immutable sequence of
  42  * {@code double} values.
  43  */
  44 @SuppressWarnings("cast")
  45 public abstract class DoubleVector extends Vector<Double> {
  46 
  47     DoubleVector() {}
  48 
  49     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
  50 
  51     // Unary operator
  52 
  53     interface FUnOp {
  54         double apply(int i, double a);
  55     }
  56 
  57     abstract DoubleVector uOp(FUnOp f);
  58 
  59     abstract DoubleVector uOp(Mask<Double> m, FUnOp f);
  60 
  61     // Binary operator
  62 
  63     interface FBinOp {
  64         double apply(int i, double a, double b);
  65     }
  66 
  67     abstract DoubleVector bOp(Vector<Double> v, FBinOp f);
  68 
  69     abstract DoubleVector bOp(Vector<Double> v, Mask<Double> m, FBinOp f);
  70 
  71     // Trinary operator
  72 
  73     interface FTriOp {
  74         double apply(int i, double a, double b, double c);
  75     }
  76 
  77     abstract DoubleVector tOp(Vector<Double> v1, Vector<Double> v2, FTriOp f);
  78 
  79     abstract DoubleVector tOp(Vector<Double> v1, Vector<Double> v2, Mask<Double> m, FTriOp f);
  80 
  81     // Reduction operator
  82 
  83     abstract double rOp(double v, FBinOp f);
  84 
  85     // Binary test
  86 
  87     interface FBinTest {
  88         boolean apply(int i, double a, double b);
  89     }
  90 
  91     abstract Mask<Double> bTest(Vector<Double> v, FBinTest f);
  92 
  93     // Foreach
  94 
  95     interface FUnCon {
  96         void apply(int i, double a);
  97     }
  98 
  99     abstract void forEach(FUnCon f);
 100 
 101     abstract void forEach(Mask<Double> m, FUnCon f);
 102 
 103     // Static factories
 104 
 105     /**
 106      * Returns a vector where all lane elements are set to the default
 107      * primitive value.
 108      *
 109      * @param species species of desired vector
 110      * @return a zero vector of given species
 111      */
 112     @ForceInline
 113     @SuppressWarnings("unchecked")
 114     public static DoubleVector zero(Species<Double> species) {
 115         return VectorIntrinsics.broadcastCoerced((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 116                                                  Double.doubleToLongBits(0.0f), species,
 117                                                  ((bits, s) -> ((DoubleSpecies)s).op(i -> Double.longBitsToDouble((long)bits))));
 118     }
 119 
 120     /**
 121      * Loads a vector from a byte array starting at an offset.
 122      * <p>
 123      * Bytes are composed into primitive lane elements according to the
 124      * native byte order of the underlying platform
 125      * <p>
 126      * This method behaves as if it returns the result of calling the
 127      * byte buffer, offset, and mask accepting
 128      * {@link #fromByteBuffer(Species<Double>, ByteBuffer, int, Mask) method} as follows:
 129      * <pre>{@code
 130      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 131      * }</pre>
 132      *
 133      * @param species species of desired vector
 134      * @param a the byte array
 135      * @param ix the offset into the array
 136      * @return a vector loaded from a byte array
 137      * @throws IndexOutOfBoundsException if {@code i < 0} or
 138      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 139      */
 140     @ForceInline
 141     @SuppressWarnings("unchecked")
 142     public static DoubleVector fromByteArray(Species<Double> species, byte[] a, int ix) {
 143         Objects.requireNonNull(a);
 144         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 145         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 146                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 147                                      a, ix, species,
 148                                      (c, idx, s) -> {
 149                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 150                                          DoubleBuffer tb = bbc.asDoubleBuffer();
 151                                          return ((DoubleSpecies)s).op(i -> tb.get());
 152                                      });
 153     }
 154 
 155     /**
 156      * Loads a vector from a byte array starting at an offset and using a
 157      * mask.
 158      * <p>
 159      * Bytes are composed into primitive lane elements according to the
 160      * native byte order of the underlying platform.
 161      * <p>
 162      * This method behaves as if it returns the result of calling the
 163      * byte buffer, offset, and mask accepting
 164      * {@link #fromByteBuffer(Species<Double>, ByteBuffer, int, Mask) method} as follows:
 165      * <pre>{@code
 166      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 167      * }</pre>
 168      *
 169      * @param species species of desired vector
 170      * @param a the byte array
 171      * @param ix the offset into the array
 172      * @param m the mask
 173      * @return a vector loaded from a byte array
 174      * @throws IndexOutOfBoundsException if {@code i < 0} or
 175      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 176      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 177      * or {@code > a.length},
 178      * for any vector lane index {@code N} where the mask at lane {@code N}
 179      * is set
 180      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 181      */
 182     @ForceInline
 183     public static DoubleVector fromByteArray(Species<Double> species, byte[] a, int ix, Mask<Double> m) {
 184         return zero(species).blend(fromByteArray(species, a, ix), m);
 185     }
 186 
 187     /**
 188      * Loads a vector from an array starting at offset.
 189      * <p>
 190      * For each vector lane, where {@code N} is the vector lane index, the
 191      * array element at index {@code i + N} is placed into the
 192      * resulting vector at lane index {@code N}.
 193      *
 194      * @param species species of desired vector
 195      * @param a the array
 196      * @param i the offset into the array
 197      * @return the vector loaded from an array
 198      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 199      * {@code i > a.length - this.length()}
 200      */
 201     @ForceInline
 202     @SuppressWarnings("unchecked")
 203     public static DoubleVector fromArray(Species<Double> species, double[] a, int i){
 204         Objects.requireNonNull(a);
 205         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 206         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 207                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 208                                      a, i, species,
 209                                      (c, idx, s) -> ((DoubleSpecies)s).op(n -> c[idx + n]));
 210     }
 211 
 212 
 213     /**
 214      * Loads a vector from an array starting at offset and using a mask.
 215      * <p>
 216      * For each vector lane, where {@code N} is the vector lane index,
 217      * if the mask lane at index {@code N} is set then the array element at
 218      * index {@code i + N} is placed into the resulting vector at lane index
 219      * {@code N}, otherwise the default element value is placed into the
 220      * resulting vector at lane index {@code N}.
 221      *
 222      * @param species species of desired vector
 223      * @param a the array
 224      * @param i the offset into the array
 225      * @param m the mask
 226      * @return the vector loaded from an array
 227      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 228      * for any vector lane index {@code N} where the mask at lane {@code N}
 229      * is set {@code i > a.length - N}
 230      */
 231     @ForceInline
 232     public static DoubleVector fromArray(Species<Double> species, double[] a, int i, Mask<Double> m) {
 233         return zero(species).blend(fromArray(species, a, i), m);
 234     }
 235 
 236     /**
 237      * Loads a vector from an array using indexes obtained from an index
 238      * map.
 239      * <p>
 240      * For each vector lane, where {@code N} is the vector lane index, the
 241      * array element at index {@code i + indexMap[j + N]} is placed into the
 242      * resulting vector at lane index {@code N}.
 243      *
 244      * @param species species of desired vector
 245      * @param a the array
 246      * @param i the offset into the array, may be negative if relative
 247      * indexes in the index map compensate to produce a value within the
 248      * array bounds
 249      * @param indexMap the index map
 250      * @param j the offset into the index map
 251      * @return the vector loaded from an array
 252      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 253      * {@code j > indexMap.length - this.length()},
 254      * or for any vector lane index {@code N} the result of
 255      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 256      */
 257     @ForceInline
 258     @SuppressWarnings("unchecked")
 259     public static DoubleVector fromArray(Species<Double> species, double[] a, int i, int[] indexMap, int j) {
 260         Objects.requireNonNull(a);
 261         Objects.requireNonNull(indexMap);
 262 
 263         if (species.length() == 1) {
 264           return DoubleVector.fromArray(species, a, i + indexMap[j]);
 265         }
 266 
 267         // Index vector: vix[0:n] = k -> i + indexMap[j + k]
 268         IntVector vix = IntVector.fromArray(IntVector.species(species.indexShape()), indexMap, j).add(i);
 269 
 270         vix = VectorIntrinsics.checkIndex(vix, a.length);
 271 
 272         return VectorIntrinsics.loadWithMap((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 273                                             IntVector.species(species.indexShape()).boxType(), a, Unsafe.ARRAY_DOUBLE_BASE_OFFSET, vix,
 274                                             a, i, indexMap, j, species,
 275                                             (double[] c, int idx, int[] iMap, int idy, Species<Double> s) ->
 276                                                 ((DoubleSpecies)s).op(n -> c[idx + iMap[idy+n]]));
 277         }
 278 
 279     /**
 280      * Loads a vector from an array using indexes obtained from an index
 281      * map and using a mask.
 282      * <p>
 283      * For each vector lane, where {@code N} is the vector lane index,
 284      * if the mask lane at index {@code N} is set then the array element at
 285      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 286      * at lane index {@code N}.
 287      *
 288      * @param species species of desired vector
 289      * @param a the array
 290      * @param i the offset into the array, may be negative if relative
 291      * indexes in the index map compensate to produce a value within the
 292      * array bounds
 293      * @param m the mask
 294      * @param indexMap the index map
 295      * @param j the offset into the index map
 296      * @return the vector loaded from an array
 297      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 298      * {@code j > indexMap.length - this.length()},
 299      * or for any vector lane index {@code N} where the mask at lane
 300      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 301      * {@code < 0} or {@code >= a.length}
 302      */
 303     @ForceInline
 304     @SuppressWarnings("unchecked")
 305     public static DoubleVector fromArray(Species<Double> species, double[] a, int i, Mask<Double> m, int[] indexMap, int j) {
 306         // @@@ This can result in out of bounds errors for unset mask lanes
 307         return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
 308     }
 309 
 310 
 311     /**
 312      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 313      * offset into the byte buffer.
 314      * <p>
 315      * Bytes are composed into primitive lane elements according to the
 316      * native byte order of the underlying platform.
 317      * <p>
 318      * This method behaves as if it returns the result of calling the
 319      * byte buffer, offset, and mask accepting
 320      * {@link #fromByteBuffer(Species<Double>, ByteBuffer, int, Mask)} method} as follows:
 321      * <pre>{@code
 322      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 323      * }</pre>
 324      *
 325      * @param species species of desired vector
 326      * @param bb the byte buffer
 327      * @param ix the offset into the byte buffer
 328      * @return a vector loaded from a byte buffer
 329      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 330      * or {@code > b.limit()},
 331      * or if there are fewer than
 332      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 333      * remaining in the byte buffer from the given offset
 334      */
 335     @ForceInline
 336     @SuppressWarnings("unchecked")
 337     public static DoubleVector fromByteBuffer(Species<Double> species, ByteBuffer bb, int ix) {
 338         if (bb.order() != ByteOrder.nativeOrder()) {
 339             throw new IllegalArgumentException();
 340         }
 341         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 342         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 343                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 344                                      bb, ix, species,
 345                                      (c, idx, s) -> {
 346                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 347                                          DoubleBuffer tb = bbc.asDoubleBuffer();
 348                                          return ((DoubleSpecies)s).op(i -> tb.get());
 349                                      });
 350     }
 351 
 352     /**
 353      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 354      * offset into the byte buffer and using a mask.
 355      * <p>
 356      * This method behaves as if the byte buffer is viewed as a primitive
 357      * {@link java.nio.Buffer buffer} for the primitive element type,


 369      * e[] es = new e[this.length()];
 370      * for (int n = 0; n < t.length; n++) {
 371      *     if (m.isSet(n))
 372      *         es[n] = eb.get(n);
 373      * }
 374      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 375      * }</pre>
 376      *
 377      * @param species species of desired vector
 378      * @param bb the byte buffer
 379      * @param ix the offset into the byte buffer
 380      * @param m the mask
 381      * @return a vector loaded from a byte buffer
 382      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 383      * or {@code > b.limit()},
 384      * for any vector lane index {@code N} where the mask at lane {@code N}
 385      * is set
 386      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 387      */
 388     @ForceInline
 389     public static DoubleVector fromByteBuffer(Species<Double> species, ByteBuffer bb, int ix, Mask<Double> m) {
 390         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 391     }
 392 
 393     /**
 394      * Returns a vector where all lane elements are set to the primitive
 395      * value {@code e}.
 396      *
 397      * @param s species of the desired vector
 398      * @param e the value
 399      * @return a vector of vector where all lane elements are set to
 400      * the primitive value {@code e}
 401      */
 402     @ForceInline
 403     @SuppressWarnings("unchecked")
 404     public static DoubleVector broadcast(Species<Double> s, double e) {
 405         return VectorIntrinsics.broadcastCoerced(
 406             (Class<DoubleVector>) s.boxType(), double.class, s.length(),
 407             Double.doubleToLongBits(e), s,
 408             ((bits, sp) -> ((DoubleSpecies)sp).op(i -> Double.longBitsToDouble((long)bits))));
 409     }
 410 
 411     /**
 412      * Returns a vector where each lane element is set to a given
 413      * primitive value.
 414      * <p>
 415      * For each vector lane, where {@code N} is the vector lane index, the
 416      * the primitive value at index {@code N} is placed into the resulting
 417      * vector at lane index {@code N}.
 418      *
 419      * @param s species of the desired vector
 420      * @param es the given primitive values
 421      * @return a vector where each lane element is set to a given primitive
 422      * value
 423      * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
 424      */
 425     @ForceInline
 426     @SuppressWarnings("unchecked")
 427     public static DoubleVector scalars(Species<Double> s, double... es) {
 428         Objects.requireNonNull(es);
 429         int ix = VectorIntrinsics.checkIndex(0, es.length, s.length());
 430         return VectorIntrinsics.load((Class<DoubleVector>) s.boxType(), double.class, s.length(),
 431                                      es, Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 432                                      es, ix, s,
 433                                      (c, idx, sp) -> ((DoubleSpecies)sp).op(n -> c[idx + n]));
 434     }
 435 
 436     /**
 437      * Returns a vector where the first lane element is set to the primtive
 438      * value {@code e}, all other lane elements are set to the default
 439      * value.
 440      *
 441      * @param s species of the desired vector
 442      * @param e the value
 443      * @return a vector where the first lane element is set to the primitive
 444      * value {@code e}
 445      */
 446     @ForceInline
 447     public static final DoubleVector single(Species<Double> s, double e) {
 448         return zero(s).with(0, e);
 449     }
 450 
 451     /**
 452      * Returns a vector where each lane element is set to a randomly
 453      * generated primitive value.
 454      *
 455      * The semantics are equivalent to calling
 456      * {@link ThreadLocalRandom#nextDouble()}
 457      *
 458      * @param s species of the desired vector
 459      * @return a vector where each lane elements is set to a randomly
 460      * generated primitive value
 461      */
 462     public static DoubleVector random(Species<Double> s) {
 463         ThreadLocalRandom r = ThreadLocalRandom.current();
 464         return ((DoubleSpecies)s).op(i -> r.nextDouble());
 465     }
 466 
 467     /**
 468      * Returns a mask where each lane is set or unset according to given
 469      * {@code boolean} values
 470      * <p>
 471      * For each mask lane, where {@code N} is the mask lane index,
 472      * if the given {@code boolean} value at index {@code N} is {@code true}
 473      * then the mask lane at index {@code N} is set, otherwise it is unset.
 474      *
 475      * @param species mask species
 476      * @param bits the given {@code boolean} values
 477      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 478      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 479      */
 480     @ForceInline
 481     public static Mask<Double> maskFromValues(Species<Double> species, boolean... bits) {
 482         if (species.boxType() == DoubleMaxVector.class)
 483             return new DoubleMaxVector.DoubleMaxMask(bits);
 484         switch (species.bitSize()) {
 485             case 64: return new Double64Vector.Double64Mask(bits);
 486             case 128: return new Double128Vector.Double128Mask(bits);
 487             case 256: return new Double256Vector.Double256Mask(bits);
 488             case 512: return new Double512Vector.Double512Mask(bits);
 489             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 490         }
 491     }
 492 
 493     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 494     static Mask<Double> trueMask(Species<Double> species) {
 495         if (species.boxType() == DoubleMaxVector.class)
 496             return DoubleMaxVector.DoubleMaxMask.TRUE_MASK;
 497         switch (species.bitSize()) {
 498             case 64: return Double64Vector.Double64Mask.TRUE_MASK;
 499             case 128: return Double128Vector.Double128Mask.TRUE_MASK;
 500             case 256: return Double256Vector.Double256Mask.TRUE_MASK;
 501             case 512: return Double512Vector.Double512Mask.TRUE_MASK;
 502             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 503         }
 504     }
 505 
 506     static Mask<Double> falseMask(Species<Double> species) {
 507         if (species.boxType() == DoubleMaxVector.class)
 508             return DoubleMaxVector.DoubleMaxMask.FALSE_MASK;
 509         switch (species.bitSize()) {
 510             case 64: return Double64Vector.Double64Mask.FALSE_MASK;
 511             case 128: return Double128Vector.Double128Mask.FALSE_MASK;
 512             case 256: return Double256Vector.Double256Mask.FALSE_MASK;
 513             case 512: return Double512Vector.Double512Mask.FALSE_MASK;
 514             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 515         }
 516     }
 517 
 518     /**
 519      * Loads a mask from a {@code boolean} array starting at an offset.
 520      * <p>
 521      * For each mask lane, where {@code N} is the mask lane index,
 522      * if the array element at index {@code ix + N} is {@code true} then the
 523      * mask lane at index {@code N} is set, otherwise it is unset.
 524      *
 525      * @param species mask species
 526      * @param bits the {@code boolean} array
 527      * @param ix the offset into the array
 528      * @return the mask loaded from a {@code boolean} array
 529      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 530      * {@code ix > bits.length - species.length()}
 531      */
 532     @ForceInline
 533     @SuppressWarnings("unchecked")
 534     public static Mask<Double> maskFromArray(Species<Double> species, boolean[] bits, int ix) {
 535         Objects.requireNonNull(bits);
 536         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 537         return VectorIntrinsics.load((Class<Mask<Double>>) species.maskType(), long.class, species.length(),
 538                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 539                                      bits, ix, species,
 540                                      (c, idx, s) -> (Mask<Double>) ((DoubleSpecies)s).opm(n -> c[idx + n]));
 541     }
 542 
 543     /**
 544      * Returns a mask where all lanes are set.
 545      *
 546      * @param species mask species
 547      * @return a mask where all lanes are set
 548      */
 549     @ForceInline
 550     @SuppressWarnings("unchecked")
 551     public static Mask<Double> maskAllTrue(Species<Double> species) {
 552         return VectorIntrinsics.broadcastCoerced((Class<Mask<Double>>) species.maskType(), long.class, species.length(),
 553                                                  (long)-1,  species,
 554                                                  ((z, s) -> trueMask(s)));
 555     }
 556 
 557     /**
 558      * Returns a mask where all lanes are unset.
 559      *
 560      * @param species mask species
 561      * @return a mask where all lanes are unset
 562      */
 563     @ForceInline
 564     @SuppressWarnings("unchecked")
 565     public static Mask<Double> maskAllFalse(Species<Double> species) {
 566         return VectorIntrinsics.broadcastCoerced((Class<Mask<Double>>) species.maskType(), long.class, species.length(),
 567                                                  0, species, 
 568                                                  ((z, s) -> falseMask(s)));
 569     }
 570 
 571     /**
 572      * Returns a shuffle of mapped indexes where each lane element is
 573      * the result of applying a mapping function to the corresponding lane
 574      * index.
 575      * <p>
 576      * Care should be taken to ensure Shuffle values produced from this
 577      * method are consumed as constants to ensure optimal generation of
 578      * code.  For example, values held in static final fields or values
 579      * held in loop constant local variables.
 580      * <p>
 581      * This method behaves as if a shuffle is created from an array of
 582      * mapped indexes as follows:
 583      * <pre>{@code
 584      *   int[] a = new int[species.length()];
 585      *   for (int i = 0; i < a.length; i++) {
 586      *       a[i] = f.applyAsInt(i);
 587      *   }
 588      *   return this.shuffleFromValues(a);
 589      * }</pre>
 590      *
 591      * @param species shuffle species
 592      * @param f the lane index mapping function
 593      * @return a shuffle of mapped indexes
 594      */
 595     @ForceInline
 596     public static Shuffle<Double> shuffle(Species<Double> species, IntUnaryOperator f) {
 597         if (species.boxType() == DoubleMaxVector.class)
 598             return new DoubleMaxVector.DoubleMaxShuffle(f);
 599         switch (species.bitSize()) {
 600             case 64: return new Double64Vector.Double64Shuffle(f);
 601             case 128: return new Double128Vector.Double128Shuffle(f);
 602             case 256: return new Double256Vector.Double256Shuffle(f);
 603             case 512: return new Double512Vector.Double512Shuffle(f);
 604             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 605         }
 606     }
 607 
 608     /**
 609      * Returns a shuffle where each lane element is the value of its
 610      * corresponding lane index.
 611      * <p>
 612      * This method behaves as if a shuffle is created from an identity
 613      * index mapping function as follows:
 614      * <pre>{@code
 615      *   return this.shuffle(i -> i);
 616      * }</pre>
 617      *
 618      * @param species shuffle species
 619      * @return a shuffle of lane indexes
 620      */
 621     @ForceInline
 622     public static Shuffle<Double> shuffleIota(Species<Double> species) {
 623         if (species.boxType() == DoubleMaxVector.class)
 624             return new DoubleMaxVector.DoubleMaxShuffle(AbstractShuffle.IDENTITY);
 625         switch (species.bitSize()) {
 626             case 64: return new Double64Vector.Double64Shuffle(AbstractShuffle.IDENTITY);
 627             case 128: return new Double128Vector.Double128Shuffle(AbstractShuffle.IDENTITY);
 628             case 256: return new Double256Vector.Double256Shuffle(AbstractShuffle.IDENTITY);
 629             case 512: return new Double512Vector.Double512Shuffle(AbstractShuffle.IDENTITY);
 630             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 631         }
 632     }
 633 
 634     /**
 635      * Returns a shuffle where each lane element is set to a given
 636      * {@code int} value logically AND'ed by the species length minus one.
 637      * <p>
 638      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 639      * the {@code int} value at index {@code N} logically AND'ed by
 640      * {@code species.length() - 1} is placed into the resulting shuffle at
 641      * lane index {@code N}.
 642      *
 643      * @param species shuffle species
 644      * @param ixs the given {@code int} values
 645      * @return a shuffle where each lane element is set to a given
 646      * {@code int} value
 647      * @throws IndexOutOfBoundsException if the number of int values is
 648      * {@code < species.length()}
 649      */
 650     @ForceInline
 651     public static Shuffle<Double> shuffleFromValues(Species<Double> species, int... ixs) {
 652         if (species.boxType() == DoubleMaxVector.class)
 653             return new DoubleMaxVector.DoubleMaxShuffle(ixs);
 654         switch (species.bitSize()) {
 655             case 64: return new Double64Vector.Double64Shuffle(ixs);
 656             case 128: return new Double128Vector.Double128Shuffle(ixs);
 657             case 256: return new Double256Vector.Double256Shuffle(ixs);
 658             case 512: return new Double512Vector.Double512Shuffle(ixs);
 659             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 660         }
 661     }
 662 
 663     /**
 664      * Loads a shuffle from an {@code int} array starting at an offset.
 665      * <p>
 666      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 667      * array element at index {@code i + N} logically AND'ed by
 668      * {@code species.length() - 1} is placed into the resulting shuffle at lane
 669      * index {@code N}.
 670      *
 671      * @param species shuffle species
 672      * @param ixs the {@code int} array
 673      * @param i the offset into the array
 674      * @return a shuffle loaded from the {@code int} array
 675      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 676      * {@code i > a.length - species.length()}
 677      */
 678     @ForceInline
 679     public static Shuffle<Double> shuffleFromArray(Species<Double> species, int[] ixs, int i) {
 680         if (species.boxType() == DoubleMaxVector.class)
 681             return new DoubleMaxVector.DoubleMaxShuffle(ixs, i);
 682         switch (species.bitSize()) {
 683             case 64: return new Double64Vector.Double64Shuffle(ixs, i);
 684             case 128: return new Double128Vector.Double128Shuffle(ixs, i);
 685             case 256: return new Double256Vector.Double256Shuffle(ixs, i);
 686             case 512: return new Double512Vector.Double512Shuffle(ixs, i);
 687             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 688         }
 689     }
 690 
 691     // Ops
 692 
 693     @Override
 694     public abstract DoubleVector add(Vector<Double> v);
 695 
 696     /**
 697      * Adds this vector to the broadcast of an input scalar.
 698      * <p>
 699      * This is a vector binary operation where the primitive addition operation
 700      * ({@code +}) is applied to lane elements.
 701      *
 702      * @param s the input scalar
 703      * @return the result of adding this vector to the broadcast of an input
 704      * scalar
 705      */
 706     public abstract DoubleVector add(double s);
 707 
 708     @Override
 709     public abstract DoubleVector add(Vector<Double> v, Mask<Double> m);
 710 
 711     /**
 712      * Adds this vector to broadcast of an input scalar,
 713      * selecting lane elements controlled by a mask.
 714      * <p>
 715      * This is a vector binary operation where the primitive addition operation
 716      * ({@code +}) is applied to lane elements.
 717      *
 718      * @param s the input scalar
 719      * @param m the mask controlling lane selection
 720      * @return the result of adding this vector to the broadcast of an input
 721      * scalar
 722      */
 723     public abstract DoubleVector add(double s, Mask<Double> m);
 724 
 725     @Override
 726     public abstract DoubleVector sub(Vector<Double> v);
 727 
 728     /**
 729      * Subtracts the broadcast of an input scalar from this vector.
 730      * <p>
 731      * This is a vector binary operation where the primitive subtraction
 732      * operation ({@code -}) is applied to lane elements.
 733      *
 734      * @param s the input scalar
 735      * @return the result of subtracting the broadcast of an input
 736      * scalar from this vector
 737      */
 738     public abstract DoubleVector sub(double s);
 739 
 740     @Override
 741     public abstract DoubleVector sub(Vector<Double> v, Mask<Double> m);
 742 
 743     /**
 744      * Subtracts the broadcast of an input scalar from this vector, selecting
 745      * lane elements controlled by a mask.
 746      * <p>
 747      * This is a vector binary operation where the primitive subtraction
 748      * operation ({@code -}) is applied to lane elements.
 749      *
 750      * @param s the input scalar
 751      * @param m the mask controlling lane selection
 752      * @return the result of subtracting the broadcast of an input
 753      * scalar from this vector
 754      */
 755     public abstract DoubleVector sub(double s, Mask<Double> m);
 756 
 757     @Override
 758     public abstract DoubleVector mul(Vector<Double> v);
 759 
 760     /**
 761      * Multiplies this vector with the broadcast of an input scalar.
 762      * <p>
 763      * This is a vector binary operation where the primitive multiplication
 764      * operation ({@code *}) is applied to lane elements.
 765      *
 766      * @param s the input scalar
 767      * @return the result of multiplying this vector with the broadcast of an
 768      * input scalar
 769      */
 770     public abstract DoubleVector mul(double s);
 771 
 772     @Override
 773     public abstract DoubleVector mul(Vector<Double> v, Mask<Double> m);
 774 
 775     /**
 776      * Multiplies this vector with the broadcast of an input scalar, selecting
 777      * lane elements controlled by a mask.
 778      * <p>
 779      * This is a vector binary operation where the primitive multiplication
 780      * operation ({@code *}) is applied to lane elements.
 781      *
 782      * @param s the input scalar
 783      * @param m the mask controlling lane selection
 784      * @return the result of multiplying this vector with the broadcast of an
 785      * input scalar
 786      */
 787     public abstract DoubleVector mul(double s, Mask<Double> m);
 788 
 789     @Override
 790     public abstract DoubleVector neg();
 791 
 792     @Override
 793     public abstract DoubleVector neg(Mask<Double> m);
 794 
 795     @Override
 796     public abstract DoubleVector abs();
 797 
 798     @Override
 799     public abstract DoubleVector abs(Mask<Double> m);
 800 
 801     @Override
 802     public abstract DoubleVector min(Vector<Double> v);
 803 
 804     @Override
 805     public abstract DoubleVector min(Vector<Double> v, Mask<Double> m);
 806 
 807     /**
 808      * Returns the minimum of this vector and the broadcast of an input scalar.
 809      * <p>
 810      * This is a vector binary operation where the operation
 811      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 812      *
 813      * @param s the input scalar
 814      * @return the minimum of this vector and the broadcast of an input scalar
 815      */
 816     public abstract DoubleVector min(double s);
 817 
 818     @Override
 819     public abstract DoubleVector max(Vector<Double> v);
 820 
 821     @Override
 822     public abstract DoubleVector max(Vector<Double> v, Mask<Double> m);
 823 
 824     /**
 825      * Returns the maximum of this vector and the broadcast of an input scalar.
 826      * <p>
 827      * This is a vector binary operation where the operation
 828      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 829      *
 830      * @param s the input scalar
 831      * @return the maximum of this vector and the broadcast of an input scalar
 832      */
 833     public abstract DoubleVector max(double s);
 834 
 835     @Override
 836     public abstract Mask<Double> equal(Vector<Double> v);
 837 
 838     /**
 839      * Tests if this vector is equal to the broadcast of an input scalar.
 840      * <p>
 841      * This is a vector binary test operation where the primitive equals
 842      * operation ({@code ==}) is applied to lane elements.
 843      *
 844      * @param s the input scalar
 845      * @return the result mask of testing if this vector is equal to the
 846      * broadcast of an input scalar
 847      */
 848     public abstract Mask<Double> equal(double s);
 849 
 850     @Override
 851     public abstract Mask<Double> notEqual(Vector<Double> v);
 852 
 853     /**
 854      * Tests if this vector is not equal to the broadcast of an input scalar.
 855      * <p>
 856      * This is a vector binary test operation where the primitive not equals
 857      * operation ({@code !=}) is applied to lane elements.
 858      *
 859      * @param s the input scalar
 860      * @return the result mask of testing if this vector is not equal to the
 861      * broadcast of an input scalar
 862      */
 863     public abstract Mask<Double> notEqual(double s);
 864 
 865     @Override
 866     public abstract Mask<Double> lessThan(Vector<Double> v);
 867 
 868     /**
 869      * Tests if this vector is less than the broadcast of an input scalar.
 870      * <p>
 871      * This is a vector binary test operation where the primitive less than
 872      * operation ({@code <}) is applied to lane elements.
 873      *
 874      * @param s the input scalar
 875      * @return the mask result of testing if this vector is less than the
 876      * broadcast of an input scalar
 877      */
 878     public abstract Mask<Double> lessThan(double s);
 879 
 880     @Override
 881     public abstract Mask<Double> lessThanEq(Vector<Double> v);
 882 
 883     /**
 884      * Tests if this vector is less or equal to the broadcast of an input scalar.
 885      * <p>
 886      * This is a vector binary test operation where the primitive less than
 887      * or equal to operation ({@code <=}) is applied to lane elements.
 888      *
 889      * @param s the input scalar
 890      * @return the mask result of testing if this vector is less than or equal
 891      * to the broadcast of an input scalar
 892      */
 893     public abstract Mask<Double> lessThanEq(double s);
 894 
 895     @Override
 896     public abstract Mask<Double> greaterThan(Vector<Double> v);
 897 
 898     /**
 899      * Tests if this vector is greater than the broadcast of an input scalar.
 900      * <p>
 901      * This is a vector binary test operation where the primitive greater than
 902      * operation ({@code >}) is applied to lane elements.
 903      *
 904      * @param s the input scalar
 905      * @return the mask result of testing if this vector is greater than the
 906      * broadcast of an input scalar
 907      */
 908     public abstract Mask<Double> greaterThan(double s);
 909 
 910     @Override
 911     public abstract Mask<Double> greaterThanEq(Vector<Double> v);
 912 
 913     /**
 914      * Tests if this vector is greater than or equal to the broadcast of an
 915      * input scalar.
 916      * <p>
 917      * This is a vector binary test operation where the primitive greater than
 918      * or equal to operation ({@code >=}) is applied to lane elements.
 919      *
 920      * @param s the input scalar
 921      * @return the mask result of testing if this vector is greater than or
 922      * equal to the broadcast of an input scalar
 923      */
 924     public abstract Mask<Double> greaterThanEq(double s);
 925 
 926     @Override
 927     public abstract DoubleVector blend(Vector<Double> v, Mask<Double> m);
 928 
 929     /**
 930      * Blends the lane elements of this vector with those of the broadcast of an
 931      * input scalar, selecting lanes controlled by a mask.
 932      * <p>
 933      * For each lane of the mask, at lane index {@code N}, if the mask lane
 934      * is set then the lane element at {@code N} from the input vector is
 935      * selected and placed into the resulting vector at {@code N},
 936      * otherwise the the lane element at {@code N} from this input vector is
 937      * selected and placed into the resulting vector at {@code N}.
 938      *
 939      * @param s the input scalar
 940      * @param m the mask controlling lane selection
 941      * @return the result of blending the lane elements of this vector with
 942      * those of the broadcast of an input scalar
 943      */
 944     public abstract DoubleVector blend(double s, Mask<Double> m);
 945 
 946     @Override
 947     public abstract DoubleVector rearrange(Vector<Double> v,
 948                                                       Shuffle<Double> s, Mask<Double> m);
 949 
 950     @Override
 951     public abstract DoubleVector rearrange(Shuffle<Double> m);
 952 
 953     @Override
 954     public abstract DoubleVector reshape(Species<Double> s);
 955 
 956     @Override
 957     public abstract DoubleVector rotateEL(int i);
 958 
 959     @Override
 960     public abstract DoubleVector rotateER(int i);
 961 
 962     @Override
 963     public abstract DoubleVector shiftEL(int i);
 964 
 965     @Override
 966     public abstract DoubleVector shiftER(int i);
 967 
 968     /**
 969      * Divides this vector by an input vector.
 970      * <p>
 971      * This is a vector binary operation where the primitive division
 972      * operation ({@code /}) is applied to lane elements.
 973      *
 974      * @param v the input vector


 982      * This is a vector binary operation where the primitive division
 983      * operation ({@code /}) is applied to lane elements.
 984      *
 985      * @param s the input scalar
 986      * @return the result of dividing this vector by the broadcast of an input
 987      * scalar
 988      */
 989     public abstract DoubleVector div(double s);
 990 
 991     /**
 992      * Divides this vector by an input vector, selecting lane elements
 993      * controlled by a mask.
 994      * <p>
 995      * This is a vector binary operation where the primitive division
 996      * operation ({@code /}) is applied to lane elements.
 997      *
 998      * @param v the input vector
 999      * @param m the mask controlling lane selection
1000      * @return the result of dividing this vector by the input vector
1001      */
1002     public abstract DoubleVector div(Vector<Double> v, Mask<Double> m);
1003 
1004     /**
1005      * Divides this vector by the broadcast of an input scalar, selecting lane
1006      * elements controlled by a mask.
1007      * <p>
1008      * This is a vector binary operation where the primitive division
1009      * operation ({@code /}) is applied to lane elements.
1010      *
1011      * @param s the input scalar
1012      * @param m the mask controlling lane selection
1013      * @return the result of dividing this vector by the broadcast of an input
1014      * scalar
1015      */
1016     public abstract DoubleVector div(double s, Mask<Double> m);
1017 
1018     /**
1019      * Calculates the square root of this vector.
1020      * <p>
1021      * This is a vector unary operation where the {@link Math#sqrt} operation
1022      * is applied to lane elements.
1023      *
1024      * @return the square root of this vector
1025      */
1026     public abstract DoubleVector sqrt();
1027 
1028     /**
1029      * Calculates the square root of this vector, selecting lane elements
1030      * controlled by a mask.
1031      * <p>
1032      * This is a vector unary operation where the {@link Math#sqrt} operation
1033      * is applied to lane elements.
1034      *
1035      * @param m the mask controlling lane selection
1036      * @return the square root of this vector
1037      */
1038     public DoubleVector sqrt(Mask<Double> m) {
1039         return uOp(m, (i, a) -> (double) Math.sqrt((double) a));
1040     }
1041 
1042     /**
1043      * Calculates the trigonometric tangent of this vector.
1044      * <p>
1045      * This is a vector unary operation with same semantic definition as
1046      * {@link Math#tan} operation applied to lane elements.
1047      * The implementation is not required to return same
1048      * results as {@link Math#tan}, but adheres to rounding, monotonicity,
1049      * and special case semantics as defined in the {@link Math#tan}
1050      * specifications. The computed result will be within 1 ulp of the
1051      * exact result.
1052      *
1053      * @return the tangent of this vector
1054      */
1055     public DoubleVector tan() {
1056         return uOp((i, a) -> (double) Math.tan((double) a));
1057     }
1058 
1059     /**
1060      * Calculates the trigonometric tangent of this vector, selecting lane
1061      * elements controlled by a mask.
1062      * <p>
1063      * Semantics for rounding, monotonicity, and special cases are
1064      * described in {@link DoubleVector#tan}
1065      *
1066      * @param m the mask controlling lane selection
1067      * @return the tangent of this vector
1068      */
1069     public DoubleVector tan(Mask<Double> m) {
1070         return uOp(m, (i, a) -> (double) Math.tan((double) a));
1071     }
1072 
1073     /**
1074      * Calculates the hyperbolic tangent of this vector.
1075      * <p>
1076      * This is a vector unary operation with same semantic definition as
1077      * {@link Math#tanh} operation applied to lane elements.
1078      * The implementation is not required to return same
1079      * results as {@link Math#tanh}, but adheres to rounding, monotonicity,
1080      * and special case semantics as defined in the {@link Math#tanh}
1081      * specifications. The computed result will be within 2.5 ulps of the
1082      * exact result.
1083      *
1084      * @return the hyperbolic tangent of this vector
1085      */
1086     public DoubleVector tanh() {
1087         return uOp((i, a) -> (double) Math.tanh((double) a));
1088     }
1089 
1090     /**
1091      * Calculates the hyperbolic tangent of this vector, selecting lane elements
1092      * controlled by a mask.
1093      * <p>
1094      * Semantics for rounding, monotonicity, and special cases are
1095      * described in {@link DoubleVector#tanh}
1096      *
1097      * @param m the mask controlling lane selection
1098      * @return the hyperbolic tangent of this vector
1099      */
1100     public DoubleVector tanh(Mask<Double> m) {
1101         return uOp(m, (i, a) -> (double) Math.tanh((double) a));
1102     }
1103 
1104     /**
1105      * Calculates the trigonometric sine of this vector.
1106      * <p>
1107      * This is a vector unary operation with same semantic definition as
1108      * {@link Math#sin} operation applied to lane elements.
1109      * The implementation is not required to return same
1110      * results as {@link Math#sin}, but adheres to rounding, monotonicity,
1111      * and special case semantics as defined in the {@link Math#sin}
1112      * specifications. The computed result will be within 1 ulp of the
1113      * exact result.
1114      *
1115      * @return the sine of this vector
1116      */
1117     public DoubleVector sin() {
1118         return uOp((i, a) -> (double) Math.sin((double) a));
1119     }
1120 
1121     /**
1122      * Calculates the trigonometric sine of this vector, selecting lane elements
1123      * controlled by a mask.
1124      * <p>
1125      * Semantics for rounding, monotonicity, and special cases are
1126      * described in {@link DoubleVector#sin}
1127      *
1128      * @param m the mask controlling lane selection
1129      * @return the sine of this vector
1130      */
1131     public DoubleVector sin(Mask<Double> m) {
1132         return uOp(m, (i, a) -> (double) Math.sin((double) a));
1133     }
1134 
1135     /**
1136      * Calculates the hyperbolic sine of this vector.
1137      * <p>
1138      * This is a vector unary operation with same semantic definition as
1139      * {@link Math#sinh} operation applied to lane elements.
1140      * The implementation is not required to return same
1141      * results as  {@link Math#sinh}, but adheres to rounding, monotonicity,
1142      * and special case semantics as defined in the {@link Math#sinh}
1143      * specifications. The computed result will be within 2.5 ulps of the
1144      * exact result.
1145      *
1146      * @return the hyperbolic sine of this vector
1147      */
1148     public DoubleVector sinh() {
1149         return uOp((i, a) -> (double) Math.sinh((double) a));
1150     }
1151 
1152     /**
1153      * Calculates the hyperbolic sine of this vector, selecting lane elements
1154      * controlled by a mask.
1155      * <p>
1156      * Semantics for rounding, monotonicity, and special cases are
1157      * described in {@link DoubleVector#sinh}
1158      *
1159      * @param m the mask controlling lane selection
1160      * @return the hyperbolic sine of this vector
1161      */
1162     public DoubleVector sinh(Mask<Double> m) {
1163         return uOp(m, (i, a) -> (double) Math.sinh((double) a));
1164     }
1165 
1166     /**
1167      * Calculates the trigonometric cosine of this vector.
1168      * <p>
1169      * This is a vector unary operation with same semantic definition as
1170      * {@link Math#cos} operation applied to lane elements.
1171      * The implementation is not required to return same
1172      * results as {@link Math#cos}, but adheres to rounding, monotonicity,
1173      * and special case semantics as defined in the {@link Math#cos}
1174      * specifications. The computed result will be within 1 ulp of the
1175      * exact result.
1176      *
1177      * @return the cosine of this vector
1178      */
1179     public DoubleVector cos() {
1180         return uOp((i, a) -> (double) Math.cos((double) a));
1181     }
1182 
1183     /**
1184      * Calculates the trigonometric cosine of this vector, selecting lane
1185      * elements controlled by a mask.
1186      * <p>
1187      * Semantics for rounding, monotonicity, and special cases are
1188      * described in {@link DoubleVector#cos}
1189      *
1190      * @param m the mask controlling lane selection
1191      * @return the cosine of this vector
1192      */
1193     public DoubleVector cos(Mask<Double> m) {
1194         return uOp(m, (i, a) -> (double) Math.cos((double) a));
1195     }
1196 
1197     /**
1198      * Calculates the hyperbolic cosine of this vector.
1199      * <p>
1200      * This is a vector unary operation with same semantic definition as
1201      * {@link Math#cosh} operation applied to lane elements.
1202      * The implementation is not required to return same
1203      * results as {@link Math#cosh}, but adheres to rounding, monotonicity,
1204      * and special case semantics as defined in the {@link Math#cosh}
1205      * specifications. The computed result will be within 2.5 ulps of the
1206      * exact result.
1207      *
1208      * @return the hyperbolic cosine of this vector
1209      */
1210     public DoubleVector cosh() {
1211         return uOp((i, a) -> (double) Math.cosh((double) a));
1212     }
1213 
1214     /**
1215      * Calculates the hyperbolic cosine of this vector, selecting lane elements
1216      * controlled by a mask.
1217      * <p>
1218      * Semantics for rounding, monotonicity, and special cases are
1219      * described in {@link DoubleVector#cosh}
1220      *
1221      * @param m the mask controlling lane selection
1222      * @return the hyperbolic cosine of this vector
1223      */
1224     public DoubleVector cosh(Mask<Double> m) {
1225         return uOp(m, (i, a) -> (double) Math.cosh((double) a));
1226     }
1227 
1228     /**
1229      * Calculates the arc sine of this vector.
1230      * <p>
1231      * This is a vector unary operation with same semantic definition as
1232      * {@link Math#asin} operation applied to lane elements.
1233      * The implementation is not required to return same
1234      * results as {@link Math#asin}, but adheres to rounding, monotonicity,
1235      * and special case semantics as defined in the {@link Math#asin}
1236      * specifications. The computed result will be within 1 ulp of the
1237      * exact result.
1238      *
1239      * @return the arc sine of this vector
1240      */
1241     public DoubleVector asin() {
1242         return uOp((i, a) -> (double) Math.asin((double) a));
1243     }
1244 
1245     /**
1246      * Calculates the arc sine of this vector, selecting lane elements
1247      * controlled by a mask.
1248      * <p>
1249      * Semantics for rounding, monotonicity, and special cases are
1250      * described in {@link DoubleVector#asin}
1251      *
1252      * @param m the mask controlling lane selection
1253      * @return the arc sine of this vector
1254      */
1255     public DoubleVector asin(Mask<Double> m) {
1256         return uOp(m, (i, a) -> (double) Math.asin((double) a));
1257     }
1258 
1259     /**
1260      * Calculates the arc cosine of this vector.
1261      * <p>
1262      * This is a vector unary operation with same semantic definition as
1263      * {@link Math#acos} operation applied to lane elements.
1264      * The implementation is not required to return same
1265      * results as {@link Math#acos}, but adheres to rounding, monotonicity,
1266      * and special case semantics as defined in the {@link Math#acos}
1267      * specifications. The computed result will be within 1 ulp of the
1268      * exact result.
1269      *
1270      * @return the arc cosine of this vector
1271      */
1272     public DoubleVector acos() {
1273         return uOp((i, a) -> (double) Math.acos((double) a));
1274     }
1275 
1276     /**
1277      * Calculates the arc cosine of this vector, selecting lane elements
1278      * controlled by a mask.
1279      * <p>
1280      * Semantics for rounding, monotonicity, and special cases are
1281      * described in {@link DoubleVector#acos}
1282      *
1283      * @param m the mask controlling lane selection
1284      * @return the arc cosine of this vector
1285      */
1286     public DoubleVector acos(Mask<Double> m) {
1287         return uOp(m, (i, a) -> (double) Math.acos((double) a));
1288     }
1289 
1290     /**
1291      * Calculates the arc tangent of this vector.
1292      * <p>
1293      * This is a vector unary operation with same semantic definition as
1294      * {@link Math#atan} operation applied to lane elements.
1295      * The implementation is not required to return same
1296      * results as {@link Math#atan}, but adheres to rounding, monotonicity,
1297      * and special case semantics as defined in the {@link Math#atan}
1298      * specifications. The computed result will be within 1 ulp of the
1299      * exact result.
1300      *
1301      * @return the arc tangent of this vector
1302      */
1303     public DoubleVector atan() {
1304         return uOp((i, a) -> (double) Math.atan((double) a));
1305     }
1306 
1307     /**
1308      * Calculates the arc tangent of this vector, selecting lane elements
1309      * controlled by a mask.
1310      * <p>
1311      * Semantics for rounding, monotonicity, and special cases are
1312      * described in {@link DoubleVector#atan}
1313      *
1314      * @param m the mask controlling lane selection
1315      * @return the arc tangent of this vector
1316      */
1317     public DoubleVector atan(Mask<Double> m) {
1318         return uOp(m, (i, a) -> (double) Math.atan((double) a));
1319     }
1320 
1321     /**
1322      * Calculates the arc tangent of this vector divided by an input vector.
1323      * <p>
1324      * This is a vector binary operation with same semantic definition as
1325      * {@link Math#atan2} operation applied to lane elements.
1326      * The implementation is not required to return same
1327      * results as {@link Math#atan2}, but adheres to rounding, monotonicity,
1328      * and special case semantics as defined in the {@link Math#atan2}
1329      * specifications. The computed result will be within 2 ulps of the
1330      * exact result.
1331      *
1332      * @param v the input vector
1333      * @return the arc tangent of this vector divided by the input vector
1334      */
1335     public DoubleVector atan2(Vector<Double> v) {
1336         return bOp(v, (i, a, b) -> (double) Math.atan2((double) a, (double) b));
1337     }


1347      * and special case semantics as defined in the {@link Math#atan2}
1348      * specifications. The computed result will be within 1 ulp of the
1349      * exact result.
1350      *
1351      * @param s the input scalar
1352      * @return the arc tangent of this vector over the input vector
1353      */
1354     public abstract DoubleVector atan2(double s);
1355 
1356     /**
1357      * Calculates the arc tangent of this vector divided by an input vector,
1358      * selecting lane elements controlled by a mask.
1359      * <p>
1360      * Semantics for rounding, monotonicity, and special cases are
1361      * described in {@link DoubleVector#atan2}
1362      *
1363      * @param v the input vector
1364      * @param m the mask controlling lane selection
1365      * @return the arc tangent of this vector divided by the input vector
1366      */
1367     public DoubleVector atan2(Vector<Double> v, Mask<Double> m) {
1368         return bOp(v, m, (i, a, b) -> (double) Math.atan2((double) a, (double) b));
1369     }
1370 
1371     /**
1372      * Calculates the arc tangent of this vector divided by the broadcast of an
1373      * an input scalar, selecting lane elements controlled by a mask.
1374      * <p>
1375      * Semantics for rounding, monotonicity, and special cases are
1376      * described in {@link DoubleVector#atan2}
1377      *
1378      * @param s the input scalar
1379      * @param m the mask controlling lane selection
1380      * @return the arc tangent of this vector over the input vector
1381      */
1382     public abstract DoubleVector atan2(double s, Mask<Double> m);
1383 
1384     /**
1385      * Calculates the cube root of this vector.
1386      * <p>
1387      * This is a vector unary operation with same semantic definition as
1388      * {@link Math#cbrt} operation applied to lane elements.
1389      * The implementation is not required to return same
1390      * results as {@link Math#cbrt}, but adheres to rounding, monotonicity,
1391      * and special case semantics as defined in the {@link Math#cbrt}
1392      * specifications. The computed result will be within 1 ulp of the
1393      * exact result.
1394      *
1395      * @return the cube root of this vector
1396      */
1397     public DoubleVector cbrt() {
1398         return uOp((i, a) -> (double) Math.cbrt((double) a));
1399     }
1400 
1401     /**
1402      * Calculates the cube root of this vector, selecting lane elements
1403      * controlled by a mask.
1404      * <p>
1405      * Semantics for rounding, monotonicity, and special cases are
1406      * described in {@link DoubleVector#cbrt}
1407      *
1408      * @param m the mask controlling lane selection
1409      * @return the cube root of this vector
1410      */
1411     public DoubleVector cbrt(Mask<Double> m) {
1412         return uOp(m, (i, a) -> (double) Math.cbrt((double) a));
1413     }
1414 
1415     /**
1416      * Calculates the natural logarithm of this vector.
1417      * <p>
1418      * This is a vector unary operation with same semantic definition as
1419      * {@link Math#log} operation applied to lane elements.
1420      * The implementation is not required to return same
1421      * results as {@link Math#log}, but adheres to rounding, monotonicity,
1422      * and special case semantics as defined in the {@link Math#log}
1423      * specifications. The computed result will be within 1 ulp of the
1424      * exact result.
1425      *
1426      * @return the natural logarithm of this vector
1427      */
1428     public DoubleVector log() {
1429         return uOp((i, a) -> (double) Math.log((double) a));
1430     }
1431 
1432     /**
1433      * Calculates the natural logarithm of this vector, selecting lane elements
1434      * controlled by a mask.
1435      * <p>
1436      * Semantics for rounding, monotonicity, and special cases are
1437      * described in {@link DoubleVector#log}
1438      *
1439      * @param m the mask controlling lane selection
1440      * @return the natural logarithm of this vector
1441      */
1442     public DoubleVector log(Mask<Double> m) {
1443         return uOp(m, (i, a) -> (double) Math.log((double) a));
1444     }
1445 
1446     /**
1447      * Calculates the base 10 logarithm of this vector.
1448      * <p>
1449      * This is a vector unary operation with same semantic definition as
1450      * {@link Math#log10} operation applied to lane elements.
1451      * The implementation is not required to return same
1452      * results as {@link Math#log10}, but adheres to rounding, monotonicity,
1453      * and special case semantics as defined in the {@link Math#log10}
1454      * specifications. The computed result will be within 1 ulp of the
1455      * exact result.
1456      *
1457      * @return the base 10 logarithm of this vector
1458      */
1459     public DoubleVector log10() {
1460         return uOp((i, a) -> (double) Math.log10((double) a));
1461     }
1462 
1463     /**
1464      * Calculates the base 10 logarithm of this vector, selecting lane elements
1465      * controlled by a mask.
1466      * <p>
1467      * Semantics for rounding, monotonicity, and special cases are
1468      * described in {@link DoubleVector#log10}
1469      *
1470      * @param m the mask controlling lane selection
1471      * @return the base 10 logarithm of this vector
1472      */
1473     public DoubleVector log10(Mask<Double> m) {
1474         return uOp(m, (i, a) -> (double) Math.log10((double) a));
1475     }
1476 
1477     /**
1478      * Calculates the natural logarithm of the sum of this vector and the
1479      * broadcast of {@code 1}.
1480      * <p>
1481      * This is a vector unary operation with same semantic definition as
1482      * {@link Math#log1p} operation applied to lane elements.
1483      * The implementation is not required to return same
1484      * results as  {@link Math#log1p}, but adheres to rounding, monotonicity,
1485      * and special case semantics as defined in the {@link Math#log1p}
1486      * specifications. The computed result will be within 1 ulp of the
1487      * exact result.
1488      *
1489      * @return the natural logarithm of the sum of this vector and the broadcast
1490      * of {@code 1}
1491      */
1492     public DoubleVector log1p() {
1493         return uOp((i, a) -> (double) Math.log1p((double) a));
1494     }
1495 
1496     /**
1497      * Calculates the natural logarithm of the sum of this vector and the
1498      * broadcast of {@code 1}, selecting lane elements controlled by a mask.
1499      * <p>
1500      * Semantics for rounding, monotonicity, and special cases are
1501      * described in {@link DoubleVector#log1p}
1502      *
1503      * @param m the mask controlling lane selection
1504      * @return the natural logarithm of the sum of this vector and the broadcast
1505      * of {@code 1}
1506      */
1507     public DoubleVector log1p(Mask<Double> m) {
1508         return uOp(m, (i, a) -> (double) Math.log1p((double) a));
1509     }
1510 
1511     /**
1512      * Calculates this vector raised to the power of an input vector.
1513      * <p>
1514      * This is a vector binary operation with same semantic definition as
1515      * {@link Math#pow} operation applied to lane elements.
1516      * The implementation is not required to return same
1517      * results as {@link Math#pow}, but adheres to rounding, monotonicity,
1518      * and special case semantics as defined in the {@link Math#pow}
1519      * specifications. The computed result will be within 1 ulp of the
1520      * exact result.
1521      *
1522      * @param v the input vector
1523      * @return this vector raised to the power of an input vector
1524      */
1525     public DoubleVector pow(Vector<Double> v) {
1526         return bOp(v, (i, a, b) -> (double) Math.pow((double) a, (double) b));
1527     }


1538      * specifications. The computed result will be within 1 ulp of the
1539      * exact result.
1540      *
1541      * @param s the input scalar
1542      * @return this vector raised to the power of the broadcast of an input
1543      * scalar.
1544      */
1545     public abstract DoubleVector pow(double s);
1546 
1547     /**
1548      * Calculates this vector raised to the power of an input vector, selecting
1549      * lane elements controlled by a mask.
1550      * <p>
1551      * Semantics for rounding, monotonicity, and special cases are
1552      * described in {@link DoubleVector#pow}
1553      *
1554      * @param v the input vector
1555      * @param m the mask controlling lane selection
1556      * @return this vector raised to the power of an input vector
1557      */
1558     public DoubleVector pow(Vector<Double> v, Mask<Double> m) {
1559         return bOp(v, m, (i, a, b) -> (double) Math.pow((double) a, (double) b));
1560     }
1561 
1562     /**
1563      * Calculates this vector raised to the power of the broadcast of an input
1564      * scalar, selecting lane elements controlled by a mask.
1565      * <p>
1566      * Semantics for rounding, monotonicity, and special cases are
1567      * described in {@link DoubleVector#pow}
1568      *
1569      * @param s the input scalar
1570      * @param m the mask controlling lane selection
1571      * @return this vector raised to the power of the broadcast of an input
1572      * scalar.
1573      */
1574     public abstract DoubleVector pow(double s, Mask<Double> m);
1575 
1576     /**
1577      * Calculates the broadcast of Euler's number {@code e} raised to the power
1578      * of this vector.
1579      * <p>
1580      * This is a vector unary operation with same semantic definition as
1581      * {@link Math#exp} operation applied to lane elements.
1582      * The implementation is not required to return same
1583      * results as {@link Math#exp}, but adheres to rounding, monotonicity,
1584      * and special case semantics as defined in the {@link Math#exp}
1585      * specifications. The computed result will be within 1 ulp of the
1586      * exact result.
1587      *
1588      * @return the broadcast of Euler's number {@code e} raised to the power of
1589      * this vector
1590      */
1591     public DoubleVector exp() {
1592         return uOp((i, a) -> (double) Math.exp((double) a));
1593     }
1594 
1595     /**
1596      * Calculates the broadcast of Euler's number {@code e} raised to the power
1597      * of this vector, selecting lane elements controlled by a mask.
1598      * <p>
1599      * Semantics for rounding, monotonicity, and special cases are
1600      * described in {@link DoubleVector#exp}
1601      *
1602      * @param m the mask controlling lane selection
1603      * @return the broadcast of Euler's number {@code e} raised to the power of
1604      * this vector
1605      */
1606     public DoubleVector exp(Mask<Double> m) {
1607         return uOp(m, (i, a) -> (double) Math.exp((double) a));
1608     }
1609 
1610     /**
1611      * Calculates the broadcast of Euler's number {@code e} raised to the power
1612      * of this vector minus the broadcast of {@code -1}.
1613      * More specifically as if the following (ignoring any differences in
1614      * numerical accuracy):
1615      * <pre>{@code
1616      *   this.exp().sub(this.species().broadcast(1))
1617      * }</pre>
1618      * <p>
1619      * This is a vector unary operation with same semantic definition as
1620      * {@link Math#expm1} operation applied to lane elements.
1621      * The implementation is not required to return same
1622      * results as {@link Math#expm1}, but adheres to rounding, monotonicity,
1623      * and special case semantics as defined in the {@link Math#expm1}
1624      * specifications. The computed result will be within 1 ulp of the
1625      * exact result.
1626      *


1631         return uOp((i, a) -> (double) Math.expm1((double) a));
1632     }
1633 
1634     /**
1635      * Calculates the broadcast of Euler's number {@code e} raised to the power
1636      * of this vector minus the broadcast of {@code -1}, selecting lane elements
1637      * controlled by a mask
1638      * More specifically as if the following (ignoring any differences in
1639      * numerical accuracy):
1640      * <pre>{@code
1641      *   this.exp(m).sub(this.species().broadcast(1), m)
1642      * }</pre>
1643      * <p>
1644      * Semantics for rounding, monotonicity, and special cases are
1645      * described in {@link DoubleVector#expm1}
1646      *
1647      * @param m the mask controlling lane selection
1648      * @return the broadcast of Euler's number {@code e} raised to the power of
1649      * this vector minus the broadcast of {@code -1}
1650      */
1651     public DoubleVector expm1(Mask<Double> m) {
1652         return uOp(m, (i, a) -> (double) Math.expm1((double) a));
1653     }
1654 
1655     /**
1656      * Calculates the product of this vector and a first input vector summed
1657      * with a second input vector.
1658      * More specifically as if the following (ignoring any differences in
1659      * numerical accuracy):
1660      * <pre>{@code
1661      *   this.mul(v1).add(v2)
1662      * }</pre>
1663      * <p>
1664      * This is a vector ternary operation where the {@link Math#fma} operation
1665      * is applied to lane elements.
1666      *
1667      * @param v1 the first input vector
1668      * @param v2 the second input vector
1669      * @return the product of this vector and the first input vector summed with
1670      * the second input vector
1671      */


1690     public abstract DoubleVector fma(double s1, double s2);
1691 
1692     /**
1693      * Calculates the product of this vector and a first input vector summed
1694      * with a second input vector, selecting lane elements controlled by a mask.
1695      * More specifically as if the following (ignoring any differences in
1696      * numerical accuracy):
1697      * <pre>{@code
1698      *   this.mul(v1, m).add(v2, m)
1699      * }</pre>
1700      * <p>
1701      * This is a vector ternary operation where the {@link Math#fma} operation
1702      * is applied to lane elements.
1703      *
1704      * @param v1 the first input vector
1705      * @param v2 the second input vector
1706      * @param m the mask controlling lane selection
1707      * @return the product of this vector and the first input vector summed with
1708      * the second input vector
1709      */
1710     public DoubleVector fma(Vector<Double> v1, Vector<Double> v2, Mask<Double> m) {
1711         return tOp(v1, v2, m, (i, a, b, c) -> Math.fma(a, b, c));
1712     }
1713 
1714     /**
1715      * Calculates the product of this vector and the broadcast of a first input
1716      * scalar summed with the broadcast of a second input scalar, selecting lane
1717      * elements controlled by a mask
1718      * More specifically as if the following:
1719      * <pre>{@code
1720      *   this.fma(this.species().broadcast(s1), this.species().broadcast(s2), m)
1721      * }</pre>
1722      * <p>
1723      * This is a vector ternary operation where the {@link Math#fma} operation
1724      * is applied to lane elements.
1725      *
1726      * @param s1 the first input scalar
1727      * @param s2 the second input scalar
1728      * @param m the mask controlling lane selection
1729      * @return the product of this vector and the broadcast of a first input
1730      * scalar summed with the broadcast of a second input scalar
1731      */
1732     public abstract DoubleVector fma(double s1, double s2, Mask<Double> m);
1733 
1734     /**
1735      * Calculates square root of the sum of the squares of this vector and an
1736      * input vector.
1737      * More specifically as if the following (ignoring any differences in
1738      * numerical accuracy):
1739      * <pre>{@code
1740      *   this.mul(this).add(v.mul(v)).sqrt()
1741      * }</pre>
1742      * <p>
1743      * This is a vector binary operation with same semantic definition as
1744      * {@link Math#hypot} operation applied to lane elements.
1745      * The implementation is not required to return same
1746      * results as {@link Math#hypot}, but adheres to rounding, monotonicity,
1747      * and special case semantics as defined in the {@link Math#hypot}
1748      * specifications. The computed result will be within 1 ulp of the
1749      * exact result.
1750      *
1751      * @param v the input vector
1752      * @return square root of the sum of the squares of this vector and an input


1779      */
1780     public abstract DoubleVector hypot(double s);
1781 
1782     /**
1783      * Calculates square root of the sum of the squares of this vector and an
1784      * input vector, selecting lane elements controlled by a mask.
1785      * More specifically as if the following (ignoring any differences in
1786      * numerical accuracy):
1787      * <pre>{@code
1788      *   this.mul(this, m).add(v.mul(v), m).sqrt(m)
1789      * }</pre>
1790      * <p>
1791      * Semantics for rounding, monotonicity, and special cases are
1792      * described in {@link DoubleVector#hypot}
1793      *
1794      * @param v the input vector
1795      * @param m the mask controlling lane selection
1796      * @return square root of the sum of the squares of this vector and an input
1797      * vector
1798      */
1799     public DoubleVector hypot(Vector<Double> v, Mask<Double> m) {
1800         return bOp(v, m, (i, a, b) -> (double) Math.hypot((double) a, (double) b));
1801     }
1802 
1803     /**
1804      * Calculates square root of the sum of the squares of this vector and the
1805      * broadcast of an input scalar, selecting lane elements controlled by a
1806      * mask.
1807      * More specifically as if the following (ignoring any differences in
1808      * numerical accuracy):
1809      * <pre>{@code
1810      *   this.mul(this, m).add(this.species().broadcast(v * v), m).sqrt(m)
1811      * }</pre>
1812      * <p>
1813      * Semantics for rounding, monotonicity, and special cases are
1814      * described in {@link DoubleVector#hypot}
1815      *
1816      * @param s the input scalar
1817      * @param m the mask controlling lane selection
1818      * @return square root of the sum of the squares of this vector and the
1819      * broadcast of an input scalar
1820      */
1821     public abstract DoubleVector hypot(double s, Mask<Double> m);
1822 
1823 
1824     @Override
1825     public abstract void intoByteArray(byte[] a, int ix);
1826 
1827     @Override
1828     public abstract void intoByteArray(byte[] a, int ix, Mask<Double> m);
1829 
1830     @Override
1831     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1832 
1833     @Override
1834     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Double> m);
1835 
1836 
1837     // Type specific horizontal reductions
1838     /**
1839      * Adds all lane elements of this vector.
1840      * <p>
1841      * This is a vector reduction operation where the addition
1842      * operation ({@code +}) is applied to lane elements,
1843      * and the identity value is {@code 0.0}.
1844      *
1845      * <p>The value of a floating-point sum is a function both of the input values as well
1846      * as the order of addition operations. The order of addition operations of this method
1847      * is intentionally not defined to allow for JVM to generate optimal machine
1848      * code for the underlying platform at runtime. If the platform supports a vector
1849      * instruction to add all values in the vector, or if there is some other efficient machine
1850      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1851      * the default implementation of adding vectors sequentially from left to right is used.
1852      * For this reason, the output of this method may vary for the same input values.
1853      *
1854      * @return the addition of all the lane elements of this vector


1858     /**
1859      * Adds all lane elements of this vector, selecting lane elements
1860      * controlled by a mask.
1861      * <p>
1862      * This is a vector reduction operation where the addition
1863      * operation ({@code +}) is applied to lane elements,
1864      * and the identity value is {@code 0.0}.
1865      *
1866      * <p>The value of a floating-point sum is a function both of the input values as well
1867      * as the order of addition operations. The order of addition operations of this method
1868      * is intentionally not defined to allow for JVM to generate optimal machine
1869      * code for the underlying platform at runtime. If the platform supports a vector
1870      * instruction to add all values in the vector, or if there is some other efficient machine
1871      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1872      * the default implementation of adding vectors sequentially from left to right is used.
1873      * For this reason, the output of this method may vary on the same input values.
1874      *
1875      * @param m the mask controlling lane selection
1876      * @return the addition of the selected lane elements of this vector
1877      */
1878     public abstract double addAll(Mask<Double> m);
1879 
1880     /**
1881      * Multiplies all lane elements of this vector.
1882      * <p>
1883      * This is a vector reduction operation where the
1884      * multiplication operation ({@code *}) is applied to lane elements,
1885      * and the identity value is {@code 1.0}.
1886      *
1887      * <p>The order of multiplication operations of this method
1888      * is intentionally not defined to allow for JVM to generate optimal machine
1889      * code for the underlying platform at runtime. If the platform supports a vector
1890      * instruction to multiply all values in the vector, or if there is some other efficient machine
1891      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1892      * the default implementation of multiplying vectors sequentially from left to right is used.
1893      * For this reason, the output of this method may vary on the same input values.
1894      *
1895      * @return the multiplication of all the lane elements of this vector
1896      */
1897     public abstract double mulAll();
1898 
1899     /**
1900      * Multiplies all lane elements of this vector, selecting lane elements
1901      * controlled by a mask.
1902      * <p>
1903      * This is a vector reduction operation where the
1904      * multiplication operation ({@code *}) is applied to lane elements,
1905      * and the identity value is {@code 1.0}.
1906      *
1907      * <p>The order of multiplication operations of this method
1908      * is intentionally not defined to allow for JVM to generate optimal machine
1909      * code for the underlying platform at runtime. If the platform supports a vector
1910      * instruction to multiply all values in the vector, or if there is some other efficient machine
1911      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1912      * the default implementation of multiplying vectors sequentially from left to right is used.
1913      * For this reason, the output of this method may vary on the same input values.
1914      *
1915      * @param m the mask controlling lane selection
1916      * @return the multiplication of all the lane elements of this vector
1917      */
1918     public abstract double mulAll(Mask<Double> m);
1919 
1920     /**
1921      * Returns the minimum lane element of this vector.
1922      * <p>
1923      * This is an associative vector reduction operation where the operation
1924      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1925      * and the identity value is
1926      * {@link Double#POSITIVE_INFINITY}.
1927      *
1928      * @return the minimum lane element of this vector
1929      */
1930     public abstract double minAll();
1931 
1932     /**
1933      * Returns the minimum lane element of this vector, selecting lane elements
1934      * controlled by a mask.
1935      * <p>
1936      * This is an associative vector reduction operation where the operation
1937      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1938      * and the identity value is
1939      * {@link Double#POSITIVE_INFINITY}.
1940      *
1941      * @param m the mask controlling lane selection
1942      * @return the minimum lane element of this vector
1943      */
1944     public abstract double minAll(Mask<Double> m);
1945 
1946     /**
1947      * Returns the maximum lane element of this vector.
1948      * <p>
1949      * This is an associative vector reduction operation where the operation
1950      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1951      * and the identity value is
1952      * {@link Double#NEGATIVE_INFINITY}.
1953      *
1954      * @return the maximum lane element of this vector
1955      */
1956     public abstract double maxAll();
1957 
1958     /**
1959      * Returns the maximum lane element of this vector, selecting lane elements
1960      * controlled by a mask.
1961      * <p>
1962      * This is an associative vector reduction operation where the operation
1963      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1964      * and the identity value is
1965      * {@link Double#NEGATIVE_INFINITY}.
1966      *
1967      * @param m the mask controlling lane selection
1968      * @return the maximum lane element of this vector
1969      */
1970     public abstract double maxAll(Mask<Double> m);
1971 
1972 
1973     // Type specific accessors
1974 
1975     /**
1976      * Gets the lane element at lane index {@code i}
1977      *
1978      * @param i the lane index
1979      * @return the lane element at lane index {@code i}
1980      * @throws IllegalArgumentException if the index is is out of range
1981      * ({@code < 0 || >= length()})
1982      */
1983     public abstract double get(int i);
1984 
1985     /**
1986      * Replaces the lane element of this vector at lane index {@code i} with
1987      * value {@code e}.
1988      * <p>
1989      * This is a cross-lane operation and behaves as if it returns the result
1990      * of blending this vector with an input vector that is the result of


2033      * @param i the offset into the array
2034      * @throws IndexOutOfBoundsException if {@code i < 0}, or
2035      * {@code i > a.length - this.length()}
2036      */
2037     public abstract void intoArray(double[] a, int i);
2038 
2039     /**
2040      * Stores this vector into an array starting at offset and using a mask.
2041      * <p>
2042      * For each vector lane, where {@code N} is the vector lane index,
2043      * if the mask lane at index {@code N} is set then the lane element at
2044      * index {@code N} is stored into the array index {@code i + N}.
2045      *
2046      * @param a the array
2047      * @param i the offset into the array
2048      * @param m the mask
2049      * @throws IndexOutOfBoundsException if {@code i < 0}, or
2050      * for any vector lane index {@code N} where the mask at lane {@code N}
2051      * is set {@code i >= a.length - N}
2052      */
2053     public abstract void intoArray(double[] a, int i, Mask<Double> m);
2054 
2055     /**
2056      * Stores this vector into an array using indexes obtained from an index
2057      * map.
2058      * <p>
2059      * For each vector lane, where {@code N} is the vector lane index, the
2060      * lane element at index {@code N} is stored into the array at index
2061      * {@code i + indexMap[j + N]}.
2062      *
2063      * @param a the array
2064      * @param i the offset into the array, may be negative if relative
2065      * indexes in the index map compensate to produce a value within the
2066      * array bounds
2067      * @param indexMap the index map
2068      * @param j the offset into the index map
2069      * @throws IndexOutOfBoundsException if {@code j < 0}, or
2070      * {@code j > indexMap.length - this.length()},
2071      * or for any vector lane index {@code N} the result of
2072      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
2073      */


2078      * map and using a mask.
2079      * <p>
2080      * For each vector lane, where {@code N} is the vector lane index,
2081      * if the mask lane at index {@code N} is set then the lane element at
2082      * index {@code N} is stored into the array at index
2083      * {@code i + indexMap[j + N]}.
2084      *
2085      * @param a the array
2086      * @param i the offset into the array, may be negative if relative
2087      * indexes in the index map compensate to produce a value within the
2088      * array bounds
2089      * @param m the mask
2090      * @param indexMap the index map
2091      * @param j the offset into the index map
2092      * @throws IndexOutOfBoundsException if {@code j < 0}, or
2093      * {@code j > indexMap.length - this.length()},
2094      * or for any vector lane index {@code N} where the mask at lane
2095      * {@code N} is set the result of {@code i + indexMap[j + N]} is
2096      * {@code < 0} or {@code >= a.length}
2097      */
2098     public abstract void intoArray(double[] a, int i, Mask<Double> m, int[] indexMap, int j);
2099     // Species
2100 
2101     @Override
2102     public abstract Species<Double> species();
2103 
2104     /**
2105      * Class representing {@link DoubleVector}'s of the same {@link Vector.Shape Shape}.
2106      */
2107     static final class DoubleSpecies extends Vector.AbstractSpecies<Double> {
2108         final Function<double[], DoubleVector> vectorFactory;
2109         final Function<boolean[], Vector.Mask<Double>> maskFactory;
2110 
2111         private DoubleSpecies(Vector.Shape shape,
2112                           Class<?> boxType,
2113                           Class<?> maskType,
2114                           Function<double[], DoubleVector> vectorFactory,
2115                           Function<boolean[], Vector.Mask<Double>> maskFactory) {
2116             super(shape, double.class, Double.SIZE, boxType, maskType);



2117             this.vectorFactory = vectorFactory;
2118             this.maskFactory = maskFactory;
2119         }
2120 
2121         interface FOp {
2122             double apply(int i);
2123         }
2124 
2125         interface FOpm {
2126             boolean apply(int i);
2127         }
2128 
2129         DoubleVector op(FOp f) {
2130             double[] res = new double[length()];
2131             for (int i = 0; i < length(); i++) {
2132                 res[i] = f.apply(i);
2133             }
2134             return vectorFactory.apply(res);
2135         }
2136 
2137         DoubleVector op(Vector.Mask<Double> o, FOp f) {
2138             double[] res = new double[length()];
2139             boolean[] mbits = ((AbstractMask<Double>)o).getBits();
2140             for (int i = 0; i < length(); i++) {
2141                 if (mbits[i]) {
2142                     res[i] = f.apply(i);
2143                 }
2144             }
2145             return vectorFactory.apply(res);
2146         }
2147 
2148         Vector.Mask<Double> opm(IntVector.IntSpecies.FOpm f) {
2149             boolean[] res = new boolean[length()];
2150             for (int i = 0; i < length(); i++) {
2151                 res[i] = (boolean)f.apply(i);
2152             }
2153             return maskFactory.apply(res);
2154         }
2155     }
2156 
2157     /**
2158      * Finds the preferred species for an element type of {@code double}.
2159      * <p>
2160      * A preferred species is a species chosen by the platform that has a
2161      * shape of maximal bit size.  A preferred species for different element
2162      * types will have the same shape, and therefore vectors, masks, and
2163      * shuffles created from such species will be shape compatible.
2164      *
2165      * @return the preferred species for an element type of {@code double}
2166      */
2167     private static DoubleSpecies preferredSpecies() {
2168         return (DoubleSpecies) Species.ofPreferred(double.class);
2169     }
2170 
2171     /**
2172      * Finds a species for an element type of {@code double} and shape.
2173      *
2174      * @param s the shape
2175      * @return a species for an element type of {@code double} and shape
2176      * @throws IllegalArgumentException if no such species exists for the shape
2177      */
2178     static DoubleSpecies species(Vector.Shape s) {
2179         Objects.requireNonNull(s);
2180         switch (s) {
2181             case S_64_BIT: return (DoubleSpecies) SPECIES_64;
2182             case S_128_BIT: return (DoubleSpecies) SPECIES_128;
2183             case S_256_BIT: return (DoubleSpecies) SPECIES_256;
2184             case S_512_BIT: return (DoubleSpecies) SPECIES_512;
2185             case S_Max_BIT: return (DoubleSpecies) SPECIES_MAX;
2186             default: throw new IllegalArgumentException("Bad shape: " + s);
2187         }
2188     }
2189 
2190     /** Species representing {@link DoubleVector}s of {@link Vector.Shape#S_64_BIT Shape.S_64_BIT}. */
2191     public static final Species<Double> SPECIES_64 = new DoubleSpecies(Shape.S_64_BIT, Double64Vector.class, Double64Vector.Double64Mask.class,
2192                                                                      Double64Vector::new, Double64Vector.Double64Mask::new);
2193 
2194     /** Species representing {@link DoubleVector}s of {@link Vector.Shape#S_128_BIT Shape.S_128_BIT}. */
2195     public static final Species<Double> SPECIES_128 = new DoubleSpecies(Shape.S_128_BIT, Double128Vector.class, Double128Vector.Double128Mask.class,
2196                                                                       Double128Vector::new, Double128Vector.Double128Mask::new);
2197 
2198     /** Species representing {@link DoubleVector}s of {@link Vector.Shape#S_256_BIT Shape.S_256_BIT}. */
2199     public static final Species<Double> SPECIES_256 = new DoubleSpecies(Shape.S_256_BIT, Double256Vector.class, Double256Vector.Double256Mask.class,
2200                                                                       Double256Vector::new, Double256Vector.Double256Mask::new);
2201 
2202     /** Species representing {@link DoubleVector}s of {@link Vector.Shape#S_512_BIT Shape.S_512_BIT}. */
2203     public static final Species<Double> SPECIES_512 = new DoubleSpecies(Shape.S_512_BIT, Double512Vector.class, Double512Vector.Double512Mask.class,
2204                                                                       Double512Vector::new, Double512Vector.Double512Mask::new);
2205 
2206     /** Species representing {@link DoubleVector}s of {@link Vector.Shape#S_Max_BIT Shape.S_Max_BIT}. */
2207     public static final Species<Double> SPECIES_MAX = new DoubleSpecies(Shape.S_Max_BIT, DoubleMaxVector.class, DoubleMaxVector.DoubleMaxMask.class,
2208                                                                       DoubleMaxVector::new, DoubleMaxVector.DoubleMaxMask::new);





2209 
2210     /**
2211      * Preferred species for {@link DoubleVector}s.
2212      * A preferred species is a species of maximal bit size for the platform.
2213      */
2214     public static final Species<Double> SPECIES_PREFERRED = (Species<Double>) preferredSpecies();
2215 }


  39 
  40 /**
  41  * A specialized {@link Vector} representing an ordered immutable sequence of
  42  * {@code double} values.
  43  */
  44 @SuppressWarnings("cast")
  45 public abstract class DoubleVector extends Vector<Double> {
  46 
  47     DoubleVector() {}
  48 
  49     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
  50 
  51     // Unary operator
  52 
  53     interface FUnOp {
  54         double apply(int i, double a);
  55     }
  56 
  57     abstract DoubleVector uOp(FUnOp f);
  58 
  59     abstract DoubleVector uOp(VectorMask<Double> m, FUnOp f);
  60 
  61     // Binary operator
  62 
  63     interface FBinOp {
  64         double apply(int i, double a, double b);
  65     }
  66 
  67     abstract DoubleVector bOp(Vector<Double> v, FBinOp f);
  68 
  69     abstract DoubleVector bOp(Vector<Double> v, VectorMask<Double> m, FBinOp f);
  70 
  71     // Trinary operator
  72 
  73     interface FTriOp {
  74         double apply(int i, double a, double b, double c);
  75     }
  76 
  77     abstract DoubleVector tOp(Vector<Double> v1, Vector<Double> v2, FTriOp f);
  78 
  79     abstract DoubleVector tOp(Vector<Double> v1, Vector<Double> v2, VectorMask<Double> m, FTriOp f);
  80 
  81     // Reduction operator
  82 
  83     abstract double rOp(double v, FBinOp f);
  84 
  85     // Binary test
  86 
  87     interface FBinTest {
  88         boolean apply(int i, double a, double b);
  89     }
  90 
  91     abstract VectorMask<Double> bTest(Vector<Double> v, FBinTest f);
  92 
  93     // Foreach
  94 
  95     interface FUnCon {
  96         void apply(int i, double a);
  97     }
  98 
  99     abstract void forEach(FUnCon f);
 100 
 101     abstract void forEach(VectorMask<Double> m, FUnCon f);
 102 
 103     // Static factories
 104 
 105     /**
 106      * Returns a vector where all lane elements are set to the default
 107      * primitive value.
 108      *
 109      * @param species species of desired vector
 110      * @return a zero vector of given species
 111      */
 112     @ForceInline
 113     @SuppressWarnings("unchecked")
 114     public static DoubleVector zero(VectorSpecies<Double> species) {
 115         return VectorIntrinsics.broadcastCoerced((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 116                                                  Double.doubleToLongBits(0.0f), species,
 117                                                  ((bits, s) -> ((DoubleSpecies)s).op(i -> Double.longBitsToDouble((long)bits))));
 118     }
 119 
 120     /**
 121      * Loads a vector from a byte array starting at an offset.
 122      * <p>
 123      * Bytes are composed into primitive lane elements according to the
 124      * native byte order of the underlying platform
 125      * <p>
 126      * This method behaves as if it returns the result of calling the
 127      * byte buffer, offset, and mask accepting
 128      * {@link #fromByteBuffer(VectorSpecies<Double>, ByteBuffer, int, VectorMask) method} as follows:
 129      * <pre>{@code
 130      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 131      * }</pre>
 132      *
 133      * @param species species of desired vector
 134      * @param a the byte array
 135      * @param ix the offset into the array
 136      * @return a vector loaded from a byte array
 137      * @throws IndexOutOfBoundsException if {@code i < 0} or
 138      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 139      */
 140     @ForceInline
 141     @SuppressWarnings("unchecked")
 142     public static DoubleVector fromByteArray(VectorSpecies<Double> species, byte[] a, int ix) {
 143         Objects.requireNonNull(a);
 144         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 145         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 146                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 147                                      a, ix, species,
 148                                      (c, idx, s) -> {
 149                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 150                                          DoubleBuffer tb = bbc.asDoubleBuffer();
 151                                          return ((DoubleSpecies)s).op(i -> tb.get());
 152                                      });
 153     }
 154 
 155     /**
 156      * Loads a vector from a byte array starting at an offset and using a
 157      * mask.
 158      * <p>
 159      * Bytes are composed into primitive lane elements according to the
 160      * native byte order of the underlying platform.
 161      * <p>
 162      * This method behaves as if it returns the result of calling the
 163      * byte buffer, offset, and mask accepting
 164      * {@link #fromByteBuffer(VectorSpecies<Double>, ByteBuffer, int, VectorMask) method} as follows:
 165      * <pre>{@code
 166      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 167      * }</pre>
 168      *
 169      * @param species species of desired vector
 170      * @param a the byte array
 171      * @param ix the offset into the array
 172      * @param m the mask
 173      * @return a vector loaded from a byte array
 174      * @throws IndexOutOfBoundsException if {@code i < 0} or
 175      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 176      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 177      * or {@code > a.length},
 178      * for any vector lane index {@code N} where the mask at lane {@code N}
 179      * is set
 180      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 181      */
 182     @ForceInline
 183     public static DoubleVector fromByteArray(VectorSpecies<Double> species, byte[] a, int ix, VectorMask<Double> m) {
 184         return zero(species).blend(fromByteArray(species, a, ix), m);
 185     }
 186 
 187     /**
 188      * Loads a vector from an array starting at offset.
 189      * <p>
 190      * For each vector lane, where {@code N} is the vector lane index, the
 191      * array element at index {@code i + N} is placed into the
 192      * resulting vector at lane index {@code N}.
 193      *
 194      * @param species species of desired vector
 195      * @param a the array
 196      * @param i the offset into the array
 197      * @return the vector loaded from an array
 198      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 199      * {@code i > a.length - this.length()}
 200      */
 201     @ForceInline
 202     @SuppressWarnings("unchecked")
 203     public static DoubleVector fromArray(VectorSpecies<Double> species, double[] a, int i){
 204         Objects.requireNonNull(a);
 205         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 206         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 207                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 208                                      a, i, species,
 209                                      (c, idx, s) -> ((DoubleSpecies)s).op(n -> c[idx + n]));
 210     }
 211 
 212 
 213     /**
 214      * Loads a vector from an array starting at offset and using a mask.
 215      * <p>
 216      * For each vector lane, where {@code N} is the vector lane index,
 217      * if the mask lane at index {@code N} is set then the array element at
 218      * index {@code i + N} is placed into the resulting vector at lane index
 219      * {@code N}, otherwise the default element value is placed into the
 220      * resulting vector at lane index {@code N}.
 221      *
 222      * @param species species of desired vector
 223      * @param a the array
 224      * @param i the offset into the array
 225      * @param m the mask
 226      * @return the vector loaded from an array
 227      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 228      * for any vector lane index {@code N} where the mask at lane {@code N}
 229      * is set {@code i > a.length - N}
 230      */
 231     @ForceInline
 232     public static DoubleVector fromArray(VectorSpecies<Double> species, double[] a, int i, VectorMask<Double> m) {
 233         return zero(species).blend(fromArray(species, a, i), m);
 234     }
 235 
 236     /**
 237      * Loads a vector from an array using indexes obtained from an index
 238      * map.
 239      * <p>
 240      * For each vector lane, where {@code N} is the vector lane index, the
 241      * array element at index {@code i + indexMap[j + N]} is placed into the
 242      * resulting vector at lane index {@code N}.
 243      *
 244      * @param species species of desired vector
 245      * @param a the array
 246      * @param i the offset into the array, may be negative if relative
 247      * indexes in the index map compensate to produce a value within the
 248      * array bounds
 249      * @param indexMap the index map
 250      * @param j the offset into the index map
 251      * @return the vector loaded from an array
 252      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 253      * {@code j > indexMap.length - this.length()},
 254      * or for any vector lane index {@code N} the result of
 255      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 256      */
 257     @ForceInline
 258     @SuppressWarnings("unchecked")
 259     public static DoubleVector fromArray(VectorSpecies<Double> species, double[] a, int i, int[] indexMap, int j) {
 260         Objects.requireNonNull(a);
 261         Objects.requireNonNull(indexMap);
 262 
 263         if (species.length() == 1) {
 264           return DoubleVector.fromArray(species, a, i + indexMap[j]);
 265         }
 266 
 267         // Index vector: vix[0:n] = k -> i + indexMap[j + k]
 268         IntVector vix = IntVector.fromArray(IntVector.species(species.indexShape()), indexMap, j).add(i);
 269 
 270         vix = VectorIntrinsics.checkIndex(vix, a.length);
 271 
 272         return VectorIntrinsics.loadWithMap((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 273                                             IntVector.species(species.indexShape()).boxType(), a, Unsafe.ARRAY_DOUBLE_BASE_OFFSET, vix,
 274                                             a, i, indexMap, j, species,
 275                                             (double[] c, int idx, int[] iMap, int idy, VectorSpecies<Double> s) ->
 276                                                 ((DoubleSpecies)s).op(n -> c[idx + iMap[idy+n]]));
 277         }
 278 
 279     /**
 280      * Loads a vector from an array using indexes obtained from an index
 281      * map and using a mask.
 282      * <p>
 283      * For each vector lane, where {@code N} is the vector lane index,
 284      * if the mask lane at index {@code N} is set then the array element at
 285      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 286      * at lane index {@code N}.
 287      *
 288      * @param species species of desired vector
 289      * @param a the array
 290      * @param i the offset into the array, may be negative if relative
 291      * indexes in the index map compensate to produce a value within the
 292      * array bounds
 293      * @param m the mask
 294      * @param indexMap the index map
 295      * @param j the offset into the index map
 296      * @return the vector loaded from an array
 297      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 298      * {@code j > indexMap.length - this.length()},
 299      * or for any vector lane index {@code N} where the mask at lane
 300      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 301      * {@code < 0} or {@code >= a.length}
 302      */
 303     @ForceInline
 304     @SuppressWarnings("unchecked")
 305     public static DoubleVector fromArray(VectorSpecies<Double> species, double[] a, int i, VectorMask<Double> m, int[] indexMap, int j) {
 306         // @@@ This can result in out of bounds errors for unset mask lanes
 307         return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
 308     }
 309 
 310 
 311     /**
 312      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 313      * offset into the byte buffer.
 314      * <p>
 315      * Bytes are composed into primitive lane elements according to the
 316      * native byte order of the underlying platform.
 317      * <p>
 318      * This method behaves as if it returns the result of calling the
 319      * byte buffer, offset, and mask accepting
 320      * {@link #fromByteBuffer(VectorSpecies<Double>, ByteBuffer, int, VectorMask)} method} as follows:
 321      * <pre>{@code
 322      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 323      * }</pre>
 324      *
 325      * @param species species of desired vector
 326      * @param bb the byte buffer
 327      * @param ix the offset into the byte buffer
 328      * @return a vector loaded from a byte buffer
 329      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 330      * or {@code > b.limit()},
 331      * or if there are fewer than
 332      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 333      * remaining in the byte buffer from the given offset
 334      */
 335     @ForceInline
 336     @SuppressWarnings("unchecked")
 337     public static DoubleVector fromByteBuffer(VectorSpecies<Double> species, ByteBuffer bb, int ix) {
 338         if (bb.order() != ByteOrder.nativeOrder()) {
 339             throw new IllegalArgumentException();
 340         }
 341         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 342         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 343                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 344                                      bb, ix, species,
 345                                      (c, idx, s) -> {
 346                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 347                                          DoubleBuffer tb = bbc.asDoubleBuffer();
 348                                          return ((DoubleSpecies)s).op(i -> tb.get());
 349                                      });
 350     }
 351 
 352     /**
 353      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 354      * offset into the byte buffer and using a mask.
 355      * <p>
 356      * This method behaves as if the byte buffer is viewed as a primitive
 357      * {@link java.nio.Buffer buffer} for the primitive element type,


 369      * e[] es = new e[this.length()];
 370      * for (int n = 0; n < t.length; n++) {
 371      *     if (m.isSet(n))
 372      *         es[n] = eb.get(n);
 373      * }
 374      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 375      * }</pre>
 376      *
 377      * @param species species of desired vector
 378      * @param bb the byte buffer
 379      * @param ix the offset into the byte buffer
 380      * @param m the mask
 381      * @return a vector loaded from a byte buffer
 382      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 383      * or {@code > b.limit()},
 384      * for any vector lane index {@code N} where the mask at lane {@code N}
 385      * is set
 386      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 387      */
 388     @ForceInline
 389     public static DoubleVector fromByteBuffer(VectorSpecies<Double> species, ByteBuffer bb, int ix, VectorMask<Double> m) {
 390         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 391     }
 392 
 393     /**
 394      * Returns a vector where all lane elements are set to the primitive
 395      * value {@code e}.
 396      *
 397      * @param s species of the desired vector
 398      * @param e the value
 399      * @return a vector of vector where all lane elements are set to
 400      * the primitive value {@code e}
 401      */
 402     @ForceInline
 403     @SuppressWarnings("unchecked")
 404     public static DoubleVector broadcast(VectorSpecies<Double> s, double e) {
 405         return VectorIntrinsics.broadcastCoerced(
 406             (Class<DoubleVector>) s.boxType(), double.class, s.length(),
 407             Double.doubleToLongBits(e), s,
 408             ((bits, sp) -> ((DoubleSpecies)sp).op(i -> Double.longBitsToDouble((long)bits))));
 409     }
 410 
 411     /**
 412      * Returns a vector where each lane element is set to a given
 413      * primitive value.
 414      * <p>
 415      * For each vector lane, where {@code N} is the vector lane index, the
 416      * the primitive value at index {@code N} is placed into the resulting
 417      * vector at lane index {@code N}.
 418      *
 419      * @param s species of the desired vector
 420      * @param es the given primitive values
 421      * @return a vector where each lane element is set to a given primitive
 422      * value
 423      * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
 424      */
 425     @ForceInline
 426     @SuppressWarnings("unchecked")
 427     public static DoubleVector scalars(VectorSpecies<Double> s, double... es) {
 428         Objects.requireNonNull(es);
 429         int ix = VectorIntrinsics.checkIndex(0, es.length, s.length());
 430         return VectorIntrinsics.load((Class<DoubleVector>) s.boxType(), double.class, s.length(),
 431                                      es, Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 432                                      es, ix, s,
 433                                      (c, idx, sp) -> ((DoubleSpecies)sp).op(n -> c[idx + n]));
 434     }
 435 
 436     /**
 437      * Returns a vector where the first lane element is set to the primtive
 438      * value {@code e}, all other lane elements are set to the default
 439      * value.
 440      *
 441      * @param s species of the desired vector
 442      * @param e the value
 443      * @return a vector where the first lane element is set to the primitive
 444      * value {@code e}
 445      */
 446     @ForceInline
 447     public static final DoubleVector single(VectorSpecies<Double> s, double e) {
 448         return zero(s).with(0, e);
 449     }
 450 
 451     /**
 452      * Returns a vector where each lane element is set to a randomly
 453      * generated primitive value.
 454      *
 455      * The semantics are equivalent to calling
 456      * {@link ThreadLocalRandom#nextDouble()}
 457      *
 458      * @param s species of the desired vector
 459      * @return a vector where each lane elements is set to a randomly
 460      * generated primitive value
 461      */
 462     public static DoubleVector random(VectorSpecies<Double> s) {
 463         ThreadLocalRandom r = ThreadLocalRandom.current();
 464         return ((DoubleSpecies)s).op(i -> r.nextDouble());
 465     }
 466 
































































































































































































































 467     // Ops
 468 
 469     @Override
 470     public abstract DoubleVector add(Vector<Double> v);
 471 
 472     /**
 473      * Adds this vector to the broadcast of an input scalar.
 474      * <p>
 475      * This is a vector binary operation where the primitive addition operation
 476      * ({@code +}) is applied to lane elements.
 477      *
 478      * @param s the input scalar
 479      * @return the result of adding this vector to the broadcast of an input
 480      * scalar
 481      */
 482     public abstract DoubleVector add(double s);
 483 
 484     @Override
 485     public abstract DoubleVector add(Vector<Double> v, VectorMask<Double> m);
 486 
 487     /**
 488      * Adds this vector to broadcast of an input scalar,
 489      * selecting lane elements controlled by a mask.
 490      * <p>
 491      * This is a vector binary operation where the primitive addition operation
 492      * ({@code +}) is applied to lane elements.
 493      *
 494      * @param s the input scalar
 495      * @param m the mask controlling lane selection
 496      * @return the result of adding this vector to the broadcast of an input
 497      * scalar
 498      */
 499     public abstract DoubleVector add(double s, VectorMask<Double> m);
 500 
 501     @Override
 502     public abstract DoubleVector sub(Vector<Double> v);
 503 
 504     /**
 505      * Subtracts the broadcast of an input scalar from this vector.
 506      * <p>
 507      * This is a vector binary operation where the primitive subtraction
 508      * operation ({@code -}) is applied to lane elements.
 509      *
 510      * @param s the input scalar
 511      * @return the result of subtracting the broadcast of an input
 512      * scalar from this vector
 513      */
 514     public abstract DoubleVector sub(double s);
 515 
 516     @Override
 517     public abstract DoubleVector sub(Vector<Double> v, VectorMask<Double> m);
 518 
 519     /**
 520      * Subtracts the broadcast of an input scalar from this vector, selecting
 521      * lane elements controlled by a mask.
 522      * <p>
 523      * This is a vector binary operation where the primitive subtraction
 524      * operation ({@code -}) is applied to lane elements.
 525      *
 526      * @param s the input scalar
 527      * @param m the mask controlling lane selection
 528      * @return the result of subtracting the broadcast of an input
 529      * scalar from this vector
 530      */
 531     public abstract DoubleVector sub(double s, VectorMask<Double> m);
 532 
 533     @Override
 534     public abstract DoubleVector mul(Vector<Double> v);
 535 
 536     /**
 537      * Multiplies this vector with the broadcast of an input scalar.
 538      * <p>
 539      * This is a vector binary operation where the primitive multiplication
 540      * operation ({@code *}) is applied to lane elements.
 541      *
 542      * @param s the input scalar
 543      * @return the result of multiplying this vector with the broadcast of an
 544      * input scalar
 545      */
 546     public abstract DoubleVector mul(double s);
 547 
 548     @Override
 549     public abstract DoubleVector mul(Vector<Double> v, VectorMask<Double> m);
 550 
 551     /**
 552      * Multiplies this vector with the broadcast of an input scalar, selecting
 553      * lane elements controlled by a mask.
 554      * <p>
 555      * This is a vector binary operation where the primitive multiplication
 556      * operation ({@code *}) is applied to lane elements.
 557      *
 558      * @param s the input scalar
 559      * @param m the mask controlling lane selection
 560      * @return the result of multiplying this vector with the broadcast of an
 561      * input scalar
 562      */
 563     public abstract DoubleVector mul(double s, VectorMask<Double> m);
 564 
 565     @Override
 566     public abstract DoubleVector neg();
 567 
 568     @Override
 569     public abstract DoubleVector neg(VectorMask<Double> m);
 570 
 571     @Override
 572     public abstract DoubleVector abs();
 573 
 574     @Override
 575     public abstract DoubleVector abs(VectorMask<Double> m);
 576 
 577     @Override
 578     public abstract DoubleVector min(Vector<Double> v);
 579 
 580     @Override
 581     public abstract DoubleVector min(Vector<Double> v, VectorMask<Double> m);
 582 
 583     /**
 584      * Returns the minimum of this vector and the broadcast of an input scalar.
 585      * <p>
 586      * This is a vector binary operation where the operation
 587      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 588      *
 589      * @param s the input scalar
 590      * @return the minimum of this vector and the broadcast of an input scalar
 591      */
 592     public abstract DoubleVector min(double s);
 593 
 594     @Override
 595     public abstract DoubleVector max(Vector<Double> v);
 596 
 597     @Override
 598     public abstract DoubleVector max(Vector<Double> v, VectorMask<Double> m);
 599 
 600     /**
 601      * Returns the maximum of this vector and the broadcast of an input scalar.
 602      * <p>
 603      * This is a vector binary operation where the operation
 604      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 605      *
 606      * @param s the input scalar
 607      * @return the maximum of this vector and the broadcast of an input scalar
 608      */
 609     public abstract DoubleVector max(double s);
 610 
 611     @Override
 612     public abstract VectorMask<Double> equal(Vector<Double> v);
 613 
 614     /**
 615      * Tests if this vector is equal to the broadcast of an input scalar.
 616      * <p>
 617      * This is a vector binary test operation where the primitive equals
 618      * operation ({@code ==}) is applied to lane elements.
 619      *
 620      * @param s the input scalar
 621      * @return the result mask of testing if this vector is equal to the
 622      * broadcast of an input scalar
 623      */
 624     public abstract VectorMask<Double> equal(double s);
 625 
 626     @Override
 627     public abstract VectorMask<Double> notEqual(Vector<Double> v);
 628 
 629     /**
 630      * Tests if this vector is not equal to the broadcast of an input scalar.
 631      * <p>
 632      * This is a vector binary test operation where the primitive not equals
 633      * operation ({@code !=}) is applied to lane elements.
 634      *
 635      * @param s the input scalar
 636      * @return the result mask of testing if this vector is not equal to the
 637      * broadcast of an input scalar
 638      */
 639     public abstract VectorMask<Double> notEqual(double s);
 640 
 641     @Override
 642     public abstract VectorMask<Double> lessThan(Vector<Double> v);
 643 
 644     /**
 645      * Tests if this vector is less than the broadcast of an input scalar.
 646      * <p>
 647      * This is a vector binary test operation where the primitive less than
 648      * operation ({@code <}) is applied to lane elements.
 649      *
 650      * @param s the input scalar
 651      * @return the mask result of testing if this vector is less than the
 652      * broadcast of an input scalar
 653      */
 654     public abstract VectorMask<Double> lessThan(double s);
 655 
 656     @Override
 657     public abstract VectorMask<Double> lessThanEq(Vector<Double> v);
 658 
 659     /**
 660      * Tests if this vector is less or equal to the broadcast of an input scalar.
 661      * <p>
 662      * This is a vector binary test operation where the primitive less than
 663      * or equal to operation ({@code <=}) is applied to lane elements.
 664      *
 665      * @param s the input scalar
 666      * @return the mask result of testing if this vector is less than or equal
 667      * to the broadcast of an input scalar
 668      */
 669     public abstract VectorMask<Double> lessThanEq(double s);
 670 
 671     @Override
 672     public abstract VectorMask<Double> greaterThan(Vector<Double> v);
 673 
 674     /**
 675      * Tests if this vector is greater than the broadcast of an input scalar.
 676      * <p>
 677      * This is a vector binary test operation where the primitive greater than
 678      * operation ({@code >}) is applied to lane elements.
 679      *
 680      * @param s the input scalar
 681      * @return the mask result of testing if this vector is greater than the
 682      * broadcast of an input scalar
 683      */
 684     public abstract VectorMask<Double> greaterThan(double s);
 685 
 686     @Override
 687     public abstract VectorMask<Double> greaterThanEq(Vector<Double> v);
 688 
 689     /**
 690      * Tests if this vector is greater than or equal to the broadcast of an
 691      * input scalar.
 692      * <p>
 693      * This is a vector binary test operation where the primitive greater than
 694      * or equal to operation ({@code >=}) is applied to lane elements.
 695      *
 696      * @param s the input scalar
 697      * @return the mask result of testing if this vector is greater than or
 698      * equal to the broadcast of an input scalar
 699      */
 700     public abstract VectorMask<Double> greaterThanEq(double s);
 701 
 702     @Override
 703     public abstract DoubleVector blend(Vector<Double> v, VectorMask<Double> m);
 704 
 705     /**
 706      * Blends the lane elements of this vector with those of the broadcast of an
 707      * input scalar, selecting lanes controlled by a mask.
 708      * <p>
 709      * For each lane of the mask, at lane index {@code N}, if the mask lane
 710      * is set then the lane element at {@code N} from the input vector is
 711      * selected and placed into the resulting vector at {@code N},
 712      * otherwise the the lane element at {@code N} from this input vector is
 713      * selected and placed into the resulting vector at {@code N}.
 714      *
 715      * @param s the input scalar
 716      * @param m the mask controlling lane selection
 717      * @return the result of blending the lane elements of this vector with
 718      * those of the broadcast of an input scalar
 719      */
 720     public abstract DoubleVector blend(double s, VectorMask<Double> m);
 721 
 722     @Override
 723     public abstract DoubleVector rearrange(Vector<Double> v,
 724                                                       VectorShuffle<Double> s, VectorMask<Double> m);
 725 
 726     @Override
 727     public abstract DoubleVector rearrange(VectorShuffle<Double> m);
 728 
 729     @Override
 730     public abstract DoubleVector reshape(VectorSpecies<Double> s);
 731 
 732     @Override
 733     public abstract DoubleVector rotateEL(int i);
 734 
 735     @Override
 736     public abstract DoubleVector rotateER(int i);
 737 
 738     @Override
 739     public abstract DoubleVector shiftEL(int i);
 740 
 741     @Override
 742     public abstract DoubleVector shiftER(int i);
 743 
 744     /**
 745      * Divides this vector by an input vector.
 746      * <p>
 747      * This is a vector binary operation where the primitive division
 748      * operation ({@code /}) is applied to lane elements.
 749      *
 750      * @param v the input vector


 758      * This is a vector binary operation where the primitive division
 759      * operation ({@code /}) is applied to lane elements.
 760      *
 761      * @param s the input scalar
 762      * @return the result of dividing this vector by the broadcast of an input
 763      * scalar
 764      */
 765     public abstract DoubleVector div(double s);
 766 
 767     /**
 768      * Divides this vector by an input vector, selecting lane elements
 769      * controlled by a mask.
 770      * <p>
 771      * This is a vector binary operation where the primitive division
 772      * operation ({@code /}) is applied to lane elements.
 773      *
 774      * @param v the input vector
 775      * @param m the mask controlling lane selection
 776      * @return the result of dividing this vector by the input vector
 777      */
 778     public abstract DoubleVector div(Vector<Double> v, VectorMask<Double> m);
 779 
 780     /**
 781      * Divides this vector by the broadcast of an input scalar, selecting lane
 782      * elements controlled by a mask.
 783      * <p>
 784      * This is a vector binary operation where the primitive division
 785      * operation ({@code /}) is applied to lane elements.
 786      *
 787      * @param s the input scalar
 788      * @param m the mask controlling lane selection
 789      * @return the result of dividing this vector by the broadcast of an input
 790      * scalar
 791      */
 792     public abstract DoubleVector div(double s, VectorMask<Double> m);
 793 
 794     /**
 795      * Calculates the square root of this vector.
 796      * <p>
 797      * This is a vector unary operation where the {@link Math#sqrt} operation
 798      * is applied to lane elements.
 799      *
 800      * @return the square root of this vector
 801      */
 802     public abstract DoubleVector sqrt();
 803 
 804     /**
 805      * Calculates the square root of this vector, selecting lane elements
 806      * controlled by a mask.
 807      * <p>
 808      * This is a vector unary operation where the {@link Math#sqrt} operation
 809      * is applied to lane elements.
 810      *
 811      * @param m the mask controlling lane selection
 812      * @return the square root of this vector
 813      */
 814     public DoubleVector sqrt(VectorMask<Double> m) {
 815         return uOp(m, (i, a) -> (double) Math.sqrt((double) a));
 816     }
 817 
 818     /**
 819      * Calculates the trigonometric tangent of this vector.
 820      * <p>
 821      * This is a vector unary operation with same semantic definition as
 822      * {@link Math#tan} operation applied to lane elements.
 823      * The implementation is not required to return same
 824      * results as {@link Math#tan}, but adheres to rounding, monotonicity,
 825      * and special case semantics as defined in the {@link Math#tan}
 826      * specifications. The computed result will be within 1 ulp of the
 827      * exact result.
 828      *
 829      * @return the tangent of this vector
 830      */
 831     public DoubleVector tan() {
 832         return uOp((i, a) -> (double) Math.tan((double) a));
 833     }
 834 
 835     /**
 836      * Calculates the trigonometric tangent of this vector, selecting lane
 837      * elements controlled by a mask.
 838      * <p>
 839      * Semantics for rounding, monotonicity, and special cases are
 840      * described in {@link DoubleVector#tan}
 841      *
 842      * @param m the mask controlling lane selection
 843      * @return the tangent of this vector
 844      */
 845     public DoubleVector tan(VectorMask<Double> m) {
 846         return uOp(m, (i, a) -> (double) Math.tan((double) a));
 847     }
 848 
 849     /**
 850      * Calculates the hyperbolic tangent of this vector.
 851      * <p>
 852      * This is a vector unary operation with same semantic definition as
 853      * {@link Math#tanh} operation applied to lane elements.
 854      * The implementation is not required to return same
 855      * results as {@link Math#tanh}, but adheres to rounding, monotonicity,
 856      * and special case semantics as defined in the {@link Math#tanh}
 857      * specifications. The computed result will be within 2.5 ulps of the
 858      * exact result.
 859      *
 860      * @return the hyperbolic tangent of this vector
 861      */
 862     public DoubleVector tanh() {
 863         return uOp((i, a) -> (double) Math.tanh((double) a));
 864     }
 865 
 866     /**
 867      * Calculates the hyperbolic tangent of this vector, selecting lane elements
 868      * controlled by a mask.
 869      * <p>
 870      * Semantics for rounding, monotonicity, and special cases are
 871      * described in {@link DoubleVector#tanh}
 872      *
 873      * @param m the mask controlling lane selection
 874      * @return the hyperbolic tangent of this vector
 875      */
 876     public DoubleVector tanh(VectorMask<Double> m) {
 877         return uOp(m, (i, a) -> (double) Math.tanh((double) a));
 878     }
 879 
 880     /**
 881      * Calculates the trigonometric sine of this vector.
 882      * <p>
 883      * This is a vector unary operation with same semantic definition as
 884      * {@link Math#sin} operation applied to lane elements.
 885      * The implementation is not required to return same
 886      * results as {@link Math#sin}, but adheres to rounding, monotonicity,
 887      * and special case semantics as defined in the {@link Math#sin}
 888      * specifications. The computed result will be within 1 ulp of the
 889      * exact result.
 890      *
 891      * @return the sine of this vector
 892      */
 893     public DoubleVector sin() {
 894         return uOp((i, a) -> (double) Math.sin((double) a));
 895     }
 896 
 897     /**
 898      * Calculates the trigonometric sine of this vector, selecting lane elements
 899      * controlled by a mask.
 900      * <p>
 901      * Semantics for rounding, monotonicity, and special cases are
 902      * described in {@link DoubleVector#sin}
 903      *
 904      * @param m the mask controlling lane selection
 905      * @return the sine of this vector
 906      */
 907     public DoubleVector sin(VectorMask<Double> m) {
 908         return uOp(m, (i, a) -> (double) Math.sin((double) a));
 909     }
 910 
 911     /**
 912      * Calculates the hyperbolic sine of this vector.
 913      * <p>
 914      * This is a vector unary operation with same semantic definition as
 915      * {@link Math#sinh} operation applied to lane elements.
 916      * The implementation is not required to return same
 917      * results as  {@link Math#sinh}, but adheres to rounding, monotonicity,
 918      * and special case semantics as defined in the {@link Math#sinh}
 919      * specifications. The computed result will be within 2.5 ulps of the
 920      * exact result.
 921      *
 922      * @return the hyperbolic sine of this vector
 923      */
 924     public DoubleVector sinh() {
 925         return uOp((i, a) -> (double) Math.sinh((double) a));
 926     }
 927 
 928     /**
 929      * Calculates the hyperbolic sine of this vector, selecting lane elements
 930      * controlled by a mask.
 931      * <p>
 932      * Semantics for rounding, monotonicity, and special cases are
 933      * described in {@link DoubleVector#sinh}
 934      *
 935      * @param m the mask controlling lane selection
 936      * @return the hyperbolic sine of this vector
 937      */
 938     public DoubleVector sinh(VectorMask<Double> m) {
 939         return uOp(m, (i, a) -> (double) Math.sinh((double) a));
 940     }
 941 
 942     /**
 943      * Calculates the trigonometric cosine of this vector.
 944      * <p>
 945      * This is a vector unary operation with same semantic definition as
 946      * {@link Math#cos} operation applied to lane elements.
 947      * The implementation is not required to return same
 948      * results as {@link Math#cos}, but adheres to rounding, monotonicity,
 949      * and special case semantics as defined in the {@link Math#cos}
 950      * specifications. The computed result will be within 1 ulp of the
 951      * exact result.
 952      *
 953      * @return the cosine of this vector
 954      */
 955     public DoubleVector cos() {
 956         return uOp((i, a) -> (double) Math.cos((double) a));
 957     }
 958 
 959     /**
 960      * Calculates the trigonometric cosine of this vector, selecting lane
 961      * elements controlled by a mask.
 962      * <p>
 963      * Semantics for rounding, monotonicity, and special cases are
 964      * described in {@link DoubleVector#cos}
 965      *
 966      * @param m the mask controlling lane selection
 967      * @return the cosine of this vector
 968      */
 969     public DoubleVector cos(VectorMask<Double> m) {
 970         return uOp(m, (i, a) -> (double) Math.cos((double) a));
 971     }
 972 
 973     /**
 974      * Calculates the hyperbolic cosine of this vector.
 975      * <p>
 976      * This is a vector unary operation with same semantic definition as
 977      * {@link Math#cosh} operation applied to lane elements.
 978      * The implementation is not required to return same
 979      * results as {@link Math#cosh}, but adheres to rounding, monotonicity,
 980      * and special case semantics as defined in the {@link Math#cosh}
 981      * specifications. The computed result will be within 2.5 ulps of the
 982      * exact result.
 983      *
 984      * @return the hyperbolic cosine of this vector
 985      */
 986     public DoubleVector cosh() {
 987         return uOp((i, a) -> (double) Math.cosh((double) a));
 988     }
 989 
 990     /**
 991      * Calculates the hyperbolic cosine of this vector, selecting lane elements
 992      * controlled by a mask.
 993      * <p>
 994      * Semantics for rounding, monotonicity, and special cases are
 995      * described in {@link DoubleVector#cosh}
 996      *
 997      * @param m the mask controlling lane selection
 998      * @return the hyperbolic cosine of this vector
 999      */
1000     public DoubleVector cosh(VectorMask<Double> m) {
1001         return uOp(m, (i, a) -> (double) Math.cosh((double) a));
1002     }
1003 
1004     /**
1005      * Calculates the arc sine of this vector.
1006      * <p>
1007      * This is a vector unary operation with same semantic definition as
1008      * {@link Math#asin} operation applied to lane elements.
1009      * The implementation is not required to return same
1010      * results as {@link Math#asin}, but adheres to rounding, monotonicity,
1011      * and special case semantics as defined in the {@link Math#asin}
1012      * specifications. The computed result will be within 1 ulp of the
1013      * exact result.
1014      *
1015      * @return the arc sine of this vector
1016      */
1017     public DoubleVector asin() {
1018         return uOp((i, a) -> (double) Math.asin((double) a));
1019     }
1020 
1021     /**
1022      * Calculates the arc sine of this vector, selecting lane elements
1023      * controlled by a mask.
1024      * <p>
1025      * Semantics for rounding, monotonicity, and special cases are
1026      * described in {@link DoubleVector#asin}
1027      *
1028      * @param m the mask controlling lane selection
1029      * @return the arc sine of this vector
1030      */
1031     public DoubleVector asin(VectorMask<Double> m) {
1032         return uOp(m, (i, a) -> (double) Math.asin((double) a));
1033     }
1034 
1035     /**
1036      * Calculates the arc cosine of this vector.
1037      * <p>
1038      * This is a vector unary operation with same semantic definition as
1039      * {@link Math#acos} operation applied to lane elements.
1040      * The implementation is not required to return same
1041      * results as {@link Math#acos}, but adheres to rounding, monotonicity,
1042      * and special case semantics as defined in the {@link Math#acos}
1043      * specifications. The computed result will be within 1 ulp of the
1044      * exact result.
1045      *
1046      * @return the arc cosine of this vector
1047      */
1048     public DoubleVector acos() {
1049         return uOp((i, a) -> (double) Math.acos((double) a));
1050     }
1051 
1052     /**
1053      * Calculates the arc cosine of this vector, selecting lane elements
1054      * controlled by a mask.
1055      * <p>
1056      * Semantics for rounding, monotonicity, and special cases are
1057      * described in {@link DoubleVector#acos}
1058      *
1059      * @param m the mask controlling lane selection
1060      * @return the arc cosine of this vector
1061      */
1062     public DoubleVector acos(VectorMask<Double> m) {
1063         return uOp(m, (i, a) -> (double) Math.acos((double) a));
1064     }
1065 
1066     /**
1067      * Calculates the arc tangent of this vector.
1068      * <p>
1069      * This is a vector unary operation with same semantic definition as
1070      * {@link Math#atan} operation applied to lane elements.
1071      * The implementation is not required to return same
1072      * results as {@link Math#atan}, but adheres to rounding, monotonicity,
1073      * and special case semantics as defined in the {@link Math#atan}
1074      * specifications. The computed result will be within 1 ulp of the
1075      * exact result.
1076      *
1077      * @return the arc tangent of this vector
1078      */
1079     public DoubleVector atan() {
1080         return uOp((i, a) -> (double) Math.atan((double) a));
1081     }
1082 
1083     /**
1084      * Calculates the arc tangent of this vector, selecting lane elements
1085      * controlled by a mask.
1086      * <p>
1087      * Semantics for rounding, monotonicity, and special cases are
1088      * described in {@link DoubleVector#atan}
1089      *
1090      * @param m the mask controlling lane selection
1091      * @return the arc tangent of this vector
1092      */
1093     public DoubleVector atan(VectorMask<Double> m) {
1094         return uOp(m, (i, a) -> (double) Math.atan((double) a));
1095     }
1096 
1097     /**
1098      * Calculates the arc tangent of this vector divided by an input vector.
1099      * <p>
1100      * This is a vector binary operation with same semantic definition as
1101      * {@link Math#atan2} operation applied to lane elements.
1102      * The implementation is not required to return same
1103      * results as {@link Math#atan2}, but adheres to rounding, monotonicity,
1104      * and special case semantics as defined in the {@link Math#atan2}
1105      * specifications. The computed result will be within 2 ulps of the
1106      * exact result.
1107      *
1108      * @param v the input vector
1109      * @return the arc tangent of this vector divided by the input vector
1110      */
1111     public DoubleVector atan2(Vector<Double> v) {
1112         return bOp(v, (i, a, b) -> (double) Math.atan2((double) a, (double) b));
1113     }


1123      * and special case semantics as defined in the {@link Math#atan2}
1124      * specifications. The computed result will be within 1 ulp of the
1125      * exact result.
1126      *
1127      * @param s the input scalar
1128      * @return the arc tangent of this vector over the input vector
1129      */
1130     public abstract DoubleVector atan2(double s);
1131 
1132     /**
1133      * Calculates the arc tangent of this vector divided by an input vector,
1134      * selecting lane elements controlled by a mask.
1135      * <p>
1136      * Semantics for rounding, monotonicity, and special cases are
1137      * described in {@link DoubleVector#atan2}
1138      *
1139      * @param v the input vector
1140      * @param m the mask controlling lane selection
1141      * @return the arc tangent of this vector divided by the input vector
1142      */
1143     public DoubleVector atan2(Vector<Double> v, VectorMask<Double> m) {
1144         return bOp(v, m, (i, a, b) -> (double) Math.atan2((double) a, (double) b));
1145     }
1146 
1147     /**
1148      * Calculates the arc tangent of this vector divided by the broadcast of an
1149      * an input scalar, selecting lane elements controlled by a mask.
1150      * <p>
1151      * Semantics for rounding, monotonicity, and special cases are
1152      * described in {@link DoubleVector#atan2}
1153      *
1154      * @param s the input scalar
1155      * @param m the mask controlling lane selection
1156      * @return the arc tangent of this vector over the input vector
1157      */
1158     public abstract DoubleVector atan2(double s, VectorMask<Double> m);
1159 
1160     /**
1161      * Calculates the cube root of this vector.
1162      * <p>
1163      * This is a vector unary operation with same semantic definition as
1164      * {@link Math#cbrt} operation applied to lane elements.
1165      * The implementation is not required to return same
1166      * results as {@link Math#cbrt}, but adheres to rounding, monotonicity,
1167      * and special case semantics as defined in the {@link Math#cbrt}
1168      * specifications. The computed result will be within 1 ulp of the
1169      * exact result.
1170      *
1171      * @return the cube root of this vector
1172      */
1173     public DoubleVector cbrt() {
1174         return uOp((i, a) -> (double) Math.cbrt((double) a));
1175     }
1176 
1177     /**
1178      * Calculates the cube root of this vector, selecting lane elements
1179      * controlled by a mask.
1180      * <p>
1181      * Semantics for rounding, monotonicity, and special cases are
1182      * described in {@link DoubleVector#cbrt}
1183      *
1184      * @param m the mask controlling lane selection
1185      * @return the cube root of this vector
1186      */
1187     public DoubleVector cbrt(VectorMask<Double> m) {
1188         return uOp(m, (i, a) -> (double) Math.cbrt((double) a));
1189     }
1190 
1191     /**
1192      * Calculates the natural logarithm of this vector.
1193      * <p>
1194      * This is a vector unary operation with same semantic definition as
1195      * {@link Math#log} operation applied to lane elements.
1196      * The implementation is not required to return same
1197      * results as {@link Math#log}, but adheres to rounding, monotonicity,
1198      * and special case semantics as defined in the {@link Math#log}
1199      * specifications. The computed result will be within 1 ulp of the
1200      * exact result.
1201      *
1202      * @return the natural logarithm of this vector
1203      */
1204     public DoubleVector log() {
1205         return uOp((i, a) -> (double) Math.log((double) a));
1206     }
1207 
1208     /**
1209      * Calculates the natural logarithm of this vector, selecting lane elements
1210      * controlled by a mask.
1211      * <p>
1212      * Semantics for rounding, monotonicity, and special cases are
1213      * described in {@link DoubleVector#log}
1214      *
1215      * @param m the mask controlling lane selection
1216      * @return the natural logarithm of this vector
1217      */
1218     public DoubleVector log(VectorMask<Double> m) {
1219         return uOp(m, (i, a) -> (double) Math.log((double) a));
1220     }
1221 
1222     /**
1223      * Calculates the base 10 logarithm of this vector.
1224      * <p>
1225      * This is a vector unary operation with same semantic definition as
1226      * {@link Math#log10} operation applied to lane elements.
1227      * The implementation is not required to return same
1228      * results as {@link Math#log10}, but adheres to rounding, monotonicity,
1229      * and special case semantics as defined in the {@link Math#log10}
1230      * specifications. The computed result will be within 1 ulp of the
1231      * exact result.
1232      *
1233      * @return the base 10 logarithm of this vector
1234      */
1235     public DoubleVector log10() {
1236         return uOp((i, a) -> (double) Math.log10((double) a));
1237     }
1238 
1239     /**
1240      * Calculates the base 10 logarithm of this vector, selecting lane elements
1241      * controlled by a mask.
1242      * <p>
1243      * Semantics for rounding, monotonicity, and special cases are
1244      * described in {@link DoubleVector#log10}
1245      *
1246      * @param m the mask controlling lane selection
1247      * @return the base 10 logarithm of this vector
1248      */
1249     public DoubleVector log10(VectorMask<Double> m) {
1250         return uOp(m, (i, a) -> (double) Math.log10((double) a));
1251     }
1252 
1253     /**
1254      * Calculates the natural logarithm of the sum of this vector and the
1255      * broadcast of {@code 1}.
1256      * <p>
1257      * This is a vector unary operation with same semantic definition as
1258      * {@link Math#log1p} operation applied to lane elements.
1259      * The implementation is not required to return same
1260      * results as  {@link Math#log1p}, but adheres to rounding, monotonicity,
1261      * and special case semantics as defined in the {@link Math#log1p}
1262      * specifications. The computed result will be within 1 ulp of the
1263      * exact result.
1264      *
1265      * @return the natural logarithm of the sum of this vector and the broadcast
1266      * of {@code 1}
1267      */
1268     public DoubleVector log1p() {
1269         return uOp((i, a) -> (double) Math.log1p((double) a));
1270     }
1271 
1272     /**
1273      * Calculates the natural logarithm of the sum of this vector and the
1274      * broadcast of {@code 1}, selecting lane elements controlled by a mask.
1275      * <p>
1276      * Semantics for rounding, monotonicity, and special cases are
1277      * described in {@link DoubleVector#log1p}
1278      *
1279      * @param m the mask controlling lane selection
1280      * @return the natural logarithm of the sum of this vector and the broadcast
1281      * of {@code 1}
1282      */
1283     public DoubleVector log1p(VectorMask<Double> m) {
1284         return uOp(m, (i, a) -> (double) Math.log1p((double) a));
1285     }
1286 
1287     /**
1288      * Calculates this vector raised to the power of an input vector.
1289      * <p>
1290      * This is a vector binary operation with same semantic definition as
1291      * {@link Math#pow} operation applied to lane elements.
1292      * The implementation is not required to return same
1293      * results as {@link Math#pow}, but adheres to rounding, monotonicity,
1294      * and special case semantics as defined in the {@link Math#pow}
1295      * specifications. The computed result will be within 1 ulp of the
1296      * exact result.
1297      *
1298      * @param v the input vector
1299      * @return this vector raised to the power of an input vector
1300      */
1301     public DoubleVector pow(Vector<Double> v) {
1302         return bOp(v, (i, a, b) -> (double) Math.pow((double) a, (double) b));
1303     }


1314      * specifications. The computed result will be within 1 ulp of the
1315      * exact result.
1316      *
1317      * @param s the input scalar
1318      * @return this vector raised to the power of the broadcast of an input
1319      * scalar.
1320      */
1321     public abstract DoubleVector pow(double s);
1322 
1323     /**
1324      * Calculates this vector raised to the power of an input vector, selecting
1325      * lane elements controlled by a mask.
1326      * <p>
1327      * Semantics for rounding, monotonicity, and special cases are
1328      * described in {@link DoubleVector#pow}
1329      *
1330      * @param v the input vector
1331      * @param m the mask controlling lane selection
1332      * @return this vector raised to the power of an input vector
1333      */
1334     public DoubleVector pow(Vector<Double> v, VectorMask<Double> m) {
1335         return bOp(v, m, (i, a, b) -> (double) Math.pow((double) a, (double) b));
1336     }
1337 
1338     /**
1339      * Calculates this vector raised to the power of the broadcast of an input
1340      * scalar, selecting lane elements controlled by a mask.
1341      * <p>
1342      * Semantics for rounding, monotonicity, and special cases are
1343      * described in {@link DoubleVector#pow}
1344      *
1345      * @param s the input scalar
1346      * @param m the mask controlling lane selection
1347      * @return this vector raised to the power of the broadcast of an input
1348      * scalar.
1349      */
1350     public abstract DoubleVector pow(double s, VectorMask<Double> m);
1351 
1352     /**
1353      * Calculates the broadcast of Euler's number {@code e} raised to the power
1354      * of this vector.
1355      * <p>
1356      * This is a vector unary operation with same semantic definition as
1357      * {@link Math#exp} operation applied to lane elements.
1358      * The implementation is not required to return same
1359      * results as {@link Math#exp}, but adheres to rounding, monotonicity,
1360      * and special case semantics as defined in the {@link Math#exp}
1361      * specifications. The computed result will be within 1 ulp of the
1362      * exact result.
1363      *
1364      * @return the broadcast of Euler's number {@code e} raised to the power of
1365      * this vector
1366      */
1367     public DoubleVector exp() {
1368         return uOp((i, a) -> (double) Math.exp((double) a));
1369     }
1370 
1371     /**
1372      * Calculates the broadcast of Euler's number {@code e} raised to the power
1373      * of this vector, selecting lane elements controlled by a mask.
1374      * <p>
1375      * Semantics for rounding, monotonicity, and special cases are
1376      * described in {@link DoubleVector#exp}
1377      *
1378      * @param m the mask controlling lane selection
1379      * @return the broadcast of Euler's number {@code e} raised to the power of
1380      * this vector
1381      */
1382     public DoubleVector exp(VectorMask<Double> m) {
1383         return uOp(m, (i, a) -> (double) Math.exp((double) a));
1384     }
1385 
1386     /**
1387      * Calculates the broadcast of Euler's number {@code e} raised to the power
1388      * of this vector minus the broadcast of {@code -1}.
1389      * More specifically as if the following (ignoring any differences in
1390      * numerical accuracy):
1391      * <pre>{@code
1392      *   this.exp().sub(this.species().broadcast(1))
1393      * }</pre>
1394      * <p>
1395      * This is a vector unary operation with same semantic definition as
1396      * {@link Math#expm1} operation applied to lane elements.
1397      * The implementation is not required to return same
1398      * results as {@link Math#expm1}, but adheres to rounding, monotonicity,
1399      * and special case semantics as defined in the {@link Math#expm1}
1400      * specifications. The computed result will be within 1 ulp of the
1401      * exact result.
1402      *


1407         return uOp((i, a) -> (double) Math.expm1((double) a));
1408     }
1409 
1410     /**
1411      * Calculates the broadcast of Euler's number {@code e} raised to the power
1412      * of this vector minus the broadcast of {@code -1}, selecting lane elements
1413      * controlled by a mask
1414      * More specifically as if the following (ignoring any differences in
1415      * numerical accuracy):
1416      * <pre>{@code
1417      *   this.exp(m).sub(this.species().broadcast(1), m)
1418      * }</pre>
1419      * <p>
1420      * Semantics for rounding, monotonicity, and special cases are
1421      * described in {@link DoubleVector#expm1}
1422      *
1423      * @param m the mask controlling lane selection
1424      * @return the broadcast of Euler's number {@code e} raised to the power of
1425      * this vector minus the broadcast of {@code -1}
1426      */
1427     public DoubleVector expm1(VectorMask<Double> m) {
1428         return uOp(m, (i, a) -> (double) Math.expm1((double) a));
1429     }
1430 
1431     /**
1432      * Calculates the product of this vector and a first input vector summed
1433      * with a second input vector.
1434      * More specifically as if the following (ignoring any differences in
1435      * numerical accuracy):
1436      * <pre>{@code
1437      *   this.mul(v1).add(v2)
1438      * }</pre>
1439      * <p>
1440      * This is a vector ternary operation where the {@link Math#fma} operation
1441      * is applied to lane elements.
1442      *
1443      * @param v1 the first input vector
1444      * @param v2 the second input vector
1445      * @return the product of this vector and the first input vector summed with
1446      * the second input vector
1447      */


1466     public abstract DoubleVector fma(double s1, double s2);
1467 
1468     /**
1469      * Calculates the product of this vector and a first input vector summed
1470      * with a second input vector, selecting lane elements controlled by a mask.
1471      * More specifically as if the following (ignoring any differences in
1472      * numerical accuracy):
1473      * <pre>{@code
1474      *   this.mul(v1, m).add(v2, m)
1475      * }</pre>
1476      * <p>
1477      * This is a vector ternary operation where the {@link Math#fma} operation
1478      * is applied to lane elements.
1479      *
1480      * @param v1 the first input vector
1481      * @param v2 the second input vector
1482      * @param m the mask controlling lane selection
1483      * @return the product of this vector and the first input vector summed with
1484      * the second input vector
1485      */
1486     public DoubleVector fma(Vector<Double> v1, Vector<Double> v2, VectorMask<Double> m) {
1487         return tOp(v1, v2, m, (i, a, b, c) -> Math.fma(a, b, c));
1488     }
1489 
1490     /**
1491      * Calculates the product of this vector and the broadcast of a first input
1492      * scalar summed with the broadcast of a second input scalar, selecting lane
1493      * elements controlled by a mask
1494      * More specifically as if the following:
1495      * <pre>{@code
1496      *   this.fma(this.species().broadcast(s1), this.species().broadcast(s2), m)
1497      * }</pre>
1498      * <p>
1499      * This is a vector ternary operation where the {@link Math#fma} operation
1500      * is applied to lane elements.
1501      *
1502      * @param s1 the first input scalar
1503      * @param s2 the second input scalar
1504      * @param m the mask controlling lane selection
1505      * @return the product of this vector and the broadcast of a first input
1506      * scalar summed with the broadcast of a second input scalar
1507      */
1508     public abstract DoubleVector fma(double s1, double s2, VectorMask<Double> m);
1509 
1510     /**
1511      * Calculates square root of the sum of the squares of this vector and an
1512      * input vector.
1513      * More specifically as if the following (ignoring any differences in
1514      * numerical accuracy):
1515      * <pre>{@code
1516      *   this.mul(this).add(v.mul(v)).sqrt()
1517      * }</pre>
1518      * <p>
1519      * This is a vector binary operation with same semantic definition as
1520      * {@link Math#hypot} operation applied to lane elements.
1521      * The implementation is not required to return same
1522      * results as {@link Math#hypot}, but adheres to rounding, monotonicity,
1523      * and special case semantics as defined in the {@link Math#hypot}
1524      * specifications. The computed result will be within 1 ulp of the
1525      * exact result.
1526      *
1527      * @param v the input vector
1528      * @return square root of the sum of the squares of this vector and an input


1555      */
1556     public abstract DoubleVector hypot(double s);
1557 
1558     /**
1559      * Calculates square root of the sum of the squares of this vector and an
1560      * input vector, selecting lane elements controlled by a mask.
1561      * More specifically as if the following (ignoring any differences in
1562      * numerical accuracy):
1563      * <pre>{@code
1564      *   this.mul(this, m).add(v.mul(v), m).sqrt(m)
1565      * }</pre>
1566      * <p>
1567      * Semantics for rounding, monotonicity, and special cases are
1568      * described in {@link DoubleVector#hypot}
1569      *
1570      * @param v the input vector
1571      * @param m the mask controlling lane selection
1572      * @return square root of the sum of the squares of this vector and an input
1573      * vector
1574      */
1575     public DoubleVector hypot(Vector<Double> v, VectorMask<Double> m) {
1576         return bOp(v, m, (i, a, b) -> (double) Math.hypot((double) a, (double) b));
1577     }
1578 
1579     /**
1580      * Calculates square root of the sum of the squares of this vector and the
1581      * broadcast of an input scalar, selecting lane elements controlled by a
1582      * mask.
1583      * More specifically as if the following (ignoring any differences in
1584      * numerical accuracy):
1585      * <pre>{@code
1586      *   this.mul(this, m).add(this.species().broadcast(v * v), m).sqrt(m)
1587      * }</pre>
1588      * <p>
1589      * Semantics for rounding, monotonicity, and special cases are
1590      * described in {@link DoubleVector#hypot}
1591      *
1592      * @param s the input scalar
1593      * @param m the mask controlling lane selection
1594      * @return square root of the sum of the squares of this vector and the
1595      * broadcast of an input scalar
1596      */
1597     public abstract DoubleVector hypot(double s, VectorMask<Double> m);
1598 
1599 
1600     @Override
1601     public abstract void intoByteArray(byte[] a, int ix);
1602 
1603     @Override
1604     public abstract void intoByteArray(byte[] a, int ix, VectorMask<Double> m);
1605 
1606     @Override
1607     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1608 
1609     @Override
1610     public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Double> m);
1611 
1612 
1613     // Type specific horizontal reductions
1614     /**
1615      * Adds all lane elements of this vector.
1616      * <p>
1617      * This is a vector reduction operation where the addition
1618      * operation ({@code +}) is applied to lane elements,
1619      * and the identity value is {@code 0.0}.
1620      *
1621      * <p>The value of a floating-point sum is a function both of the input values as well
1622      * as the order of addition operations. The order of addition operations of this method
1623      * is intentionally not defined to allow for JVM to generate optimal machine
1624      * code for the underlying platform at runtime. If the platform supports a vector
1625      * instruction to add all values in the vector, or if there is some other efficient machine
1626      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1627      * the default implementation of adding vectors sequentially from left to right is used.
1628      * For this reason, the output of this method may vary for the same input values.
1629      *
1630      * @return the addition of all the lane elements of this vector


1634     /**
1635      * Adds all lane elements of this vector, selecting lane elements
1636      * controlled by a mask.
1637      * <p>
1638      * This is a vector reduction operation where the addition
1639      * operation ({@code +}) is applied to lane elements,
1640      * and the identity value is {@code 0.0}.
1641      *
1642      * <p>The value of a floating-point sum is a function both of the input values as well
1643      * as the order of addition operations. The order of addition operations of this method
1644      * is intentionally not defined to allow for JVM to generate optimal machine
1645      * code for the underlying platform at runtime. If the platform supports a vector
1646      * instruction to add all values in the vector, or if there is some other efficient machine
1647      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1648      * the default implementation of adding vectors sequentially from left to right is used.
1649      * For this reason, the output of this method may vary on the same input values.
1650      *
1651      * @param m the mask controlling lane selection
1652      * @return the addition of the selected lane elements of this vector
1653      */
1654     public abstract double addAll(VectorMask<Double> m);
1655 
1656     /**
1657      * Multiplies all lane elements of this vector.
1658      * <p>
1659      * This is a vector reduction operation where the
1660      * multiplication operation ({@code *}) is applied to lane elements,
1661      * and the identity value is {@code 1.0}.
1662      *
1663      * <p>The order of multiplication operations of this method
1664      * is intentionally not defined to allow for JVM to generate optimal machine
1665      * code for the underlying platform at runtime. If the platform supports a vector
1666      * instruction to multiply all values in the vector, or if there is some other efficient machine
1667      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1668      * the default implementation of multiplying vectors sequentially from left to right is used.
1669      * For this reason, the output of this method may vary on the same input values.
1670      *
1671      * @return the multiplication of all the lane elements of this vector
1672      */
1673     public abstract double mulAll();
1674 
1675     /**
1676      * Multiplies all lane elements of this vector, selecting lane elements
1677      * controlled by a mask.
1678      * <p>
1679      * This is a vector reduction operation where the
1680      * multiplication operation ({@code *}) is applied to lane elements,
1681      * and the identity value is {@code 1.0}.
1682      *
1683      * <p>The order of multiplication operations of this method
1684      * is intentionally not defined to allow for JVM to generate optimal machine
1685      * code for the underlying platform at runtime. If the platform supports a vector
1686      * instruction to multiply all values in the vector, or if there is some other efficient machine
1687      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1688      * the default implementation of multiplying vectors sequentially from left to right is used.
1689      * For this reason, the output of this method may vary on the same input values.
1690      *
1691      * @param m the mask controlling lane selection
1692      * @return the multiplication of all the lane elements of this vector
1693      */
1694     public abstract double mulAll(VectorMask<Double> m);
1695 
1696     /**
1697      * Returns the minimum lane element of this vector.
1698      * <p>
1699      * This is an associative vector reduction operation where the operation
1700      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1701      * and the identity value is
1702      * {@link Double#POSITIVE_INFINITY}.
1703      *
1704      * @return the minimum lane element of this vector
1705      */
1706     public abstract double minAll();
1707 
1708     /**
1709      * Returns the minimum lane element of this vector, selecting lane elements
1710      * controlled by a mask.
1711      * <p>
1712      * This is an associative vector reduction operation where the operation
1713      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1714      * and the identity value is
1715      * {@link Double#POSITIVE_INFINITY}.
1716      *
1717      * @param m the mask controlling lane selection
1718      * @return the minimum lane element of this vector
1719      */
1720     public abstract double minAll(VectorMask<Double> m);
1721 
1722     /**
1723      * Returns the maximum lane element of this vector.
1724      * <p>
1725      * This is an associative vector reduction operation where the operation
1726      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1727      * and the identity value is
1728      * {@link Double#NEGATIVE_INFINITY}.
1729      *
1730      * @return the maximum lane element of this vector
1731      */
1732     public abstract double maxAll();
1733 
1734     /**
1735      * Returns the maximum lane element of this vector, selecting lane elements
1736      * controlled by a mask.
1737      * <p>
1738      * This is an associative vector reduction operation where the operation
1739      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1740      * and the identity value is
1741      * {@link Double#NEGATIVE_INFINITY}.
1742      *
1743      * @param m the mask controlling lane selection
1744      * @return the maximum lane element of this vector
1745      */
1746     public abstract double maxAll(VectorMask<Double> m);
1747 
1748 
1749     // Type specific accessors
1750 
1751     /**
1752      * Gets the lane element at lane index {@code i}
1753      *
1754      * @param i the lane index
1755      * @return the lane element at lane index {@code i}
1756      * @throws IllegalArgumentException if the index is is out of range
1757      * ({@code < 0 || >= length()})
1758      */
1759     public abstract double get(int i);
1760 
1761     /**
1762      * Replaces the lane element of this vector at lane index {@code i} with
1763      * value {@code e}.
1764      * <p>
1765      * This is a cross-lane operation and behaves as if it returns the result
1766      * of blending this vector with an input vector that is the result of


1809      * @param i the offset into the array
1810      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1811      * {@code i > a.length - this.length()}
1812      */
1813     public abstract void intoArray(double[] a, int i);
1814 
1815     /**
1816      * Stores this vector into an array starting at offset and using a mask.
1817      * <p>
1818      * For each vector lane, where {@code N} is the vector lane index,
1819      * if the mask lane at index {@code N} is set then the lane element at
1820      * index {@code N} is stored into the array index {@code i + N}.
1821      *
1822      * @param a the array
1823      * @param i the offset into the array
1824      * @param m the mask
1825      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1826      * for any vector lane index {@code N} where the mask at lane {@code N}
1827      * is set {@code i >= a.length - N}
1828      */
1829     public abstract void intoArray(double[] a, int i, VectorMask<Double> m);
1830 
1831     /**
1832      * Stores this vector into an array using indexes obtained from an index
1833      * map.
1834      * <p>
1835      * For each vector lane, where {@code N} is the vector lane index, the
1836      * lane element at index {@code N} is stored into the array at index
1837      * {@code i + indexMap[j + N]}.
1838      *
1839      * @param a the array
1840      * @param i the offset into the array, may be negative if relative
1841      * indexes in the index map compensate to produce a value within the
1842      * array bounds
1843      * @param indexMap the index map
1844      * @param j the offset into the index map
1845      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1846      * {@code j > indexMap.length - this.length()},
1847      * or for any vector lane index {@code N} the result of
1848      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1849      */


1854      * map and using a mask.
1855      * <p>
1856      * For each vector lane, where {@code N} is the vector lane index,
1857      * if the mask lane at index {@code N} is set then the lane element at
1858      * index {@code N} is stored into the array at index
1859      * {@code i + indexMap[j + N]}.
1860      *
1861      * @param a the array
1862      * @param i the offset into the array, may be negative if relative
1863      * indexes in the index map compensate to produce a value within the
1864      * array bounds
1865      * @param m the mask
1866      * @param indexMap the index map
1867      * @param j the offset into the index map
1868      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1869      * {@code j > indexMap.length - this.length()},
1870      * or for any vector lane index {@code N} where the mask at lane
1871      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1872      * {@code < 0} or {@code >= a.length}
1873      */
1874     public abstract void intoArray(double[] a, int i, VectorMask<Double> m, int[] indexMap, int j);
1875     // Species
1876 
1877     @Override
1878     public abstract VectorSpecies<Double> species();
1879 
1880     /**
1881      * Class representing {@link DoubleVector}'s of the same {@link VectorShape VectorShape}.
1882      */
1883     static final class DoubleSpecies extends AbstractSpecies<Double> {
1884         final Function<double[], DoubleVector> vectorFactory;

1885 
1886         private DoubleSpecies(VectorShape shape,
1887                           Class<?> boxType,
1888                           Class<?> maskType,
1889                           Function<double[], DoubleVector> vectorFactory,
1890                           Function<boolean[], VectorMask<Double>> maskFactory,
1891                           Function<IntUnaryOperator, VectorShuffle<Double>> shuffleFromArrayFactory,
1892                           fShuffleFromArray<Double> shuffleFromOpFactory) {
1893             super(shape, double.class, Double.SIZE, boxType, maskType, maskFactory,
1894                   shuffleFromArrayFactory, shuffleFromOpFactory);
1895             this.vectorFactory = vectorFactory;

1896         }
1897 
1898         interface FOp {
1899             double apply(int i);
1900         }
1901 




1902         DoubleVector op(FOp f) {
1903             double[] res = new double[length()];
1904             for (int i = 0; i < length(); i++) {
1905                 res[i] = f.apply(i);
1906             }
1907             return vectorFactory.apply(res);
1908         }
1909 
1910         DoubleVector op(VectorMask<Double> o, FOp f) {
1911             double[] res = new double[length()];
1912             boolean[] mbits = ((AbstractMask<Double>)o).getBits();
1913             for (int i = 0; i < length(); i++) {
1914                 if (mbits[i]) {
1915                     res[i] = f.apply(i);
1916                 }
1917             }
1918             return vectorFactory.apply(res);
1919         }








1920     }
1921 
1922     /**
1923      * Finds the preferred species for an element type of {@code double}.
1924      * <p>
1925      * A preferred species is a species chosen by the platform that has a
1926      * shape of maximal bit size.  A preferred species for different element
1927      * types will have the same shape, and therefore vectors, masks, and
1928      * shuffles created from such species will be shape compatible.
1929      *
1930      * @return the preferred species for an element type of {@code double}
1931      */
1932     private static DoubleSpecies preferredSpecies() {
1933         return (DoubleSpecies) VectorSpecies.ofPreferred(double.class);
1934     }
1935 
1936     /**
1937      * Finds a species for an element type of {@code double} and shape.
1938      *
1939      * @param s the shape
1940      * @return a species for an element type of {@code double} and shape
1941      * @throws IllegalArgumentException if no such species exists for the shape
1942      */
1943     static DoubleSpecies species(VectorShape s) {
1944         Objects.requireNonNull(s);
1945         switch (s) {
1946             case S_64_BIT: return (DoubleSpecies) SPECIES_64;
1947             case S_128_BIT: return (DoubleSpecies) SPECIES_128;
1948             case S_256_BIT: return (DoubleSpecies) SPECIES_256;
1949             case S_512_BIT: return (DoubleSpecies) SPECIES_512;
1950             case S_Max_BIT: return (DoubleSpecies) SPECIES_MAX;
1951             default: throw new IllegalArgumentException("Bad shape: " + s);
1952         }
1953     }
1954 
1955     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */
1956     public static final VectorSpecies<Double> SPECIES_64 = new DoubleSpecies(VectorShape.S_64_BIT, Double64Vector.class, Double64Vector.Double64Mask.class,
1957                                                                      Double64Vector::new, Double64Vector.Double64Mask::new,
1958                                                                      Double64Vector.Double64Shuffle::new, Double64Vector.Double64Shuffle::new);
1959 
1960     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */
1961     public static final VectorSpecies<Double> SPECIES_128 = new DoubleSpecies(VectorShape.S_128_BIT, Double128Vector.class, Double128Vector.Double128Mask.class,
1962                                                                       Double128Vector::new, Double128Vector.Double128Mask::new,
1963                                                                       Double128Vector.Double128Shuffle::new, Double128Vector.Double128Shuffle::new);
1964 
1965     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */
1966     public static final VectorSpecies<Double> SPECIES_256 = new DoubleSpecies(VectorShape.S_256_BIT, Double256Vector.class, Double256Vector.Double256Mask.class,
1967                                                                       Double256Vector::new, Double256Vector.Double256Mask::new,
1968                                                                       Double256Vector.Double256Shuffle::new, Double256Vector.Double256Shuffle::new);
1969 
1970     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */
1971     public static final VectorSpecies<Double> SPECIES_512 = new DoubleSpecies(VectorShape.S_512_BIT, Double512Vector.class, Double512Vector.Double512Mask.class,
1972                                                                       Double512Vector::new, Double512Vector.Double512Mask::new,
1973                                                                       Double512Vector.Double512Shuffle::new, Double512Vector.Double512Shuffle::new);
1974 
1975     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */
1976     public static final VectorSpecies<Double> SPECIES_MAX = new DoubleSpecies(VectorShape.S_Max_BIT, DoubleMaxVector.class, DoubleMaxVector.DoubleMaxMask.class,
1977                                                                       DoubleMaxVector::new, DoubleMaxVector.DoubleMaxMask::new,
1978                                                                       DoubleMaxVector.DoubleMaxShuffle::new, DoubleMaxVector.DoubleMaxShuffle::new);
1979 
1980     /**
1981      * Preferred species for {@link DoubleVector}s.
1982      * A preferred species is a species of maximal bit size for the platform.
1983      */
1984     public static final VectorSpecies<Double> SPECIES_PREFERRED = (VectorSpecies<Double>) preferredSpecies();
1985 }
< prev index next >