Java tutorial
/*- ******************************************************************************* * Copyright (c) 2011, 2014 Diamond Light Source Ltd. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Peter Chang - initial API and implementation and/or initial documentation *******************************************************************************/ // This is generated from ComplexDoubleDataset.java by fromcpxdouble.py package org.eclipse.dataset; import java.util.Arrays; import org.apache.commons.math3.complex.Complex; import org.apache.commons.math3.stat.descriptive.SummaryStatistics; /** * Extend compound dataset to hold complex float values // PRIM_TYPE */ public class ComplexFloatDataset extends CompoundFloatDataset { // CLASS_TYPE // pin UID to base class private static final long serialVersionUID = Dataset.serialVersionUID; private static final int ISIZE = 2; // number of elements per item @Override public int getDtype() { return Dataset.COMPLEX64; // DATA_TYPE } public ComplexFloatDataset() { super(ISIZE); } /** * Create a zero-filled dataset of given shape * @param shape */ public ComplexFloatDataset(final int... shape) { super(ISIZE, shape); } /** * Create a dataset using given data (real and imaginary parts are grouped in pairs) * @param data * @param shape (can be null to create 1D dataset) */ public ComplexFloatDataset(final float[] data, final int... shape) { // PRIM_TYPE super(ISIZE, data, shape); } /** * Copy a dataset * @param dataset */ public ComplexFloatDataset(final ComplexFloatDataset dataset) { super(dataset); } /** * Create a dataset using given data (real and imaginary parts are given separately) * @param realData * @param imagData * @param shape (can be null to create 1D dataset) */ public ComplexFloatDataset(final float[] realData, final float[] imagData, int... shape) { // PRIM_TYPE if (realData == null || imagData == null) { throw new IllegalArgumentException("Data must not be null"); } int dsize = realData.length > imagData.length ? imagData.length : realData.length; if (shape == null || shape.length == 0) { shape = new int[] { dsize }; } isize = ISIZE; size = calcSize(shape); if (size != dsize) { throw new IllegalArgumentException(String.format( "Shape %s is not compatible with size of data array, %d", Arrays.toString(shape), dsize)); } this.shape = shape.clone(); odata = data = createArray(size); for (int i = 0, n = 0; i < size; i++) { data[n++] = realData[i]; data[n++] = imagData[i]; } } /** * Create a dataset using given data (real and imaginary parts are given separately) * @param real * @param imag */ public ComplexFloatDataset(final Dataset real, final Dataset imag) { super(ISIZE, real.getShapeRef()); real.checkCompatibility(imag); IndexIterator riter = real.getIterator(); IndexIterator iiter = imag.getIterator(); for (int i = 0; riter.hasNext() && iiter.hasNext();) { data[i++] = (float) real.getElementDoubleAbs(riter.index); // ADD_CAST data[i++] = (float) imag.getElementDoubleAbs(iiter.index); // ADD_CAST } } /** * Cast a dataset to this complex type * @param dataset */ public ComplexFloatDataset(final Dataset dataset) { super(ISIZE, dataset.getShapeRef()); copyToView(dataset, this, true, false); offset = 0; stride = null; base = null; IndexIterator iter = dataset.getIterator(); int disize = dataset.getElementsPerItem(); if (disize == 1) { for (int i = 0; iter.hasNext(); i += isize) { data[i] = (float) dataset.getElementDoubleAbs(iter.index); // ADD_CAST } } else { for (int i = 0; iter.hasNext(); i += isize) { data[i] = (float) dataset.getElementDoubleAbs(iter.index); // ADD_CAST data[i + 1] = (float) dataset.getElementDoubleAbs(iter.index + 1); // ADD_CAST } } } @Override public ComplexFloatDataset clone() { return new ComplexFloatDataset(this); } /** * Create a dataset from an object which could be a Java list, array (of arrays...) * or Number. Ragged sequences or arrays are padded with zeros. * * @param obj * @return dataset with contents given by input */ public static ComplexFloatDataset createFromObject(final Object obj) { ComplexFloatDataset result = new ComplexFloatDataset(); result.shape = getShapeFromObject(obj); result.size = calcSize(result.shape); result.odata = result.data = result.createArray(result.size); int[] pos = new int[result.shape.length]; result.fillData(obj, 0, pos); return result; } /** * @param stop * @return a new 1D dataset, filled with values determined by parameters * @deprecated Use {@link #createRange(double)} */ @Deprecated public static ComplexFloatDataset arange(final double stop) { return createRange(0, stop, 1); } /** * @param start * @param stop * @param step * @return a new 1D dataset, filled with values determined by parameters * @deprecated Use {@link #createRange(double, double, double)} */ @Deprecated public static ComplexFloatDataset arange(final double start, final double stop, final double step) { return createRange(start, stop, step); } /** * @param stop * @return a new 1D dataset, filled with values determined by parameters */ public static ComplexFloatDataset createRange(final double stop) { return createRange(0, stop, 1); } /** * @param start * @param stop * @param step * @return a new 1D dataset, filled with values determined by parameters */ public static ComplexFloatDataset createRange(final double start, final double stop, final double step) { int size = calcSteps(start, stop, step); ComplexFloatDataset result = new ComplexFloatDataset(size); for (int i = 0; i < size; i++) { result.data[i * ISIZE] = (float) (start + i * step); // ADD_CAST } return result; } /** * @param shape * @return a dataset filled with ones */ public static ComplexFloatDataset ones(final int... shape) { return new ComplexFloatDataset(shape).fill(1); } @Override public ComplexFloatDataset fill(final Object obj) { float vr = (float) toReal(obj); // PRIM_TYPE // ADD_CAST float vi = (float) toImag(obj); // PRIM_TYPE // ADD_CAST IndexIterator iter = getIterator(); while (iter.hasNext()) { data[iter.index] = vr; data[iter.index + 1] = vi; } setDirty(); return this; } @Override public ComplexFloatDataset getView() { ComplexFloatDataset view = new ComplexFloatDataset(); copyToView(this, view, true, true); view.data = data; return view; } /** * Get complex value at absolute index in the internal array. * * This is an internal method with no checks so can be dangerous. Use with care or ideally with an iterator. * * @param index absolute index * @return value */ public Complex getComplexAbs(final int index) { return new Complex(data[index], data[index + 1]); } @Override public Object getObjectAbs(final int index) { return new Complex(data[index], data[index + 1]); } @Override public String getStringAbs(final int index) { float di = data[index + 1]; // PRIM_TYPE if (stringFormat == null) { return di >= 0 ? String.format("%.8g + %.8gj", data[index], di) : // FORMAT_STRING String.format("%.8g - %.8gj", data[index], -di); // FORMAT_STRING } StringBuilder s = new StringBuilder(); s.append(stringFormat.format(data[index])); if (di >= 0) { s.append(" + "); s.append(stringFormat.format(di)); } else { s.append(" - "); s.append(stringFormat.format(-di)); } s.append('j'); return s.toString(); } /** * Set values at absolute index in the internal array. * * This is an internal method with no checks so can be dangerous. Use with care or ideally with an iterator. * @param index absolute index * @param val new values */ public void setAbs(final int index, final Complex val) { setAbs(index, (float) val.getReal(), (float) val.getImaginary()); // PRIM_TYPE } @Override public void setObjectAbs(final int index, final Object obj) { setAbs(index, (float) toReal(obj), (float) toImag(obj)); // PRIM_TYPE } /** * Set item at index to complex value given by real and imaginary parts * @param index absolute index * @param real * @param imag */ public void setAbs(final int index, final float real, final float imag) { // PRIM_TYPE data[index] = real; data[index + 1] = imag; setDirty(); } /** * @param i * @return item in given position */ public Complex get(final int i) { int n = get1DIndex(i); Complex z = new Complex(data[n], data[n + 1]); return z; } /** * @param i * @param j * @return item in given position */ public Complex get(final int i, final int j) { int n = get1DIndex(i, j); Complex z = new Complex(data[n], data[n + 1]); return z; } /** * @param pos * @return item in given position */ public Complex get(final int... pos) { int n = get1DIndex(pos); Complex z = new Complex(data[n], data[n + 1]); return z; } @Override public Object getObject(final int i) { return getComplex(i); } @Override public Object getObject(final int i, final int j) { return getComplex(i, j); } @Override public Object getObject(final int... pos) { return getComplex(pos); } /** * @param i * @return item in given position */ public float getReal(final int i) { // PRIM_TYPE return (float) getFirstValue(i); // PRIM_TYPE } /** * @param i * @param j * @return item in given position */ public float getReal(final int i, final int j) { // PRIM_TYPE return (float) getFirstValue(i, j); // PRIM_TYPE } /** * @param pos * @return item in given position */ public float getReal(final int... pos) { // PRIM_TYPE return (float) getFirstValue(pos); // PRIM_TYPE } /** * @param i * @return item in given position */ public float getImag(final int i) { // PRIM_TYPE return data[get1DIndex(i) + 1]; } /** * @param i * @param j * @return item in given position */ public float getImag(final int i, final int j) { // PRIM_TYPE return data[get1DIndex(i, j) + 1]; } /** * @param pos * @return item in given position */ public float getImag(final int... pos) { // PRIM_TYPE return data[get1DIndex(pos) + 1]; } /** * @param i * @return item in given position */ public Complex getComplex(final int i) { return get(i); } /** * @param i * @param j * @return item in given position */ public Complex getComplex(final int i, final int j) { return get(i, j); } /** * @param pos * @return item in given position */ public Complex getComplex(final int... pos) { return get(pos); } @Override public void set(final Object obj, final int i) { setItem(new float[] { (float) toReal(obj), (float) toImag(obj) }, i); // PRIM_TYPE } @Override public void set(final Object obj, final int i, final int j) { setItem(new float[] { (float) toReal(obj), (float) toImag(obj) }, i, j); // PRIM_TYPE } @Override public void set(final Object obj, int... pos) { if (pos == null || (pos.length == 0 && shape.length > 0)) { pos = new int[shape.length]; } setItem(new float[] { (float) toReal(obj), (float) toImag(obj) }, pos); // PRIM_TYPE } /** * Set real and imaginary values at given position * @param dr * @param di * @param i */ public void set(final float dr, final float di, final int i) { // PRIM_TYPE setItem(new float[] { dr, di }, i); // PRIM_TYPE } /** * Set real and imaginary values at given position * @param dr * @param di * @param i * @param j */ public void set(final float dr, final float di, final int i, final int j) { // PRIM_TYPE setItem(new float[] { dr, di }, i, j); // PRIM_TYPE } /** * Set real and imaginary values at given position * @param dr * @param di * @param pos */ public void set(final float dr, final float di, final int... pos) { // PRIM_TYPE setItem(new float[] { dr, di }, pos); // PRIM_TYPE } public FloatDataset imag() { // CLASS_TYPE FloatDataset rdataset = new FloatDataset(shape); // CLASS_TYPE IndexIterator iter = getIterator(); IndexIterator riter = rdataset.getIterator(); float[] rdata = rdataset.data; // PRIM_TYPE while (iter.hasNext() && riter.hasNext()) rdata[riter.index] = data[iter.index + 1]; return rdataset; } /** * @return view of imaginary values */ public FloatDataset imagView() { // CLASS_TYPE return getElementsView(1); } @Override public Number max(boolean... switches) { throw new UnsupportedOperationException("Cannot compare complex numbers"); } @Override public Number min(boolean... switches) { throw new UnsupportedOperationException("Cannot compare complex numbers"); } @Override public Object sum() { final String n = storeName(false, STORE_STATS_ITEM_NAME); if (storedValues == null || storedValues.isEmpty()) { calculateSummaryStats(false, false, n); } final SummaryStatistics rstats = (SummaryStatistics) storedValues.get(n + "0"); final SummaryStatistics istats = (SummaryStatistics) storedValues.get(n + "1"); return new Complex(rstats.getSum(), istats.getSum()); } @Override public Object mean(boolean... switches) { final String n = storeName(false, STORE_STATS_ITEM_NAME); if (storedValues == null || storedValues.isEmpty()) { calculateSummaryStats(false, false, n); } final SummaryStatistics rstats = (SummaryStatistics) storedValues.get(n + "0"); final SummaryStatistics istats = (SummaryStatistics) storedValues.get(n + "1"); return new Complex(rstats.getMean(), istats.getMean()); } @Override public int[] maxPos(boolean ignoreNaNs) { throw new UnsupportedOperationException("Cannot compare complex numbers"); } @Override public int[] minPos(boolean ignoreNaNs) { throw new UnsupportedOperationException("Cannot compare complex numbers"); } @Override public ComplexFloatDataset getSlice(final SliceIterator siter) { ComplexFloatDataset result = new ComplexFloatDataset(siter.getShape()); float[] rdata = result.data; // PRIM_TYPE IndexIterator riter = result.getIterator(); while (siter.hasNext() && riter.hasNext()) { rdata[riter.index] = data[siter.index]; rdata[riter.index + 1] = data[siter.index + 1]; } result.setName(name + BLOCK_OPEN + Slice.createString(siter.shape, siter.start, siter.stop, siter.step) + BLOCK_CLOSE); return result; } @Override ComplexFloatDataset setSlicedView(Dataset view, Dataset d) { final BroadcastIterator it = BroadcastIterator.createIterator(view, d); if (d instanceof ComplexFloatDataset || d instanceof ComplexFloatDataset) { while (it.hasNext()) { data[it.aIndex] = (float) it.bDouble; // ADD_CAST data[it.aIndex + 1] = (float) d.getElementDoubleAbs(it.bIndex + 1); // GET_ELEMENT_WITH_CAST } } else { while (it.hasNext()) { data[it.aIndex] = (float) it.bDouble; // ADD_CAST data[it.aIndex + 1] = 0; } } return this; } @Override public ComplexFloatDataset setSlice(final Object o, final IndexIterator siter) { if (o instanceof ComplexFloatDataset) { ComplexFloatDataset zds = (ComplexFloatDataset) o; if (!areShapesCompatible(siter.getShape(), zds.shape)) { throw new IllegalArgumentException( String.format("Input dataset is not compatible with slice: %s cf %s", Arrays.toString(zds.shape), Arrays.toString(siter.getShape()))); } IndexIterator oiter = zds.getIterator(); float[] odata = zds.data; while (siter.hasNext() && oiter.hasNext()) { data[siter.index] = odata[oiter.index]; data[siter.index + 1] = odata[oiter.index + 1]; } } else if (o instanceof ComplexDoubleDataset) { // IGNORE_CLASS ComplexDoubleDataset zds = (ComplexDoubleDataset) o; // IGNORE_CLASS if (!areShapesCompatible(siter.getShape(), zds.shape)) { throw new IllegalArgumentException( String.format("Input dataset is not compatible with slice: %s cf %s", Arrays.toString(zds.shape), Arrays.toString(siter.getShape()))); } IndexIterator oiter = zds.getIterator(); double[] odata = zds.data; while (siter.hasNext() && oiter.hasNext()) { data[siter.index] = (float) odata[oiter.index]; // PRIM_TYPE // ADD_CAST data[siter.index + 1] = (float) odata[oiter.index + 1]; // PRIM_TYPE // ADD_CAST } } else if (o instanceof IDataset) { super.setSlice(o, siter); } else { try { float vr = (float) toReal(o); // PRIM_TYPE // ADD_CAST float vi = (float) toImag(o); // PRIM_TYPE // ADD_CAST while (siter.hasNext()) { data[siter.index] = vr; data[siter.index + 1] = vi; } } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Object for setting slice is not a dataset or number"); } } setDirty(); return this; } @Override public ComplexFloatDataset iadd(final Object b) { Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); boolean useLong = bds.elementClass().equals(Long.class); if (bds.getSize() == 1) { final IndexIterator it = getIterator(); if (useLong) { // note no complex longs final long lb = bds.getElementLongAbs(0); while (it.hasNext()) { data[it.index] += lb; } } else { final double db = bds.getElementDoubleAbs(0); if (!bds.isComplex() || bds.getElementDoubleAbs(1) == 0) { while (it.hasNext()) { data[it.index] += db; } } else { final double vi = bds.getElementDoubleAbs(1); while (it.hasNext()) { data[it.index] += db; data[it.index + 1] += vi; } } } } else { final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); it.setOutputDouble(!useLong); if (useLong) { // note no complex longs while (it.hasNext()) { data[it.aIndex] += it.bLong; } } else { if (bds.isComplex()) { while (it.hasNext()) { data[it.aIndex] += it.bDouble; data[it.aIndex + 1] += bds.getElementDoubleAbs(it.bIndex + 1); } } else { while (it.hasNext()) { data[it.aIndex] += it.bDouble; } } } } setDirty(); return this; } @Override public ComplexFloatDataset isubtract(final Object b) { Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); boolean useLong = bds.elementClass().equals(Long.class); if (bds.getSize() == 1) { final IndexIterator it = getIterator(); if (useLong) { // note no complex longs final long lb = bds.getElementLongAbs(0); while (it.hasNext()) { data[it.index] -= lb; } } else { final double db = bds.getElementDoubleAbs(0); if (!bds.isComplex() || bds.getElementDoubleAbs(1) == 0) { while (it.hasNext()) { data[it.index] -= db; } } else { final double vi = bds.getElementDoubleAbs(1); while (it.hasNext()) { data[it.index] -= db; data[it.index + 1] -= vi; } } } } else { final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); it.setOutputDouble(!useLong); if (useLong) { // note no complex longs while (it.hasNext()) { data[it.aIndex] -= it.bLong; } } else { if (bds.isComplex()) { while (it.hasNext()) { data[it.aIndex] -= it.bDouble; data[it.aIndex + 1] -= bds.getElementDoubleAbs(it.bIndex + 1); } } else { while (it.hasNext()) { data[it.aIndex] -= it.bDouble; } } } } setDirty(); return this; } @Override public ComplexFloatDataset imultiply(final Object b) { Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); boolean useLong = bds.elementClass().equals(Long.class); if (bds.getSize() == 1) { final IndexIterator it = getIterator(); if (useLong) { // note no complex longs final long r2 = bds.getElementLongAbs(0); while (it.hasNext()) { data[it.index] *= r2; data[it.index + 1] *= r2; } } else { final double r2 = bds.getElementDoubleAbs(0); if (!bds.isComplex() || bds.getElementDoubleAbs(1) == 0) { while (it.hasNext()) { data[it.index] *= r2; data[it.index + 1] *= r2; } } else { final double i2 = bds.getElementDoubleAbs(1); while (it.hasNext()) { double r1 = data[it.index]; double i1 = data[it.index + 1]; data[it.index] = (float) (r1 * r2 - i1 * i2); // ADD_CAST data[it.index + 1] = (float) (r1 * i2 + i1 * r2); // ADD_CAST } } } } else { final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); it.setOutputDouble(!useLong); if (useLong) { // note no complex longs while (it.hasNext()) { data[it.aIndex] *= it.bDouble; data[it.aIndex + 1] *= it.bDouble; } } else { if (bds.isComplex()) { while (it.hasNext()) { double r1 = it.aDouble; double r2 = it.bDouble; double i1 = data[it.aIndex + 1]; double i2 = bds.getElementDoubleAbs(it.bIndex + 1); data[it.aIndex] = (float) (r1 * r2 - i1 * i2); // ADD_CAST data[it.aIndex + 1] = (float) (r1 * i2 + i1 * r2); // ADD_CAST } } else { while (it.hasNext()) { data[it.aIndex] *= it.bDouble; data[it.aIndex + 1] *= it.bDouble; } } } } setDirty(); return this; } @Override public ComplexFloatDataset idivide(final Object b) { Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); boolean useLong = bds.elementClass().equals(Long.class); if (bds.getSize() == 1) { final IndexIterator it = getIterator(); if (useLong) { // note no complex longs final long r2 = bds.getElementLongAbs(0); while (it.hasNext()) { data[it.index] /= r2; data[it.index + 1] /= r2; } } else { final double r2 = bds.getElementDoubleAbs(0); if (!bds.isComplex() || bds.getElementDoubleAbs(1) == 0) { while (it.hasNext()) { data[it.index] /= r2; data[it.index + 1] /= r2; } } else { final double i2 = bds.getElementDoubleAbs(1); if (Math.abs(r2) < Math.abs(i2)) { double q = r2 / i2; double den = r2 * q + i2; while (it.hasNext()) { double r1 = data[it.index]; double i1 = data[it.index + 1]; data[it.index] = (float) ((r1 * q + i1) / den); // ADD_CAST data[it.index + 1] = (float) ((i1 * q - r1) / den); // ADD_CAST } } else { double q = i2 / r2; double den = i2 * q + r2; if (den == 0) { while (it.hasNext()) { data[it.index] = Float.NaN; // CLASS_TYPE data[it.index + 1] = Float.NaN; // CLASS_TYPE } } else { while (it.hasNext()) { double r1 = data[it.index]; double i1 = data[it.index + 1]; data[it.index] = (float) ((i1 * q + r1) / den); // ADD_CAST data[it.index + 1] = (float) ((i1 - r1 * q) / den); // ADD_CAST } } } } } } else { final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); it.setOutputDouble(!useLong); if (useLong) { while (it.hasNext()) { data[it.aIndex] /= it.bLong; data[it.aIndex + 1] /= it.bLong; } } else { if (bds.isComplex()) { while (it.hasNext()) { double r1 = it.aDouble; double r2 = it.bDouble; double i1 = data[it.aIndex + 1]; double i2 = bds.getElementDoubleAbs(it.bIndex + 1); if (Math.abs(r2) < Math.abs(i2)) { double q = r2 / i2; double den = r2 * q + i2; data[it.aIndex] = (float) ((r1 * q + i1) / den); // ADD_CAST data[it.aIndex + 1] = (float) ((i1 * q - r1) / den); // ADD_CAST } else { double q = i2 / r2; double den = i2 * q + r2; if (den == 0) { data[it.aIndex] = Float.NaN; // CLASS_TYPE data[it.aIndex + 1] = Float.NaN; // CLASS_TYPE } else { data[it.aIndex] = (float) ((i1 * q + r1) / den); // ADD_CAST data[it.aIndex + 1] = (float) ((i1 - r1 * q) / den); // ADD_CAST } } } } else { while (it.hasNext()) { data[it.aIndex] /= it.bDouble; data[it.aIndex + 1] /= it.bDouble; } } } } setDirty(); return this; } @Override public ComplexFloatDataset iremainder(final Object b) { throw new UnsupportedOperationException("Unsupported method for class"); } @Override public ComplexFloatDataset ipower(final Object b) { Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); if (bds.getSize() == 1) { final IndexIterator it = getIterator(); final double r2 = bds.getElementDoubleAbs(0); if (!bds.isComplex() || bds.getElementDoubleAbs(1) == 0) { while (it.hasNext()) { final Complex zd = new Complex(data[it.index], data[it.index + 1]).pow(r2); data[it.index] = (float) zd.getReal(); // ADD_CAST data[it.index + 1] = (float) zd.getImaginary(); // ADD_CAST } } else { final Complex zv = new Complex(r2, bds.getElementDoubleAbs(1)); while (it.hasNext()) { final Complex zd = new Complex(data[it.index], data[it.index + 1]).pow(zv); data[it.index] = (float) zd.getReal(); // ADD_CAST data[it.index + 1] = (float) zd.getImaginary(); // ADD_CAST } } } else { final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); it.setOutputDouble(true); if (bds.isComplex()) { while (it.hasNext()) { final Complex zv = new Complex(it.bDouble, bds.getElementDoubleAbs(it.bIndex + 1)); final Complex zd = new Complex(it.aDouble, data[it.aIndex + 1]).pow(zv); data[it.aIndex] = (float) zd.getReal(); // ADD_CAST data[it.aIndex + 1] = (float) zd.getImaginary(); // ADD_CAST } } else { while (it.hasNext()) { final Complex zd = new Complex(it.aDouble, data[it.aIndex + 1]).pow(it.bDouble); data[it.aIndex] = (float) zd.getReal(); // ADD_CAST data[it.aIndex + 1] = (float) zd.getImaginary(); // ADD_CAST } } } setDirty(); return this; } @Override public double residual(final Object b, Dataset w, boolean ignoreNaNs) { Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); it.setOutputDouble(true); double sum = 0; double comp = 0; final int bis = bds.getElementsPerItem(); if (bis == 1) { if (w == null) { while (it.hasNext()) { double diffr = it.aDouble - it.bDouble; double diffi = data[it.aIndex + 1]; if (ignoreNaNs && (Double.isNaN(diffr) || Double.isNaN(diffi))) { continue; } double err = diffr * diffr - comp; double temp = sum + err; comp = (temp - sum) - err; sum = temp; err = diffi * diffi - comp; temp = sum + err; comp = (temp - sum) - err; sum = temp; } } else { IndexIterator itw = w.getIterator(); while (it.hasNext() && itw.hasNext()) { final double dw = w.getElementDoubleAbs(itw.index); double diffr = it.aDouble - it.bDouble; double diffi = data[it.aIndex + 1]; if (ignoreNaNs && (Double.isNaN(diffr) || Double.isNaN(diffi))) { continue; } double err = diffr * diffr * dw - comp; double temp = sum + err; comp = (temp - sum) - err; sum = temp; err = diffi * diffi * dw - comp; temp = sum + err; comp = (temp - sum) - err; sum = temp; } } } else { if (w == null) { while (it.hasNext()) { double diffr = it.aDouble - it.bDouble; double diffi = data[it.aIndex] - bds.getElementDoubleAbs(it.bIndex + 1); if (ignoreNaNs && (Double.isNaN(diffr) || Double.isNaN(diffi))) { continue; } double err = diffr * diffr - comp; double temp = sum + err; comp = (temp - sum) - err; sum = temp; err = diffi * diffi - comp; temp = sum + err; comp = (temp - sum) - err; sum = temp; } } else { IndexIterator itw = w.getIterator(); while (it.hasNext() && itw.hasNext()) { final double dw = w.getElementDoubleAbs(itw.index); double diffr = it.aDouble - it.bDouble; double diffi = data[it.aIndex] - bds.getElementDoubleAbs(it.bIndex + 1); if (ignoreNaNs && (Double.isNaN(diffr) || Double.isNaN(diffi))) { continue; } double err = diffr * diffr * dw - comp; double temp = sum + err; comp = (temp - sum) - err; sum = temp; err = diffi * diffi * dw - comp; temp = sum + err; comp = (temp - sum) - err; sum = temp; } } } return sum; } }