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