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