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