    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.Arrays;
    018
    019import org.apache.commons.math3.complex.Complex;
    020
    021/**
    022 * Extend compound dataset for double values // PRIM_TYPE
    023 */
    024public class CompoundDoubleDataset extends AbstractCompoundDataset {
    025        // pin UID to base class
    026        private static final long serialVersionUID = Dataset.serialVersionUID;
    027
    028        protected double[] data; // subclass alias // PRIM_TYPE
    029
    030        @Override
    031        protected void setData() {
    032                data = (double[]) odata; // PRIM_TYPE
    033        }
    034
    035        protected double[] createArray(final int size) { // PRIM_TYPE
    036                double[] array = null; // PRIM_TYPE
    037
    038                try {
    039                        array = new double[isize * size]; // PRIM_TYPE
    040                } catch (OutOfMemoryError e) {
    041                        logger.error("The size of the dataset ({}) that is being created is too large "
    042                                        + "and there is not enough memory to hold it.", size);
    043                        throw new OutOfMemoryError("The dimensions given are too large, and there is "
    044                                        + "not enough memory available in the Java Virtual Machine");
    045                }
    046                return array;
    047        }
    048
    049        @Override
    050        public int getDType() {
    051                return Dataset.ARRAYFLOAT64; // DATA_TYPE
    052        }
    053
    054        /**
    055         * Create a null dataset
    056         */
    057        CompoundDoubleDataset() {
    058        }
    059
    060        /**
    061         * Create a null dataset
    062         * @param itemSize
    063         */
    064        CompoundDoubleDataset(final int itemSize) {
    065                isize = itemSize;
    066        }
    067
    068        /**
    069         * Create a zero-filled dataset of given item size and shape
    070         * @param itemSize
    071         * @param shape
    072         */
    073        CompoundDoubleDataset(final int itemSize, final int[] shape) {
    074                isize = itemSize;
    075                if (shape != null) {
    076                        size = ShapeUtils.calcSize(shape);
    077                        this.shape = shape.clone();
    078
    079                        try {
    080                                odata = data = createArray(size);
    081                        } catch (Throwable t) {
    082                                logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    083                                throw new IllegalArgumentException(t);
    084                        }
    085                }
    086        }
    087
    088        /**
    089         * Copy a dataset
    090         * @param dataset
    091         */
    092        CompoundDoubleDataset(final CompoundDoubleDataset dataset) {
    093                isize = dataset.isize;
    094
    095                copyToView(dataset, this, true, true);
    096                try {
    097                        if (dataset.stride == null) {
    098                                if (dataset.data != null) {
    099                                        odata = data = dataset.data.clone();
    100                                }
    101                        } else {
    102                                offset = 0;
    103                                stride = null;
    104                                base = null;
    105                                odata = data = createArray(size);
    106                                IndexIterator iter = dataset.getIterator();
    107                                for (int j = 0; iter.hasNext();) {
    108                                        for (int i = 0; i < isize; i++) {
    109                                                data[j++] = dataset.data[iter.index + i];
    110                                        }
    111                                }
    112                        }
    113                } catch (Throwable t) {
    114                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    115                        throw new IllegalArgumentException(t);
    116                }
    117        }
    118
    119        /**
    120         * Create a dataset using given dataset
    121         * @param dataset
    122         */
    123        CompoundDoubleDataset(final CompoundDataset dataset) {
    124                copyToView(dataset, this, true, false);
    125                offset = 0;
    126                stride = null;
    127                base = null;
    128                isize = dataset.getElementsPerItem();
    129                try {
    130                        odata = data = createArray(size);
    131                } catch (Throwable t) {
    132                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    133                        throw new IllegalArgumentException(t);
    134                }
    135
    136                IndexIterator iter = dataset.getIterator();
    137                for (int j = 0; iter.hasNext();) {
    138                        for (int i = 0; i < isize; i++) {
    139                                data[j++] = dataset.getElementDoubleAbs(iter.index + i); // GET_ELEMENT_WITH_CAST
    140                        }
    141                }
    142        }
    143
    144        /**
    145         * Create a dataset using given data (elements are grouped together)
    146         * @param itemSize
    147         * @param data
    148         * @param shape
    149         *            (can be null to create 1D dataset)
    150         */
    151        CompoundDoubleDataset(final int itemSize, final double[] data, int... shape) { // PRIM_TYPE
    152                isize = itemSize;
    153                if (data != null) {
    154                        if (shape == null || (shape.length == 0 && data.length > isize)) {
    155                                shape = new int[] { data.length / isize };
    156                        }
    157                        size = ShapeUtils.calcSize(shape);
    158                        if (size * isize != data.length) {
    159                                throw new IllegalArgumentException(String.format("Shape %s is not compatible with size of data array, %d",
    160                                                Arrays.toString(shape), data.length / isize));
    161                        }
    162                        this.shape = size == 0 ? null : shape.clone();
    163
    164                        odata = this.data = data;
    165                }
    166        }
    167
    168        /**
    169         * Create a dataset using given datasets
    170         * @param datasets
    171         */
    172        CompoundDoubleDataset(final Dataset... datasets) {
    173                if (datasets.length < 1) {
    174                        throw new IllegalArgumentException("Array of datasets must have length greater than zero");
    175                }
    176
    177                for (int i = 1; i < datasets.length; i++) {
    178                        datasets[0].checkCompatibility(datasets[i]);
    179                }
    180
    181                isize = datasets.length;
    182                size = ShapeUtils.calcSize(datasets[0].getShapeRef());
    183                shape = datasets[0].getShape();
    184
    185                try {
    186                        odata = data = createArray(size);
    187                } catch (Throwable t) {
    188                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    189                        throw new IllegalArgumentException(t);
    190                }
    191
    192                IndexIterator[] iters = new IndexIterator[isize];
    193                for (int i = 0; i < datasets.length; i++) {
    194                        iters[i] = datasets[i].getIterator();
    195                }
    196
    197                for (int j = 0; iters[0].hasNext();) {
    198                        data[j++] = datasets[0].getElementDoubleAbs(iters[0].index); // GET_ELEMENT_WITH_CAST
    199                        for (int i = 1; i < datasets.length; i++) {
    200                                iters[i].hasNext();
    201                                data[j++] = datasets[i].getElementDoubleAbs(iters[i].index); // GET_ELEMENT_WITH_CAST
    202                        }
    203                }
    204        }
    205
    206        /**
    207         * Cast a dataset to this compound type. If repeat is set, the first element of each item in the given dataset is
    208         * repeated across all elements of an item. Otherwise, each item comprises a truncated or zero-padded copy of
    209         * elements from the given dataset.
    210         * @param itemSize
    211         * @param repeat
    212         *            repeat first element
    213         * @param dataset
    214         */
    215        CompoundDoubleDataset(final int itemSize, final boolean repeat, final Dataset dataset) {
    216                isize = itemSize;
    217                size = dataset.getSize();
    218                shape = dataset.getShape();
    219                name = new String(dataset.getName());
    220
    221                try {
    222                        odata = data = createArray(size);
    223                } catch (Throwable t) {
    224                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    225                        throw new IllegalArgumentException(t);
    226                }
    227                final int os = dataset.getElementsPerItem();
    228
    229                IndexIterator iter = dataset.getIterator();
    230                if (repeat) {
    231                        int i = 0;
    232                        while (iter.hasNext()) {
    233                                final double v = dataset.getElementDoubleAbs(iter.index); // PRIM_TYPE // GET_ELEMENT_WITH_CAST
    234                                for (int k = 0; k < isize; k++) {
    235                                        data[i++] = v;
    236                                }
    237                        }
    238                } else {
    239                        final int kmax = Math.min(isize, os);
    240                        int i = 0;
    241                        while (iter.hasNext()) {
    242                                for (int k = 0; k < kmax; k++) {
    243                                        data[i + k] = dataset.getElementDoubleAbs(iter.index + k); // GET_ELEMENT_WITH_CAST
    244                                }
    245                                i += isize;
    246                        }
    247                }
    248        }
    249
    250        @Override
    251        public boolean equals(Object obj) {
    252                if (!super.equals(obj)) {
    253                        return false;
    254                }
    255
    256                if (getRank() == 0 && !getClass().equals(obj.getClass())) // already true for zero-rank dataset
    257                        return true;
    258
    259                CompoundDoubleDataset other = (CompoundDoubleDataset) obj;
    260                IndexIterator iter = getIterator();
    261                IndexIterator oiter = other.getIterator();
    262                while (iter.hasNext() && oiter.hasNext()) {
    263                        for (int j = 0; j < isize; j++) {
    264                                if (data[iter.index+j] != other.data[oiter.index+j])
    265                                        return false;
    266                        }
    267                }
    268                return true;
    269        }
    270
    271        @Override
    272        public int hashCode() {
    273                return super.hashCode();
    274        }
    275
    276        @Override
    277        public CompoundDoubleDataset clone() {
    278                return new CompoundDoubleDataset(this);
    279        }
    280
    281        /**
    282         * Create a dataset from an object which could be a Java list, array (of arrays...) or Number. Ragged
    283         * sequences or arrays are padded with zeros. The item size is the last dimension of the corresponding
    284         * elemental dataset
    285         *
    286         * @param obj
    287         * @return dataset with contents given by input
    288         */
    289        static CompoundDoubleDataset createFromObject(final Object obj) {
    290                DoubleDataset result = DoubleDataset.createFromObject(obj); // CLASS_TYPE
    291                return (CompoundDoubleDataset) DatasetUtils.createCompoundDatasetFromLastAxis(result, true);
    292        }
    293
    294        /**
    295         * Create a 1D dataset from an object which could be a Java list, array (of arrays...) or Number. Ragged
    296         * sequences or arrays are padded with zeros.
    297         *
    298         * @param itemSize
    299         * @param obj
    300         * @return dataset with contents given by input
    301         */
    302        public static CompoundDoubleDataset createFromObject(final int itemSize, final Object obj) {
    303                DoubleDataset result = DoubleDataset.createFromObject(obj); // CLASS_TYPE
    304                return new CompoundDoubleDataset(itemSize, result.getData(), null);
    305        }
    306
    307        /**
    308         * @param stop
    309         * @return a new 1D dataset, filled with values determined by parameters
    310         */
    311        static CompoundDoubleDataset createRange(final int itemSize, final double stop) {
    312                return createRange(itemSize, 0., stop, 1.);
    313        }
    314
    315        /**
    316         * @param start
    317         * @param stop
    318         * @param step
    319         * @return a new 1D dataset, filled with values determined by parameters
    320         */
    321        static CompoundDoubleDataset createRange(final int itemSize, final double start, final double stop,
    322                        final double step) {
    323                int size = calcSteps(start, stop, step);
    324                CompoundDoubleDataset result = new CompoundDoubleDataset(itemSize, new int[] { size });
    325                for (int i = 0; i < size; i++) {
    326                        result.data[i * result.isize] = (start + i * step); // PRIM_TYPE // ADD_CAST
    327                }
    328                return result;
    329        }
    330
    331        /**
    332         * @param shape
    333         * @return a dataset filled with ones
    334         */
    335        static CompoundDoubleDataset ones(final int itemSize, final int... shape) {
    336                return new CompoundDoubleDataset(itemSize, shape).fill(1);
    337        }
    338
    339        /**
    340         * Create a compound dataset using last dimension of given dataset
    341         * @param a
    342         * @param shareData
    343         * @return compound dataset
    344         */
    345        public static CompoundDoubleDataset createCompoundDatasetWithLastDimension(final Dataset a, final boolean shareData) {
    346                if (a.getElementsPerItem() != 1) {
    347                        logger.error("Need a single-element dataset");
    348                        throw new IllegalArgumentException("Need a single-element dataset");
    349                }
    350                if (a.getDType() != Dataset.FLOAT64) { // DATA_TYPE
    351                        logger.error("Dataset type must be double"); // PRIM_TYPE
    352                        throw new IllegalArgumentException("Dataset type must be double"); // PRIM_TYPE
    353                }
    354
    355                final int[] shape = a.getShapeRef();
    356                if (shape == null) {
    357                        return new CompoundDoubleDataset(0);
    358                }
    359
    360                final int rank = shape.length - 1;
    361                final int is = rank < 0 ? 1 : shape[rank];
    362
    363                CompoundDoubleDataset result = new CompoundDoubleDataset(is);
    364
    365                result.shape = rank > 0 ? Arrays.copyOf(shape, rank) : (rank < 0 ? new int[] {} : new int[] {1});
    366                result.size = ShapeUtils.calcSize(result.shape);
    367                result.odata = shareData ? a.getBuffer() : a.clone().getBuffer();
    368                result.setName(a.getName());
    369                result.setData();
    370                return result;
    371        }
    372
    373        @Override
    374        public DoubleDataset asNonCompoundDataset(final boolean shareData) { // CLASS_TYPE
    375                DoubleDataset result = new DoubleDataset(); // CLASS_TYPE
    376                final int is = getElementsPerItem();
    377                final int rank = is == 1 ? shape.length : shape.length + 1;
    378                final int[] nshape = Arrays.copyOf(shape, rank);
    379                if (is != 1)
    380                        nshape[rank-1] = is;
    381
    382                result.shape = nshape;
    383                result.size = ShapeUtils.calcSize(nshape);
    384                result.odata = shareData ? data : data.clone();
    385                result.setName(name);
    386                result.setData();
    387                return result;
    388        }
    389
    390        @Override
    391        public CompoundDoubleDataset fill(final Object obj) {
    392                setDirty();
    393                double[] vr = DTypeUtils.toDoubleArray(obj, isize); // PRIM_TYPE // CLASS_TYPE
    394                IndexIterator iter = getIterator();
    395
    396                while (iter.hasNext()) {
    397                        for (int i = 0; i < isize; i++) {
    398                                data[iter.index + i] = vr[i]; // PRIM_TYPE
    399                        }
    400                }
    401
    402                return this;
    403        }
    404
    405        /**
    406         * This is a typed version of {@link #getBuffer()}
    407         * @return data buffer as linear array
    408         */
    409        public double[] getData() { // PRIM_TYPE
    410                return data;
    411        }
    412
    413        @Override
    414        protected int getBufferLength() {
    415                if (data == null)
    416                        return 0;
    417                return data.length;
    418        }
    419
    420        @Override
    421        public CompoundDoubleDataset getView(boolean deepCopyMetadata) {
    422                CompoundDoubleDataset view = new CompoundDoubleDataset(isize);
    423                copyToView(this, view, true, deepCopyMetadata);
    424                view.setData();
    425                return view;
    426        }
    427
    428        /**
    429         * Get values at absolute index in the internal array. This is an internal method with no checks so can be
    430         * dangerous. Use with care or ideally with an iterator.
    431         *
    432         * @param index
    433         *            absolute index
    434         * @return values
    435         */
    436        public double[] getAbs(final int index) { // PRIM_TYPE
    437                double[] result = new double[isize]; // PRIM_TYPE
    438                for (int i = 0; i < isize; i++) {
    439                        result[i] = data[index + i];
    440                }
    441                return result;
    442        }
    443
    444        /**
    445         * Get values at absolute index in the internal array. This is an internal method with no checks so can be
    446         * dangerous. Use with care or ideally with an iterator.
    447         *
    448         * @param index
    449         *            absolute index
    450         * @param values
    451         */
    452        public void getAbs(final int index, final double[] values) { // PRIM_TYPE
    453                for (int i = 0; i < isize; i++) {
    454                        values[i] = data[index + i];
    455                }
    456        }
    457
    458        @Override
    459        public boolean getElementBooleanAbs(final int index) {
    460                return data[index] != 0;
    461        }
    462
    463        @Override
    464        public double getElementDoubleAbs(final int index) {
    465                return data[index];
    466        }
    467
    468        @Override
    469        public long getElementLongAbs(final int index) {
    470                return DTypeUtils.toLong(data[index]); // OMIT_TOLONG_INT
    471        }
    472
    473        @Override
    474        protected void setItemDirect(final int dindex, final int sindex, final Object src) {
    475                setDirty();
    476                double[] dsrc = (double[]) src; // PRIM_TYPE
    477                for (int i = 0; i < isize; i++) {
    478                        data[dindex + i] = dsrc[sindex + i];
    479                }
    480        }
    481
    482        /**
    483         * Set values at absolute index in the internal array. This is an internal method with no checks so can be
    484         * dangerous. Use with care or ideally with an iterator.
    485         *
    486         * @param index
    487         *            absolute index
    488         * @param val
    489         *            new values
    490         */
    491        public void setAbs(final int index, final double[] val) { // PRIM_TYPE
    492                setDirty();
    493                for (int i = 0; i < isize; i++) {
    494                        data[index + i] = val[i];
    495                }
    496        }
    497
    498        /**
    499         * Set element value at absolute index in the internal array. This is an internal method with no checks so can be
    500         * dangerous. Use with care or ideally with an iterator.
    501         *
    502         * @param index
    503         *            absolute index
    504         * @param val
    505         *            new value
    506         */
    507        public void setAbs(final int index, final double val) { // PRIM_TYPE
    508                setDirty();
    509                data[index] = val;
    510        }
    511
    512        @Override
    513        public Object getObject() {
    514                return getDoubleArray(); // PRIM_TYPE
    515        }
    516
    517        @Override
    518        public Object getObject(final int i) {
    519                return getDoubleArray(i); // PRIM_TYPE
    520        }
    521
    522        @Override
    523        public Object getObject(final int i, final int j) {
    524                return getDoubleArray(i, j); // PRIM_TYPE
    525        }
    526
    527        @Override
    528        public Object getObject(final int... pos) {
    529                return getDoubleArray(pos); // PRIM_TYPE
    530        }
    531
    532        @Override
    533        public byte[] getByteArray() {
    534                byte[] result = new byte[isize];
    535                int index = getFirst1DIndex();
    536                for (int k = 0; k < isize; k++) {
    537                        result[k] = (byte) data[index + k]; // OMIT_UPCAST
    538                }
    539                return result;
    540        }
    541
    542        @Override
    543        public byte[] getByteArray(final int i) {
    544                byte[] result = new byte[isize];
    545                int index = get1DIndex(i);
    546                for (int k = 0; k < isize; k++) {
    547                        result[k] = (byte) data[index + k]; // OMIT_UPCAST
    548                }
    549                return result;
    550        }
    551
    552        @Override
    553        public byte[] getByteArray(final int i, final int j) {
    554                byte[] result = new byte[isize];
    555                int index = get1DIndex(i, j);
    556                for (int k = 0; k < isize; k++) {
    557                        result[k] = (byte) data[index + k]; // OMIT_UPCAST
    558                }
    559                return result;
    560        }
    561
    562        @Override
    563        public byte[] getByteArray(final int... pos) {
    564                byte[] result = new byte[isize];
    565                int index = get1DIndex(pos);
    566                for (int k = 0; k < isize; k++) {
    567                        result[k] = (byte) data[index + k]; // OMIT_UPCAST
    568                }
    569                return result;
    570        }
    571
    572        @Override
    573        public short[] getShortArray() {
    574                short[] result = new short[isize];
    575                int index = getFirst1DIndex();
    576                for (int k = 0; k < isize; k++) {
    577                        result[k] = (short) data[index + k]; // OMIT_UPCAST
    578                }
    579                return result;
    580        }
    581
    582        @Override
    583        public short[] getShortArray(final int i) {
    584                short[] result = new short[isize];
    585                int index = get1DIndex(i);
    586                for (int k = 0; k < isize; k++) {
    587                        result[k] = (short) data[index + k]; // OMIT_UPCAST
    588                }
    589                return result;
    590        }
    591
    592        @Override
    593        public short[] getShortArray(final int i, final int j) {
    594                short[] result = new short[isize];
    595                int index = get1DIndex(i, j);
    596                for (int k = 0; k < isize; k++) {
    597                        result[k] = (short) data[index + k]; // OMIT_UPCAST
    598                }
    599                return result;
    600        }
    601
    602        @Override
    603        public short[] getShortArray(final int... pos) {
    604                short[] result = new short[isize];
    605                int index = get1DIndex(pos);
    606                for (int k = 0; k < isize; k++) {
    607                        result[k] = (short) data[index + k]; // OMIT_UPCAST
    608                }
    609                return result;
    610        }
    611
    612        @Override
    613        public int[] getIntArray() {
    614                int[] result = new int[isize];
    615                int index = getFirst1DIndex();
    616                for (int k = 0; k < isize; k++) {
    617                        result[k] = (int) data[index + k]; // OMIT_UPCAST
    618                }
    619                return result;
    620        }
    621
    622        @Override
    623        public int[] getIntArray(final int i) {
    624                int[] result = new int[isize];
    625                int index = get1DIndex(i);
    626                for (int k = 0; k < isize; k++) {
    627                        result[k] = (int) data[index + k]; // OMIT_UPCAST
    628                }
    629                return result;
    630        }
    631
    632        @Override
    633        public int[] getIntArray(final int i, final int j) {
    634                int[] result = new int[isize];
    635                int index = get1DIndex(i, j);
    636                for (int k = 0; k < isize; k++) {
    637                        result[k] = (int) data[index + k]; // OMIT_UPCAST
    638                }
    639                return result;
    640        }
    641
    642        @Override
    643        public int[] getIntArray(final int... pos) {
    644                int[] result = new int[isize];
    645                int index = get1DIndex(pos);
    646                for (int k = 0; k < isize; k++) {
    647                        result[k] = (int) data[index + k]; // OMIT_UPCAST
    648                }
    649                return result;
    650        }
    651
    652        @Override
    653        public long[] getLongArray() {
    654                long[] result = new long[isize];
    655                int index = getFirst1DIndex();
    656                for (int k = 0; k < isize; k++) {
    657                        result[k] = (long) data[index + k]; // OMIT_UPCAST
    658                }
    659                return result;
    660        }
    661
    662        @Override
    663        public long[] getLongArray(final int i) {
    664                long[] result = new long[isize];
    665                int index = get1DIndex(i);
    666                for (int k = 0; k < isize; k++) {
    667                        result[k] = (long) data[index + k]; // OMIT_UPCAST
    668                }
    669                return result;
    670        }
    671
    672        @Override
    673        public long[] getLongArray(final int i, final int j) {
    674                long[] result = new long[isize];
    675                int index = get1DIndex(i, j);
    676                for (int k = 0; k < isize; k++) {
    677                        result[k] = (long) data[index + k]; // OMIT_UPCAST
    678                }
    679                return result;
    680        }
    681
    682        @Override
    683        public long[] getLongArray(final int... pos) {
    684                long[] result = new long[isize];
    685                int index = get1DIndex(pos);
    686                for (int k = 0; k < isize; k++) {
    687                        result[k] = (long) data[index + k]; // OMIT_UPCAST
    688                }
    689                return result;
    690        }
    691
    692        @Override
    693        public float[] getFloatArray() {
    694                float[] result = new float[isize];
    695                int index = getFirst1DIndex();
    696                for (int k = 0; k < isize; k++) {
    697                        result[k] = (float) data[index + k]; // OMIT_REAL_CAST
    698                }
    699                return result;
    700        }
    701
    702        @Override
    703        public float[] getFloatArray(final int i) {
    704                float[] result = new float[isize];
    705                int index = get1DIndex(i);
    706                for (int k = 0; k < isize; k++) {
    707                        result[k] = (float) data[index + k]; // OMIT_REAL_CAST
    708                }
    709                return result;
    710        }
    711
    712        @Override
    713        public float[] getFloatArray(final int i, final int j) {
    714                float[] result = new float[isize];
    715                int index = get1DIndex(i, j);
    716                for (int k = 0; k < isize; k++) {
    717                        result[k] = (float) data[index + k]; // OMIT_REAL_CAST
    718                }
    719                return result;
    720        }
    721
    722        @Override
    723        public float[] getFloatArray(final int... pos) {
    724                float[] result = new float[isize];
    725                int index = get1DIndex(pos);
    726                for (int k = 0; k < isize; k++) {
    727                        result[k] = (float) data[index + k]; // OMIT_REAL_CAST
    728                }
    729                return result;
    730        }
    731
    732        @Override
    733        public double[] getDoubleArray() {
    734                double[] result = new double[isize];
    735                int index = getFirst1DIndex();
    736                for (int k = 0; k < isize; k++) {
    737                        result[k] = data[index + k]; // OMIT_REAL_CAST
    738                }
    739                return result;
    740        }
    741
    742        @Override
    743        public double[] getDoubleArray(final int i) {
    744                double[] result = new double[isize];
    745                int index = get1DIndex(i);
    746                for (int k = 0; k < isize; k++) {
    747                        result[k] = data[index + k]; // OMIT_REAL_CAST
    748                }
    749                return result;
    750        }
    751
    752        @Override
    753        public double[] getDoubleArray(final int i, final int j) {
    754                double[] result = new double[isize];
    755                int index = get1DIndex(i, j);
    756                for (int k = 0; k < isize; k++) {
    757                        result[k] = data[index + k]; // OMIT_REAL_CAST
    758                }
    759                return result;
    760        }
    761
    762        @Override
    763        public double[] getDoubleArray(final int... pos) {
    764                double[] result = new double[isize];
    765                int index = get1DIndex(pos);
    766                for (int k = 0; k < isize; k++) {
    767                        result[k] = data[index + k]; // OMIT_REAL_CAST
    768                }
    769                return result;
    770        }
    771
    772        @Override
    773        public void getDoubleArrayAbs(final int index, final double[] darray) {
    774                for (int i = 0; i < isize; i++) {
    775                        darray[i] = data[index + i];
    776                }
    777        }
    778
    779        @Override
    780        public String getString() {
    781                return getStringAbs(getFirst1DIndex());
    782        }
    783
    784        @Override
    785        public String getString(final int i) {
    786                return getStringAbs(get1DIndex(i));
    787        }
    788
    789        @Override
    790        public String getString(final int i, final int j) {
    791                return getStringAbs(get1DIndex(i, j));
    792        }
    793
    794        @Override
    795        public String getString(final int... pos) {
    796                return getStringAbs(get1DIndex(pos));
    797        }
    798
    799        @Override
    800        protected double getFirstValue() {
    801                return data[getFirst1DIndex()];
    802        }
    803
    804        @Override
    805        protected double getFirstValue(int i) {
    806                return data[get1DIndex(i)];
    807        }
    808
    809        @Override
    810        protected double getFirstValue(int i, int j) {
    811                return data[get1DIndex(i, j)];
    812        }
    813
    814        @Override
    815        protected double getFirstValue(final int... pos) {
    816                return data[get1DIndex(pos)];
    817        }
    818
    819        @Override
    820        public Object getObjectAbs(final int index) {
    821                double[] result = new double[isize]; // PRIM_TYPE
    822                for (int i = 0; i < isize; i++) {
    823                        result[i] = data[index + i];
    824                }
    825                return result;
    826        }
    827
    828        @Override
    829        public String getStringAbs(final int index) {
    830                StringBuilder s = new StringBuilder();
    831                s.append('(');
    832                s.append(stringFormat == null ? String.format("%.8g", data[index]) : // FORMAT_STRING
    833                        stringFormat.format(data[index]));
    834                for (int i = 1; i < isize; i++) {
    835                        s.append(' ');
    836                        s.append(stringFormat == null ? String.format("%.8g", data[index + i]) : // FORMAT_STRING
    837                                stringFormat.format(data[index + i]));
    838                }
    839                s.append(')');
    840                return s.toString();
    841        }
    842
    843        @Override
    844        public void setObjectAbs(final int index, final Object obj) {
    845                double[] oa = DTypeUtils.toDoubleArray(obj, isize); // PRIM_TYPE // CLASS_TYPE
    846                setAbs(index, oa);
    847        }
    848
    849        @Override
    850        public void set(final Object obj) {
    851                setItem(DTypeUtils.toDoubleArray(obj, isize)); // CLASS_TYPE
    852        }
    853
    854        @Override
    855        public void set(final Object obj, final int i) {
    856                setItem(DTypeUtils.toDoubleArray(obj, isize), i); // CLASS_TYPE
    857        }
    858
    859        @Override
    860        public void set(final Object obj, final int i, final int j) {
    861                setItem(DTypeUtils.toDoubleArray(obj, isize), i, j); // CLASS_TYPE
    862        }
    863
    864        @Override
    865        public void set(final Object obj, int... pos) {
    866                if (pos == null || (pos.length == 0 && shape.length > 0)) {
    867                        pos = new int[shape.length];
    868                }
    869
    870                setItem(DTypeUtils.toDoubleArray(obj, isize), pos); // CLASS_TYPE
    871        }
    872
    873        /**
    874         * Set values at first position. The dataset must not be null
    875         *
    876         * @param d
    877         * @since 2.0
    878         */
    879        public void setItem(final double[] d) { // PRIM_TYPE
    880                if (d.length > isize) {
    881                        throw new IllegalArgumentException("Array is larger than number of elements in an item");
    882                }
    883                setAbs(getFirst1DIndex(), d);
    884        }
    885
    886        /**
    887         * Set values at given position. The dataset must be 1D
    888         *
    889         * @param d
    890         * @param i
    891         */
    892        public void setItem(final double[] d, final int i) { // PRIM_TYPE
    893                if (d.length > isize) {
    894                        throw new IllegalArgumentException("Array is larger than number of elements in an item");
    895                }
    896                setAbs(get1DIndex(i), d);
    897        }
    898
    899        /**
    900         * Set values at given position. The dataset must be 1D
    901         *
    902         * @param d
    903         * @param i
    904         * @param j
    905         */
    906        public void setItem(final double[] d, final int i, final int j) { // PRIM_TYPE
    907                if (d.length > isize) {
    908                        throw new IllegalArgumentException("Array is larger than number of elements in an item");
    909                }
    910                setAbs(get1DIndex(i, j), d);
    911        }
    912
    913        /**
    914         * Set values at given position
    915         *
    916         * @param d
    917         * @param pos
    918         */
    919        public void setItem(final double[] d, final int... pos) { // PRIM_TYPE
    920                if (d.length > isize) {
    921                        throw new IllegalArgumentException("Array is larger than number of elements in an item");
    922                }
    923                setAbs(get1DIndex(pos), d);
    924        }
    925
    926        private void setDoubleArrayAbs(final int index, final double[] d) {
    927                for (int i = 0; i < isize; i++)
    928                        data[index + i] = d[i]; // ADD_CAST
    929        }
    930
    931        @Override
    932        public void resize(int... newShape) {
    933                setDirty();
    934                IndexIterator iter = getIterator();
    935                int nsize = ShapeUtils.calcSize(newShape);
    936                double[] ndata; // PRIM_TYPE
    937                try {
    938                        ndata = createArray(nsize);
    939                } catch (Throwable t) {
    940                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    941                        throw new IllegalArgumentException(t);
    942                }
    943
    944                int i = 0;
    945                while (iter.hasNext() && i < nsize) {
    946                        for (int j = 0; j < isize; j++) {
    947                                ndata[i++] = data[iter.index + j];
    948                        }
    949                }
    950
    951                odata = data = ndata;
    952                size = nsize;
    953                shape = newShape;
    954                stride = null;
    955                offset = 0;
    956                base = null;
    957        }
    958
    959        @Override
    960        public CompoundDoubleDataset getSlice(final SliceIterator siter) {
    961                CompoundDoubleDataset result = new CompoundDoubleDataset(isize, siter.getShape());
    962                double[] rdata = result.data; // PRIM_TYPE
    963                IndexIterator riter = result.getIterator();
    964
    965                while (siter.hasNext() && riter.hasNext()) {
    966                        for (int i = 0; i < isize; i++)
    967                                rdata[riter.index + i] = data[siter.index + i];
    968                }
    969
    970                result.setName(name + BLOCK_OPEN + Slice.createString(siter.shape, siter.start, siter.stop, siter.step) + BLOCK_CLOSE);
    971                return result;
    972        }
    973
    974        @Override
    975        public DoubleDataset getElementsView(int element) { // CLASS_TYPE
    976                if (element < 0)
    977                        element += isize;
    978                if (element < 0 || element > isize) {
    979                        throw new IllegalArgumentException(String.format("Invalid choice of element: %d/%d", element, isize));
    980                }
    981
    982                DoubleDataset view = new DoubleDataset(shape); // CLASS_TYPE
    983
    984                copyToView(this, view, true, true);
    985                view.setData();
    986                if (view.stride == null) {
    987                        int[] offset = new int[1];
    988                        view.stride = createStrides(this, offset);
    989                        view.offset = offset[0] + element;
    990                        view.base = base == null ? this : base;
    991                } else {
    992                        view.offset += element;
    993                }
    994
    995                return view;
    996        }
    997
    998        @Override
    999        public DoubleDataset getElements(int element) { // CLASS_TYPE
    1000                final DoubleDataset elements = new DoubleDataset(shape); // CLASS_TYPE
    1001
    1002                copyElements(elements, element);
    1003                return elements;
    1004        }
    1005
    1006        @Override
    1007        public void copyElements(Dataset destination, int element) {
    1008                if (element < 0)
    1009                        element += isize;
    1010                if (element < 0 || element > isize) {
    1011                        throw new IllegalArgumentException(String.format("Invalid choice of element: %d/%d", element, isize));
    1012                }
    1013                if (getElementClass() != destination.getElementClass()) {
    1014                        throw new IllegalArgumentException("Element class of destination does not match this dataset");
    1015                }
    1016
    1017                final IndexIterator it = getIterator(element);
    1018                final double[] elements = ((DoubleDataset) destination).data; // CLASS_TYPE // PRIM_TYPE
    1019                destination.setDirty();
    1020
    1021                int n = 0;
    1022                while (it.hasNext()) {
    1023                        elements[n] = data[it.index];
    1024                        n++;
    1025                }
    1026        }
    1027
    1028        @Override
    1029        public void setElements(Dataset source, int element) {
    1030                setDirty();
    1031                if (element < 0)
    1032                        element += isize;
    1033                if (element < 0 || element > isize) {
    1034                        throw new IllegalArgumentException(String.format("Invalid choice of element: %d/%d", element, isize));
    1035                }
    1036                if (getElementClass() != source.getElementClass()) {
    1037                        throw new IllegalArgumentException("Element class of destination does not match this dataset");
    1038                }
    1039
    1040                final IndexIterator it = getIterator(element);
    1041                final double[] elements = ((DoubleDataset) source).data; // CLASS_TYPE // PRIM_TYPE
    1042
    1043                int n = 0;
    1044                while (it.hasNext()) {
    1045                        data[it.index] = elements[n];
    1046                        n++;
    1047                }
    1048        }
    1049
    1050        @Override
    1051        public void fillDataset(Dataset result, IndexIterator iter) {
    1052                IndexIterator riter = result.getIterator();
    1053                result.setDirty();
    1054
    1055                double[] rdata = ((CompoundDoubleDataset) result).data; // PRIM_TYPE
    1056
    1057                while (riter.hasNext() && iter.hasNext()) {
    1058                        for (int i = 0; i < isize; i++) {
    1059                                rdata[riter.index + i] = data[iter.index + i];
    1060                        }
    1061                }
    1062        }
    1063
    1064        @Override
    1065        public CompoundDoubleDataset setByBoolean(final Object o, Dataset selection) {
    1066                setDirty();
    1067                if (o instanceof Dataset) {
    1068                        Dataset ds = (Dataset) o;
    1069                        final int length = ((Number) selection.sum()).intValue();
    1070                        if (length != ds.getSize()) {
    1071                                throw new IllegalArgumentException(
    1072                                                "Number of true items in selection does not match number of items in dataset");
    1073                        }
    1074
    1075                        IndexIterator iter = ds.getIterator();
    1076                        BooleanIterator biter = getBooleanIterator(selection);
    1077
    1078                        if (ds instanceof AbstractCompoundDataset) {
    1079                                if (isize != ds.getElementsPerItem()) {
    1080                                        throw new IllegalArgumentException("Input dataset is not compatible with slice");
    1081                                }
    1082
    1083                                while (biter.hasNext() && iter.hasNext()) {
    1084                                        for (int i = 0; i < isize; i++) {
    1085                                                data[biter.index + i] = ds.getElementDoubleAbs(iter.index + i); // GET_ELEMENT_WITH_CAST
    1086                                        }
    1087                                }
    1088                        } else {
    1089                                while (biter.hasNext() && iter.hasNext()) {
    1090                                        data[biter.index] = ds.getElementDoubleAbs(iter.index); // GET_ELEMENT_WITH_CAST
    1091                                        for (int i = 1; i < isize; i++) {
    1092                                                data[biter.index + i] = 0;
    1093                                        }
    1094                                }
    1095                        }
    1096                } else {
    1097                        try {
    1098                                final double[] vr = DTypeUtils.toDoubleArray(o, isize); // PRIM_TYPE // CLASS_TYPE
    1099
    1100                                final BooleanIterator biter = getBooleanIterator(selection);
    1101
    1102                                while (biter.hasNext()) {
    1103                                        for (int i = 0; i < isize; i++) {
    1104                                                data[biter.index + i] = vr[i];
    1105                                        }
    1106                                }
    1107                        } catch (IllegalArgumentException e) {
    1108                                throw new IllegalArgumentException("Object for setting is not a dataset or number");
    1109                        }
    1110                }
    1111                return this;
    1112        }
    1113
    1114        @Override
    1115        public CompoundDoubleDataset setBy1DIndex(final Object o, Dataset index) {
    1116                setDirty();
    1117                if (o instanceof Dataset) {
    1118                        Dataset ds = (Dataset) o;
    1119                        if (index.getSize() != ds.getSize()) {
    1120                                throw new IllegalArgumentException(
    1121                                                "Number of items in selection does not match number of items in dataset");
    1122                        }
    1123
    1124                        IndexIterator oiter = ds.getIterator();
    1125                        final IntegerIterator iter = new IntegerIterator(index, size, isize);
    1126
    1127                        if (ds instanceof AbstractCompoundDataset) {
    1128                                if (isize != ds.getElementsPerItem()) {
    1129                                        throw new IllegalArgumentException("Input dataset is not compatible with slice");
    1130                                }
    1131
    1132                                double[] temp = new double[isize];
    1133                                while (iter.hasNext() && oiter.hasNext()) {
    1134                                        ((AbstractCompoundDataset) ds).getDoubleArrayAbs(oiter.index, temp);
    1135                                        setDoubleArrayAbs(iter.index, temp);
    1136                                }
    1137                                while (iter.hasNext() && oiter.hasNext()) {
    1138                                        for (int i = 0; i < isize; i++) {
    1139                                                data[iter.index + i] = ds.getElementDoubleAbs(oiter.index + i); // GET_ELEMENT_WITH_CAST
    1140                                        }
    1141                                }
    1142                        } else {
    1143                                while (iter.hasNext() && oiter.hasNext()) {
    1144                                        data[iter.index] = ds.getElementDoubleAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    1145                                        for (int i = 1; i < isize; i++) {
    1146                                                data[iter.index + i] = 0;
    1147                                        }
    1148                                }
    1149                        }
    1150                } else {
    1151                        try {
    1152                                final double[] vr = DTypeUtils.toDoubleArray(o, isize); // PRIM_TYPE // CLASS_TYPE
    1153
    1154                                final IntegerIterator iter = new IntegerIterator(index, size, isize);
    1155
    1156                                while (iter.hasNext()) {
    1157                                        setAbs(iter.index, vr);
    1158                                }
    1159                        } catch (IllegalArgumentException e) {
    1160                                throw new IllegalArgumentException("Object for setting is not a dataset or number");
    1161                        }
    1162                }
    1163                return this;
    1164        }
    1165
    1166        @Override
    1167        public CompoundDoubleDataset setByIndexes(final Object o, final Object... indexes) {
    1168                setDirty();
    1169                final IntegersIterator iter = new IntegersIterator(shape, indexes);
    1170                final int[] pos = iter.getPos();
    1171
    1172                if (o instanceof Dataset) {
    1173                        Dataset ds = (Dataset) o;
    1174                        if (ShapeUtils.calcSize(iter.getShape()) != ds.getSize()) {
    1175                                throw new IllegalArgumentException(
    1176                                                "Number of items in selection does not match number of items in dataset");
    1177                        }
    1178
    1179                        IndexIterator oiter = ds.getIterator();
    1180
    1181                        if (ds instanceof AbstractCompoundDataset) {
    1182                                if (isize != ds.getElementsPerItem()) {
    1183                                        throw new IllegalArgumentException("Input dataset is not compatible with slice");
    1184                                }
    1185
    1186                                double[] temp = new double[isize];
    1187                                while (iter.hasNext() && oiter.hasNext()) {
    1188                                        ((AbstractCompoundDataset) ds).getDoubleArray(temp, pos);
    1189                                        setDoubleArrayAbs(get1DIndex(pos), temp);
    1190                                }
    1191                        } else {
    1192                                while (iter.hasNext() && oiter.hasNext()) {
    1193                                        int n = get1DIndex(pos);
    1194                                        data[n] = ds.getElementDoubleAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    1195                                        for (int i = 1; i < isize; i++) {
    1196                                                data[n + i] = 0;
    1197                                        }
    1198                                }
    1199                        }
    1200                } else {
    1201                        try {
    1202                                final double[] vr = DTypeUtils.toDoubleArray(o, isize); // PRIM_TYPE // CLASS_TYPE
    1203
    1204                                while (iter.hasNext()) {
    1205                                        setAbs(get1DIndex(pos), vr);
    1206                                }
    1207                        } catch (IllegalArgumentException e) {
    1208                                throw new IllegalArgumentException("Object for setting is not a dataset or number");
    1209                        }
    1210                }
    1211                return this;
    1212        }
    1213
    1214        @Override
    1215        CompoundDoubleDataset setSlicedView(Dataset view, Dataset d) {
    1216                setDirty();
    1217                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(view, d);
    1218
    1219                final int is = view.getElementsPerItem();
    1220
    1221                if (is > 1) {
    1222                        if (d.getElementsPerItem() == 1) {
    1223                                while (it.hasNext()) {
    1224                                        final double bv = it.bDouble; // PRIM_TYPE // BCAST_WITH_CAST d.getElementDoubleAbs(it.bIndex);
    1225                                        data[it.aIndex] = bv;
    1226                                        for (int j = 1; j < is; j++) {
    1227                                                data[it.aIndex + j] = bv;
    1228                                        }
    1229                                }
    1230                        } else {
    1231                                while (it.hasNext()) {
    1232                                        data[it.aIndex] = it.bDouble; // BCAST_WITH_CAST d.getElementDoubleAbs(it.bIndex);
    1233                                        for (int j = 1; j < is; j++) {
    1234                                                data[it.aIndex + j] = d.getElementDoubleAbs(it.bIndex + j); // GET_ELEMENT_WITH_CAST
    1235                                        }
    1236                                }
    1237                        }
    1238                } else {
    1239                        while (it.hasNext()) {
    1240                                data[it.aIndex] = it.bDouble; // BCAST_WITH_CAST d.getElementDoubleAbs(it.bIndex);
    1241                        }
    1242                }
    1243                return this;
    1244        }
    1245
    1246        @Override
    1247        public CompoundDoubleDataset setSlice(final Object o, final IndexIterator siter) {
    1248                setDirty();
    1249                if (o instanceof IDataset) {
    1250                        final IDataset ds = (IDataset) o;
    1251                        final int[] oshape = ds.getShape();
    1252
    1253                        if (!ShapeUtils.areShapesCompatible(siter.getShape(), oshape)) {
    1254                                throw new IllegalArgumentException(String.format(
    1255                                                "Input dataset is not compatible with slice: %s cf %s", Arrays.toString(oshape),
    1256                                                Arrays.toString(siter.getShape())));
    1257                        }
    1258
    1259                        if (ds instanceof Dataset) {
    1260                                final Dataset ads = (Dataset) ds;
    1261                                IndexIterator oiter = ads.getIterator();
    1262
    1263                                if (ds instanceof AbstractCompoundDataset) {
    1264                                        if (isize != ads.getElementsPerItem()) {
    1265                                                throw new IllegalArgumentException("Input dataset is not compatible with slice");
    1266                                        }
    1267
    1268                                        while (siter.hasNext() && oiter.hasNext()) {
    1269                                                for (int i = 0; i < isize; i++) {
    1270                                                        data[siter.index + i] = ads.getElementDoubleAbs(oiter.index + i); // GET_ELEMENT_WITH_CAST
    1271                                                }
    1272                                        }
    1273                                } else {
    1274                                        while (siter.hasNext() && oiter.hasNext()) {
    1275                                                data[siter.index] = ads.getElementDoubleAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    1276                                                for (int i = 1; i < isize; i++) {
    1277                                                        data[siter.index + i] = 0;
    1278                                                }
    1279                                        }
    1280                                }
    1281                        } else {
    1282                                final IndexIterator oiter = new PositionIterator(oshape);
    1283                                final int[] pos = oiter.getPos();
    1284
    1285                                if (ds.getElementsPerItem() == 1) {
    1286                                        while (siter.hasNext() && oiter.hasNext()) {
    1287                                                data[siter.index] = ds.getDouble(pos); // PRIM_TYPE
    1288                                                for (int i = 1; i < isize; i++) {
    1289                                                        data[siter.index + i] = 0;
    1290                                                }
    1291                                        }
    1292                                } else {
    1293                                        while (siter.hasNext() && oiter.hasNext()) {
    1294                                                final double[] val = DTypeUtils.toDoubleArray(ds.getObject(pos), isize); // PRIM_TYPE // CLASS_TYPE
    1295                                                for (int i = 0; i < isize; i++) {
    1296                                                        data[siter.index + i] = val[i];
    1297                                                }
    1298                                        }
    1299                                }
    1300                        }
    1301                } else {
    1302                        try {
    1303                                final double[] vr = DTypeUtils.toDoubleArray(o, isize); // PRIM_TYPE // CLASS_TYPE
    1304
    1305                                while (siter.hasNext()) {
    1306                                        for (int i = 0; i < isize; i++) {
    1307                                                data[siter.index + i] = vr[i];
    1308                                        }
    1309                                }
    1310                        } catch (IllegalArgumentException e) {
    1311                                throw new IllegalArgumentException("Object for setting slice is not a dataset or number");
    1312                        }
    1313                }
    1314                return this;
    1315        }
    1316
    1317        @Override
    1318        public void copyItemsFromAxes(final int[] pos, final boolean[] axes, final Dataset dest) {
    1319                double[] ddata = (double[]) dest.getBuffer(); // PRIM_TYPE
    1320
    1321                if (dest.getElementsPerItem() != isize) {
    1322                        throw new IllegalArgumentException(String.format(
    1323                                        "Destination dataset is incompatible as it has %d elements per item not %d",
    1324                                        dest.getElementsPerItem(), isize));
    1325                }
    1326
    1327                SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
    1328                int[] sshape = ShapeUtils.squeezeShape(siter.getShape(), false);
    1329
    1330                IndexIterator diter = dest.getSliceIterator(null, sshape, null);
    1331
    1332                if (ddata.length < ShapeUtils.calcSize(sshape)) {
    1333                        throw new IllegalArgumentException("destination array is not large enough");
    1334                }
    1335
    1336                dest.setDirty();
    1337                while (siter.hasNext() && diter.hasNext()) {
    1338                        for (int i = 0; i < isize; i++) {
    1339                                ddata[diter.index + i] = data[siter.index + i];
    1340                        }
    1341                }
    1342        }
    1343
    1344        @Override
    1345        public void setItemsOnAxes(final int[] pos, final boolean[] axes, final Object src) {
    1346                setDirty();
    1347                double[] sdata = (double[]) src; // PRIM_TYPE
    1348
    1349                SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
    1350
    1351                if (sdata.length < ShapeUtils.calcSize(siter.getShape())) {
    1352                        throw new IllegalArgumentException("source array is not large enough");
    1353                }
    1354
    1355                for (int i = 0; siter.hasNext(); i++) {
    1356                        for (int j = 0; j < isize; j++) {
    1357                                data[siter.index + j] = sdata[isize * i + j];
    1358                        }
    1359                }
    1360        }
    1361
    1362        @Override
    1363        public boolean containsNans() {
    1364                final IndexIterator iter = getIterator(); // REAL_ONLY
    1365                while (iter.hasNext()) { // REAL_ONLY
    1366                        for (int i = 0; i < isize; i++) { // REAL_ONLY
    1367                                if (Double.isNaN(data[iter.index + i])) // CLASS_TYPE // REAL_ONLY
    1368                                        return true; // REAL_ONLY
    1369                        } // REAL_ONLY
    1370                } // REAL_ONLY
    1371                return false;
    1372        }
    1373
    1374        @Override
    1375        public boolean containsInfs() {
    1376                final IndexIterator iter = getIterator(); // REAL_ONLY
    1377                while (iter.hasNext()) { // REAL_ONLY
    1378                        for (int i = 0; i < isize; i++) { // REAL_ONLY
    1379                                if (Double.isInfinite(data[iter.index + i])) // CLASS_TYPE // REAL_ONLY
    1380                                        return true; // REAL_ONLY
    1381                        } // REAL_ONLY
    1382                } // REAL_ONLY
    1383                return false;
    1384        }
    1385
    1386        @Override
    1387        public boolean containsInvalidNumbers() {
    1388                IndexIterator iter = getIterator(); // REAL_ONLY
    1389                while (iter.hasNext()) { // REAL_ONLY
    1390                        for (int i = 0; i < isize; i++) { // REAL_ONLY
    1391                                double x = data[iter.index + i]; // PRIM_TYPE // REAL_ONLY
    1392                                if (Double.isNaN(x) || Double.isInfinite(x)) // CLASS_TYPE // REAL_ONLY
    1393                                        return true; // REAL_ONLY
    1394                        } // REAL_ONLY
    1395                } // REAL_ONLY
    1396                return false;
    1397        }
    1398
    1399        @Override
    1400        public CompoundDoubleDataset iadd(final Object b) {
    1401                setDirty();
    1402                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    1403                boolean useLong = bds.getElementClass().equals(Long.class);
    1404                int is = bds.getElementsPerItem();
    1405                if (bds.getSize() == 1) {
    1406                        final IndexIterator it = getIterator();
    1407                        final int bOffset = bds.getOffset();
    1408                        if (is == 1) {
    1409                                if (useLong) {
    1410                                        final long lb = bds.getElementLongAbs(bOffset);
    1411                                        while (it.hasNext()) {
    1412                                                for (int i = 0; i < isize; i++) {
    1413                                                        data[it.index + i] += lb;
    1414                                                }
    1415                                        }
    1416                                } else {
    1417                                        final double db = bds.getElementDoubleAbs(bOffset);
    1418                                        while (it.hasNext()) {
    1419                                                for (int i = 0; i < isize; i++) {
    1420                                                        data[it.index + i] += db;
    1421                                                }
    1422                                        }
    1423                                }
    1424                        } else if (is == isize) {
    1425                                if (useLong) {
    1426                                        while (it.hasNext()) {
    1427                                                for (int i = 0; i < isize; i++) {
    1428                                                        data[it.index + i] += bds.getElementLongAbs(i);
    1429                                                }
    1430                                        }
    1431                                } else {
    1432                                        while (it.hasNext()) {
    1433                                                for (int i = 0; i < isize; i++) {
    1434                                                        data[it.index + i] += bds.getElementDoubleAbs(i);
    1435                                                }
    1436                                        }
    1437                                }
    1438                        } else {
    1439                                throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1440                        }
    1441                } else {
    1442                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
    1443                        it.setOutputDouble(!useLong);
    1444                        if (is == 1) {
    1445                                if (useLong) {
    1446                                        while (it.hasNext()) {
    1447                                                final long lb = it.bLong;
    1448                                                data[it.aIndex] += lb;
    1449                                                for (int i = 1; i < isize; i++) {
    1450                                                        data[it.aIndex + i] += lb;
    1451                                                }
    1452                                        }
    1453                                } else {
    1454                                        while (it.hasNext()) {
    1455                                                final double db = it.bDouble;
    1456                                                data[it.aIndex] += db;
    1457                                                for (int i = 1; i < isize; i++) {
    1458                                                        data[it.aIndex + i] += db;
    1459                                                }
    1460                                        }
    1461                                }
    1462                        } else if (is == isize) {
    1463                                if (useLong) {
    1464                                        while (it.hasNext()) {
    1465                                                data[it.aIndex] += it.bLong;
    1466                                                for (int i = 1; i < isize; i++) {
    1467                                                        data[it.aIndex + i] += bds.getElementLongAbs(it.bIndex + i);
    1468                                                }
    1469                                        }
    1470                                } else {
    1471                                        while (it.hasNext()) {
    1472                                                data[it.aIndex] += it.bDouble;
    1473                                                for (int i = 1; i < isize; i++) {
    1474                                                        data[it.aIndex + i] += bds.getElementDoubleAbs(it.bIndex + i);
    1475                                                }
    1476                                        }
    1477                                }
    1478                        } else {
    1479                                throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1480                        }
    1481                }
    1482                return this;
    1483        }
    1484
    1485        @Override
    1486        public CompoundDoubleDataset isubtract(final Object b) {
    1487                setDirty();
    1488                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    1489                boolean useLong = bds.getElementClass().equals(Long.class);
    1490                int is = bds.getElementsPerItem();
    1491                if (bds.getSize() == 1) {
    1492                        final IndexIterator it = getIterator();
    1493                        final int bOffset = bds.getOffset();
    1494                        if (is == 1) {
    1495                                if (useLong) {
    1496                                        final long lb = bds.getElementLongAbs(bOffset);
    1497                                        while (it.hasNext()) {
    1498                                                for (int i = 0; i < isize; i++) {
    1499                                                        data[it.index + i] -= lb;
    1500                                                }
    1501                                        }
    1502                                } else {
    1503                                        final double db = bds.getElementDoubleAbs(bOffset);
    1504                                        while (it.hasNext()) {
    1505                                                for (int i = 0; i < isize; i++) {
    1506                                                        data[it.index + i] -= db;
    1507                                                }
    1508                                        }
    1509                                }
    1510                        } else if (is == isize) {
    1511                                if (useLong) {
    1512                                        while (it.hasNext()) {
    1513                                                for (int i = 0; i < isize; i++) {
    1514                                                        data[it.index + i] -= bds.getElementLongAbs(i);
    1515                                                }
    1516                                        }
    1517                                } else {
    1518                                        while (it.hasNext()) {
    1519                                                for (int i = 0; i < isize; i++) {
    1520                                                        data[it.index + i] -= bds.getElementDoubleAbs(i);
    1521                                                }
    1522                                        }
    1523                                }
    1524                        } else {
    1525                                throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1526                        }
    1527                } else {
    1528                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
    1529                        it.setOutputDouble(!useLong);
    1530                        if (is == 1) {
    1531                                if (useLong) {
    1532                                        while (it.hasNext()) {
    1533                                                final long lb = it.bLong;
    1534                                                data[it.aIndex] += lb;
    1535                                                for (int i = 1; i < isize; i++) {
    1536                                                        data[it.aIndex + i] -= lb;
    1537                                                }
    1538                                        }
    1539                                } else {
    1540                                        while (it.hasNext()) {
    1541                                                final double db = it.bDouble;
    1542                                                data[it.aIndex] += db;
    1543                                                for (int i = 1; i < isize; i++) {
    1544                                                        data[it.aIndex + i] -= db;
    1545                                                }
    1546                                        }
    1547                                }
    1548                        } else if (is == isize) {
    1549                                if (useLong) {
    1550                                        while (it.hasNext()) {
    1551                                                data[it.aIndex] += it.bLong;
    1552                                                for (int i = 1; i < isize; i++) {
    1553                                                        data[it.aIndex + i] -= bds.getElementLongAbs(it.bIndex + i);
    1554                                                }
    1555                                        }
    1556                                } else {
    1557                                        while (it.hasNext()) {
    1558                                                data[it.aIndex] += it.bDouble;
    1559                                                for (int i = 1; i < isize; i++) {
    1560                                                        data[it.aIndex + i] -= bds.getElementDoubleAbs(it.bIndex + i);
    1561                                                }
    1562                                        }
    1563                                }
    1564                        } else {
    1565                                throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1566                        }
    1567                }
    1568                return this;
    1569        }
    1570
    1571        @Override
    1572        public CompoundDoubleDataset imultiply(final Object b) {
    1573                setDirty();
    1574                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    1575                boolean useLong = bds.getElementClass().equals(Long.class);
    1576                int is = bds.getElementsPerItem();
    1577                if (bds.getSize() == 1) {
    1578                        final IndexIterator it = getIterator();
    1579                        final int bOffset = bds.getOffset();
    1580                        if (useLong) {
    1581                                if (is == 1) {
    1582                                        final long lb = bds.getElementLongAbs(bOffset);
    1583                                        while (it.hasNext()) {
    1584                                                for (int i = 0; i < isize; i++) {
    1585                                                        data[it.index + i] *= lb;
    1586                                                }
    1587                                        }
    1588                                } else if (is == isize) {
    1589                                        while (it.hasNext()) {
    1590                                                for (int i = 0; i < isize; i++) {
    1591                                                        data[it.index + i] *= bds.getElementLongAbs(i);
    1592                                                }
    1593                                        }
    1594                                } else {
    1595                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1596                                }
    1597                        } else {
    1598                                if (is == 1) {
    1599                                        final double db = bds.getElementDoubleAbs(bOffset);
    1600                                        while (it.hasNext()) {
    1601                                                for (int i = 0; i < isize; i++) {
    1602                                                        data[it.index + i] *= db;
    1603                                                }
    1604                                        }
    1605                                } else if (is == isize) {
    1606                                        while (it.hasNext()) {
    1607                                                for (int i = 0; i < isize; i++) {
    1608                                                        data[it.index + i] *= bds.getElementDoubleAbs(i);
    1609                                                }
    1610                                        }
    1611                                } else {
    1612                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1613                                }
    1614                        }
    1615                } else {
    1616                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
    1617                        it.setOutputDouble(!useLong);
    1618                        if (useLong) {
    1619                                if (is == 1) {
    1620                                        while (it.hasNext()) {
    1621                                                final double lb = it.bLong;
    1622                                                for (int i = 0; i < isize; i++) {
    1623                                                        data[it.aIndex + i] *= lb;
    1624                                                }
    1625                                        }
    1626                                } else if (is == isize) {
    1627                                        while (it.hasNext()) {
    1628                                                data[it.aIndex] *= it.bLong;
    1629                                                for (int i = 1; i < isize; i++) {
    1630                                                        data[it.aIndex + i] *= bds.getElementLongAbs(it.bIndex + i);
    1631                                                }
    1632                                        }
    1633                                } else {
    1634                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1635                                }
    1636                        } else {
    1637                                if (is == 1) {
    1638                                        while (it.hasNext()) {
    1639                                                final double db = it.bDouble;
    1640                                                for (int i = 0; i < isize; i++) {
    1641                                                        data[it.aIndex + i] *= db;
    1642                                                }
    1643                                        }
    1644                                } else if (is == isize) {
    1645                                        while (it.hasNext()) {
    1646                                                data[it.aIndex] *= it.bDouble;
    1647                                                for (int i = 1; i < isize; i++) {
    1648                                                        data[it.aIndex + i] *= bds.getElementDoubleAbs(it.bIndex + i);
    1649                                                }
    1650                                        }
    1651                                } else {
    1652                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1653                                }
    1654                        }
    1655                }
    1656                return this;
    1657        }
    1658
    1659        @Override
    1660        public CompoundDoubleDataset idivide(final Object b) {
    1661                setDirty();
    1662                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    1663                boolean useLong = bds.getElementClass().equals(Long.class);
    1664                int is = bds.getElementsPerItem();
    1665                if (bds.getSize() == 1) {
    1666                        final IndexIterator it = getIterator();
    1667                        final int bOffset = bds.getOffset();
    1668                        if (useLong) {
    1669                                if (is == 1) {
    1670                                        final long lb = bds.getElementLongAbs(bOffset);
    1671                                        // if (lb == 0) { // INT_USE
    1672                                        //      fill(0); // INT_USE
    1673                                        // } else { // INT_USE
    1674                                        while (it.hasNext()) {
    1675                                                for (int i = 0; i < isize; i++) {
    1676                                                        data[it.index + i] /= lb;
    1677                                                }
    1678                                        }
    1679                                        // } // INT_USE
    1680                                } else if (is == isize) {
    1681                                        while (it.hasNext()) {
    1682                                                for (int i = 0; i < isize; i++) {
    1683                                                        final long lb = bds.getElementLongAbs(i);
    1684                                                        data[it.index + i] /= lb; // INT_EXCEPTION
    1685                                                }
    1686                                        }
    1687                                } else {
    1688                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1689                                }
    1690                        } else {
    1691                                if (is == 1) {
    1692                                        final double db = bds.getElementDoubleAbs(bOffset);
    1693                                        // if (db == 0) { // INT_USE
    1694                                        //      fill(0); // INT_USE
    1695                                        // } else { // INT_USE
    1696                                        while (it.hasNext()) {
    1697                                                for (int i = 0; i < isize; i++) {
    1698                                                        data[it.index + i] /= db;
    1699                                                }
    1700                                        }
    1701                                        // } // INT_USE
    1702                                } else if (is == isize) {
    1703                                        while (it.hasNext()) {
    1704                                                for (int i = 0; i < isize; i++) {
    1705                                                        final double db = bds.getElementDoubleAbs(i);
    1706                                                        data[it.index + i] /= db; // INT_EXCEPTION
    1707                                                }
    1708                                        }
    1709                                } else {
    1710                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1711                                }
    1712                        }
    1713                } else {
    1714                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
    1715                        it.setOutputDouble(!useLong);
    1716                        if (useLong) {
    1717                                if (is == 1) {
    1718                                        while (it.hasNext()) {
    1719                                                final long lb = it.bLong;
    1720                                                // if (lb == 0) { // INT_USE
    1721                                                //      for (int i = 0; i < isize; i++) { // INT_USE
    1722                                                //              data[it.aIndex + i] = 0; // INT_USE
    1723                                                //      }// INT_USE
    1724                                                // } else { // INT_USE
    1725                                                for (int i = 0; i < isize; i++) {
    1726                                                        data[it.aIndex + i] /= lb;
    1727                                                }
    1728                                                // } // INT_USE
    1729                                        }
    1730                                } else if (is == isize) {
    1731                                        while (it.hasNext()) {
    1732                                                for (int i = 0; i < isize; i++) {
    1733                                                        final long lb = bds.getElementLongAbs(it.bIndex + i);
    1734                                                        data[it.aIndex + i] /= lb; // INT_EXCEPTION
    1735                                                }
    1736                                        }
    1737                                } else {
    1738                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1739                                }
    1740                        } else {
    1741                                if (is == 1) {
    1742                                        while (it.hasNext()) {
    1743                                                final double db = it.bDouble;
    1744                                                // if (db == 0) { // INT_USE
    1745                                                //      for (int i = 0; i < isize; i++) { // INT_USE
    1746                                                //              data[it.aIndex + i] = 0; // INT_USE
    1747                                                //      }// INT_USE
    1748                                                // } else { // INT_USE
    1749                                                for (int i = 0; i < isize; i++) {
    1750                                                        data[it.aIndex + i] /= db;
    1751                                                }
    1752                                                // } // INT_USE
    1753                                        }
    1754                                } else if (is == isize) {
    1755                                        while (it.hasNext()) {
    1756                                                for (int i = 0; i < isize; i++) {
    1757                                                        final double db = bds.getElementDoubleAbs(it.bIndex + i);
    1758                                                        data[it.aIndex + i] /= db; // INT_EXCEPTION
    1759                                                }
    1760                                        }
    1761                                } else {
    1762                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1763                                }
    1764                        }
    1765                }
    1766                return this;
    1767        }
    1768
    1769        @Override
    1770        public CompoundDoubleDataset ifloor() {
    1771                setDirty(); // REAL_ONLY
    1772                final IndexIterator it = getIterator(); // REAL_ONLY
    1773                while (it.hasNext()) { // REAL_ONLY
    1774                        for (int i = 0; i < isize; i++) { // REAL_ONLY
    1775                                data[it.index + i] = Math.floor(data[it.index] + i); // REAL_ONLY // ADD_CAST
    1776                        } // REAL_ONLY
    1777                } // REAL_ONLY
    1778                return this;
    1779        }
    1780
    1781        @Override
    1782        public CompoundDoubleDataset iremainder(final Object b) {
    1783                setDirty();
    1784                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    1785                boolean useLong = bds.getElementClass().equals(Long.class);
    1786                int is = bds.getElementsPerItem();
    1787                if (bds.getSize() == 1) {
    1788                        final IndexIterator it = getIterator();
    1789                        final int bOffset = bds.getOffset();
    1790                        if (useLong) {
    1791                                if (is == 1) {
    1792                                        final long lb = bds.getElementLongAbs(bOffset);
    1793                                        // if (lb == 0) { // INT_USE
    1794                                        //      fill(0); // INT_USE
    1795                                        // } else { // INT_USE
    1796                                        while (it.hasNext()) {
    1797                                                for (int i = 0; i < isize; i++) {
    1798                                                        data[it.index + i] %= lb;
    1799                                                }
    1800                                        }
    1801                                        // } // INT_USE
    1802                                } else if (is == isize) {
    1803                                        while (it.hasNext()) {
    1804                                                for (int i = 0; i < isize; i++) {
    1805                                                        data[it.index + i] %= bds.getElementLongAbs(i); // INT_EXCEPTION
    1806                                                }
    1807                                        }
    1808                                } else {
    1809                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1810                                }
    1811                        } else {
    1812                                if (is == 1) {
    1813                                        final double db = bds.getElementDoubleAbs(bOffset);
    1814                                        // if (db == 0) { // INT_USE
    1815                                        //      fill(0); // INT_USE
    1816                                        // } else { // INT_USE
    1817                                        while (it.hasNext()) {
    1818                                                for (int i = 0; i < isize; i++) {
    1819                                                        data[it.index + i] %= db;
    1820                                                }
    1821                                        }
    1822                                        // } // INT_USE
    1823                                } else if (is == isize) {
    1824                                        while (it.hasNext()) {
    1825                                                for (int i = 0; i < isize; i++) {
    1826                                                        data[it.index + i] %= bds.getElementDoubleAbs(i); // INT_EXCEPTION
    1827                                                }
    1828                                        }
    1829                                } else {
    1830                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1831                                }
    1832                        }
    1833                } else {
    1834                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
    1835                        it.setOutputDouble(!useLong);
    1836                        if (useLong) {
    1837                                if (is == 1) {
    1838                                        while (it.hasNext()) {
    1839                                                final long lb = it.bLong;
    1840                                                // if (lb == 0) { // INT_USE
    1841                                                //      for (int i = 0; i < isize; i++) // INT_USE
    1842                                                //              data[it.aIndex + i] = 0; // INT_USE
    1843                                                // } else { // INT_USE
    1844                                                for (int i = 0; i < isize; i++)
    1845                                                        data[it.aIndex + i] %= lb;
    1846                                                // } // INT_USE
    1847                                        }
    1848                                } else if (is == isize) {
    1849                                        while (it.hasNext()) {
    1850                                                for (int i = 0; i < isize; i++) {
    1851                                                        final long lb = bds.getElementLongAbs(it.bIndex + i);
    1852                                                        data[it.aIndex + i] %= lb; // INT_EXCEPTION
    1853                                                }
    1854                                        }
    1855                                } else {
    1856                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1857                                }
    1858                        } else {
    1859                                if (is == 1) {
    1860                                        while (it.hasNext()) {
    1861                                                final double db = it.bDouble;
    1862                                                // if (db == 0) { // INT_USE
    1863                                                //      for (int i = 0; i < isize; i++) // INT_USE
    1864                                                //              data[it.aIndex + i] = 0; // INT_USE
    1865                                                // } else { // INT_USE
    1866                                                for (int i = 0; i < isize; i++) {
    1867                                                        data[it.aIndex + i] %= db;
    1868                                                }
    1869                                                // } // INT_USE
    1870                                        }
    1871                                } else if (is == isize) {
    1872                                        while (it.hasNext()) {
    1873                                                for (int i = 0; i < isize; i++) {
    1874                                                        final double db = bds.getElementDoubleAbs(it.bIndex + i);
    1875                                                        data[it.aIndex + i] %= db; // INT_EXCEPTION
    1876                                                }
    1877                                        }
    1878                                } else {
    1879                                        throw new IllegalArgumentException("Argument does not have same number of elements per item or is not a non-compound dataset");
    1880                                }
    1881                        }
    1882                }
    1883                return this;
    1884        }
    1885
    1886        @Override
    1887        public CompoundDoubleDataset ipower(final Object b) {
    1888                setDirty();
    1889                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    1890                final int is = bds.getElementsPerItem();
    1891                if (bds.getSize() == 1) {
    1892                        final int bOffset = bds.getOffset();
    1893                        final double vr = bds.getElementDoubleAbs(bOffset);
    1894                        final IndexIterator it = getIterator();
    1895                        if (bds.isComplex()) {
    1896                                final double vi = bds.getElementDoubleAbs(bOffset + 1);
    1897                                if (vi == 0) {
    1898                                        while (it.hasNext()) {
    1899                                                for (int i = 0; i < isize; i++) {
    1900                                                        final double v = Math.pow(data[it.index + i], vr);
    1901                                                        // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
    1902                                                        //      data[it.index + i] = 0; // INT_USE
    1903                                                        // } else { // INT_USE
    1904                                                        data[it.index + i] = v; // PRIM_TYPE_LONG // ADD_CAST
    1905                                                        // } // INT_USE
    1906                                                }
    1907                                        }
    1908                                } else {
    1909                                        final Complex zv = new Complex(vr, vi);
    1910                                        while (it.hasNext()) {
    1911                                                for (int i = 0; i < isize; i++) {
    1912                                                        Complex zd = new Complex(data[it.index + i], 0);
    1913                                                        final double v = zd.pow(zv).getReal();
    1914                                                        // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
    1915                                                        //      data[it.index + i] = 0; // INT_USE
    1916                                                        // } else { // INT_USE
    1917                                                        data[it.index + i] = v; // PRIM_TYPE_LONG // ADD_CAST
    1918                                                        // } // INT_USE
    1919                                                }
    1920                                        }
    1921                                }
    1922                        } else if (is == 1) {
    1923                                while (it.hasNext()) {
    1924                                        for (int i = 0; i < isize; i++) {
    1925                                                final double v = Math.pow(data[it.index + i], vr);
    1926                                                // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
    1927                                                //      data[it.index + i] = 0; // INT_USE
    1928                                                // } else { // INT_USE
    1929                                                data[it.index + i] = v; // PRIM_TYPE_LONG // ADD_CAST
    1930                                                // } // INT_USE
    1931                                        }
    1932                                }
    1933                        } else if (is == isize) {
    1934                                while (it.hasNext()) {
    1935                                        for (int i = 0; i < isize; i++) {
    1936                                                final double v = Math.pow(data[it.index + i], bds.getElementDoubleAbs(i));
    1937                                                // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
    1938                                                //      data[it.index + i] = 0; // INT_USE
    1939                                                // } else { // INT_USE
    1940                                                data[it.index + i] = v; // PRIM_TYPE_LONG // ADD_CAST
    1941                                                // } // INT_USE
    1942                                        }
    1943                                }
    1944                        }
    1945                } else {
    1946                        final BroadcastIterator it = BroadcastIterator.createIterator(this, bds);
    1947                        it.setOutputDouble(true);
    1948                        if (bds.isComplex()) {
    1949                                while (it.hasNext()) {
    1950                                        final Complex zv = new Complex(it.bDouble, bds.getElementDoubleAbs(it.bIndex + 1));
    1951                                        double v = new Complex(it.aDouble, 0).pow(zv).getReal();
    1952                                        // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
    1953                                        //      data[it.aIndex] = 0; // INT_USE
    1954                                        // } else { // INT_USE
    1955                                        data[it.aIndex] = v; // PRIM_TYPE_LONG // ADD_CAST
    1956                                        // } // INT_USE
    1957                                        for (int i = 1; i < isize; i++) {
    1958                                                v = new Complex(data[it.aIndex + i], 0).pow(zv).getReal();
    1959                                                // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
    1960                                                //      data[it.aIndex + i] = 0; // INT_USE
    1961                                                // } else { // INT_USE
    1962                                                data[it.aIndex + i] = v; // PRIM_TYPE_LONG // ADD_CAST
    1963                                                // } // INT_USE
    1964                                        }
    1965                                }
    1966                        } else {
    1967                                while (it.hasNext()) {
    1968                                        double v = Math.pow(it.aDouble, it.bDouble);
    1969                                        // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
    1970                                        //      data[it.aIndex] = 0; // INT_USE
    1971                                        // } else { // INT_USE
    1972                                        data[it.aIndex] = v; // PRIM_TYPE_LONG // ADD_CAST
    1973                                        // } // INT_USE
    1974                                        for (int i = 1; i < isize; i++) {
    1975                                                v = Math.pow(data[it.aIndex + i], bds.getElementDoubleAbs(it.bIndex + i));
    1976                                                // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
    1977                                                //      data[it.aIndex + i] = 0; // INT_USE
    1978                                                // } else { // INT_USE
    1979                                                data[it.aIndex + i] = v; // PRIM_TYPE_LONG // ADD_CAST
    1980                                                // } // INT_USE
    1981                                        }
    1982                                }
    1983                        }
    1984                }
    1985                return this;
    1986        }
    1987
    1988        @Override
    1989        public double residual(final Object b, final Dataset w, boolean ignoreNaNs) {
    1990                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    1991                final BroadcastIterator it = BroadcastIterator.createIterator(this, bds);
    1992                it.setOutputDouble(true);
    1993                double sum = 0;
    1994                double comp = 0;
    1995                final int bis = bds.getElementsPerItem();
    1996
    1997                if (bis == 1) {
    1998                        if (w == null) {
    1999                                while (it.hasNext()) {
    2000                                        final double db = it.bDouble;
    2001                                        double diff = it.aDouble - db;
    2002                                        if (ignoreNaNs) { // REAL_ONLY
    2003                                                if (Double.isNaN(diff)) // REAL_ONLY
    2004                                                        continue; // REAL_ONLY
    2005                                                boolean skip = false; // REAL_ONLY
    2006                                                for (int i = 1; i < isize; i++) { // REAL_ONLY
    2007                                                        if (Double.isNaN(data[it.aIndex + i])) { // REAL_ONLY
    2008                                                                skip = true; // REAL_ONLY
    2009                                                                break; // REAL_ONLY
    2010                                                        } // REAL_ONLY
    2011                                                } // REAL_ONLY
    2012                                                if (skip) { // REAL_ONLY
    2013                                                        continue; // REAL_ONLY
    2014                                                } // REAL_ONLY
    2015                                        } // REAL_ONLY
    2016                                        double err = diff * diff - comp;
    2017                                        double temp = sum + err;
    2018                                        comp = (temp - sum) - err;
    2019                                        sum = temp;
    2020                                        for (int i = 1; i < isize; i++) {
    2021                                                diff = data[it.aIndex + i] - db;
    2022                                                err = diff * diff - comp;
    2023                                                temp = sum + err;
    2024                                                comp = (temp - sum) - err;
    2025                                                sum = temp;
    2026                                        }
    2027                                }
    2028                        } else {
    2029                                IndexIterator itw = w.getIterator();
    2030                                while (it.hasNext() && itw.hasNext()) {
    2031                                        final double db = it.bDouble;
    2032                                        double diff = it.aDouble - db;
    2033                                        if (ignoreNaNs) { // REAL_ONLY
    2034                                                if (Double.isNaN(diff)) // REAL_ONLY
    2035                                                        continue; // REAL_ONLY
    2036                                                boolean skip = false; // REAL_ONLY
    2037                                                for (int i = 1; i < isize; i++) { // REAL_ONLY
    2038                                                        if (Double.isNaN(data[it.aIndex + i])) { // REAL_ONLY
    2039                                                                skip = true; // REAL_ONLY
    2040                                                                break; // REAL_ONLY
    2041                                                        } // REAL_ONLY
    2042                                                } // REAL_ONLY
    2043                                                if (skip) { // REAL_ONLY
    2044                                                        continue; // REAL_ONLY
    2045                                                } // REAL_ONLY
    2046                                        } // REAL_ONLY
    2047                                        final double dw = w.getElementDoubleAbs(itw.index);
    2048                                        double err = diff * diff * dw - comp;
    2049                                        double temp = sum + err;
    2050                                        comp = (temp - sum) - err;
    2051                                        sum = temp;
    2052                                        for (int i = 1; i < isize; i++) {
    2053                                                diff = data[it.aIndex + i] - db;
    2054                                                err = diff * diff * dw - comp;
    2055                                                temp = sum + err;
    2056                                                comp = (temp - sum) - err;
    2057                                                sum = temp;
    2058                                        }
    2059                                }
    2060                        }
    2061                } else {
    2062                        if (w == null) {
    2063                                while (it.hasNext()) {
    2064                                        double diff = it.aDouble - it.bDouble;
    2065                                        if (ignoreNaNs) { // REAL_ONLY
    2066                                                if (Double.isNaN(diff)) // REAL_ONLY
    2067                                                        continue; // REAL_ONLY
    2068                                                boolean skip = false; // REAL_ONLY
    2069                                                for (int i = 1; i < isize; i++) { // REAL_ONLY
    2070                                                        if (Double.isNaN(data[it.aIndex + i]) || Double.isNaN(bds.getElementDoubleAbs(it.bIndex + i))) { // REAL_ONLY
    2071                                                                skip = true; // REAL_ONLY
    2072                                                                break; // REAL_ONLY
    2073                                                        } // REAL_ONLY
    2074                                                } // REAL_ONLY
    2075                                                if (skip) { // REAL_ONLY
    2076                                                        continue; // REAL_ONLY
    2077                                                } // REAL_ONLY
    2078                                        } // REAL_ONLY
    2079                                        double err = diff * diff - comp;
    2080                                        double temp = sum + err;
    2081                                        comp = (temp - sum) - err;
    2082                                        sum = temp;
    2083                                        for (int i = 1; i < isize; i++) {
    2084                                                diff = data[it.aIndex + i] - bds.getElementDoubleAbs(it.bIndex + i);
    2085                                                err = diff * diff - comp;
    2086                                                temp = sum + err;
    2087                                                comp = (temp - sum) - err;
    2088                                                sum = temp;
    2089                                        }
    2090                                }
    2091                        } else {
    2092                                IndexIterator itw = w.getIterator();
    2093                                while (it.hasNext() && itw.hasNext()) {
    2094                                        double diff = it.aDouble - it.bDouble;
    2095                                        if (ignoreNaNs) { // REAL_ONLY
    2096                                                if (Double.isNaN(diff)) // REAL_ONLY
    2097                                                        continue; // REAL_ONLY
    2098                                                boolean skip = false; // REAL_ONLY
    2099                                                for (int i = 1; i < isize; i++) { // REAL_ONLY
    2100                                                        if (Double.isNaN(data[it.aIndex + i]) || Double.isNaN(bds.getElementDoubleAbs(it.bIndex + i))) { // REAL_ONLY
    2101                                                                skip = true; // REAL_ONLY
    2102                                                                break; // REAL_ONLY
    2103                                                        } // REAL_ONLY
    2104                                                } // REAL_ONLY
    2105                                                if (skip) { // REAL_ONLY
    2106                                                        continue; // REAL_ONLY
    2107                                                } // REAL_ONLY
    2108                                        } // REAL_ONLY
    2109                                        final double dw = w.getElementDoubleAbs(itw.index);
    2110                                        double err = diff * diff * dw - comp;
    2111                                        double temp = sum + err;
    2112                                        comp = (temp - sum) - err;
    2113                                        sum = temp;
    2114                                        for (int i = 1; i < isize; i++) {
    2115                                                diff = data[it.aIndex + i] - bds.getElementDoubleAbs(it.bIndex + i);
    2116                                                err = diff * diff * dw - comp;
    2117                                                temp = sum + err;
    2118                                                comp = (temp - sum) - err;
    2119                                                sum = temp;
    2120                                        }
    2121                                }
    2122                        }
    2123                }
    2124                return sum;
    2125        }
    2126}