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