001/*- 002 ******************************************************************************* 003 * Copyright (c) 2011, 2016 Diamond Light Source Ltd. 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Peter Chang - initial API and implementation and/or initial documentation 011 *******************************************************************************/ 012 013// This is generated from ComplexDoubleDataset.java by fromcpxdouble.py 014 015package org.eclipse.january.dataset; 016 017 018import java.util.Arrays; 019 020import org.apache.commons.math3.complex.Complex; 021 022 023/** 024 * Extend compound dataset to hold complex float values // PRIM_TYPE 025 */ 026public class ComplexFloatDataset extends CompoundFloatDataset { // CLASS_TYPE 027 // pin UID to base class 028 private static final long serialVersionUID = Dataset.serialVersionUID; 029 030 private static final int ISIZE = 2; // number of elements per item 031 032 @Override 033 public int getDType() { 034 return Dataset.COMPLEX64; // DATA_TYPE 035 } 036 037 /** 038 * Create a null dataset 039 */ 040 ComplexFloatDataset() { 041 super(ISIZE); 042 } 043 044 /** 045 * Create a zero-filled dataset of given shape 046 * @param shape 047 */ 048 ComplexFloatDataset(final int... shape) { 049 super(ISIZE, shape); 050 } 051 052 /** 053 * Create a dataset using given data (real and imaginary parts are grouped in pairs) 054 * @param data 055 * @param shape (can be null to create 1D dataset) 056 */ 057 ComplexFloatDataset(final float[] data, final int... shape) { // PRIM_TYPE 058 super(ISIZE, data, shape); 059 } 060 061 /** 062 * Copy a dataset 063 * @param dataset 064 */ 065 ComplexFloatDataset(final ComplexFloatDataset dataset) { 066 super(dataset); 067 } 068 069 /** 070 * Create a dataset using given data (real and imaginary parts are given separately) 071 * @param realData 072 * @param imagData 073 * @param shape (can be null or zero-length to create 1D dataset) 074 */ 075 ComplexFloatDataset(final float[] realData, final float[] imagData, int... shape) { // PRIM_TYPE 076 if (realData == null || imagData == null) { 077 throw new IllegalArgumentException("Data must not be null"); 078 } 079 int dsize = realData.length > imagData.length ? imagData.length : realData.length; 080 if (shape == null || shape.length == 0) { 081 shape = new int[] {dsize}; 082 } 083 isize = ISIZE; 084 size = ShapeUtils.calcSize(shape); 085 if (size != dsize) { 086 throw new IllegalArgumentException(String.format("Shape %s is not compatible with size of data array, %d", 087 Arrays.toString(shape), dsize)); 088 } 089 this.shape = size == 0 ? null : shape.clone(); 090 091 try { 092 odata = data = createArray(size); 093 } catch (Throwable t) { 094 logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t); 095 throw new IllegalArgumentException(t); 096 } 097 098 for (int i = 0, n = 0; i < size; i++) { 099 data[n++] = realData[i]; 100 data[n++] = imagData[i]; 101 } 102 } 103 104 /** 105 * Create a dataset using given data (real and imaginary parts are given separately) 106 * @param real 107 * @param imag 108 */ 109 ComplexFloatDataset(final Dataset real, final Dataset imag) { 110 super(ISIZE, real.getShapeRef()); 111 real.checkCompatibility(imag); 112 113 IndexIterator riter = real.getIterator(); 114 IndexIterator iiter = imag.getIterator(); 115 116 for (int i = 0; riter.hasNext() && iiter.hasNext();) { 117 data[i++] = (float) real.getElementDoubleAbs(riter.index); // ADD_CAST 118 data[i++] = (float) imag.getElementDoubleAbs(iiter.index); // ADD_CAST 119 } 120 } 121 122 /** 123 * Copy and cast a dataset to this complex type 124 * @param dataset 125 */ 126 ComplexFloatDataset(final Dataset dataset) { 127 super(ISIZE, dataset.getShapeRef()); 128 copyToView(dataset, this, true, false); 129 offset = 0; 130 stride = null; 131 base = null; 132 133 IndexIterator iter = dataset.getIterator(); 134 int disize = dataset.getElementsPerItem(); 135 if (disize == 1) { 136 for (int i = 0; iter.hasNext(); i += isize) { 137 data[i] = (float) dataset.getElementDoubleAbs(iter.index); // ADD_CAST 138 } 139 } else { 140 for (int i = 0; iter.hasNext(); i += isize) { 141 data[i] = (float) dataset.getElementDoubleAbs(iter.index); // ADD_CAST 142 data[i+1] = (float) dataset.getElementDoubleAbs(iter.index+1); // ADD_CAST 143 } 144 } 145 } 146 147 @Override 148 public ComplexFloatDataset clone() { 149 return new ComplexFloatDataset(this); 150 } 151 152 /** 153 * Create a dataset from an object which could be a Java list, array (of arrays...) 154 * or Number. Ragged sequences or arrays are padded with zeros. 155 * 156 * @param obj 157 * @return dataset with contents given by input 158 */ 159 static ComplexFloatDataset createFromObject(final Object obj) { 160 ComplexFloatDataset result = new ComplexFloatDataset(); 161 162 result.shape = ShapeUtils.getShapeFromObject(obj); 163 result.size = ShapeUtils.calcSize(result.shape); 164 165 try { 166 result.odata = result.data = result.createArray(result.size); 167 } catch (Throwable t) { 168 logger.error("Could not create a dataset of shape {}", Arrays.toString(result.shape), t); 169 throw new IllegalArgumentException(t); 170 } 171 172 int[] pos = new int[result.shape.length]; 173 result.fillData(obj, 0, pos); 174 return result; 175 } 176 177 /** 178 * @param stop 179 * @return a new 1D dataset, filled with values determined by parameters 180 */ 181 static ComplexFloatDataset createRange(final double stop) { 182 return createRange(0, stop, 1); 183 } 184 185 /** 186 * @param start 187 * @param stop 188 * @param step 189 * @return a new 1D dataset, filled with values determined by parameters 190 */ 191 static ComplexFloatDataset createRange(final double start, final double stop, final double step) { 192 int size = calcSteps(start, stop, step); 193 ComplexFloatDataset result = new ComplexFloatDataset(size); 194 for (int i = 0; i < size; i ++) { 195 result.data[i*ISIZE] = (float) (start + i*step); // ADD_CAST 196 } 197 return result; 198 } 199 200 /** 201 * @param shape 202 * @return a dataset filled with ones 203 */ 204 static ComplexFloatDataset ones(final int... shape) { 205 return new ComplexFloatDataset(shape).fill(1); 206 } 207 208 @Override 209 public ComplexFloatDataset fill(final Object obj) { 210 setDirty(); 211 float vr = (float) DTypeUtils.toReal(obj); // PRIM_TYPE // ADD_CAST 212 float vi = (float) DTypeUtils.toImag(obj); // PRIM_TYPE // ADD_CAST 213 IndexIterator iter = getIterator(); 214 215 while (iter.hasNext()) { 216 data[iter.index] = vr; 217 data[iter.index+1] = vi; 218 } 219 220 return this; 221 } 222 223 @Override 224 public ComplexFloatDataset getView(boolean deepCopyMetadata) { 225 ComplexFloatDataset view = new ComplexFloatDataset(); 226 copyToView(this, view, true, deepCopyMetadata); 227 view.data = data; 228 return view; 229 } 230 231 /** 232 * Get complex value at absolute index in the internal array. 233 * 234 * This is an internal method with no checks so can be dangerous. Use with care or ideally with an iterator. 235 * 236 * @param index absolute index 237 * @return value 238 */ 239 public Complex getComplexAbs(final int index) { 240 return new Complex(data[index], data[index+1]); 241 } 242 243 @Override 244 public Object getObjectAbs(final int index) { 245 return new Complex(data[index], data[index+1]); 246 } 247 248 @Override 249 public String getStringAbs(final int index) { 250 float di = data[index + 1]; // PRIM_TYPE 251 if (stringFormat == null) { 252 return di >= 0 ? String.format("%.8g + %.8gj", data[index], di) : // FORMAT_STRING 253 String.format("%.8g - %.8gj", data[index], -di); // FORMAT_STRING 254 } 255 StringBuilder s = new StringBuilder(); 256 s.append(stringFormat.format(data[index])); 257 if (di >= 0) { 258 s.append(" + "); 259 s.append(stringFormat.format(di)); 260 } else { 261 s.append(" - "); 262 s.append(stringFormat.format(-di)); 263 } 264 s.append('j'); 265 return s.toString(); 266 } 267 268 /** 269 * Set values at absolute index in the internal array. 270 * 271 * This is an internal method with no checks so can be dangerous. Use with care or ideally with an iterator. 272 * @param index absolute index 273 * @param val new values 274 */ 275 public void setAbs(final int index, final Complex val) { 276 setAbs(index, (float) val.getReal(), (float) val.getImaginary()); // PRIM_TYPE 277 } 278 279 @Override 280 public void setObjectAbs(final int index, final Object obj) { 281 setAbs(index, (float) DTypeUtils.toReal(obj), (float) DTypeUtils.toImag(obj)); // PRIM_TYPE 282 } 283 284 /** 285 * Set item at index to complex value given by real and imaginary parts 286 * @param index absolute index 287 * @param real 288 * @param imag 289 */ 290 public void setAbs(final int index, final float real, final float imag) { // PRIM_TYPE 291 setDirty(); 292 data[index] = real; 293 data[index+1] = imag; 294 } 295 296 /** 297 * @return item in first position 298 * @since 2.0 299 */ 300 public Complex get() { 301 int n = getFirst1DIndex(); 302 Complex z = new Complex(data[n], data[n+1]); 303 return z; 304 } 305 306 /** 307 * @param i 308 * @return item in given position 309 */ 310 public Complex get(final int i) { 311 int n = get1DIndex(i); 312 Complex z = new Complex(data[n], data[n+1]); 313 return z; 314 } 315 316 /** 317 * @param i 318 * @param j 319 * @return item in given position 320 */ 321 public Complex get(final int i, final int j) { 322 int n = get1DIndex(i, j); 323 Complex z = new Complex(data[n], data[n+1]); 324 return z; 325 } 326 327 /** 328 * @param pos 329 * @return item in given position 330 */ 331 public Complex get(final int... pos) { 332 int n = get1DIndex(pos); 333 Complex z = new Complex(data[n], data[n+1]); 334 return z; 335 } 336 337 @Override 338 public Object getObject() { 339 return get(); 340 } 341 342 @Override 343 public Object getObject(final int i) { 344 return get(i); 345 } 346 347 @Override 348 public Object getObject(final int i, final int j) { 349 return get(i, j); 350 } 351 352 @Override 353 public Object getObject(final int... pos) { 354 return getComplex(pos); 355 } 356 357 /** 358 * @return item in first position 359 * @since 2.0 360 */ 361 public float getReal() { // PRIM_TYPE 362 return (float) getFirstValue(); // PRIM_TYPE 363 } 364 365 /** 366 * @param i 367 * @return item in given position 368 */ 369 public float getReal(final int i) { // PRIM_TYPE 370 return (float) getFirstValue(i); // PRIM_TYPE 371 } 372 373 /** 374 * @param i 375 * @param j 376 * @return item in given position 377 */ 378 public float getReal(final int i, final int j) { // PRIM_TYPE 379 return (float) getFirstValue(i, j); // PRIM_TYPE 380 } 381 382 /** 383 * @param pos 384 * @return item in given position 385 */ 386 public float getReal(final int... pos) { // PRIM_TYPE 387 return (float) getFirstValue(pos); // PRIM_TYPE 388 } 389 390 /** 391 * @return item in first position 392 * @since 2.0 393 */ 394 public float getImag() { // PRIM_TYPE 395 return data[getFirst1DIndex() + 1]; 396 } 397 398 /** 399 * @param i 400 * @return item in given position 401 */ 402 public float getImag(final int i) { // PRIM_TYPE 403 return data[get1DIndex(i) + 1]; 404 } 405 406 /** 407 * @param i 408 * @param j 409 * @return item in given position 410 */ 411 public float getImag(final int i, final int j) { // PRIM_TYPE 412 return data[get1DIndex(i, j) + 1]; 413 } 414 415 /** 416 * @param pos 417 * @return item in given position 418 */ 419 public float getImag(final int... pos) { // PRIM_TYPE 420 return data[get1DIndex(pos) + 1]; 421 } 422 423 /** 424 * @return item in first position 425 * @since 2.0 426 */ 427 public Complex getComplex() { 428 return get(); 429 } 430 431 /** 432 * @param i 433 * @return item in given position 434 */ 435 public Complex getComplex(final int i) { 436 return get(i); 437 } 438 439 /** 440 * @param i 441 * @param j 442 * @return item in given position 443 */ 444 public Complex getComplex(final int i, final int j) { 445 return get(i, j); 446 } 447 448 /** 449 * @param pos 450 * @return item in given position 451 */ 452 public Complex getComplex(final int... pos) { 453 return get(pos); 454 } 455 456 @Override 457 public void set(final Object obj, final int i) { 458 setItem(new float[] {(float) DTypeUtils.toReal(obj), (float) DTypeUtils.toImag(obj)}, i); // PRIM_TYPE 459 } 460 461 @Override 462 public void set(final Object obj, final int i, final int j) { 463 setItem(new float[] {(float) DTypeUtils.toReal(obj), (float) DTypeUtils.toImag(obj)}, i, j); // PRIM_TYPE 464 } 465 466 @Override 467 public void set(final Object obj, int... pos) { 468 if (pos == null || (pos.length == 0 && shape.length > 0)) { 469 pos = new int[shape.length]; 470 } 471 472 setItem(new float[] {(float) DTypeUtils.toReal(obj), (float) DTypeUtils.toImag(obj)}, pos); // PRIM_TYPE 473 } 474 475 /** 476 * Set real and imaginary values at given position 477 * @param dr 478 * @param di 479 * @param i 480 */ 481 public void set(final float dr, final float di, final int i) { // PRIM_TYPE 482 setItem(new float[] {dr, di}, i); // PRIM_TYPE 483 } 484 485 /** 486 * Set real and imaginary values at given position 487 * @param dr 488 * @param di 489 * @param i 490 * @param j 491 */ 492 public void set(final float dr, final float di, final int i, final int j) { // PRIM_TYPE 493 setItem(new float[] {dr, di}, i, j); // PRIM_TYPE 494 } 495 496 /** 497 * Set real and imaginary values at given position 498 * @param dr 499 * @param di 500 * @param pos 501 * @since 2.0 502 */ 503 public void set(final float dr, final float di, final int... pos) { // PRIM_TYPE 504 setItem(new float[] {dr, di}, pos); // PRIM_TYPE 505 } 506 507 /** 508 * @since 2.0 509 */ 510 @Override 511 public FloatDataset getRealPart() { // CLASS_TYPE 512 return getElements(0); 513 } 514 515 /** 516 * @since 2.0 517 */ 518 @Override 519 public FloatDataset getRealView() { // CLASS_TYPE 520 return getElementsView(0); 521 } 522 523 /** 524 * @return imaginary part of dataset as new dataset 525 * @since 2.0 526 */ 527 public FloatDataset getImaginaryPart() { // CLASS_TYPE 528 return getElements(1); 529 } 530 531 /** 532 * @return view of imaginary values 533 */ 534 public FloatDataset getImaginaryView() { // CLASS_TYPE 535 return getElementsView(1); 536 } 537 538 @Override 539 public Number max(boolean... switches) { 540 throw new UnsupportedOperationException("Cannot compare complex numbers"); 541 } 542 543 @Override 544 public Number min(boolean... switches) { 545 throw new UnsupportedOperationException("Cannot compare complex numbers"); 546 } 547 548 @Override 549 public Object sum(boolean... switches) { // FIXME 550 double[] sum = (double[]) super.sum(switches); 551 return new Complex(sum[0], sum[1]); 552 } 553 554 @Override 555 public Object mean(boolean... switches) { 556 double[] mean = (double[]) super.mean(switches); 557 return new Complex(mean[0], mean[1]); 558 } 559 560 @Override 561 public int[] maxPos(boolean... switches) { 562 throw new UnsupportedOperationException("Cannot compare complex numbers"); 563 } 564 565 @Override 566 public int[] minPos(boolean... switches) { 567 throw new UnsupportedOperationException("Cannot compare complex numbers"); 568 } 569 570 @Override 571 public ComplexFloatDataset getSlice(final SliceIterator siter) { 572 ComplexFloatDataset result = new ComplexFloatDataset(siter.getShape()); 573 float[] rdata = result.data; // PRIM_TYPE 574 IndexIterator riter = result.getIterator(); 575 576 while (siter.hasNext() && riter.hasNext()) { 577 rdata[riter.index] = data[siter.index]; 578 rdata[riter.index+1] = data[siter.index+1]; 579 } 580 581 result.setName(name + BLOCK_OPEN + Slice.createString(siter.shape, siter.start, siter.stop, siter.step) + BLOCK_CLOSE); 582 return result; 583 } 584 585 @Override 586 ComplexFloatDataset setSlicedView(Dataset view, Dataset d) { 587 setDirty(); 588 final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(view, d); 589 590 if (d instanceof ComplexFloatDataset || d instanceof ComplexFloatDataset) { 591 while (it.hasNext()) { 592 data[it.aIndex] = (float) it.bDouble; // BCAST_WITH_CAST d.getElementDoubleAbs(it.bIndex); 593 data[it.aIndex + 1] = (float) d.getElementDoubleAbs(it.bIndex + 1); // GET_ELEMENT_WITH_CAST 594 } 595 } else { 596 while (it.hasNext()) { 597 data[it.aIndex] = (float) it.bDouble; // BCAST_WITH_CAST d.getElementDoubleAbs(it.bIndex); 598 data[it.aIndex + 1] = 0; 599 } 600 } 601 return this; 602 } 603 604 @Override 605 public ComplexFloatDataset setSlice(final Object o, final IndexIterator siter) { 606 setDirty(); 607 if (o instanceof ComplexFloatDataset) { 608 ComplexFloatDataset zds = (ComplexFloatDataset) o; 609 610 if (!ShapeUtils.areShapesCompatible(siter.getShape(), zds.shape)) { 611 throw new IllegalArgumentException(String.format( 612 "Input dataset is not compatible with slice: %s cf %s", Arrays.toString(zds.shape), 613 Arrays.toString(siter.getShape()))); 614 } 615 616 IndexIterator oiter = zds.getIterator(); 617 float[] odata = zds.data; 618 619 while (siter.hasNext() && oiter.hasNext()) { 620 data[siter.index] = odata[oiter.index]; 621 data[siter.index+1] = odata[oiter.index+1]; 622 } 623 } else if (o instanceof ComplexDoubleDataset) { // IGNORE_CLASS 624 ComplexDoubleDataset zds = (ComplexDoubleDataset) o; // IGNORE_CLASS 625 626 if (!ShapeUtils.areShapesCompatible(siter.getShape(), zds.shape)) { 627 throw new IllegalArgumentException(String.format( 628 "Input dataset is not compatible with slice: %s cf %s", Arrays.toString(zds.shape), 629 Arrays.toString(siter.getShape()))); 630 } 631 632 IndexIterator oiter = zds.getIterator(); 633 double[] odata = zds.data; 634 635 while (siter.hasNext() && oiter.hasNext()) { 636 data[siter.index] = (float) odata[oiter.index]; // PRIM_TYPE // ADD_CAST 637 data[siter.index+1] = (float) odata[oiter.index+1]; // PRIM_TYPE // ADD_CAST 638 } 639 } else if (o instanceof IDataset) { 640 super.setSlice(o, siter); 641 } else { 642 try { 643 float vr = (float) DTypeUtils.toReal(o); // PRIM_TYPE // ADD_CAST 644 float vi = (float) DTypeUtils.toImag(o); // PRIM_TYPE // ADD_CAST 645 646 while (siter.hasNext()) { 647 data[siter.index] = vr; 648 data[siter.index + 1] = vi; 649 } 650 } catch (IllegalArgumentException e) { 651 throw new IllegalArgumentException("Object for setting slice is not a dataset or number"); 652 } 653 } 654 return this; 655 } 656 657 @Override 658 public ComplexFloatDataset iadd(final Object b) { 659 setDirty(); 660 Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); 661 boolean useLong = bds.getElementClass().equals(Long.class); 662 if (bds.getSize() == 1) { 663 final IndexIterator it = getIterator(); 664 final int bOffset = bds.getOffset(); 665 if (useLong) { // note no complex longs 666 final long lb = bds.getElementLongAbs(bOffset); 667 while (it.hasNext()) { 668 data[it.index] += lb; 669 } 670 } else { 671 final double db = bds.getElementDoubleAbs(bOffset); 672 if (!bds.isComplex() || bds.getElementDoubleAbs(bOffset + 1) == 0) { 673 while (it.hasNext()) { 674 data[it.index] += db; 675 } 676 } else { 677 final double vi = bds.getElementDoubleAbs(bOffset + 1); 678 while (it.hasNext()) { 679 data[it.index] += db; 680 data[it.index + 1] += vi; 681 } 682 } 683 } 684 } else { 685 final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); 686 it.setOutputDouble(!useLong); 687 if (useLong) { // note no complex longs 688 while (it.hasNext()) { 689 data[it.aIndex] += it.bLong; 690 } 691 } else { 692 if (bds.isComplex()) { 693 while (it.hasNext()) { 694 data[it.aIndex] += it.bDouble; 695 data[it.aIndex + 1] += bds.getElementDoubleAbs(it.bIndex + 1); 696 } 697 } else { 698 while (it.hasNext()) { 699 data[it.aIndex] += it.bDouble; 700 } 701 } 702 } 703 } 704 return this; 705 } 706 707 @Override 708 public ComplexFloatDataset isubtract(final Object b) { 709 setDirty(); 710 Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); 711 boolean useLong = bds.getElementClass().equals(Long.class); 712 if (bds.getSize() == 1) { 713 final IndexIterator it = getIterator(); 714 final int bOffset = bds.getOffset(); 715 if (useLong) { // note no complex longs 716 final long lb = bds.getElementLongAbs(bOffset); 717 while (it.hasNext()) { 718 data[it.index] -= lb; 719 } 720 } else { 721 final double db = bds.getElementDoubleAbs(bOffset); 722 if (!bds.isComplex() || bds.getElementDoubleAbs(bOffset + 1) == 0) { 723 while (it.hasNext()) { 724 data[it.index] -= db; 725 } 726 } else { 727 final double vi = bds.getElementDoubleAbs(bOffset + 1); 728 while (it.hasNext()) { 729 data[it.index] -= db; 730 data[it.index + 1] -= vi; 731 } 732 } 733 } 734 } else { 735 final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); 736 it.setOutputDouble(!useLong); 737 if (useLong) { // note no complex longs 738 while (it.hasNext()) { 739 data[it.aIndex] -= it.bLong; 740 } 741 } else { 742 if (bds.isComplex()) { 743 while (it.hasNext()) { 744 data[it.aIndex] -= it.bDouble; 745 data[it.aIndex + 1] -= bds.getElementDoubleAbs(it.bIndex + 1); 746 } 747 } else { 748 while (it.hasNext()) { 749 data[it.aIndex] -= it.bDouble; 750 } 751 } 752 } 753 } 754 return this; 755 } 756 757 @Override 758 public ComplexFloatDataset imultiply(final Object b) { 759 setDirty(); 760 Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); 761 boolean useLong = bds.getElementClass().equals(Long.class); 762 if (bds.getSize() == 1) { 763 final IndexIterator it = getIterator(); 764 final int bOffset = bds.getOffset(); 765 if (useLong) { // note no complex longs 766 final long r2 = bds.getElementLongAbs(bOffset); 767 while (it.hasNext()) { 768 data[it.index] *= r2; 769 data[it.index + 1] *= r2; 770 } 771 } else { 772 final double r2 = bds.getElementDoubleAbs(bOffset); 773 if (!bds.isComplex() || bds.getElementDoubleAbs(bOffset + 1) == 0) { 774 while (it.hasNext()) { 775 data[it.index] *= r2; 776 data[it.index + 1] *= r2; 777 } 778 } else { 779 final double i2 = bds.getElementDoubleAbs(bOffset + 1); 780 while (it.hasNext()) { 781 double r1 = data[it.index]; 782 double i1 = data[it.index + 1]; 783 data[it.index] = (float) (r1*r2 - i1*i2); // ADD_CAST 784 data[it.index + 1] = (float) (r1*i2 + i1*r2); // ADD_CAST 785 } 786 } 787 } 788 } else { 789 final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); 790 it.setOutputDouble(!useLong); 791 if (useLong) { // note no complex longs 792 while (it.hasNext()) { 793 data[it.aIndex] *= it.bDouble; 794 data[it.aIndex + 1] *= it.bDouble; 795 } 796 } else { 797 if (bds.isComplex()) { 798 while (it.hasNext()) { 799 double r1 = it.aDouble; 800 double r2 = it.bDouble; 801 double i1 = data[it.aIndex + 1]; 802 double i2 = bds.getElementDoubleAbs(it.bIndex + 1); 803 data[it.aIndex] = (float) (r1*r2 - i1*i2); // ADD_CAST 804 data[it.aIndex + 1] = (float) (r1*i2 + i1*r2); // ADD_CAST 805 } 806 } else { 807 while (it.hasNext()) { 808 data[it.aIndex] *= it.bDouble; 809 data[it.aIndex + 1] *= it.bDouble; 810 } 811 } 812 } 813 } 814 return this; 815 } 816 817 @Override 818 public ComplexFloatDataset idivide(final Object b) { 819 setDirty(); 820 Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); 821 boolean useLong = bds.getElementClass().equals(Long.class); 822 if (bds.getSize() == 1) { 823 final IndexIterator it = getIterator(); 824 final int bOffset = bds.getOffset(); 825 if (useLong) { // note no complex longs 826 final long r2 = bds.getElementLongAbs(bOffset); 827 while (it.hasNext()) { 828 data[it.index] /= r2; 829 data[it.index + 1] /= r2; 830 } 831 } else { 832 final double r2 = bds.getElementDoubleAbs(bOffset); 833 if (!bds.isComplex() || bds.getElementDoubleAbs(bOffset + 1) == 0) { 834 while (it.hasNext()) { 835 data[it.index] /= r2; 836 data[it.index + 1] /= r2; 837 } 838 } else { 839 final double i2 = bds.getElementDoubleAbs(bOffset + 1); 840 if (Math.abs(r2) < Math.abs(i2)) { 841 double q = r2/i2; 842 double den = r2*q + i2; 843 while (it.hasNext()) { 844 double r1 = data[it.index]; 845 double i1 = data[it.index + 1]; 846 data[it.index] = (float) ((r1*q + i1) / den); // ADD_CAST 847 data[it.index + 1] = (float) ((i1*q - r1) / den); // ADD_CAST 848 } 849 } else { 850 double q = i2/r2; 851 double den = i2*q + r2; 852 if (den == 0) { 853 while (it.hasNext()) { 854 data[it.index] = Float.NaN; // CLASS_TYPE 855 data[it.index + 1] = Float.NaN; // CLASS_TYPE 856 } 857 } else { 858 while (it.hasNext()) { 859 double r1 = data[it.index]; 860 double i1 = data[it.index + 1]; 861 data[it.index] = (float) ((i1 * q + r1) / den); // ADD_CAST 862 data[it.index + 1] = (float) ((i1 - r1 * q) / den); // ADD_CAST 863 } 864 } 865 } 866 } 867 } 868 } else { 869 final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); 870 it.setOutputDouble(!useLong); 871 if (useLong) { 872 while (it.hasNext()) { 873 data[it.aIndex] /= it.bLong; 874 data[it.aIndex + 1] /= it.bLong; 875 } 876 } else { 877 if (bds.isComplex()) { 878 while (it.hasNext()) { 879 double r1 = it.aDouble; 880 double r2 = it.bDouble; 881 double i1 = data[it.aIndex + 1]; 882 double i2 = bds.getElementDoubleAbs(it.bIndex + 1); 883 if (Math.abs(r2) < Math.abs(i2)) { 884 double q = r2/i2; 885 double den = r2*q + i2; 886 data[it.aIndex] = (float) ((r1*q + i1) / den); // ADD_CAST 887 data[it.aIndex + 1] = (float) ((i1*q - r1) / den); // ADD_CAST 888 } else { 889 double q = i2/r2; 890 double den = i2*q + r2; 891 if (den == 0) { 892 data[it.aIndex] = Float.NaN; // CLASS_TYPE 893 data[it.aIndex + 1] = Float.NaN; // CLASS_TYPE 894 } else { 895 data[it.aIndex] = (float) ((i1 * q + r1) / den); // ADD_CAST 896 data[it.aIndex + 1] = (float) ((i1 - r1 * q) / den); // ADD_CAST 897 } 898 } 899 } 900 } else { 901 while (it.hasNext()) { 902 data[it.aIndex] /= it.bDouble; 903 data[it.aIndex + 1] /= it.bDouble; 904 } 905 } 906 } 907 } 908 return this; 909 } 910 911 @Override 912 public ComplexFloatDataset iremainder(final Object b) { 913 throw new UnsupportedOperationException("Unsupported method for class"); 914 } 915 916 @Override 917 public ComplexFloatDataset ipower(final Object b) { 918 setDirty(); 919 Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); 920 if (bds.getSize() == 1) { 921 final IndexIterator it = getIterator(); 922 final int bOffset = bds.getOffset(); 923 final double r2 = bds.getElementDoubleAbs(bOffset); 924 if (!bds.isComplex() || bds.getElementDoubleAbs(bOffset + 1) == 0) { 925 while (it.hasNext()) { 926 final Complex zd = new Complex(data[it.index], data[it.index + 1]).pow(r2); 927 data[it.index] = (float) zd.getReal(); // ADD_CAST 928 data[it.index + 1] = (float) zd.getImaginary(); // ADD_CAST 929 } 930 } else { 931 final Complex zv = new Complex(r2, bds.getElementDoubleAbs(bOffset + 1)); 932 while (it.hasNext()) { 933 final Complex zd = new Complex(data[it.index], data[it.index + 1]).pow(zv); 934 data[it.index] = (float) zd.getReal(); // ADD_CAST 935 data[it.index + 1] = (float) zd.getImaginary(); // ADD_CAST 936 } 937 } 938 } else { 939 final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); 940 it.setOutputDouble(true); 941 if (bds.isComplex()) { 942 while (it.hasNext()) { 943 final Complex zv = new Complex(it.bDouble, bds.getElementDoubleAbs(it.bIndex + 1)); 944 final Complex zd = new Complex(it.aDouble, data[it.aIndex + 1]).pow(zv); 945 data[it.aIndex] = (float) zd.getReal(); // ADD_CAST 946 data[it.aIndex + 1] = (float) zd.getImaginary(); // ADD_CAST 947 } 948 } else { 949 while (it.hasNext()) { 950 final Complex zd = new Complex(it.aDouble, data[it.aIndex + 1]).pow(it.bDouble); 951 data[it.aIndex] = (float) zd.getReal(); // ADD_CAST 952 data[it.aIndex + 1] = (float) zd.getImaginary(); // ADD_CAST 953 } 954 } 955 } 956 return this; 957 } 958 959 @Override 960 public double residual(final Object b, Dataset w, boolean ignoreNaNs) { 961 Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); 962 final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); 963 it.setOutputDouble(true); 964 double sum = 0; 965 double comp = 0; 966 final int bis = bds.getElementsPerItem(); 967 968 if (bis == 1) { 969 if (w == null) { 970 while (it.hasNext()) { 971 double diffr = it.aDouble - it.bDouble; 972 double diffi = data[it.aIndex + 1]; 973 if (ignoreNaNs && (Double.isNaN(diffr) || Double.isNaN(diffi))) { 974 continue; 975 } 976 double err = diffr * diffr - comp; 977 double temp = sum + err; 978 comp = (temp - sum) - err; 979 sum = temp; 980 981 err = diffi * diffi - comp; 982 temp = sum + err; 983 comp = (temp - sum) - err; 984 sum = temp; 985 } 986 } else { 987 IndexIterator itw = w.getIterator(); 988 while (it.hasNext() && itw.hasNext()) { 989 final double dw = w.getElementDoubleAbs(itw.index); 990 double diffr = it.aDouble - it.bDouble; 991 double diffi = data[it.aIndex + 1]; 992 if (ignoreNaNs && (Double.isNaN(diffr) || Double.isNaN(diffi))) { 993 continue; 994 } 995 double err = diffr * diffr * dw - comp; 996 double temp = sum + err; 997 comp = (temp - sum) - err; 998 sum = temp; 999 1000 err = diffi * diffi * dw - comp; 1001 temp = sum + err; 1002 comp = (temp - sum) - err; 1003 sum = temp; 1004 } 1005 } 1006 } else { 1007 if (w == null) { 1008 while (it.hasNext()) { 1009 double diffr = it.aDouble - it.bDouble; 1010 double diffi = data[it.aIndex] - bds.getElementDoubleAbs(it.bIndex + 1); 1011 if (ignoreNaNs && (Double.isNaN(diffr) || Double.isNaN(diffi))) { 1012 continue; 1013 } 1014 double err = diffr * diffr - comp; 1015 double temp = sum + err; 1016 comp = (temp - sum) - err; 1017 sum = temp; 1018 1019 err = diffi * diffi - comp; 1020 temp = sum + err; 1021 comp = (temp - sum) - err; 1022 sum = temp; 1023 } 1024 } else { 1025 IndexIterator itw = w.getIterator(); 1026 while (it.hasNext() && itw.hasNext()) { 1027 final double dw = w.getElementDoubleAbs(itw.index); 1028 double diffr = it.aDouble - it.bDouble; 1029 double diffi = data[it.aIndex] - bds.getElementDoubleAbs(it.bIndex + 1); 1030 if (ignoreNaNs && (Double.isNaN(diffr) || Double.isNaN(diffi))) { 1031 continue; 1032 } 1033 double err = diffr * diffr * dw - comp; 1034 double temp = sum + err; 1035 comp = (temp - sum) - err; 1036 sum = temp; 1037 1038 err = diffi * diffi * dw - comp; 1039 temp = sum + err; 1040 comp = (temp - sum) - err; 1041 sum = temp; 1042 } 1043 } 1044 } 1045 return sum; 1046 } 1047}