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