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