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