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