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