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