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