    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// GEN_COMMENT
    014
    015package org.eclipse.january.dataset;
    016
    017import java.util.ArrayList;
    018import java.util.Arrays;
    019import java.util.List;
    020import java.util.Set;
    021import java.util.TreeSet;
    022
    023import org.apache.commons.math3.complex.Complex; // NAN_OMIT
    024import org.eclipse.january.metadata.StatisticsMetadata;
    025
    026
    027/**
    028 * Extend dataset for double values // PRIM_TYPE
    029 */
    030public class DoubleDataset extends AbstractDataset {
    031        // pin UID to base class
    032        private static final long serialVersionUID = Dataset.serialVersionUID;
    033
    034        protected double[] data; // subclass alias // PRIM_TYPE
    035
    036        @Override
    037        protected void setData() {
    038                data = (double[]) odata; // PRIM_TYPE
    039        }
    040
    041        protected static double[] createArray(final int size) { // PRIM_TYPE
    042                double[] array = null; // PRIM_TYPE
    043
    044                try {
    045                        array = new double[size]; // PRIM_TYPE
    046                } catch (OutOfMemoryError e) {
    047                        logger.error("The size of the dataset ({}) that is being created is too large "
    048                                        + "and there is not enough memory to hold it.", size);
    049                        throw new OutOfMemoryError("The dimensions given are too large, and there is "
    050                                        + "not enough memory available in the Java Virtual Machine");
    051                }
    052                return array;
    053        }
    054
    055        @Override
    056        public int getDType() {
    057                return FLOAT64; // DATA_TYPE
    058        }
    059
    060        /**
    061         * Create a null dataset
    062         */
    063        DoubleDataset() {
    064        }
    065
    066        /**
    067         * Create a zero-filled dataset of given shape
    068         * @param shape
    069         */
    070        DoubleDataset(final int... shape) {
    071                if (shape != null) {
    072                        size = ShapeUtils.calcSize(shape);
    073                        this.shape = shape.clone();
    074
    075                        try {
    076                                odata = data = createArray(size);
    077                        } catch (Throwable t) {
    078                                logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    079                                throw new IllegalArgumentException(t);
    080                        }
    081                }
    082        }
    083
    084        /**
    085         * Create a dataset using given data
    086         * @param data
    087         * @param shape
    088         *            (can be null to create 1D dataset)
    089         */
    090        DoubleDataset(final double[] data, int... shape) { // PRIM_TYPE
    091                if (data == null) {
    092                        throw new IllegalArgumentException("Data must not be null");
    093                }
    094                if (shape == null || shape.length == 0) {
    095                        shape = new int[] { data.length };
    096                }
    097                size = ShapeUtils.calcSize(shape);
    098                if (size != data.length) {
    099                        throw new IllegalArgumentException(String.format("Shape %s is not compatible with size of data array, %d",
    100                                        Arrays.toString(shape), data.length));
    101                }
    102                this.shape = size == 0 ? null : shape.clone();
    103
    104                odata = this.data = data;
    105        }
    106
    107        /**
    108         * Copy a dataset
    109         * @param dataset
    110         */
    111        DoubleDataset(final DoubleDataset dataset) {
    112                copyToView(dataset, this, true, true);
    113
    114                try {
    115                        if (dataset.stride == null) {
    116                                if (dataset.data != null) {
    117                                        odata = data = dataset.data.clone();
    118                                }
    119                        } else {
    120                                offset = 0;
    121                                stride = null;
    122                                base = null;
    123                                odata = data = createArray(size);
    124
    125                                IndexIterator iter = dataset.getIterator();
    126                                for (int i = 0; iter.hasNext(); i++) {
    127                                        data[i] = dataset.data[iter.index];
    128                                }
    129                        }
    130                } catch (Throwable t) {
    131                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    132                        throw new IllegalArgumentException(t);
    133                }
    134        }
    135
    136        /**
    137         * Copy and cast a dataset to this class type
    138         * @param dataset
    139         */
    140        DoubleDataset(final Dataset dataset) {
    141                copyToView(dataset, this, true, false);
    142                offset = 0;
    143                stride = null;
    144                base = null;
    145                try {
    146                        odata = data = createArray(size);
    147                } catch (Throwable t) {
    148                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    149                        throw new IllegalArgumentException(t);
    150                }
    151                IndexIterator iter = dataset.getIterator();
    152                for (int i = 0; iter.hasNext(); i++) {
    153                        data[i] = dataset.getElementDoubleAbs(iter.index); // GET_ELEMENT_WITH_CAST
    154                }
    155        }
    156
    157        @Override
    158        public boolean equals(Object obj) {
    159                if (this == obj) {
    160                        return true;
    161                }
    162
    163                if (obj == null) {
    164                        return false;
    165                }
    166
    167                if (!getClass().equals(obj.getClass())) {
    168                        if (getRank() == 0) { // for zero-rank datasets
    169                                return obj.equals(getObjectAbs(offset));
    170                        }
    171                        return false;
    172                }
    173
    174                DoubleDataset other = (DoubleDataset) obj;
    175                if (size != other.size) {
    176                        return false;
    177                }
    178                if (!Arrays.equals(shape, other.shape)) {
    179                        return false;
    180                }
    181                if (data == other.data && stride == null && other.stride == null) {
    182                        return true;
    183                }
    184
    185                IndexIterator iter = getIterator();
    186                IndexIterator oiter = other.getIterator();
    187                while (iter.hasNext() && oiter.hasNext()) {
    188                        if (data[iter.index] != other.data[oiter.index]) { // OBJECT_UNEQUAL
    189                                return false;
    190                        }
    191                }
    192                return true;
    193        }
    194
    195        @Override
    196        public int hashCode() {
    197                return super.hashCode();
    198        }
    199
    200        @Override
    201        public DoubleDataset clone() {
    202                return new DoubleDataset(this);
    203        }
    204
    205        /**
    206         * Create a dataset from an object which could be a Java list, array (of arrays...) or Number. Ragged
    207         * sequences or arrays are padded with zeros.
    208         *
    209         * @param obj
    210         * @return dataset with contents given by input
    211         */
    212        static DoubleDataset createFromObject(final Object obj) {
    213                DoubleDataset result = new DoubleDataset();
    214
    215                if (obj != null) {
    216                        result.shape = ShapeUtils.getShapeFromObject(obj);
    217                        result.size = ShapeUtils.calcSize(result.shape);
    218
    219                        try {
    220                                result.odata = result.data = createArray(result.size);
    221                        } catch (Throwable t) {
    222                                logger.error("Could not create a dataset of shape {}", Arrays.toString(result.shape), t);
    223                                throw new IllegalArgumentException(t);
    224                        }
    225
    226                        int[] pos = new int[result.shape.length];
    227                        result.fillData(obj, 0, pos);
    228                }
    229
    230                return result;
    231        }
    232         // NAN_OMIT
    233        /** // NAN_OMIT
    234         * // NAN_OMIT
    235         * @param stop // NAN_OMIT
    236         * @return a new 1D dataset, filled with values determined by parameters // NAN_OMIT
    237         */ // NAN_OMIT
    238        static DoubleDataset createRange(final double stop) { // NAN_OMIT
    239                return createRange(0, stop, 1); // NAN_OMIT
    240        } // NAN_OMIT
    241         // NAN_OMIT
    242        /** // NAN_OMIT
    243         * // NAN_OMIT
    244         * @param start // NAN_OMIT
    245         * @param stop // NAN_OMIT
    246         * @param step // NAN_OMIT
    247         * @return a new 1D dataset, filled with values determined by parameters // NAN_OMIT
    248         */ // NAN_OMIT
    249        static DoubleDataset createRange(final double start, final double stop, final double step) { // NAN_OMIT
    250                int size = calcSteps(start, stop, step); // NAN_OMIT
    251                DoubleDataset result = new DoubleDataset(size); // NAN_OMIT
    252                for (int i = 0; i < size; i++) { // NAN_OMIT
    253                        result.data[i] = (start + i * step); // PRIM_TYPE // NAN_OMIT // ADD_CAST
    254                } // NAN_OMIT
    255                return result; // NAN_OMIT
    256        } // NAN_OMIT
    257
    258        /**
    259         * @param shape
    260         * @return a dataset filled with ones
    261         */
    262        static DoubleDataset ones(final int... shape) {
    263                return new DoubleDataset(shape).fill(1);
    264        }
    265
    266        @Override
    267        public DoubleDataset fill(final Object obj) {
    268                setDirty();
    269                double dv = DTypeUtils.toReal(obj); // PRIM_TYPE // FROM_OBJECT
    270                IndexIterator iter = getIterator();
    271                while (iter.hasNext()) {
    272                        data[iter.index] = dv;
    273                }
    274
    275                return this;
    276        }
    277
    278        /**
    279         * This is a typed version of {@link #getBuffer()}
    280         * @return data buffer as linear array
    281         */
    282        public double[] getData() { // PRIM_TYPE
    283                return data;
    284        }
    285
    286        @Override
    287        protected int getBufferLength() {
    288                if (data == null)
    289                        return 0;
    290                return data.length;
    291        }
    292
    293        @Override
    294        public DoubleDataset getView(boolean deepCopyMetadata) {
    295                DoubleDataset view = new DoubleDataset();
    296                copyToView(this, view, true, deepCopyMetadata);
    297                view.setData();
    298                return view;
    299        }
    300
    301        /**
    302         * Get a value from an absolute index of the internal array. This is an internal method with no checks so can be
    303         * dangerous. Use with care or ideally with an iterator.
    304         *
    305         * @param index
    306         *            absolute index
    307         * @return value
    308         */
    309        public double getAbs(final int index) { // PRIM_TYPE
    310                return data[index];
    311        }
    312
    313        @Override
    314        public boolean getElementBooleanAbs(final int index) {
    315                return data[index] != 0; // BOOLEAN_FALSE
    316        }
    317
    318        @Override
    319        public double getElementDoubleAbs(final int index) {
    320                return data[index]; // BOOLEAN_ZERO
    321        }
    322
    323        @Override
    324        public long getElementLongAbs(final int index) {
    325                return DTypeUtils.toLong(data[index]); // BOOLEAN_ZERO // OMIT_TOLONG_INT
    326        }
    327
    328        @Override
    329        public Object getObjectAbs(final int index) {
    330                return data[index];
    331        }
    332
    333        @Override
    334        public String getStringAbs(final int index) {
    335                return stringFormat == null ? String.format("%.8g", data[index]) : // FORMAT_STRING
    336                        stringFormat.format(data[index]);
    337        }
    338
    339        /**
    340         * Set a value at absolute index in the internal array. This is an internal method with no checks so can be
    341         * dangerous. Use with care or ideally with an iterator.
    342         *
    343         * @param index
    344         *            absolute index
    345         * @param val
    346         *            new value
    347         */
    348        public void setAbs(final int index, final double val) { // PRIM_TYPE
    349                setDirty();
    350                data[index] = val;
    351        }
    352
    353        @Override
    354        protected void setItemDirect(final int dindex, final int sindex, final Object src) {
    355                setDirty();
    356                double[] dsrc = (double[]) src; // PRIM_TYPE
    357                data[dindex] = dsrc[sindex];
    358        }
    359
    360        @Override
    361        public void setObjectAbs(final int index, final Object obj) {
    362                if (index < 0 || index > data.length) {
    363                        throw new IndexOutOfBoundsException("Index given is outside dataset");
    364                }
    365
    366                setAbs(index, DTypeUtils.toReal(obj)); // FROM_OBJECT
    367        }
    368
    369        /**
    370         * @return item in first position
    371         * @since 2.0
    372         */
    373        public double get() { // PRIM_TYPE
    374                return data[getFirst1DIndex()];
    375        }
    376
    377        /**
    378         * @param i
    379         * @return item in given position
    380         */
    381        public double get(final int i) { // PRIM_TYPE
    382                return data[get1DIndex(i)];
    383        }
    384
    385        /**
    386         * @param i
    387         * @param j
    388         * @return item in given position
    389         */
    390        public double get(final int i, final int j) { // PRIM_TYPE
    391                return data[get1DIndex(i, j)];
    392        }
    393
    394        /**
    395         * @param pos
    396         * @return item in given position
    397         */
    398        public double get(final int... pos) { // PRIM_TYPE
    399                return data[get1DIndex(pos)];
    400        }
    401
    402        @Override
    403        public Object getObject() {
    404                return Double.valueOf(get()); // CLASS_TYPE
    405        }
    406
    407        @Override
    408        public Object getObject(final int i) {
    409                return Double.valueOf(get(i)); // CLASS_TYPE
    410        }
    411
    412        @Override
    413        public Object getObject(final int i, final int j) {
    414                return Double.valueOf(get(i, j)); // CLASS_TYPE
    415        }
    416
    417        @Override
    418        public Object getObject(final int... pos) {
    419                return Double.valueOf(get(pos)); // CLASS_TYPE
    420        }
    421
    422        @Override
    423        public String getString() {
    424                return getStringAbs(getFirst1DIndex());
    425        }
    426
    427        @Override
    428        public String getString(final int i) {
    429                return getStringAbs(get1DIndex(i));
    430        }
    431
    432        @Override
    433        public String getString(final int i, final int j) {
    434                return getStringAbs(get1DIndex(i, j));
    435        }
    436
    437        @Override
    438        public String getString(final int... pos) {
    439                return getStringAbs(get1DIndex(pos));
    440        }
    441
    442        @Override
    443        public double getDouble() {
    444                return get(); // BOOLEAN_ZERO
    445        }
    446
    447        @Override
    448        public double getDouble(final int i) {
    449                return get(i); // BOOLEAN_ZERO
    450        }
    451
    452        @Override
    453        public double getDouble(final int i, final int j) {
    454                return get(i, j); // BOOLEAN_ZERO
    455        }
    456
    457        @Override
    458        public double getDouble(final int... pos) {
    459                return get(pos); // BOOLEAN_ZERO
    460        }
    461
    462        @Override
    463        public float getFloat() {
    464                return (float) get(); // BOOLEAN_ZERO // OMIT_REAL_CAST
    465        }
    466
    467        @Override
    468        public float getFloat(final int i) {
    469                return (float) get(i); // BOOLEAN_ZERO // OMIT_REAL_CAST
    470        }
    471
    472        @Override
    473        public float getFloat(final int i, final int j) {
    474                return (float) get(i, j); // BOOLEAN_ZERO // OMIT_REAL_CAST
    475        }
    476
    477        @Override
    478        public float getFloat(final int... pos) {
    479                return (float) get(pos); // BOOLEAN_ZERO // OMIT_REAL_CAST
    480        }
    481
    482        @Override
    483        public long getLong() {
    484                return (long) get(); // BOOLEAN_ZERO // OMIT_UPCAST
    485        }
    486
    487        @Override
    488        public long getLong(final int i) {
    489                return (long) get(i); // BOOLEAN_ZERO // OMIT_UPCAST
    490        }
    491
    492        @Override
    493        public long getLong(final int i, final int j) {
    494                return (long) get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
    495        }
    496
    497        @Override
    498        public long getLong(final int... pos) {
    499                return (long) get(pos); // BOOLEAN_ZERO // OMIT_UPCAST
    500        }
    501
    502        @Override
    503        public int getInt() {
    504                return (int) get(); // BOOLEAN_ZERO // OMIT_UPCAST
    505        }
    506
    507        @Override
    508        public int getInt(final int i) {
    509                return (int) get(i); // BOOLEAN_ZERO // OMIT_UPCAST
    510        }
    511
    512        @Override
    513        public int getInt(final int i, final int j) {
    514                return (int) get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
    515        }
    516
    517        @Override
    518        public int getInt(final int... pos) {
    519                return (int) get(pos); // BOOLEAN_ZERO // OMIT_UPCAST
    520        }
    521
    522        @Override
    523        public short getShort() {
    524                return (short) get(); // BOOLEAN_ZERO // OMIT_UPCAST
    525        }
    526
    527        @Override
    528        public short getShort(final int i) {
    529                return (short) get(i); // BOOLEAN_ZERO // OMIT_UPCAST
    530        }
    531
    532        @Override
    533        public short getShort(final int i, final int j) {
    534                return (short) get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
    535        }
    536
    537        @Override
    538        public short getShort(final int... pos) {
    539                return (short) get(pos); // BOOLEAN_ZERO // OMIT_UPCAST
    540        }
    541
    542        @Override
    543        public byte getByte() {
    544                return (byte) get(); // BOOLEAN_ZERO // OMIT_UPCAST
    545        }
    546
    547        @Override
    548        public byte getByte(final int i) {
    549                return (byte) get(i); // BOOLEAN_ZERO // OMIT_UPCAST
    550        }
    551
    552        @Override
    553        public byte getByte(final int i, final int j) {
    554                return (byte) get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
    555        }
    556
    557        @Override
    558        public byte getByte(final int... pos) {
    559                return (byte) get(pos); // BOOLEAN_ZERO // OMIT_UPCAST
    560        }
    561
    562        @Override
    563        public boolean getBoolean() {
    564                return get() != 0; // BOOLEAN_FALSE
    565        }
    566
    567        @Override
    568        public boolean getBoolean(final int i) {
    569                return get(i) != 0; // BOOLEAN_FALSE
    570        }
    571
    572        @Override
    573        public boolean getBoolean(final int i, final int j) {
    574                return get(i, j) != 0; // BOOLEAN_FALSE
    575        }
    576
    577        @Override
    578        public boolean getBoolean(final int... pos) {
    579                return get(pos) != 0; // BOOLEAN_FALSE
    580        }
    581
    582        /**
    583         * Sets the value at first point to the passed value. The dataset must not be null
    584         *
    585         * @param value
    586         * @since 2.0
    587         */
    588        public void setItem(final double value) { // PRIM_TYPE
    589                setAbs(getFirst1DIndex(), value);
    590        }
    591
    592        /**
    593         * Sets the value at a particular point to the passed value. The dataset must be 1D
    594         *
    595         * @param value
    596         * @param i
    597         */
    598        public void setItem(final double value, final int i) { // PRIM_TYPE
    599                setAbs(get1DIndex(i), value);
    600        }
    601
    602        /**
    603         * Sets the value at a particular point to the passed value. The dataset must be 2D
    604         *
    605         * @param value
    606         * @param i
    607         * @param j
    608         */
    609        public void setItem(final double value, final int i, final int j) { // PRIM_TYPE
    610                setAbs(get1DIndex(i, j), value);
    611        }
    612
    613        /**
    614         * Sets the value at a particular point to the passed value
    615         *
    616         * @param value
    617         * @param pos
    618         */
    619        public void setItem(final double value, final int... pos) { // PRIM_TYPE
    620                setAbs(get1DIndex(pos), value);
    621        }
    622
    623        @Override
    624        public void set(final Object obj) {
    625                setItem(DTypeUtils.toReal(obj)); // FROM_OBJECT
    626        }
    627
    628        @Override
    629        public void set(final Object obj, final int i) {
    630                setItem(DTypeUtils.toReal(obj), i); // FROM_OBJECT
    631        }
    632
    633        @Override
    634        public void set(final Object obj, final int i, final int j) {
    635                setItem(DTypeUtils.toReal(obj), i, j); // FROM_OBJECT
    636        }
    637
    638        @Override
    639        public void set(final Object obj, int... pos) {
    640                if (pos == null || (pos.length == 0 && shape.length > 0)) {
    641                        pos = new int[shape.length];
    642                }
    643
    644                setItem(DTypeUtils.toReal(obj), pos); // FROM_OBJECT
    645        }
    646
    647        @Override
    648        public void resize(int... newShape) {
    649                setDirty();
    650                final IndexIterator iter = getIterator();
    651                final int nsize = ShapeUtils.calcSize(newShape);
    652                final double[] ndata; // PRIM_TYPE
    653                try {
    654                        ndata = createArray(nsize);
    655                } catch (Throwable t) {
    656                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    657                        throw new IllegalArgumentException(t);
    658                }
    659                for (int i = 0; iter.hasNext() && i < nsize; i++) {
    660                        ndata[i] = data[iter.index];
    661                }
    662
    663                odata = data = ndata;
    664                size = nsize;
    665                shape = newShape;
    666                stride = null;
    667                offset = 0;
    668                base = null;
    669        }
    670
    671        @Override
    672        public DoubleDataset sort(Integer axis) {
    673                setDirty(); // BOOLEAN_OMIT
    674                if (axis == null) { // BOOLEAN_OMIT
    675                        if (stride == null) { // BOOLEAN_OMIT
    676                                Arrays.sort(data); // BOOLEAN_OMIT
    677                        } else { // BOOLEAN_OMIT
    678                                DoubleDataset ads = clone().sort(null); // BOOLEAN_OMIT
    679                                setSlicedView(getView(false), ads); // BOOLEAN_OMIT
    680                        } // BOOLEAN_OMIT
    681                } else { // BOOLEAN_OMIT
    682                        axis = checkAxis(axis); // BOOLEAN_OMIT
    683                         // BOOLEAN_OMIT
    684                        DoubleDataset ads = new DoubleDataset(shape[axis]); // BOOLEAN_OMIT
    685                        PositionIterator pi = getPositionIterator(axis); // BOOLEAN_OMIT
    686                        int[] pos = pi.getPos(); // BOOLEAN_OMIT
    687                        boolean[] hit = pi.getOmit(); // BOOLEAN_OMIT
    688                        while (pi.hasNext()) { // BOOLEAN_OMIT
    689                                copyItemsFromAxes(pos, hit, ads); // BOOLEAN_OMIT
    690                                Arrays.sort(ads.data); // BOOLEAN_OMIT
    691                                setItemsOnAxes(pos, hit, ads.data); // BOOLEAN_OMIT
    692                        } // BOOLEAN_OMIT
    693                } // BOOLEAN_OMIT
    694                return this; // BOOLEAN_OMIT
    695                // throw new UnsupportedOperationException("Cannot sort dataset"); // BOOLEAN_USE
    696        }
    697
    698        @Override
    699        public DoubleDataset getUniqueItems() {
    700                Set<Double> set = new TreeSet<Double>(); // CLASS_TYPE
    701                IndexIterator it = getIterator();
    702                while (it.hasNext()) {
    703                        set.add(data[it.index]);
    704                }
    705
    706                DoubleDataset u = new DoubleDataset(set.size()); // CLASS_TYPE
    707                int i = 0;
    708                double[] udata = u.getData(); // PRIM_TYPE
    709                for (Double v : set) { // CLASS_TYPE
    710                        udata[i++] = v;
    711                }
    712                return u;
    713        }
    714
    715        @Override
    716        public DoubleDataset getSlice(final SliceIterator siter) {
    717                DoubleDataset result = new DoubleDataset(siter.getShape());
    718                double[] rdata = result.data; // PRIM_TYPE
    719
    720                for (int i = 0; siter.hasNext(); i++)
    721                        rdata[i] = data[siter.index];
    722
    723                result.setName(name + BLOCK_OPEN + Slice.createString(siter.shape, siter.start, siter.stop, siter.step) + BLOCK_CLOSE);
    724                return result;
    725        }
    726
    727        @Override
    728        public void fillDataset(Dataset result, IndexIterator iter) {
    729                IndexIterator riter = result.getIterator();
    730                result.setDirty();
    731
    732                double[] rdata = ((DoubleDataset) result).data; // PRIM_TYPE
    733
    734                while (riter.hasNext() && iter.hasNext()) {
    735                        rdata[riter.index] = data[iter.index];
    736                }
    737        }
    738
    739        @Override
    740        public DoubleDataset setByBoolean(final Object obj, Dataset selection) {
    741                setDirty();
    742                if (obj instanceof Dataset) {
    743                        final Dataset ds = (Dataset) obj;
    744                        final int length = ((Number) selection.sum()).intValue();
    745                        if (length != ds.getSize()) {
    746                                throw new IllegalArgumentException(
    747                                                "Number of true items in selection does not match number of items in dataset");
    748                        }
    749
    750                        final IndexIterator oiter = ds.getIterator();
    751                        final BooleanIterator biter = getBooleanIterator(selection);
    752
    753                        while (biter.hasNext() && oiter.hasNext()) {
    754                                data[biter.index] = ds.getElementDoubleAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    755                        }
    756                } else {
    757                        final double dv = DTypeUtils.toReal(obj); // PRIM_TYPE // FROM_OBJECT
    758                        final BooleanIterator biter = getBooleanIterator(selection);
    759
    760                        while (biter.hasNext()) {
    761                                data[biter.index] = dv;
    762                        }
    763                }
    764                return this;
    765        }
    766
    767        @Override
    768        public DoubleDataset setBy1DIndex(final Object obj, final Dataset index) {
    769                setDirty();
    770                if (obj instanceof Dataset) {
    771                        final Dataset ds = (Dataset) obj;
    772                        if (index.getSize() != ds.getSize()) {
    773                                throw new IllegalArgumentException(
    774                                                "Number of items in index dataset does not match number of items in dataset");
    775                        }
    776
    777                        final IndexIterator oiter = ds.getIterator();
    778                        final IntegerIterator iter = new IntegerIterator(index, size);
    779
    780                        while (iter.hasNext() && oiter.hasNext()) {
    781                                data[iter.index] = ds.getElementDoubleAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    782                        }
    783                } else {
    784                        final double dv = DTypeUtils.toReal(obj); // PRIM_TYPE // FROM_OBJECT
    785                        IntegerIterator iter = new IntegerIterator(index, size);
    786
    787                        while (iter.hasNext()) {
    788                                data[iter.index] = dv;
    789                        }
    790                }
    791                return this;
    792        }
    793
    794        @Override
    795        public DoubleDataset setByIndexes(final Object obj, final Object... indexes) {
    796                setDirty();
    797                final IntegersIterator iter = new IntegersIterator(shape, indexes);
    798                final int[] pos = iter.getPos();
    799
    800                if (obj instanceof Dataset) {
    801                        final Dataset ds = (Dataset) obj;
    802                        if (ShapeUtils.calcSize(iter.getShape()) != ds.getSize()) {
    803                                throw new IllegalArgumentException(
    804                                                "Number of items in index datasets does not match number of items in dataset");
    805                        }
    806
    807                        final IndexIterator oiter = ds.getIterator();
    808
    809                        while (iter.hasNext() && oiter.hasNext()) {
    810                                setItem(ds.getElementDoubleAbs(oiter.index), pos); // GET_ELEMENT_WITH_CAST
    811                        }
    812                } else {
    813                        final double dv = DTypeUtils.toReal(obj); // PRIM_TYPE // FROM_OBJECT
    814
    815                        while (iter.hasNext()) {
    816                                setItem(dv, pos);
    817                        }
    818                }
    819                return this;
    820        }
    821
    822        @Override
    823        DoubleDataset setSlicedView(Dataset view, Dataset d) {
    824                setDirty();
    825                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(view, d);
    826
    827                while (it.hasNext()) {
    828                        data[it.aIndex] = it.bDouble; // BCAST_WITH_CAST d.getElementDoubleAbs(it.bIndex);
    829                }
    830                return this;
    831        }
    832
    833        @Override
    834        public DoubleDataset setSlice(final Object obj, final IndexIterator siter) {
    835                setDirty();
    836
    837                if (obj instanceof IDataset) {
    838                        final IDataset ds = (IDataset) obj;
    839                        final int[] oshape = ds.getShape();
    840
    841                        if (!ShapeUtils.areShapesCompatible(siter.getShape(), oshape)) {
    842                                throw new IllegalArgumentException(String.format(
    843                                                "Input dataset is not compatible with slice: %s cf %s", Arrays.toString(oshape),
    844                                                Arrays.toString(siter.getShape())));
    845                        }
    846
    847                        if (ds instanceof Dataset) {
    848                                final Dataset ads = (Dataset) ds;
    849                                final IndexIterator oiter = ads.getIterator();
    850
    851                                while (siter.hasNext() && oiter.hasNext())
    852                                        data[siter.index] = ads.getElementDoubleAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    853                        } else {
    854                                final IndexIterator oiter = new PositionIterator(oshape);
    855                                final int[] pos = oiter.getPos();
    856
    857                                while (siter.hasNext() && oiter.hasNext())
    858                                        data[siter.index] = ds.getDouble(pos); // PRIM_TYPE
    859                        }
    860                } else {
    861                        try {
    862                                double v = DTypeUtils.toReal(obj); // PRIM_TYPE // FROM_OBJECT
    863
    864                                while (siter.hasNext())
    865                                        data[siter.index] = v;
    866                        } catch (IllegalArgumentException e) {
    867                                throw new IllegalArgumentException("Object for setting slice is not a dataset or number");
    868                        }
    869                }
    870                return this;
    871        }
    872
    873        @Override
    874        public void copyItemsFromAxes(final int[] pos, final boolean[] axes, final Dataset dest) {
    875                double[] ddata = (double[]) dest.getBuffer(); // PRIM_TYPE
    876
    877                SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
    878                int[] sshape = ShapeUtils.squeezeShape(siter.getShape(), false);
    879
    880                IndexIterator diter = dest.getSliceIterator(null, sshape, null);
    881
    882                if (ddata.length < ShapeUtils.calcSize(sshape)) {
    883                        throw new IllegalArgumentException("destination array is not large enough");
    884                }
    885
    886                dest.setDirty();
    887                while (siter.hasNext() && diter.hasNext()) {
    888                        ddata[diter.index] = data[siter.index];
    889                }
    890        }
    891
    892        @Override
    893        public void setItemsOnAxes(final int[] pos, final boolean[] axes, final Object src) {
    894                setDirty();
    895                double[] sdata = (double[]) src; // PRIM_TYPE
    896
    897                SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
    898
    899                if (sdata.length < ShapeUtils.calcSize(siter.getShape())) {
    900                        throw new IllegalArgumentException("destination array is not large enough");
    901                }
    902
    903                for (int i = 0; siter.hasNext(); i++) {
    904                        data[siter.index] = sdata[i];
    905                }
    906        }
    907
    908        private List<int[]> findPositions(final double value) { // PRIM_TYPE
    909                IndexIterator iter = getIterator(true);
    910                List<int[]> posns = new ArrayList<int[]>();
    911                int[] pos = iter.getPos();
    912
    913                if (Double.isNaN(value)) { // CLASS_TYPE // REAL_ONLY
    914                        while (iter.hasNext()) { // REAL_ONLY
    915                                if (Double.isNaN(data[iter.index])) { // REAL_ONLY
    916                                        posns.add(pos.clone()); // REAL_ONLY
    917                                } // REAL_ONLY
    918                        } // REAL_ONLY
    919                } else // REAL_ONLY
    920                {
    921                        while (iter.hasNext()) {
    922                                if (data[iter.index] == value) {
    923                                        posns.add(pos.clone());
    924                                }
    925                        }
    926                }
    927                return posns;
    928        }
    929
    930        @Override
    931        public int[] maxPos(boolean... ignoreInvalids) {
    932                StatisticsMetadata<Number> md = getStats(); // PRIM_TYPE // NAN_OMIT
    933                // StatisticsMetadata<Number> md = getStats(); // BOOLEAN_USE
    934                // StatisticsMetadata<String> md = getStringStats(); // OBJECT_USE
    935                List<int[]> max = md.getMaximumPositions(ignoreInvalids);
    936
    937                if (max == null) {
    938                        max = findPositions(md.getMaximum(ignoreInvalids).doubleValue()); // PRIM_TYPE // NAN_OMIT
    939                        // max = findPositions(md.getMaximum(ignoreInvalids).intValue() != 0); // BOOLEAN_USE
    940                        // max = findPositions(md.getMaximum(ignoreInvalids).toString()); // OBJECT_USE
    941
    942                        md.setMaximumPositions(max);
    943                }
    944
    945                return max.get(0); // first maximum
    946        }
    947
    948        @Override
    949        public int[] minPos(boolean... ignoreInvalids) {
    950                StatisticsMetadata<Number> md = getStats(); // PRIM_TYPE // NAN_OMIT
    951                // StatisticsMetadata<Number> md = getStats(); // BOOLEAN_USE
    952                // StatisticsMetadata<String> md = getStringStats(); // OBJECT_USE
    953                List<int[]> min = md.getMinimumPositions(ignoreInvalids);
    954
    955                if (min == null) {
    956                        min = findPositions(md.getMinimum(ignoreInvalids).doubleValue()); // PRIM_TYPE // NAN_OMIT
    957                        // min = findPositions(md.getMinimum(ignoreInvalids).intValue() != 0); // BOOLEAN_USE
    958                        // min = findPositions(md.getMinimum(ignoreInvalids).toString()); // OBJECT_USE
    959
    960                        md.setMinimumPositions(min);
    961                }
    962
    963                return min.get(0); // first minimum
    964        }
    965
    966        @Override
    967        public boolean containsNans() {
    968                IndexIterator iter = getIterator(); // REAL_ONLY
    969                while (iter.hasNext()) { // REAL_ONLY
    970                        if (Double.isNaN(data[iter.index])) // CLASS_TYPE // REAL_ONLY
    971                                return true; // REAL_ONLY
    972                } // REAL_ONLY
    973                return false;
    974        }
    975
    976        @Override
    977        public boolean containsInfs() {
    978                IndexIterator iter = getIterator(); // REAL_ONLY
    979                while (iter.hasNext()) { // REAL_ONLY
    980                        if (Double.isInfinite(data[iter.index])) // CLASS_TYPE // REAL_ONLY
    981                                return true; // REAL_ONLY
    982                } // REAL_ONLY
    983                return false;
    984        }
    985
    986        @Override
    987        public boolean containsInvalidNumbers() {
    988                IndexIterator iter = getIterator(); // REAL_ONLY
    989                while (iter.hasNext()) { // REAL_ONLY
    990                        double x = data[iter.index]; // PRIM_TYPE // REAL_ONLY
    991                        if (Double.isNaN(x) || Double.isInfinite(x)) // CLASS_TYPE // REAL_ONLY
    992                                return true; // REAL_ONLY
    993                } // REAL_ONLY
    994                return false;
    995        }
    996
    997        @Override
    998        public DoubleDataset iadd(final Object b) {
    999                setDirty(); // NAN_OMIT
    1000                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
    1001                boolean useLong = bds.getElementClass().equals(Long.class); // NAN_OMIT
    1002                if (bds.getSize() == 1) { // NAN_OMIT
    1003                        final IndexIterator it = getIterator(); // NAN_OMIT
    1004                        final int bOffset = bds.getOffset(); // NAN_OMIT
    1005                        if (useLong) { // NAN_OMIT
    1006                                final long lb = bds.getElementLongAbs(bOffset); // NAN_OMIT
    1007                                while (it.hasNext()) { // NAN_OMIT
    1008                                        data[it.index] += lb; // NAN_OMIT
    1009                                } // NAN_OMIT
    1010                        } else { // NAN_OMIT
    1011                                final double db = bds.getElementDoubleAbs(bOffset); // NAN_OMIT
    1012                                while (it.hasNext()) { // NAN_OMIT
    1013                                        data[it.index] += db; // NAN_OMIT
    1014                                } // NAN_OMIT
    1015                        } // NAN_OMIT
    1016                } else { // NAN_OMIT
    1017                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); // NAN_OMIT
    1018                        it.setOutputDouble(!useLong); // NAN_OMIT
    1019                        if (useLong) { // NAN_OMIT
    1020                                while (it.hasNext()) { // NAN_OMIT
    1021                                        data[it.aIndex] += it.bLong; // NAN_OMIT
    1022                                } // NAN_OMIT
    1023                        } else { // NAN_OMIT
    1024                                while (it.hasNext()) { // NAN_OMIT
    1025                                        data[it.aIndex] += it.bDouble; // NAN_OMIT
    1026                                } // NAN_OMIT
    1027                        } // NAN_OMIT
    1028                } // NAN_OMIT
    1029                return this;
    1030        }
    1031
    1032        @Override
    1033        public DoubleDataset isubtract(final Object b) {
    1034                setDirty(); // NAN_OMIT
    1035                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
    1036                boolean useLong = bds.getElementClass().equals(Long.class); // NAN_OMIT
    1037                if (bds.getSize() == 1) { // NAN_OMIT
    1038                        final IndexIterator it = getIterator(); // NAN_OMIT
    1039                        final int bOffset = bds.getOffset(); // NAN_OMIT
    1040                        if (useLong) { // NAN_OMIT
    1041                                final long lb = bds.getElementLongAbs(bOffset); // NAN_OMIT
    1042                                while (it.hasNext()) { // NAN_OMIT
    1043                                        data[it.index] -= lb; // NAN_OMIT
    1044                                } // NAN_OMIT
    1045                        } else { // NAN_OMIT
    1046                                final double db = bds.getElementDoubleAbs(bOffset); // NAN_OMIT
    1047                                while (it.hasNext()) { // NAN_OMIT
    1048                                        data[it.index] -= db; // NAN_OMIT
    1049                                } // NAN_OMIT
    1050                        } // NAN_OMIT
    1051                } else { // NAN_OMIT
    1052                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); // NAN_OMIT
    1053                        if (useLong) { // NAN_OMIT
    1054                                it.setOutputDouble(false); // NAN_OMIT
    1055                                while (it.hasNext()) { // NAN_OMIT
    1056                                        data[it.aIndex] -= it.bLong; // NAN_OMIT
    1057                                } // NAN_OMIT
    1058                        } else { // NAN_OMIT
    1059                                it.setOutputDouble(true); // NAN_OMIT
    1060                                while (it.hasNext()) { // NAN_OMIT
    1061                                        data[it.aIndex] -= it.bDouble; // NAN_OMIT
    1062                                } // NAN_OMIT
    1063                        } // NAN_OMIT
    1064                } // NAN_OMIT
    1065                return this;
    1066        }
    1067
    1068        @Override
    1069        public DoubleDataset imultiply(final Object b) {
    1070                setDirty(); // NAN_OMIT
    1071                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
    1072                boolean useLong = bds.getElementClass().equals(Long.class); // NAN_OMIT
    1073                if (bds.getSize() == 1) { // NAN_OMIT
    1074                        final IndexIterator it = getIterator(); // NAN_OMIT
    1075                        final int bOffset = bds.getOffset(); // NAN_OMIT
    1076                        if (useLong) { // NAN_OMIT
    1077                                final long lb = bds.getElementLongAbs(bOffset); // NAN_OMIT
    1078                                while (it.hasNext()) { // NAN_OMIT
    1079                                        data[it.index] *= lb; // NAN_OMIT
    1080                                } // NAN_OMIT
    1081                        } else { // NAN_OMIT
    1082                                final double db = bds.getElementDoubleAbs(bOffset); // NAN_OMIT
    1083                                while (it.hasNext()) { // NAN_OMIT
    1084                                        data[it.index] *= db; // NAN_OMIT
    1085                                } // NAN_OMIT
    1086                        } // NAN_OMIT
    1087                } else { // NAN_OMIT
    1088                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); // NAN_OMIT
    1089                        it.setOutputDouble(!useLong); // NAN_OMIT
    1090                        if (useLong) { // NAN_OMIT
    1091                                while (it.hasNext()) { // NAN_OMIT
    1092                                        data[it.aIndex] *= it.bLong; // NAN_OMIT
    1093                                } // NAN_OMIT
    1094                        } else { // NAN_OMIT
    1095                                while (it.hasNext()) { // NAN_OMIT
    1096                                        data[it.aIndex] *= it.bDouble; // NAN_OMIT
    1097                                } // NAN_OMIT
    1098                        } // NAN_OMIT
    1099                } // NAN_OMIT
    1100                return this;
    1101        }
    1102
    1103        @Override
    1104        public DoubleDataset idivide(final Object b) {
    1105                setDirty(); // NAN_OMIT
    1106                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
    1107                boolean useLong = bds.getElementClass().equals(Long.class); // NAN_OMIT
    1108                if (bds.getSize() == 1) { // NAN_OMIT
    1109                        final int bOffset = bds.getOffset(); // NAN_OMIT
    1110                        if (useLong) { // NAN_OMIT
    1111                                final long lb = bds.getElementLongAbs(bOffset); // NAN_OMIT
    1112                                // if (lb == 0) { // INT_USE // NAN_OMIT
    1113                                //      fill(0); // INT_USE // NAN_OMIT
    1114                                // } else { // INT_USE // NAN_OMIT
    1115                                final IndexIterator it = getIterator(); // NAN_OMIT
    1116                                while (it.hasNext()) { // NAN_OMIT
    1117                                        data[it.index] /= lb; // NAN_OMIT
    1118                                } // NAN_OMIT
    1119                                // } // INT_USE // NAN_OMIT
    1120                        } else { // NAN_OMIT
    1121                                final double db = bds.getElementDoubleAbs(bOffset); // NAN_OMIT
    1122                                // if (db == 0) { // INT_USE // NAN_OMIT
    1123                                //      fill(0); // INT_USE // NAN_OMIT
    1124                                // } else { // INT_USE // NAN_OMIT
    1125                                final IndexIterator it = getIterator(); // NAN_OMIT
    1126                                while (it.hasNext()) { // NAN_OMIT
    1127                                        data[it.index] /= db; // NAN_OMIT
    1128                                } // NAN_OMIT
    1129                                // } // INT_USE // NAN_OMIT
    1130                        } // NAN_OMIT
    1131                } else { // NAN_OMIT
    1132                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); // NAN_OMIT
    1133                        it.setOutputDouble(!useLong); // NAN_OMIT
    1134                        if (useLong) { // NAN_OMIT
    1135                                while (it.hasNext()) { // NAN_OMIT
    1136                                        // if (it.bLong == 0) { // INT_USE // NAN_OMIT
    1137                                        //      data[it.aIndex] = 0; // INT_USE // NAN_OMIT
    1138                                        // } else { // INT_USE // NAN_OMIT
    1139                                        data[it.aIndex] /= it.bLong; // NAN_OMIT
    1140                                        // } // INT_USE // NAN_OMIT
    1141                                } // NAN_OMIT
    1142                        } else { // NAN_OMIT
    1143                                while (it.hasNext()) { // NAN_OMIT
    1144                                        // if (it.bDouble == 0) { // INT_USE // NAN_OMIT
    1145                                        //      data[it.aIndex] = 0; // INT_USE // NAN_OMIT
    1146                                        // } else { // INT_USE // NAN_OMIT
    1147                                        data[it.aIndex] /= it.bDouble; // NAN_OMIT
    1148                                        // } // INT_USE // NAN_OMIT
    1149                                } // NAN_OMIT
    1150                        } // NAN_OMIT
    1151                } // NAN_OMIT
    1152                return this;
    1153        }
    1154
    1155        @Override
    1156        public DoubleDataset ifloor() {
    1157                setDirty(); // REAL_ONLY
    1158                IndexIterator it = getIterator(); // REAL_ONLY
    1159                while (it.hasNext()) { // REAL_ONLY
    1160                        data[it.index] = Math.floor(data[it.index]); // PRIM_TYPE // REAL_ONLY // ADD_CAST
    1161                } // REAL_ONLY
    1162                return this;
    1163        }
    1164
    1165        @Override
    1166        public DoubleDataset iremainder(final Object b) {
    1167                setDirty(); // NAN_OMIT
    1168                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
    1169                boolean useLong = bds.getElementClass().equals(Long.class); // NAN_OMIT
    1170                if (bds.getSize() == 1) { // NAN_OMIT
    1171                        final int bOffset = bds.getOffset(); // NAN_OMIT
    1172                        if (useLong) { // NAN_OMIT
    1173                                final long lb = bds.getElementLongAbs(bOffset); // NAN_OMIT
    1174                                // if (lb == 0) { // INT_USE // NAN_OMIT
    1175                                //      fill(0); // INT_USE // NAN_OMIT
    1176                                // } else { // INT_USE // NAN_OMIT
    1177                                final IndexIterator it = getIterator(); // NAN_OMIT
    1178                                while (it.hasNext()) { // NAN_OMIT
    1179                                        data[it.index] %= lb; // NAN_OMIT
    1180                                } // NAN_OMIT
    1181                                // } // INT_USE // NAN_OMIT
    1182                        } else { // NAN_OMIT
    1183                                final long lb = bds.getElementLongAbs(bOffset); // NAN_OMIT
    1184                                // if (lb == 0) { // INT_USE // NAN_OMIT
    1185                                //      fill(0); // INT_USE // NAN_OMIT
    1186                                // } else { // INT_USE // NAN_OMIT
    1187                                final IndexIterator it = getIterator(); // NAN_OMIT
    1188                                while (it.hasNext()) { // NAN_OMIT
    1189                                        data[it.index] %= lb; // NAN_OMIT
    1190                                } // NAN_OMIT
    1191                                // } // INT_USE // NAN_OMIT
    1192                        } // NAN_OMIT
    1193                } else { // NAN_OMIT
    1194                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); // NAN_OMIT
    1195                        it.setOutputDouble(!useLong); // NAN_OMIT
    1196                        if (useLong) { // NAN_OMIT
    1197                                while (it.hasNext()) { // NAN_OMIT
    1198                                        data[it.aIndex] %= it.bLong; // NAN_OMIT // INT_EXCEPTION
    1199                                } // NAN_OMIT
    1200                        } else { // NAN_OMIT
    1201                                while (it.hasNext()) { // NAN_OMIT
    1202                                        data[it.aIndex] %= it.bDouble; // NAN_OMIT
    1203                                } // NAN_OMIT
    1204                        } // NAN_OMIT
    1205                } // NAN_OMIT
    1206                return this;
    1207        }
    1208
    1209        @Override
    1210        public DoubleDataset ipower(final Object b) {
    1211                setDirty(); // NAN_OMIT
    1212                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
    1213                if (bds.getSize() == 1) { // NAN_OMIT
    1214                        final int bOffset = bds.getOffset(); // NAN_OMIT
    1215                        final double vr = bds.getElementDoubleAbs(bOffset); // NAN_OMIT
    1216                        final IndexIterator it = getIterator(); // NAN_OMIT
    1217                        if (bds.isComplex()) { // NAN_OMIT
    1218                                final double vi = bds.getElementDoubleAbs(bOffset + 1); // NAN_OMIT
    1219                                if (vi == 0) { // NAN_OMIT
    1220                                        while (it.hasNext()) { // NAN_OMIT
    1221                                                final double v = Math.pow(data[it.index], vr); // NAN_OMIT
    1222                                                // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE // NAN_OMIT
    1223                                                //      data[it.index] = 0; // INT_USE // NAN_OMIT
    1224                                                // } else { // INT_USE // NAN_OMIT
    1225                                                data[it.index] = v; // PRIM_TYPE_LONG // NAN_OMIT // ADD_CAST
    1226                                                // } // INT_USE // NAN_OMIT
    1227                                        } // NAN_OMIT
    1228                                } else { // NAN_OMIT
    1229                                        final Complex zv = new Complex(vr, vi); // NAN_OMIT
    1230                                        while (it.hasNext()) { // NAN_OMIT
    1231                                                Complex zd = new Complex(data[it.index], 0); // NAN_OMIT
    1232                                                final double v = zd.pow(zv).getReal(); // NAN_OMIT
    1233                                                // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE // NAN_OMIT
    1234                                                //      data[it.index] = 0; // INT_USE // NAN_OMIT
    1235                                                // } else { // INT_USE // NAN_OMIT
    1236                                                data[it.index] = v; // PRIM_TYPE_LONG // NAN_OMIT // ADD_CAST
    1237                                                // } // INT_USE // NAN_OMIT
    1238                                        } // NAN_OMIT
    1239                                } // NAN_OMIT
    1240                        } else {// NAN_OMIT
    1241                                while (it.hasNext()) { // NAN_OMIT
    1242                                        final double v = Math.pow(data[it.index], vr); // NAN_OMIT
    1243                                        // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE // NAN_OMIT
    1244                                        //      data[it.index] = 0; // INT_USE // NAN_OMIT
    1245                                        // } else { // INT_USE // NAN_OMIT
    1246                                        data[it.index] = v; // PRIM_TYPE_LONG // NAN_OMIT // ADD_CAST
    1247                                        // } // INT_USE // NAN_OMIT
    1248                                } // NAN_OMIT
    1249                        } // NAN_OMIT
    1250                } else { // NAN_OMIT
    1251                        final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); // NAN_OMIT
    1252                        it.setOutputDouble(true); // NAN_OMIT
    1253                        if (bds.isComplex()) { // NAN_OMIT
    1254                                while (it.hasNext()) { // NAN_OMIT
    1255                                        final Complex zv = new Complex(it.bDouble, bds.getElementDoubleAbs(it.bIndex + 1)); // NAN_OMIT
    1256                                        final double v = new Complex(it.aDouble, 0).pow(zv).getReal(); // NAN_OMIT
    1257                                        // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE // NAN_OMIT
    1258                                        //      data[it.aIndex] = 0; // INT_USE // NAN_OMIT
    1259                                        // } else { // INT_USE // NAN_OMIT
    1260                                        data[it.aIndex] = v; // PRIM_TYPE_LONG // NAN_OMIT // ADD_CAST
    1261                                        // } // INT_USE // NAN_OMIT
    1262                                } // NAN_OMIT
    1263                        } else {// NAN_OMIT
    1264                                while (it.hasNext()) { // NAN_OMIT
    1265                                        final double v = Math.pow(it.aDouble, it.bDouble); // NAN_OMIT
    1266                                        // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE // NAN_OMIT
    1267                                        //      data[it.aIndex] = 0; // INT_USE // NAN_OMIT
    1268                                        // } else { // INT_USE // NAN_OMIT
    1269                                        data[it.aIndex] = v; // PRIM_TYPE_LONG // NAN_OMIT // ADD_CAST
    1270                                        // } // INT_USE // NAN_OMIT
    1271                                } // NAN_OMIT
    1272                        } // NAN_OMIT
    1273                } // NAN_OMIT
    1274                return this;
    1275        }
    1276
    1277        @Override
    1278        public double residual(final Object b, final Dataset w, boolean ignoreNaNs) {
    1279                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
    1280                final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); // NAN_OMIT
    1281                it.setOutputDouble(true); // NAN_OMIT
    1282                double sum = 0;
    1283                double comp = 0; // NAN_OMIT
    1284                if (ignoreNaNs) { // REAL_ONLY // NAN_OMIT
    1285                        if (w == null) { // REAL_ONLY // NAN_OMIT
    1286                                while (it.hasNext()) { // REAL_ONLY // NAN_OMIT
    1287                                        final double diff = it.aDouble - it.bDouble; // REAL_ONLY // NAN_OMIT
    1288                                        if (Double.isNaN(diff)) // REAL_ONLY // NAN_OMIT
    1289                                                continue; // REAL_ONLY // NAN_OMIT
    1290                                        final double err = diff * diff - comp; // REAL_ONLY // NAN_OMIT
    1291                                        final double temp = sum + err; // REAL_ONLY // NAN_OMIT
    1292                                        comp = (temp - sum) - err; // REAL_ONLY // NAN_OMIT
    1293                                        sum = temp; // REAL_ONLY // NAN_OMIT
    1294                                } // REAL_ONLY // NAN_OMIT
    1295                        } else { // REAL_ONLY // NAN_OMIT
    1296                                IndexIterator itw = w.getIterator(); // REAL_ONLY // NAN_OMIT
    1297                                while (it.hasNext() && itw.hasNext()) { // REAL_ONLY // NAN_OMIT
    1298                                        final double diff = it.aDouble - it.bDouble; // REAL_ONLY // NAN_OMIT
    1299                                        if (Double.isNaN(diff)) // REAL_ONLY // NAN_OMIT
    1300                                                continue; // REAL_ONLY // NAN_OMIT
    1301                                        final double err = diff * diff * w.getElementDoubleAbs(itw.index) - comp; // REAL_ONLY // NAN_OMIT
    1302                                        final double temp = sum + err; // REAL_ONLY // NAN_OMIT
    1303                                        comp = (temp - sum) - err; // REAL_ONLY // NAN_OMIT
    1304                                        sum = temp; // REAL_ONLY // NAN_OMIT
    1305                                } // REAL_ONLY // NAN_OMIT
    1306                        } // REAL_ONLY // NAN_OMIT
    1307                } else // REAL_ONLY // NAN_OMIT
    1308                { // NAN_OMIT
    1309                        if (w == null) { // NAN_OMIT
    1310                                while (it.hasNext()) { // NAN_OMIT
    1311                                        final double diff = it.aDouble - it.bDouble; // NAN_OMIT
    1312                                        final double err = diff * diff - comp; // NAN_OMIT
    1313                                        final double temp = sum + err; // NAN_OMIT
    1314                                        comp = (temp - sum) - err; // NAN_OMIT
    1315                                        sum = temp; // NAN_OMIT
    1316                                } // NAN_OMIT
    1317                        } else { // NAN_OMIT
    1318                                IndexIterator itw = w.getIterator(); // NAN_OMIT
    1319                                while (it.hasNext() && itw.hasNext()) { // NAN_OMIT
    1320                                        final double diff = it.aDouble - it.bDouble; // NAN_OMIT
    1321                                        final double err = diff * diff * w.getElementDoubleAbs(itw.index) - comp; // NAN_OMIT
    1322                                        final double temp = sum + err; // NAN_OMIT
    1323                                        comp = (temp - sum) - err; // NAN_OMIT
    1324                                        sum = temp; // NAN_OMIT
    1325                                } // NAN_OMIT
    1326                        } // NAN_OMIT
    1327                } // NAN_OMIT
    1328                return sum;
    1329        }
    1330}