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