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