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