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}