1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import java.nio.ByteBuffer;
  28 import java.nio.DoubleBuffer;
  29 import java.nio.ByteOrder;
  30 import java.util.Objects;
  31 import java.util.function.IntUnaryOperator;
  32 import java.util.concurrent.ThreadLocalRandom;
  33 
  34 import jdk.internal.misc.Unsafe;
  35 import jdk.internal.vm.annotation.ForceInline;
  36 import static jdk.incubator.vector.VectorIntrinsics.*;
  37 
  38 
  39 /**
  40  * A specialized {@link Vector} representing an ordered immutable sequence of
  41  * {@code double} values.
  42  */
  43 @SuppressWarnings("cast")
  44 public abstract class DoubleVector extends Vector<Double> {
  45 
  46     DoubleVector() {}
  47 
  48     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
  49 
  50     // Unary operator
  51 
  52     interface FUnOp {
  53         double apply(int i, double a);
  54     }
  55 
  56     abstract DoubleVector uOp(FUnOp f);
  57 
  58     abstract DoubleVector uOp(Mask<Double> m, FUnOp f);
  59 
  60     // Binary operator
  61 
  62     interface FBinOp {
  63         double apply(int i, double a, double b);
  64     }
  65 
  66     abstract DoubleVector bOp(Vector<Double> v, FBinOp f);
  67 
  68     abstract DoubleVector bOp(Vector<Double> v, Mask<Double> m, FBinOp f);
  69 
  70     // Trinary operator
  71 
  72     interface FTriOp {
  73         double apply(int i, double a, double b, double c);
  74     }
  75 
  76     abstract DoubleVector tOp(Vector<Double> v1, Vector<Double> v2, FTriOp f);
  77 
  78     abstract DoubleVector tOp(Vector<Double> v1, Vector<Double> v2, Mask<Double> m, FTriOp f);
  79 
  80     // Reduction operator
  81 
  82     abstract double rOp(double v, FBinOp f);
  83 
  84     // Binary test
  85 
  86     interface FBinTest {
  87         boolean apply(int i, double a, double b);
  88     }
  89 
  90     abstract Mask<Double> bTest(Vector<Double> v, FBinTest f);
  91 
  92     // Foreach
  93 
  94     interface FUnCon {
  95         void apply(int i, double a);
  96     }
  97 
  98     abstract void forEach(FUnCon f);
  99 
 100     abstract void forEach(Mask<Double> m, FUnCon f);
 101 
 102     // Static factories
 103 
 104     /**
 105      * Returns a vector where all lane elements are set to the default
 106      * primitive value.
 107      *
 108      * @return a zero vector
 109      */
 110     @ForceInline
 111     @SuppressWarnings("unchecked")
 112     public static DoubleVector zero(DoubleSpecies species) {
 113         return species.zero();
 114     }
 115 
 116     /**
 117      * Loads a vector from a byte array starting at an offset.
 118      * <p>
 119      * Bytes are composed into primitive lane elements according to the
 120      * native byte order of the underlying platform
 121      * <p>
 122      * This method behaves as if it returns the result of calling the
 123      * byte buffer, offset, and mask accepting
 124      * {@link #fromByteBuffer(DoubleSpecies, ByteBuffer, int, Mask) method} as follows:
 125      * <pre>{@code
 126      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 127      * }</pre>
 128      *
 129      * @param a the byte array
 130      * @param ix the offset into the array
 131      * @return a vector loaded from a byte array
 132      * @throws IndexOutOfBoundsException if {@code i < 0} or
 133      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 134      */
 135     @ForceInline
 136     @SuppressWarnings("unchecked")
 137     public static DoubleVector fromByteArray(DoubleSpecies species, byte[] a, int ix) {
 138         Objects.requireNonNull(a);
 139         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 140         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 141                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 142                                      a, ix, species,
 143                                      (c, idx, s) -> {
 144                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 145                                          DoubleBuffer tb = bbc.asDoubleBuffer();
 146                                          return ((DoubleSpecies)s).op(i -> tb.get());
 147                                      });
 148     }
 149 
 150     /**
 151      * Loads a vector from a byte array starting at an offset and using a
 152      * mask.
 153      * <p>
 154      * Bytes are composed into primitive lane elements according to the
 155      * native byte order of the underlying platform.
 156      * <p>
 157      * This method behaves as if it returns the result of calling the
 158      * byte buffer, offset, and mask accepting
 159      * {@link #fromByteBuffer(DoubleSpecies, ByteBuffer, int, Mask) method} as follows:
 160      * <pre>{@code
 161      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 162      * }</pre>
 163      *
 164      * @param a the byte array
 165      * @param ix the offset into the array
 166      * @param m the mask
 167      * @return a vector loaded from a byte array
 168      * @throws IndexOutOfBoundsException if {@code i < 0} or
 169      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 170      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 171      * or {@code > a.length},
 172      * for any vector lane index {@code N} where the mask at lane {@code N}
 173      * is set
 174      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 175      */
 176     @ForceInline
 177     public static DoubleVector fromByteArray(DoubleSpecies species, byte[] a, int ix, Mask<Double> m) {
 178         return zero(species).blend(fromByteArray(species, a, ix), m);
 179     }
 180 
 181     /**
 182      * Loads a vector from an array starting at offset.
 183      * <p>
 184      * For each vector lane, where {@code N} is the vector lane index, the
 185      * array element at index {@code i + N} is placed into the
 186      * resulting vector at lane index {@code N}.
 187      *
 188      * @param a the array
 189      * @param i the offset into the array
 190      * @return the vector loaded from an array
 191      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 192      * {@code i > a.length - this.length()}
 193      */
 194     @ForceInline
 195     @SuppressWarnings("unchecked")
 196     public static DoubleVector fromArray(DoubleSpecies species, double[] a, int i){
 197         Objects.requireNonNull(a);
 198         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 199         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 200                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 201                                      a, i, species,
 202                                      (c, idx, s) -> ((DoubleSpecies)s).op(n -> c[idx + n]));
 203     }
 204 
 205 
 206     /**
 207      * Loads a vector from an array starting at offset and using a mask.
 208      * <p>
 209      * For each vector lane, where {@code N} is the vector lane index,
 210      * if the mask lane at index {@code N} is set then the array element at
 211      * index {@code i + N} is placed into the resulting vector at lane index
 212      * {@code N}, otherwise the default element value is placed into the
 213      * resulting vector at lane index {@code N}.
 214      *
 215      * @param a the array
 216      * @param i the offset into the array
 217      * @param m the mask
 218      * @return the vector loaded from an array
 219      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 220      * for any vector lane index {@code N} where the mask at lane {@code N}
 221      * is set {@code i > a.length - N}
 222      */
 223     @ForceInline
 224     public static DoubleVector fromArray(DoubleSpecies species, double[] a, int i, Mask<Double> m) {
 225         return zero(species).blend(fromArray(species, a, i), m);
 226     }
 227 
 228     /**
 229      * Loads a vector from an array using indexes obtained from an index
 230      * map.
 231      * <p>
 232      * For each vector lane, where {@code N} is the vector lane index, the
 233      * array element at index {@code i + indexMap[j + N]} is placed into the
 234      * resulting vector at lane index {@code N}.
 235      *
 236      * @param a the array
 237      * @param i the offset into the array, may be negative if relative
 238      * indexes in the index map compensate to produce a value within the
 239      * array bounds
 240      * @param indexMap the index map
 241      * @param j the offset into the index map
 242      * @return the vector loaded from an array
 243      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 244      * {@code j > indexMap.length - this.length()},
 245      * or for any vector lane index {@code N} the result of
 246      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 247      */
 248     @ForceInline
 249     @SuppressWarnings("unchecked")
 250     public static DoubleVector fromArray(DoubleSpecies species, double[] a, int i, int[] indexMap, int j) {
 251         Objects.requireNonNull(a);
 252         Objects.requireNonNull(indexMap);
 253 
 254         if (species.length() == 1) {
 255           return DoubleVector.fromArray(species, a, i + indexMap[j]);
 256         }
 257 
 258         // Index vector: vix[0:n] = k -> i + indexMap[j + i]
 259         IntVector vix = IntVector.fromArray(species.indexSpecies(), indexMap, j).add(i);
 260 
 261         vix = VectorIntrinsics.checkIndex(vix, a.length);
 262 
 263         return VectorIntrinsics.loadWithMap((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 264                                             species.indexSpecies().vectorType(), a, Unsafe.ARRAY_DOUBLE_BASE_OFFSET, vix,
 265                                             a, i, indexMap, j, species,
 266                                            (c, idx, iMap, idy, s) -> ((DoubleSpecies)s).op(n -> c[idx + iMap[idy+n]]));
 267         }
 268 
 269     /**
 270      * Loads a vector from an array using indexes obtained from an index
 271      * map and using a mask.
 272      * <p>
 273      * For each vector lane, where {@code N} is the vector lane index,
 274      * if the mask lane at index {@code N} is set then the array element at
 275      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 276      * at lane index {@code N}.
 277      *
 278      * @param a the array
 279      * @param i the offset into the array, may be negative if relative
 280      * indexes in the index map compensate to produce a value within the
 281      * array bounds
 282      * @param indexMap the index map
 283      * @param j the offset into the index map
 284      * @return the vector loaded from an array
 285      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 286      * {@code j > indexMap.length - this.length()},
 287      * or for any vector lane index {@code N} where the mask at lane
 288      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 289      * {@code < 0} or {@code >= a.length}
 290      */
 291     @ForceInline
 292     @SuppressWarnings("unchecked")
 293     public static DoubleVector fromArray(DoubleSpecies species, double[] a, int i, Mask<Double> m, int[] indexMap, int j) {
 294         // @@@ This can result in out of bounds errors for unset mask lanes
 295         return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
 296     }
 297 
 298 
 299     /**
 300      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 301      * offset into the byte buffer.
 302      * <p>
 303      * Bytes are composed into primitive lane elements according to the
 304      * native byte order of the underlying platform.
 305      * <p>
 306      * This method behaves as if it returns the result of calling the
 307      * byte buffer, offset, and mask accepting
 308      * {@link #fromByteBuffer(DoubleSpecies, ByteBuffer, int, Mask)} method} as follows:
 309      * <pre>{@code
 310      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 311      * }</pre>
 312      *
 313      * @param bb the byte buffer
 314      * @param ix the offset into the byte buffer
 315      * @return a vector loaded from a byte buffer
 316      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 317      * or {@code > b.limit()},
 318      * or if there are fewer than
 319      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 320      * remaining in the byte buffer from the given offset
 321      */
 322     @ForceInline
 323     @SuppressWarnings("unchecked")
 324     public static DoubleVector fromByteBuffer(DoubleSpecies species, ByteBuffer bb, int ix) {
 325         if (bb.order() != ByteOrder.nativeOrder()) {
 326             throw new IllegalArgumentException();
 327         }
 328         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 329         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 330                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 331                                      bb, ix, species,
 332                                      (c, idx, s) -> {
 333                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 334                                          DoubleBuffer tb = bbc.asDoubleBuffer();
 335                                          return ((DoubleSpecies)s).op(i -> tb.get());
 336                                      });
 337     }
 338 
 339     /**
 340      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 341      * offset into the byte buffer and using a mask.
 342      * <p>
 343      * This method behaves as if the byte buffer is viewed as a primitive
 344      * {@link java.nio.Buffer buffer} for the primitive element type,
 345      * according to the native byte order of the underlying platform, and
 346      * the returned vector is loaded with a mask from a primitive array
 347      * obtained from the primitive buffer.
 348      * The following pseudocode expresses the behaviour, where
 349      * {@coce EBuffer} is the primitive buffer type, {@code e} is the
 350      * primitive element type, and {@code ESpecies<S>} is the primitive
 351      * species for {@code e}:
 352      * <pre>{@code
 353      * EBuffer eb = b.duplicate().
 354      *     order(ByteOrder.nativeOrder()).position(i).
 355      *     asEBuffer();
 356      * e[] es = new e[this.length()];
 357      * for (int n = 0; n < t.length; n++) {
 358      *     if (m.isSet(n))
 359      *         es[n] = eb.get(n);
 360      * }
 361      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 362      * }</pre>
 363      *
 364      * @param bb the byte buffer
 365      * @param ix the offset into the byte buffer
 366      * @return a vector loaded from a byte buffer
 367      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 368      * or {@code > b.limit()},
 369      * for any vector lane index {@code N} where the mask at lane {@code N}
 370      * is set
 371      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 372      */
 373     @ForceInline
 374     public static DoubleVector fromByteBuffer(DoubleSpecies species, ByteBuffer bb, int ix, Mask<Double> m) {
 375         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 376     }
 377 
 378     @ForceInline
 379     public static Mask<Double> maskFromValues(DoubleSpecies species, boolean... bits) {
 380         if (species.boxType() == DoubleMaxVector.class)
 381             return new DoubleMaxVector.DoubleMaxMask(bits);
 382         switch (species.bitSize()) {
 383             case 64: return new Double64Vector.Double64Mask(bits);
 384             case 128: return new Double128Vector.Double128Mask(bits);
 385             case 256: return new Double256Vector.Double256Mask(bits);
 386             case 512: return new Double512Vector.Double512Mask(bits);
 387             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 388         }
 389     }
 390 
 391     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 392     static Mask<Double> trueMask(DoubleSpecies species) {
 393         if (species.boxType() == DoubleMaxVector.class)
 394             return DoubleMaxVector.DoubleMaxMask.TRUE_MASK;
 395         switch (species.bitSize()) {
 396             case 64: return Double64Vector.Double64Mask.TRUE_MASK;
 397             case 128: return Double128Vector.Double128Mask.TRUE_MASK;
 398             case 256: return Double256Vector.Double256Mask.TRUE_MASK;
 399             case 512: return Double512Vector.Double512Mask.TRUE_MASK;
 400             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 401         }
 402     }
 403 
 404     static Mask<Double> falseMask(DoubleSpecies species) {
 405         if (species.boxType() == DoubleMaxVector.class)
 406             return DoubleMaxVector.DoubleMaxMask.FALSE_MASK;
 407         switch (species.bitSize()) {
 408             case 64: return Double64Vector.Double64Mask.FALSE_MASK;
 409             case 128: return Double128Vector.Double128Mask.FALSE_MASK;
 410             case 256: return Double256Vector.Double256Mask.FALSE_MASK;
 411             case 512: return Double512Vector.Double512Mask.FALSE_MASK;
 412             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 413         }
 414     }
 415 
 416     @ForceInline
 417     @SuppressWarnings("unchecked")
 418     public static Mask<Double> maskFromArray(DoubleSpecies species, boolean[] bits, int ix) {
 419         Objects.requireNonNull(bits);
 420         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 421         return VectorIntrinsics.load((Class<Mask<Double>>) species.maskType(), long.class, species.length(),
 422                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 423                                      bits, ix, species,
 424                                      (c, idx, s) -> (Mask<Double>) ((DoubleSpecies)s).opm(n -> c[idx + n]));
 425     }
 426 
 427     @ForceInline
 428     @SuppressWarnings("unchecked")
 429     public static Mask<Double> maskAllTrue(DoubleSpecies species) {
 430         return VectorIntrinsics.broadcastCoerced((Class<Mask<Double>>) species.maskType(), long.class, species.length(),
 431                                                  (long)-1,  species,
 432                                                  ((z, s) -> trueMask((DoubleSpecies)s)));
 433     }
 434 
 435     @ForceInline
 436     @SuppressWarnings("unchecked")
 437     public static Mask<Double> maskAllFalse(DoubleSpecies species) {
 438         return VectorIntrinsics.broadcastCoerced((Class<Mask<Double>>) species.maskType(), long.class, species.length(),
 439                                                  0, species, 
 440                                                  ((z, s) -> falseMask((DoubleSpecies)s)));
 441     }
 442 
 443     @ForceInline
 444     public static Shuffle<Double> shuffle(DoubleSpecies species, IntUnaryOperator f) {
 445         if (species.boxType() == DoubleMaxVector.class)
 446             return new DoubleMaxVector.DoubleMaxShuffle(f);
 447         switch (species.bitSize()) {
 448             case 64: return new Double64Vector.Double64Shuffle(f);
 449             case 128: return new Double128Vector.Double128Shuffle(f);
 450             case 256: return new Double256Vector.Double256Shuffle(f);
 451             case 512: return new Double512Vector.Double512Shuffle(f);
 452             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 453         }
 454     }
 455 
 456     @ForceInline
 457     public static Shuffle<Double> shuffleIota(DoubleSpecies species) {
 458         if (species.boxType() == DoubleMaxVector.class)
 459             return new DoubleMaxVector.DoubleMaxShuffle(AbstractShuffle.IDENTITY);
 460         switch (species.bitSize()) {
 461             case 64: return new Double64Vector.Double64Shuffle(AbstractShuffle.IDENTITY);
 462             case 128: return new Double128Vector.Double128Shuffle(AbstractShuffle.IDENTITY);
 463             case 256: return new Double256Vector.Double256Shuffle(AbstractShuffle.IDENTITY);
 464             case 512: return new Double512Vector.Double512Shuffle(AbstractShuffle.IDENTITY);
 465             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 466         }
 467     }
 468 
 469     @ForceInline
 470     public static Shuffle<Double> shuffleFromValues(DoubleSpecies species, int... ixs) {
 471         if (species.boxType() == DoubleMaxVector.class)
 472             return new DoubleMaxVector.DoubleMaxShuffle(ixs);
 473         switch (species.bitSize()) {
 474             case 64: return new Double64Vector.Double64Shuffle(ixs);
 475             case 128: return new Double128Vector.Double128Shuffle(ixs);
 476             case 256: return new Double256Vector.Double256Shuffle(ixs);
 477             case 512: return new Double512Vector.Double512Shuffle(ixs);
 478             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 479         }
 480     }
 481 
 482     @ForceInline
 483     public static Shuffle<Double> shuffleFromArray(DoubleSpecies species, int[] ixs, int i) {
 484         if (species.boxType() == DoubleMaxVector.class)
 485             return new DoubleMaxVector.DoubleMaxShuffle(ixs, i);
 486         switch (species.bitSize()) {
 487             case 64: return new Double64Vector.Double64Shuffle(ixs, i);
 488             case 128: return new Double128Vector.Double128Shuffle(ixs, i);
 489             case 256: return new Double256Vector.Double256Shuffle(ixs, i);
 490             case 512: return new Double512Vector.Double512Shuffle(ixs, i);
 491             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 492         }
 493     }
 494 
 495 
 496     // Ops
 497 
 498     @Override
 499     public abstract DoubleVector add(Vector<Double> v);
 500 
 501     /**
 502      * Adds this vector to the broadcast of an input scalar.
 503      * <p>
 504      * This is a vector binary operation where the primitive addition operation
 505      * ({@code +}) is applied to lane elements.
 506      *
 507      * @param s the input scalar
 508      * @return the result of adding this vector to the broadcast of an input
 509      * scalar
 510      */
 511     public abstract DoubleVector add(double s);
 512 
 513     @Override
 514     public abstract DoubleVector add(Vector<Double> v, Mask<Double> m);
 515 
 516     /**
 517      * Adds this vector to broadcast of an input scalar,
 518      * selecting lane elements controlled by a mask.
 519      * <p>
 520      * This is a vector binary operation where the primitive addition operation
 521      * ({@code +}) is applied to lane elements.
 522      *
 523      * @param s the input scalar
 524      * @param m the mask controlling lane selection
 525      * @return the result of adding this vector to the broadcast of an input
 526      * scalar
 527      */
 528     public abstract DoubleVector add(double s, Mask<Double> m);
 529 
 530     @Override
 531     public abstract DoubleVector sub(Vector<Double> v);
 532 
 533     /**
 534      * Subtracts the broadcast of an input scalar from this vector.
 535      * <p>
 536      * This is a vector binary operation where the primitive subtraction
 537      * operation ({@code -}) is applied to lane elements.
 538      *
 539      * @param s the input scalar
 540      * @return the result of subtracting the broadcast of an input
 541      * scalar from this vector
 542      */
 543     public abstract DoubleVector sub(double s);
 544 
 545     @Override
 546     public abstract DoubleVector sub(Vector<Double> v, Mask<Double> m);
 547 
 548     /**
 549      * Subtracts the broadcast of an input scalar from this vector, selecting
 550      * lane elements controlled by a mask.
 551      * <p>
 552      * This is a vector binary operation where the primitive subtraction
 553      * operation ({@code -}) is applied to lane elements.
 554      *
 555      * @param s the input scalar
 556      * @param m the mask controlling lane selection
 557      * @return the result of subtracting the broadcast of an input
 558      * scalar from this vector
 559      */
 560     public abstract DoubleVector sub(double s, Mask<Double> m);
 561 
 562     @Override
 563     public abstract DoubleVector mul(Vector<Double> v);
 564 
 565     /**
 566      * Multiplies this vector with the broadcast of an input scalar.
 567      * <p>
 568      * This is a vector binary operation where the primitive multiplication
 569      * operation ({@code *}) is applied to lane elements.
 570      *
 571      * @param s the input scalar
 572      * @return the result of multiplying this vector with the broadcast of an
 573      * input scalar
 574      */
 575     public abstract DoubleVector mul(double s);
 576 
 577     @Override
 578     public abstract DoubleVector mul(Vector<Double> v, Mask<Double> m);
 579 
 580     /**
 581      * Multiplies this vector with the broadcast of an input scalar, selecting
 582      * lane elements controlled by a mask.
 583      * <p>
 584      * This is a vector binary operation where the primitive multiplication
 585      * operation ({@code *}) is applied to lane elements.
 586      *
 587      * @param s the input scalar
 588      * @param m the mask controlling lane selection
 589      * @return the result of multiplying this vector with the broadcast of an
 590      * input scalar
 591      */
 592     public abstract DoubleVector mul(double s, Mask<Double> m);
 593 
 594     @Override
 595     public abstract DoubleVector neg();
 596 
 597     @Override
 598     public abstract DoubleVector neg(Mask<Double> m);
 599 
 600     @Override
 601     public abstract DoubleVector abs();
 602 
 603     @Override
 604     public abstract DoubleVector abs(Mask<Double> m);
 605 
 606     @Override
 607     public abstract DoubleVector min(Vector<Double> v);
 608 
 609     @Override
 610     public abstract DoubleVector min(Vector<Double> v, Mask<Double> m);
 611 
 612     /**
 613      * Returns the minimum of this vector and the broadcast of an input scalar.
 614      * <p>
 615      * This is a vector binary operation where the operation
 616      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 617      *
 618      * @param s the input scalar
 619      * @return the minimum of this vector and the broadcast of an input scalar
 620      */
 621     public abstract DoubleVector min(double s);
 622 
 623     @Override
 624     public abstract DoubleVector max(Vector<Double> v);
 625 
 626     @Override
 627     public abstract DoubleVector max(Vector<Double> v, Mask<Double> m);
 628 
 629     /**
 630      * Returns the maximum of this vector and the broadcast of an input scalar.
 631      * <p>
 632      * This is a vector binary operation where the operation
 633      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 634      *
 635      * @param s the input scalar
 636      * @return the maximum of this vector and the broadcast of an input scalar
 637      */
 638     public abstract DoubleVector max(double s);
 639 
 640     @Override
 641     public abstract Mask<Double> equal(Vector<Double> v);
 642 
 643     /**
 644      * Tests if this vector is equal to the broadcast of an input scalar.
 645      * <p>
 646      * This is a vector binary test operation where the primitive equals
 647      * operation ({@code ==}) is applied to lane elements.
 648      *
 649      * @param s the input scalar
 650      * @return the result mask of testing if this vector is equal to the
 651      * broadcast of an input scalar
 652      */
 653     public abstract Mask<Double> equal(double s);
 654 
 655     @Override
 656     public abstract Mask<Double> notEqual(Vector<Double> v);
 657 
 658     /**
 659      * Tests if this vector is not equal to the broadcast of an input scalar.
 660      * <p>
 661      * This is a vector binary test operation where the primitive not equals
 662      * operation ({@code !=}) is applied to lane elements.
 663      *
 664      * @param s the input scalar
 665      * @return the result mask of testing if this vector is not equal to the
 666      * broadcast of an input scalar
 667      */
 668     public abstract Mask<Double> notEqual(double s);
 669 
 670     @Override
 671     public abstract Mask<Double> lessThan(Vector<Double> v);
 672 
 673     /**
 674      * Tests if this vector is less than the broadcast of an input scalar.
 675      * <p>
 676      * This is a vector binary test operation where the primitive less than
 677      * operation ({@code <}) is applied to lane elements.
 678      *
 679      * @param s the input scalar
 680      * @return the mask result of testing if this vector is less than the
 681      * broadcast of an input scalar
 682      */
 683     public abstract Mask<Double> lessThan(double s);
 684 
 685     @Override
 686     public abstract Mask<Double> lessThanEq(Vector<Double> v);
 687 
 688     /**
 689      * Tests if this vector is less or equal to the broadcast of an input scalar.
 690      * <p>
 691      * This is a vector binary test operation where the primitive less than
 692      * or equal to operation ({@code <=}) is applied to lane elements.
 693      *
 694      * @param s the input scalar
 695      * @return the mask result of testing if this vector is less than or equal
 696      * to the broadcast of an input scalar
 697      */
 698     public abstract Mask<Double> lessThanEq(double s);
 699 
 700     @Override
 701     public abstract Mask<Double> greaterThan(Vector<Double> v);
 702 
 703     /**
 704      * Tests if this vector is greater than the broadcast of an input scalar.
 705      * <p>
 706      * This is a vector binary test operation where the primitive greater than
 707      * operation ({@code >}) is applied to lane elements.
 708      *
 709      * @param s the input scalar
 710      * @return the mask result of testing if this vector is greater than the
 711      * broadcast of an input scalar
 712      */
 713     public abstract Mask<Double> greaterThan(double s);
 714 
 715     @Override
 716     public abstract Mask<Double> greaterThanEq(Vector<Double> v);
 717 
 718     /**
 719      * Tests if this vector is greater than or equal to the broadcast of an
 720      * input scalar.
 721      * <p>
 722      * This is a vector binary test operation where the primitive greater than
 723      * or equal to operation ({@code >=}) is applied to lane elements.
 724      *
 725      * @param s the input scalar
 726      * @return the mask result of testing if this vector is greater than or
 727      * equal to the broadcast of an input scalar
 728      */
 729     public abstract Mask<Double> greaterThanEq(double s);
 730 
 731     @Override
 732     public abstract DoubleVector blend(Vector<Double> v, Mask<Double> m);
 733 
 734     /**
 735      * Blends the lane elements of this vector with those of the broadcast of an
 736      * input scalar, selecting lanes controlled by a mask.
 737      * <p>
 738      * For each lane of the mask, at lane index {@code N}, if the mask lane
 739      * is set then the lane element at {@code N} from the input vector is
 740      * selected and placed into the resulting vector at {@code N},
 741      * otherwise the the lane element at {@code N} from this input vector is
 742      * selected and placed into the resulting vector at {@code N}.
 743      *
 744      * @param s the input scalar
 745      * @param m the mask controlling lane selection
 746      * @return the result of blending the lane elements of this vector with
 747      * those of the broadcast of an input scalar
 748      */
 749     public abstract DoubleVector blend(double s, Mask<Double> m);
 750 
 751     @Override
 752     public abstract DoubleVector rearrange(Vector<Double> v,
 753                                                       Shuffle<Double> s, Mask<Double> m);
 754 
 755     @Override
 756     public abstract DoubleVector rearrange(Shuffle<Double> m);
 757 
 758     @Override
 759     public abstract DoubleVector reshape(Species<Double> s);
 760 
 761     @Override
 762     public abstract DoubleVector rotateEL(int i);
 763 
 764     @Override
 765     public abstract DoubleVector rotateER(int i);
 766 
 767     @Override
 768     public abstract DoubleVector shiftEL(int i);
 769 
 770     @Override
 771     public abstract DoubleVector shiftER(int i);
 772 
 773     /**
 774      * Divides this vector by an input vector.
 775      * <p>
 776      * This is a vector binary operation where the primitive division
 777      * operation ({@code /}) is applied to lane elements.
 778      *
 779      * @param v the input vector
 780      * @return the result of dividing this vector by the input vector
 781      */
 782     public abstract DoubleVector div(Vector<Double> v);
 783 
 784     /**
 785      * Divides this vector by the broadcast of an input scalar.
 786      * <p>
 787      * This is a vector binary operation where the primitive division
 788      * operation ({@code /}) is applied to lane elements.
 789      *
 790      * @param s the input scalar
 791      * @return the result of dividing this vector by the broadcast of an input
 792      * scalar
 793      */
 794     public abstract DoubleVector div(double s);
 795 
 796     /**
 797      * Divides this vector by an input vector, selecting lane elements
 798      * controlled by a mask.
 799      * <p>
 800      * This is a vector binary operation where the primitive division
 801      * operation ({@code /}) is applied to lane elements.
 802      *
 803      * @param v the input vector
 804      * @param m the mask controlling lane selection
 805      * @return the result of dividing this vector by the input vector
 806      */
 807     public abstract DoubleVector div(Vector<Double> v, Mask<Double> m);
 808 
 809     /**
 810      * Divides this vector by the broadcast of an input scalar, selecting lane
 811      * elements controlled by a mask.
 812      * <p>
 813      * This is a vector binary operation where the primitive division
 814      * operation ({@code /}) is applied to lane elements.
 815      *
 816      * @param s the input scalar
 817      * @param m the mask controlling lane selection
 818      * @return the result of dividing this vector by the broadcast of an input
 819      * scalar
 820      */
 821     public abstract DoubleVector div(double s, Mask<Double> m);
 822 
 823     /**
 824      * Calculates the square root of this vector.
 825      * <p>
 826      * This is a vector unary operation where the {@link Math#sqrt} operation
 827      * is applied to lane elements.
 828      *
 829      * @return the square root of this vector
 830      */
 831     public abstract DoubleVector sqrt();
 832 
 833     /**
 834      * Calculates the square root of this vector, selecting lane elements
 835      * controlled by a mask.
 836      * <p>
 837      * This is a vector unary operation where the {@link Math#sqrt} operation
 838      * is applied to lane elements.
 839      *
 840      * @param m the mask controlling lane selection
 841      * @return the square root of this vector
 842      */
 843     public DoubleVector sqrt(Mask<Double> m) {
 844         return uOp(m, (i, a) -> (double) Math.sqrt((double) a));
 845     }
 846 
 847     /**
 848      * Calculates the trigonometric tangent of this vector.
 849      * <p>
 850      * This is a vector unary operation with same semantic definition as
 851      * {@link Math#tan} operation applied to lane elements.
 852      * The implementation is not required to return same
 853      * results as {@link Math#tan}, but adheres to rounding, monotonicity,
 854      * and special case semantics as defined in the {@link Math#tan}
 855      * specifications. The computed result will be within 1 ulp of the
 856      * exact result.
 857      *
 858      * @return the tangent of this vector
 859      */
 860     public DoubleVector tan() {
 861         return uOp((i, a) -> (double) Math.tan((double) a));
 862     }
 863 
 864     /**
 865      * Calculates the trigonometric tangent of this vector, selecting lane
 866      * elements controlled by a mask.
 867      * <p>
 868      * Semantics for rounding, monotonicity, and special cases are
 869      * described in {@link DoubleVector#tan}
 870      *
 871      * @param m the mask controlling lane selection
 872      * @return the tangent of this vector
 873      */
 874     public DoubleVector tan(Mask<Double> m) {
 875         return uOp(m, (i, a) -> (double) Math.tan((double) a));
 876     }
 877 
 878     /**
 879      * Calculates the hyperbolic tangent of this vector.
 880      * <p>
 881      * This is a vector unary operation with same semantic definition as
 882      * {@link Math#tanh} operation applied to lane elements.
 883      * The implementation is not required to return same
 884      * results as {@link Math#tanh}, but adheres to rounding, monotonicity,
 885      * and special case semantics as defined in the {@link Math#tanh}
 886      * specifications. The computed result will be within 2.5 ulps of the
 887      * exact result.
 888      *
 889      * @return the hyperbolic tangent of this vector
 890      */
 891     public DoubleVector tanh() {
 892         return uOp((i, a) -> (double) Math.tanh((double) a));
 893     }
 894 
 895     /**
 896      * Calculates the hyperbolic tangent of this vector, selecting lane elements
 897      * controlled by a mask.
 898      * <p>
 899      * Semantics for rounding, monotonicity, and special cases are
 900      * described in {@link DoubleVector#tanh}
 901      *
 902      * @param m the mask controlling lane selection
 903      * @return the hyperbolic tangent of this vector
 904      */
 905     public DoubleVector tanh(Mask<Double> m) {
 906         return uOp(m, (i, a) -> (double) Math.tanh((double) a));
 907     }
 908 
 909     /**
 910      * Calculates the trigonometric sine of this vector.
 911      * <p>
 912      * This is a vector unary operation with same semantic definition as
 913      * {@link Math#sin} operation applied to lane elements.
 914      * The implementation is not required to return same
 915      * results as {@link Math#sin}, but adheres to rounding, monotonicity,
 916      * and special case semantics as defined in the {@link Math#sin}
 917      * specifications. The computed result will be within 1 ulp of the
 918      * exact result.
 919      *
 920      * @return the sine of this vector
 921      */
 922     public DoubleVector sin() {
 923         return uOp((i, a) -> (double) Math.sin((double) a));
 924     }
 925 
 926     /**
 927      * Calculates the trigonometric sine of this vector, selecting lane elements
 928      * controlled by a mask.
 929      * <p>
 930      * Semantics for rounding, monotonicity, and special cases are
 931      * described in {@link DoubleVector#sin}
 932      *
 933      * @param m the mask controlling lane selection
 934      * @return the sine of this vector
 935      */
 936     public DoubleVector sin(Mask<Double> m) {
 937         return uOp(m, (i, a) -> (double) Math.sin((double) a));
 938     }
 939 
 940     /**
 941      * Calculates the hyperbolic sine of this vector.
 942      * <p>
 943      * This is a vector unary operation with same semantic definition as
 944      * {@link Math#sinh} operation applied to lane elements.
 945      * The implementation is not required to return same
 946      * results as  {@link Math#sinh}, but adheres to rounding, monotonicity,
 947      * and special case semantics as defined in the {@link Math#sinh}
 948      * specifications. The computed result will be within 2.5 ulps of the
 949      * exact result.
 950      *
 951      * @return the hyperbolic sine of this vector
 952      */
 953     public DoubleVector sinh() {
 954         return uOp((i, a) -> (double) Math.sinh((double) a));
 955     }
 956 
 957     /**
 958      * Calculates the hyperbolic sine of this vector, selecting lane elements
 959      * controlled by a mask.
 960      * <p>
 961      * Semantics for rounding, monotonicity, and special cases are
 962      * described in {@link DoubleVector#sinh}
 963      *
 964      * @param m the mask controlling lane selection
 965      * @return the hyperbolic sine of this vector
 966      */
 967     public DoubleVector sinh(Mask<Double> m) {
 968         return uOp(m, (i, a) -> (double) Math.sinh((double) a));
 969     }
 970 
 971     /**
 972      * Calculates the trigonometric cosine of this vector.
 973      * <p>
 974      * This is a vector unary operation with same semantic definition as
 975      * {@link Math#cos} operation applied to lane elements.
 976      * The implementation is not required to return same
 977      * results as {@link Math#cos}, but adheres to rounding, monotonicity,
 978      * and special case semantics as defined in the {@link Math#cos}
 979      * specifications. The computed result will be within 1 ulp of the
 980      * exact result.
 981      *
 982      * @return the cosine of this vector
 983      */
 984     public DoubleVector cos() {
 985         return uOp((i, a) -> (double) Math.cos((double) a));
 986     }
 987 
 988     /**
 989      * Calculates the trigonometric cosine of this vector, selecting lane
 990      * elements controlled by a mask.
 991      * <p>
 992      * Semantics for rounding, monotonicity, and special cases are
 993      * described in {@link DoubleVector#cos}
 994      *
 995      * @param m the mask controlling lane selection
 996      * @return the cosine of this vector
 997      */
 998     public DoubleVector cos(Mask<Double> m) {
 999         return uOp(m, (i, a) -> (double) Math.cos((double) a));
1000     }
1001 
1002     /**
1003      * Calculates the hyperbolic cosine of this vector.
1004      * <p>
1005      * This is a vector unary operation with same semantic definition as
1006      * {@link Math#cosh} operation applied to lane elements.
1007      * The implementation is not required to return same
1008      * results as {@link Math#cosh}, but adheres to rounding, monotonicity,
1009      * and special case semantics as defined in the {@link Math#cosh}
1010      * specifications. The computed result will be within 2.5 ulps of the
1011      * exact result.
1012      *
1013      * @return the hyperbolic cosine of this vector
1014      */
1015     public DoubleVector cosh() {
1016         return uOp((i, a) -> (double) Math.cosh((double) a));
1017     }
1018 
1019     /**
1020      * Calculates the hyperbolic cosine of this vector, selecting lane elements
1021      * controlled by a mask.
1022      * <p>
1023      * Semantics for rounding, monotonicity, and special cases are
1024      * described in {@link DoubleVector#cosh}
1025      *
1026      * @param m the mask controlling lane selection
1027      * @return the hyperbolic cosine of this vector
1028      */
1029     public DoubleVector cosh(Mask<Double> m) {
1030         return uOp(m, (i, a) -> (double) Math.cosh((double) a));
1031     }
1032 
1033     /**
1034      * Calculates the arc sine of this vector.
1035      * <p>
1036      * This is a vector unary operation with same semantic definition as
1037      * {@link Math#asin} operation applied to lane elements.
1038      * The implementation is not required to return same
1039      * results as {@link Math#asin}, but adheres to rounding, monotonicity,
1040      * and special case semantics as defined in the {@link Math#asin}
1041      * specifications. The computed result will be within 1 ulp of the
1042      * exact result.
1043      *
1044      * @return the arc sine of this vector
1045      */
1046     public DoubleVector asin() {
1047         return uOp((i, a) -> (double) Math.asin((double) a));
1048     }
1049 
1050     /**
1051      * Calculates the arc sine of this vector, selecting lane elements
1052      * controlled by a mask.
1053      * <p>
1054      * Semantics for rounding, monotonicity, and special cases are
1055      * described in {@link DoubleVector#asin}
1056      *
1057      * @param m the mask controlling lane selection
1058      * @return the arc sine of this vector
1059      */
1060     public DoubleVector asin(Mask<Double> m) {
1061         return uOp(m, (i, a) -> (double) Math.asin((double) a));
1062     }
1063 
1064     /**
1065      * Calculates the arc cosine of this vector.
1066      * <p>
1067      * This is a vector unary operation with same semantic definition as
1068      * {@link Math#acos} operation applied to lane elements.
1069      * The implementation is not required to return same
1070      * results as {@link Math#acos}, but adheres to rounding, monotonicity,
1071      * and special case semantics as defined in the {@link Math#acos}
1072      * specifications. The computed result will be within 1 ulp of the
1073      * exact result.
1074      *
1075      * @return the arc cosine of this vector
1076      */
1077     public DoubleVector acos() {
1078         return uOp((i, a) -> (double) Math.acos((double) a));
1079     }
1080 
1081     /**
1082      * Calculates the arc cosine of this vector, selecting lane elements
1083      * controlled by a mask.
1084      * <p>
1085      * Semantics for rounding, monotonicity, and special cases are
1086      * described in {@link DoubleVector#acos}
1087      *
1088      * @param m the mask controlling lane selection
1089      * @return the arc cosine of this vector
1090      */
1091     public DoubleVector acos(Mask<Double> m) {
1092         return uOp(m, (i, a) -> (double) Math.acos((double) a));
1093     }
1094 
1095     /**
1096      * Calculates the arc tangent of this vector.
1097      * <p>
1098      * This is a vector unary operation with same semantic definition as
1099      * {@link Math#atan} operation applied to lane elements.
1100      * The implementation is not required to return same
1101      * results as {@link Math#atan}, but adheres to rounding, monotonicity,
1102      * and special case semantics as defined in the {@link Math#atan}
1103      * specifications. The computed result will be within 1 ulp of the
1104      * exact result.
1105      *
1106      * @return the arc tangent of this vector
1107      */
1108     public DoubleVector atan() {
1109         return uOp((i, a) -> (double) Math.atan((double) a));
1110     }
1111 
1112     /**
1113      * Calculates the arc tangent of this vector, selecting lane elements
1114      * controlled by a mask.
1115      * <p>
1116      * Semantics for rounding, monotonicity, and special cases are
1117      * described in {@link DoubleVector#atan}
1118      *
1119      * @param m the mask controlling lane selection
1120      * @return the arc tangent of this vector
1121      */
1122     public DoubleVector atan(Mask<Double> m) {
1123         return uOp(m, (i, a) -> (double) Math.atan((double) a));
1124     }
1125 
1126     /**
1127      * Calculates the arc tangent of this vector divided by an input vector.
1128      * <p>
1129      * This is a vector binary operation with same semantic definition as
1130      * {@link Math#atan2} operation applied to lane elements.
1131      * The implementation is not required to return same
1132      * results as {@link Math#atan2}, but adheres to rounding, monotonicity,
1133      * and special case semantics as defined in the {@link Math#atan2}
1134      * specifications. The computed result will be within 2 ulps of the
1135      * exact result.
1136      *
1137      * @param v the input vector
1138      * @return the arc tangent of this vector divided by the input vector
1139      */
1140     public DoubleVector atan2(Vector<Double> v) {
1141         return bOp(v, (i, a, b) -> (double) Math.atan2((double) a, (double) b));
1142     }
1143 
1144     /**
1145      * Calculates the arc tangent of this vector divided by the broadcast of an
1146      * an input scalar.
1147      * <p>
1148      * This is a vector binary operation with same semantic definition as
1149      * {@link Math#atan2} operation applied to lane elements.
1150      * The implementation is not required to return same
1151      * results as {@link Math#atan2}, but adheres to rounding, monotonicity,
1152      * and special case semantics as defined in the {@link Math#atan2}
1153      * specifications. The computed result will be within 1 ulp of the
1154      * exact result.
1155      *
1156      * @param s the input scalar
1157      * @return the arc tangent of this vector over the input vector
1158      */
1159     public abstract DoubleVector atan2(double s);
1160 
1161     /**
1162      * Calculates the arc tangent of this vector divided by an input vector,
1163      * selecting lane elements controlled by a mask.
1164      * <p>
1165      * Semantics for rounding, monotonicity, and special cases are
1166      * described in {@link DoubleVector#atan2}
1167      *
1168      * @param v the input vector
1169      * @param m the mask controlling lane selection
1170      * @return the arc tangent of this vector divided by the input vector
1171      */
1172     public DoubleVector atan2(Vector<Double> v, Mask<Double> m) {
1173         return bOp(v, m, (i, a, b) -> (double) Math.atan2((double) a, (double) b));
1174     }
1175 
1176     /**
1177      * Calculates the arc tangent of this vector divided by the broadcast of an
1178      * an input scalar, selecting lane elements controlled by a mask.
1179      * <p>
1180      * Semantics for rounding, monotonicity, and special cases are
1181      * described in {@link DoubleVector#atan2}
1182      *
1183      * @param s the input scalar
1184      * @param m the mask controlling lane selection
1185      * @return the arc tangent of this vector over the input vector
1186      */
1187     public abstract DoubleVector atan2(double s, Mask<Double> m);
1188 
1189     /**
1190      * Calculates the cube root of this vector.
1191      * <p>
1192      * This is a vector unary operation with same semantic definition as
1193      * {@link Math#cbrt} operation applied to lane elements.
1194      * The implementation is not required to return same
1195      * results as {@link Math#cbrt}, but adheres to rounding, monotonicity,
1196      * and special case semantics as defined in the {@link Math#cbrt}
1197      * specifications. The computed result will be within 1 ulp of the
1198      * exact result.
1199      *
1200      * @return the cube root of this vector
1201      */
1202     public DoubleVector cbrt() {
1203         return uOp((i, a) -> (double) Math.cbrt((double) a));
1204     }
1205 
1206     /**
1207      * Calculates the cube root of this vector, selecting lane elements
1208      * controlled by a mask.
1209      * <p>
1210      * Semantics for rounding, monotonicity, and special cases are
1211      * described in {@link DoubleVector#cbrt}
1212      *
1213      * @param m the mask controlling lane selection
1214      * @return the cube root of this vector
1215      */
1216     public DoubleVector cbrt(Mask<Double> m) {
1217         return uOp(m, (i, a) -> (double) Math.cbrt((double) a));
1218     }
1219 
1220     /**
1221      * Calculates the natural logarithm of this vector.
1222      * <p>
1223      * This is a vector unary operation with same semantic definition as
1224      * {@link Math#log} operation applied to lane elements.
1225      * The implementation is not required to return same
1226      * results as {@link Math#log}, but adheres to rounding, monotonicity,
1227      * and special case semantics as defined in the {@link Math#log}
1228      * specifications. The computed result will be within 1 ulp of the
1229      * exact result.
1230      *
1231      * @return the natural logarithm of this vector
1232      */
1233     public DoubleVector log() {
1234         return uOp((i, a) -> (double) Math.log((double) a));
1235     }
1236 
1237     /**
1238      * Calculates the natural logarithm of this vector, selecting lane elements
1239      * controlled by a mask.
1240      * <p>
1241      * Semantics for rounding, monotonicity, and special cases are
1242      * described in {@link DoubleVector#log}
1243      *
1244      * @param m the mask controlling lane selection
1245      * @return the natural logarithm of this vector
1246      */
1247     public DoubleVector log(Mask<Double> m) {
1248         return uOp(m, (i, a) -> (double) Math.log((double) a));
1249     }
1250 
1251     /**
1252      * Calculates the base 10 logarithm of this vector.
1253      * <p>
1254      * This is a vector unary operation with same semantic definition as
1255      * {@link Math#log10} operation applied to lane elements.
1256      * The implementation is not required to return same
1257      * results as {@link Math#log10}, but adheres to rounding, monotonicity,
1258      * and special case semantics as defined in the {@link Math#log10}
1259      * specifications. The computed result will be within 1 ulp of the
1260      * exact result.
1261      *
1262      * @return the base 10 logarithm of this vector
1263      */
1264     public DoubleVector log10() {
1265         return uOp((i, a) -> (double) Math.log10((double) a));
1266     }
1267 
1268     /**
1269      * Calculates the base 10 logarithm of this vector, selecting lane elements
1270      * controlled by a mask.
1271      * <p>
1272      * Semantics for rounding, monotonicity, and special cases are
1273      * described in {@link DoubleVector#log10}
1274      *
1275      * @param m the mask controlling lane selection
1276      * @return the base 10 logarithm of this vector
1277      */
1278     public DoubleVector log10(Mask<Double> m) {
1279         return uOp(m, (i, a) -> (double) Math.log10((double) a));
1280     }
1281 
1282     /**
1283      * Calculates the natural logarithm of the sum of this vector and the
1284      * broadcast of {@code 1}.
1285      * <p>
1286      * This is a vector unary operation with same semantic definition as
1287      * {@link Math#log1p} operation applied to lane elements.
1288      * The implementation is not required to return same
1289      * results as  {@link Math#log1p}, but adheres to rounding, monotonicity,
1290      * and special case semantics as defined in the {@link Math#log1p}
1291      * specifications. The computed result will be within 1 ulp of the
1292      * exact result.
1293      *
1294      * @return the natural logarithm of the sum of this vector and the broadcast
1295      * of {@code 1}
1296      */
1297     public DoubleVector log1p() {
1298         return uOp((i, a) -> (double) Math.log1p((double) a));
1299     }
1300 
1301     /**
1302      * Calculates the natural logarithm of the sum of this vector and the
1303      * broadcast of {@code 1}, selecting lane elements controlled by a mask.
1304      * <p>
1305      * Semantics for rounding, monotonicity, and special cases are
1306      * described in {@link DoubleVector#log1p}
1307      *
1308      * @param m the mask controlling lane selection
1309      * @return the natural logarithm of the sum of this vector and the broadcast
1310      * of {@code 1}
1311      */
1312     public DoubleVector log1p(Mask<Double> m) {
1313         return uOp(m, (i, a) -> (double) Math.log1p((double) a));
1314     }
1315 
1316     /**
1317      * Calculates this vector raised to the power of an input vector.
1318      * <p>
1319      * This is a vector binary operation with same semantic definition as
1320      * {@link Math#pow} operation applied to lane elements.
1321      * The implementation is not required to return same
1322      * results as {@link Math#pow}, but adheres to rounding, monotonicity,
1323      * and special case semantics as defined in the {@link Math#pow}
1324      * specifications. The computed result will be within 1 ulp of the
1325      * exact result.
1326      *
1327      * @param v the input vector
1328      * @return this vector raised to the power of an input vector
1329      */
1330     public DoubleVector pow(Vector<Double> v) {
1331         return bOp(v, (i, a, b) -> (double) Math.pow((double) a, (double) b));
1332     }
1333 
1334     /**
1335      * Calculates this vector raised to the power of the broadcast of an input
1336      * scalar.
1337      * <p>
1338      * This is a vector binary operation with same semantic definition as
1339      * {@link Math#pow} operation applied to lane elements.
1340      * The implementation is not required to return same
1341      * results as {@link Math#pow}, but adheres to rounding, monotonicity,
1342      * and special case semantics as defined in the {@link Math#pow}
1343      * specifications. The computed result will be within 1 ulp of the
1344      * exact result.
1345      *
1346      * @param s the input scalar
1347      * @return this vector raised to the power of the broadcast of an input
1348      * scalar.
1349      */
1350     public abstract DoubleVector pow(double s);
1351 
1352     /**
1353      * Calculates this vector raised to the power of an input vector, selecting
1354      * lane elements controlled by a mask.
1355      * <p>
1356      * Semantics for rounding, monotonicity, and special cases are
1357      * described in {@link DoubleVector#pow}
1358      *
1359      * @param v the input vector
1360      * @param m the mask controlling lane selection
1361      * @return this vector raised to the power of an input vector
1362      */
1363     public DoubleVector pow(Vector<Double> v, Mask<Double> m) {
1364         return bOp(v, m, (i, a, b) -> (double) Math.pow((double) a, (double) b));
1365     }
1366 
1367     /**
1368      * Calculates this vector raised to the power of the broadcast of an input
1369      * scalar, selecting lane elements controlled by a mask.
1370      * <p>
1371      * Semantics for rounding, monotonicity, and special cases are
1372      * described in {@link DoubleVector#pow}
1373      *
1374      * @param s the input scalar
1375      * @param m the mask controlling lane selection
1376      * @return this vector raised to the power of the broadcast of an input
1377      * scalar.
1378      */
1379     public abstract DoubleVector pow(double s, Mask<Double> m);
1380 
1381     /**
1382      * Calculates the broadcast of Euler's number {@code e} raised to the power
1383      * of this vector.
1384      * <p>
1385      * This is a vector unary operation with same semantic definition as
1386      * {@link Math#exp} operation applied to lane elements.
1387      * The implementation is not required to return same
1388      * results as {@link Math#exp}, but adheres to rounding, monotonicity,
1389      * and special case semantics as defined in the {@link Math#exp}
1390      * specifications. The computed result will be within 1 ulp of the
1391      * exact result.
1392      *
1393      * @return the broadcast of Euler's number {@code e} raised to the power of
1394      * this vector
1395      */
1396     public DoubleVector exp() {
1397         return uOp((i, a) -> (double) Math.exp((double) a));
1398     }
1399 
1400     /**
1401      * Calculates the broadcast of Euler's number {@code e} raised to the power
1402      * of this vector, selecting lane elements controlled by a mask.
1403      * <p>
1404      * Semantics for rounding, monotonicity, and special cases are
1405      * described in {@link DoubleVector#exp}
1406      *
1407      * @param m the mask controlling lane selection
1408      * @return the broadcast of Euler's number {@code e} raised to the power of
1409      * this vector
1410      */
1411     public DoubleVector exp(Mask<Double> m) {
1412         return uOp(m, (i, a) -> (double) Math.exp((double) a));
1413     }
1414 
1415     /**
1416      * Calculates the broadcast of Euler's number {@code e} raised to the power
1417      * of this vector minus the broadcast of {@code -1}.
1418      * More specifically as if the following (ignoring any differences in
1419      * numerical accuracy):
1420      * <pre>{@code
1421      *   this.exp().sub(this.species().broadcast(1))
1422      * }</pre>
1423      * <p>
1424      * This is a vector unary operation with same semantic definition as
1425      * {@link Math#expm1} operation applied to lane elements.
1426      * The implementation is not required to return same
1427      * results as {@link Math#expm1}, but adheres to rounding, monotonicity,
1428      * and special case semantics as defined in the {@link Math#expm1}
1429      * specifications. The computed result will be within 1 ulp of the
1430      * exact result.
1431      *
1432      * @return the broadcast of Euler's number {@code e} raised to the power of
1433      * this vector minus the broadcast of {@code -1}
1434      */
1435     public DoubleVector expm1() {
1436         return uOp((i, a) -> (double) Math.expm1((double) a));
1437     }
1438 
1439     /**
1440      * Calculates the broadcast of Euler's number {@code e} raised to the power
1441      * of this vector minus the broadcast of {@code -1}, selecting lane elements
1442      * controlled by a mask
1443      * More specifically as if the following (ignoring any differences in
1444      * numerical accuracy):
1445      * <pre>{@code
1446      *   this.exp(m).sub(this.species().broadcast(1), m)
1447      * }</pre>
1448      * <p>
1449      * Semantics for rounding, monotonicity, and special cases are
1450      * described in {@link DoubleVector#expm1}
1451      *
1452      * @param m the mask controlling lane selection
1453      * @return the broadcast of Euler's number {@code e} raised to the power of
1454      * this vector minus the broadcast of {@code -1}
1455      */
1456     public DoubleVector expm1(Mask<Double> m) {
1457         return uOp(m, (i, a) -> (double) Math.expm1((double) a));
1458     }
1459 
1460     /**
1461      * Calculates the product of this vector and a first input vector summed
1462      * with a second input vector.
1463      * More specifically as if the following (ignoring any differences in
1464      * numerical accuracy):
1465      * <pre>{@code
1466      *   this.mul(v1).add(v2)
1467      * }</pre>
1468      * <p>
1469      * This is a vector ternary operation where the {@link Math#fma} operation
1470      * is applied to lane elements.
1471      *
1472      * @param v1 the first input vector
1473      * @param v2 the second input vector
1474      * @return the product of this vector and the first input vector summed with
1475      * the second input vector
1476      */
1477     public abstract DoubleVector fma(Vector<Double> v1, Vector<Double> v2);
1478 
1479     /**
1480      * Calculates the product of this vector and the broadcast of a first input
1481      * scalar summed with the broadcast of a second input scalar.
1482      * More specifically as if the following:
1483      * <pre>{@code
1484      *   this.fma(this.species().broadcast(s1), this.species().broadcast(s2))
1485      * }</pre>
1486      * <p>
1487      * This is a vector ternary operation where the {@link Math#fma} operation
1488      * is applied to lane elements.
1489      *
1490      * @param s1 the first input scalar
1491      * @param s2 the second input scalar
1492      * @return the product of this vector and the broadcast of a first input
1493      * scalar summed with the broadcast of a second input scalar
1494      */
1495     public abstract DoubleVector fma(double s1, double s2);
1496 
1497     /**
1498      * Calculates the product of this vector and a first input vector summed
1499      * with a second input vector, selecting lane elements controlled by a mask.
1500      * More specifically as if the following (ignoring any differences in
1501      * numerical accuracy):
1502      * <pre>{@code
1503      *   this.mul(v1, m).add(v2, m)
1504      * }</pre>
1505      * <p>
1506      * This is a vector ternary operation where the {@link Math#fma} operation
1507      * is applied to lane elements.
1508      *
1509      * @param v1 the first input vector
1510      * @param v2 the second input vector
1511      * @param m the mask controlling lane selection
1512      * @return the product of this vector and the first input vector summed with
1513      * the second input vector
1514      */
1515     public DoubleVector fma(Vector<Double> v1, Vector<Double> v2, Mask<Double> m) {
1516         return tOp(v1, v2, m, (i, a, b, c) -> Math.fma(a, b, c));
1517     }
1518 
1519     /**
1520      * Calculates the product of this vector and the broadcast of a first input
1521      * scalar summed with the broadcast of a second input scalar, selecting lane
1522      * elements controlled by a mask
1523      * More specifically as if the following:
1524      * <pre>{@code
1525      *   this.fma(this.species().broadcast(s1), this.species().broadcast(s2), m)
1526      * }</pre>
1527      * <p>
1528      * This is a vector ternary operation where the {@link Math#fma} operation
1529      * is applied to lane elements.
1530      *
1531      * @param s1 the first input scalar
1532      * @param s2 the second input scalar
1533      * @param m the mask controlling lane selection
1534      * @return the product of this vector and the broadcast of a first input
1535      * scalar summed with the broadcast of a second input scalar
1536      */
1537     public abstract DoubleVector fma(double s1, double s2, Mask<Double> m);
1538 
1539     /**
1540      * Calculates square root of the sum of the squares of this vector and an
1541      * input vector.
1542      * More specifically as if the following (ignoring any differences in
1543      * numerical accuracy):
1544      * <pre>{@code
1545      *   this.mul(this).add(v.mul(v)).sqrt()
1546      * }</pre>
1547      * <p>
1548      * This is a vector binary operation with same semantic definition as
1549      * {@link Math#hypot} operation applied to lane elements.
1550      * The implementation is not required to return same
1551      * results as {@link Math#hypot}, but adheres to rounding, monotonicity,
1552      * and special case semantics as defined in the {@link Math#hypot}
1553      * specifications. The computed result will be within 1 ulp of the
1554      * exact result.
1555      *
1556      * @param v the input vector
1557      * @return square root of the sum of the squares of this vector and an input
1558      * vector
1559      */
1560     public DoubleVector hypot(Vector<Double> v) {
1561         return bOp(v, (i, a, b) -> (double) Math.hypot((double) a, (double) b));
1562     }
1563 
1564     /**
1565      * Calculates square root of the sum of the squares of this vector and the
1566      * broadcast of an input scalar.
1567      * More specifically as if the following (ignoring any differences in
1568      * numerical accuracy):
1569      * <pre>{@code
1570      *   this.mul(this).add(this.species().broadcast(v * v)).sqrt()
1571      * }</pre>
1572      * <p>
1573      * This is a vector binary operation with same semantic definition as
1574      * {@link Math#hypot} operation applied to lane elements.
1575      * The implementation is not required to return same
1576      * results as {@link Math#hypot}, but adheres to rounding, monotonicity,
1577      * and special case semantics as defined in the {@link Math#hypot}
1578      * specifications. The computed result will be within 1 ulp of the
1579      * exact result.
1580      *
1581      * @param s the input scalar
1582      * @return square root of the sum of the squares of this vector and the
1583      * broadcast of an input scalar
1584      */
1585     public abstract DoubleVector hypot(double s);
1586 
1587     /**
1588      * Calculates square root of the sum of the squares of this vector and an
1589      * input vector, selecting lane elements controlled by a mask.
1590      * More specifically as if the following (ignoring any differences in
1591      * numerical accuracy):
1592      * <pre>{@code
1593      *   this.mul(this, m).add(v.mul(v), m).sqrt(m)
1594      * }</pre>
1595      * <p>
1596      * Semantics for rounding, monotonicity, and special cases are
1597      * described in {@link DoubleVector#hypot}
1598      *
1599      * @param v the input vector
1600      * @param m the mask controlling lane selection
1601      * @return square root of the sum of the squares of this vector and an input
1602      * vector
1603      */
1604     public DoubleVector hypot(Vector<Double> v, Mask<Double> m) {
1605         return bOp(v, m, (i, a, b) -> (double) Math.hypot((double) a, (double) b));
1606     }
1607 
1608     /**
1609      * Calculates square root of the sum of the squares of this vector and the
1610      * broadcast of an input scalar, selecting lane elements controlled by a
1611      * mask.
1612      * More specifically as if the following (ignoring any differences in
1613      * numerical accuracy):
1614      * <pre>{@code
1615      *   this.mul(this, m).add(this.species().broadcast(v * v), m).sqrt(m)
1616      * }</pre>
1617      * <p>
1618      * Semantics for rounding, monotonicity, and special cases are
1619      * described in {@link DoubleVector#hypot}
1620      *
1621      * @param s the input scalar
1622      * @param m the mask controlling lane selection
1623      * @return square root of the sum of the squares of this vector and the
1624      * broadcast of an input scalar
1625      */
1626     public abstract DoubleVector hypot(double s, Mask<Double> m);
1627 
1628 
1629     @Override
1630     public abstract void intoByteArray(byte[] a, int ix);
1631 
1632     @Override
1633     public abstract void intoByteArray(byte[] a, int ix, Mask<Double> m);
1634 
1635     @Override
1636     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1637 
1638     @Override
1639     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Double> m);
1640 
1641 
1642     // Type specific horizontal reductions
1643 
1644     /**
1645      * Adds all lane elements of this vector.
1646      * <p>
1647      * This is an associative vector reduction operation where the addition
1648      * operation ({@code +}) is applied to lane elements,
1649      * and the identity value is {@code 0}.
1650      *
1651      * @return the addition of all the lane elements of this vector
1652      */
1653     public abstract double addAll();
1654 
1655     /**
1656      * Adds all lane elements of this vector, selecting lane elements
1657      * controlled by a mask.
1658      * <p>
1659      * This is an associative vector reduction operation where the addition
1660      * operation ({@code +}) is applied to lane elements,
1661      * and the identity value is {@code 0}.
1662      *
1663      * @param m the mask controlling lane selection
1664      * @return the addition of all the lane elements of this vector
1665      */
1666     public abstract double addAll(Mask<Double> m);
1667 
1668     /**
1669      * Subtracts all lane elements of this vector.
1670      * <p>
1671      * This is an associative vector reduction operation where the subtraction
1672      * operation ({@code -}) is applied to lane elements,
1673      * and the identity value is {@code 0}.
1674      *
1675      * @return the subtraction of all the lane elements of this vector
1676      */
1677     public abstract double subAll();
1678 
1679     /**
1680      * Subtracts all lane elements of this vector, selecting lane elements
1681      * controlled by a mask.
1682      * <p>
1683      * This is an associative vector reduction operation where the subtraction
1684      * operation ({@code -}) is applied to lane elements,
1685      * and the identity value is {@code 0}.
1686      *
1687      * @param m the mask controlling lane selection
1688      * @return the subtraction of all the lane elements of this vector
1689      */
1690     public abstract double subAll(Mask<Double> m);
1691 
1692     /**
1693      * Multiplies all lane elements of this vector.
1694      * <p>
1695      * This is an associative vector reduction operation where the
1696      * multiplication operation ({@code *}) is applied to lane elements,
1697      * and the identity value is {@code 1}.
1698      *
1699      * @return the multiplication of all the lane elements of this vector
1700      */
1701     public abstract double mulAll();
1702 
1703     /**
1704      * Multiplies all lane elements of this vector, selecting lane elements
1705      * controlled by a mask.
1706      * <p>
1707      * This is an associative vector reduction operation where the
1708      * multiplication operation ({@code *}) is applied to lane elements,
1709      * and the identity value is {@code 1}.
1710      *
1711      * @param m the mask controlling lane selection
1712      * @return the multiplication of all the lane elements of this vector
1713      */
1714     public abstract double mulAll(Mask<Double> m);
1715 
1716     /**
1717      * Returns the minimum lane element of this vector.
1718      * <p>
1719      * This is an associative vector reduction operation where the operation
1720      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1721      * and the identity value is {@link Double#MAX_VALUE}.
1722      *
1723      * @return the minimum lane element of this vector
1724      */
1725     public abstract double minAll();
1726 
1727     /**
1728      * Returns the minimum lane element of this vector, selecting lane elements
1729      * controlled by a mask.
1730      * <p>
1731      * This is an associative vector reduction operation where the operation
1732      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1733      * and the identity value is {@link Double#MAX_VALUE}.
1734      *
1735      * @param m the mask controlling lane selection
1736      * @return the minimum lane element of this vector
1737      */
1738     public abstract double minAll(Mask<Double> m);
1739 
1740     /**
1741      * Returns the maximum lane element of this vector.
1742      * <p>
1743      * This is an associative vector reduction operation where the operation
1744      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1745      * and the identity value is {@link Double#MIN_VALUE}.
1746      *
1747      * @return the maximum lane element of this vector
1748      */
1749     public abstract double maxAll();
1750 
1751     /**
1752      * Returns the maximum lane element of this vector, selecting lane elements
1753      * controlled by a mask.
1754      * <p>
1755      * This is an associative vector reduction operation where the operation
1756      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1757      * and the identity value is {@link Double#MIN_VALUE}.
1758      *
1759      * @param m the mask controlling lane selection
1760      * @return the maximum lane element of this vector
1761      */
1762     public abstract double maxAll(Mask<Double> m);
1763 
1764 
1765     // Type specific accessors
1766 
1767     /**
1768      * Gets the lane element at lane index {@code i}
1769      *
1770      * @param i the lane index
1771      * @return the lane element at lane index {@code i}
1772      * @throws IllegalArgumentException if the index is is out of range
1773      * ({@code < 0 || >= length()})
1774      */
1775     public abstract double get(int i);
1776 
1777     /**
1778      * Replaces the lane element of this vector at lane index {@code i} with
1779      * value {@code e}.
1780      * <p>
1781      * This is a cross-lane operation and behaves as if it returns the result
1782      * of blending this vector with an input vector that is the result of
1783      * broadcasting {@code e} and a mask that has only one lane set at lane
1784      * index {@code i}.
1785      *
1786      * @param i the lane index of the lane element to be replaced
1787      * @param e the value to be placed
1788      * @return the result of replacing the lane element of this vector at lane
1789      * index {@code i} with value {@code e}.
1790      * @throws IllegalArgumentException if the index is is out of range
1791      * ({@code < 0 || >= length()})
1792      */
1793     public abstract DoubleVector with(int i, double e);
1794 
1795     // Type specific extractors
1796 
1797     /**
1798      * Returns an array containing the lane elements of this vector.
1799      * <p>
1800      * This method behaves as if it {@link #intoArray(double[], int)} stores}
1801      * this vector into an allocated array and returns the array as follows:
1802      * <pre>{@code
1803      *   double[] a = new double[this.length()];
1804      *   this.intoArray(a, 0);
1805      *   return a;
1806      * }</pre>
1807      *
1808      * @return an array containing the the lane elements of this vector
1809      */
1810     @ForceInline
1811     public final double[] toArray() {
1812         double[] a = new double[species().length()];
1813         intoArray(a, 0);
1814         return a;
1815     }
1816 
1817     /**
1818      * Stores this vector into an array starting at offset.
1819      * <p>
1820      * For each vector lane, where {@code N} is the vector lane index,
1821      * the lane element at index {@code N} is stored into the array at index
1822      * {@code i + N}.
1823      *
1824      * @param a the array
1825      * @param i the offset into the array
1826      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1827      * {@code i > a.length - this.length()}
1828      */
1829     public abstract void intoArray(double[] a, int i);
1830 
1831     /**
1832      * Stores this vector into an array starting at offset and using a mask.
1833      * <p>
1834      * For each vector lane, where {@code N} is the vector lane index,
1835      * if the mask lane at index {@code N} is set then the lane element at
1836      * index {@code N} is stored into the array index {@code i + N}.
1837      *
1838      * @param a the array
1839      * @param i the offset into the array
1840      * @param m the mask
1841      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1842      * for any vector lane index {@code N} where the mask at lane {@code N}
1843      * is set {@code i >= a.length - N}
1844      */
1845     public abstract void intoArray(double[] a, int i, Mask<Double> m);
1846 
1847     /**
1848      * Stores this vector into an array using indexes obtained from an index
1849      * map.
1850      * <p>
1851      * For each vector lane, where {@code N} is the vector lane index, the
1852      * lane element at index {@code N} is stored into the array at index
1853      * {@code i + indexMap[j + N]}.
1854      *
1855      * @param a the array
1856      * @param i the offset into the array, may be negative if relative
1857      * indexes in the index map compensate to produce a value within the
1858      * array bounds
1859      * @param indexMap the index map
1860      * @param j the offset into the index map
1861      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1862      * {@code j > indexMap.length - this.length()},
1863      * or for any vector lane index {@code N} the result of
1864      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1865      */
1866     public abstract void intoArray(double[] a, int i, int[] indexMap, int j);
1867 
1868     /**
1869      * Stores this vector into an array using indexes obtained from an index
1870      * map and using a mask.
1871      * <p>
1872      * For each vector lane, where {@code N} is the vector lane index,
1873      * if the mask lane at index {@code N} is set then the lane element at
1874      * index {@code N} is stored into the array at index
1875      * {@code i + indexMap[j + N]}.
1876      *
1877      * @param a the array
1878      * @param i the offset into the array, may be negative if relative
1879      * indexes in the index map compensate to produce a value within the
1880      * array bounds
1881      * @param m the mask
1882      * @param indexMap the index map
1883      * @param j the offset into the index map
1884      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1885      * {@code j > indexMap.length - this.length()},
1886      * or for any vector lane index {@code N} where the mask at lane
1887      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1888      * {@code < 0} or {@code >= a.length}
1889      */
1890     public abstract void intoArray(double[] a, int i, Mask<Double> m, int[] indexMap, int j);
1891     // Species
1892 
1893     @Override
1894     public abstract DoubleSpecies species();
1895 
1896     /**
1897      * A specialized factory for creating {@link DoubleVector} value of the same
1898      * shape, and a {@link Mask} and {@link Shuffle} values of the same shape
1899      * and {@code int} element type.
1900      */
1901     public static abstract class DoubleSpecies extends Vector.Species<Double> {
1902         interface FOp {
1903             double apply(int i);
1904         }
1905 
1906         abstract DoubleVector op(FOp f);
1907 
1908         abstract DoubleVector op(Mask<Double> m, FOp f);
1909 
1910         interface FOpm {
1911             boolean apply(int i);
1912         }
1913 
1914         abstract Mask<Double> opm(FOpm f);
1915 
1916         abstract IntVector.IntSpecies indexSpecies();
1917 
1918 
1919         // Factories
1920 
1921         @Override
1922         public abstract DoubleVector zero();
1923 
1924         /**
1925          * Returns a vector where all lane elements are set to the primitive
1926          * value {@code e}.
1927          *
1928          * @param e the value
1929          * @return a vector of vector where all lane elements are set to
1930          * the primitive value {@code e}
1931          */
1932         public abstract DoubleVector broadcast(double e);
1933 
1934         /**
1935          * Returns a vector where the first lane element is set to the primtive
1936          * value {@code e}, all other lane elements are set to the default
1937          * value.
1938          *
1939          * @param e the value
1940          * @return a vector where the first lane element is set to the primitive
1941          * value {@code e}
1942          */
1943         @ForceInline
1944         public final DoubleVector single(double e) {
1945             return zero().with(0, e);
1946         }
1947 
1948         /**
1949          * Returns a vector where each lane element is set to a randomly
1950          * generated primitive value.
1951          *
1952          * The semantics are equivalent to calling
1953          * {@link ThreadLocalRandom#nextDouble }
1954          *
1955          * @return a vector where each lane elements is set to a randomly
1956          * generated primitive value
1957          */
1958         public DoubleVector random() {
1959             ThreadLocalRandom r = ThreadLocalRandom.current();
1960             return op(i -> r.nextDouble());
1961         }
1962 
1963         /**
1964          * Returns a vector where each lane element is set to a given
1965          * primitive value.
1966          * <p>
1967          * For each vector lane, where {@code N} is the vector lane index, the
1968          * the primitive value at index {@code N} is placed into the resulting
1969          * vector at lane index {@code N}.
1970          *
1971          * @param es the given primitive values
1972          * @return a vector where each lane element is set to a given primitive
1973          * value
1974          * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
1975          */
1976         public abstract DoubleVector scalars(double... es);
1977     }
1978 
1979     /**
1980      * Finds the preferred species for an element type of {@code double}.
1981      * <p>
1982      * A preferred species is a species chosen by the platform that has a
1983      * shape of maximal bit size.  A preferred species for different element
1984      * types will have the same shape, and therefore vectors, masks, and
1985      * shuffles created from such species will be shape compatible.
1986      *
1987      * @return the preferred species for an element type of {@code double}
1988      */
1989     @SuppressWarnings("unchecked")
1990     public static DoubleSpecies preferredSpecies() {
1991         return (DoubleSpecies) Species.ofPreferred(double.class);
1992     }
1993 
1994     /**
1995      * Finds a species for an element type of {@code double} and shape.
1996      *
1997      * @param s the shape
1998      * @return a species for an element type of {@code double} and shape
1999      * @throws IllegalArgumentException if no such species exists for the shape
2000      */
2001     @SuppressWarnings("unchecked")
2002     public static DoubleSpecies species(Vector.Shape s) {
2003         Objects.requireNonNull(s);
2004         switch (s) {
2005             case S_64_BIT: return Double64Vector.SPECIES;
2006             case S_128_BIT: return Double128Vector.SPECIES;
2007             case S_256_BIT: return Double256Vector.SPECIES;
2008             case S_512_BIT: return Double512Vector.SPECIES;
2009             case S_Max_BIT: return DoubleMaxVector.SPECIES;
2010             default: throw new IllegalArgumentException("Bad shape: " + s);
2011         }
2012     }
2013 }