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.ArrayList;
018import java.util.Arrays;
019import java.util.List;
020import java.util.Set;
021import java.util.TreeSet;
022
023import org.apache.commons.math3.complex.Complex; // NAN_OMIT
024import org.eclipse.january.metadata.StatisticsMetadata;
025
026
027/**
028 * Extend dataset for double values // PRIM_TYPE
029 */
030public class DoubleDataset extends AbstractDataset {
031        // pin UID to base class
032        private static final long serialVersionUID = Dataset.serialVersionUID;
033
034        protected double[] data; // subclass alias // PRIM_TYPE
035
036        @Override
037        protected void setData() {
038                data = (double[]) odata; // PRIM_TYPE
039        }
040
041        protected static double[] createArray(final int size) { // PRIM_TYPE
042                double[] array = null; // PRIM_TYPE
043
044                try {
045                        array = new double[size]; // PRIM_TYPE
046                } catch (OutOfMemoryError e) {
047                        logger.error("The size of the dataset ({}) that is being created is too large "
048                                        + "and there is not enough memory to hold it.", size);
049                        throw new OutOfMemoryError("The dimensions given are too large, and there is "
050                                        + "not enough memory available in the Java Virtual Machine");
051                }
052                return array;
053        }
054
055        @Override
056        public int getDType() {
057                return FLOAT64; // DATA_TYPE
058        }
059
060        /**
061         * Create a null dataset
062         */
063        DoubleDataset() {
064        }
065
066        /**
067         * Create a zero-filled dataset of given shape
068         * @param shape
069         */
070        DoubleDataset(final int... shape) {
071                if (shape != null) {
072                        size = ShapeUtils.calcSize(shape);
073                        this.shape = shape.clone();
074        
075                        try {
076                                odata = data = createArray(size);
077                        } catch (Throwable t) {
078                                logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
079                                throw new IllegalArgumentException(t);
080                        }
081                }
082        }
083
084        /**
085         * Create a dataset using given data
086         * @param data
087         * @param shape
088         *            (can be null to create 1D dataset)
089         */
090        DoubleDataset(final double[] data, int... shape) { // PRIM_TYPE
091                if (data == null) {
092                        throw new IllegalArgumentException("Data must not be null");
093                }
094                if (shape == null || shape.length == 0) {
095                        shape = new int[] { data.length };
096                }
097                size = ShapeUtils.calcSize(shape);
098                if (size != data.length) {
099                        throw new IllegalArgumentException(String.format("Shape %s is not compatible with size of data array, %d",
100                                        Arrays.toString(shape), data.length));
101                }
102                this.shape = size == 0 ? null : shape.clone();
103
104                odata = this.data = data;
105        }
106
107        /**
108         * Copy a dataset
109         * @param dataset
110         */
111        DoubleDataset(final DoubleDataset dataset) {
112                copyToView(dataset, this, true, true);
113
114                try {
115                        if (dataset.stride == null) {
116                                odata = data = dataset.data.clone();
117                        } else {
118                                offset = 0;
119                                stride = null;
120                                base = null;
121                                odata = data = createArray(size);
122
123                                IndexIterator iter = dataset.getIterator();
124                                for (int i = 0; iter.hasNext(); i++) {
125                                        data[i] = dataset.data[iter.index];
126                                }
127                        }
128                } catch (Throwable t) {
129                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
130                        throw new IllegalArgumentException(t);
131                }
132        }
133
134        /**
135         * Copy and cast a dataset to this class type
136         * @param dataset
137         */
138        DoubleDataset(final Dataset dataset) {
139                copyToView(dataset, this, true, false);
140                offset = 0;
141                stride = null;
142                base = null;
143                try {
144                        odata = data = createArray(size);
145                } catch (Throwable t) {
146                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
147                        throw new IllegalArgumentException(t);
148                }
149                IndexIterator iter = dataset.getIterator();
150                for (int i = 0; iter.hasNext(); i++) {
151                        data[i] = dataset.getElementDoubleAbs(iter.index); // GET_ELEMENT_WITH_CAST
152                }
153        }
154
155        @Override
156        public boolean equals(Object obj) {
157                if (!super.equals(obj)) {
158                        return false;
159                }
160
161                if (getRank() == 0 && !getClass().equals(obj.getClass())) // already true for zero-rank dataset
162                        return true;
163
164                DoubleDataset other = (DoubleDataset) obj;
165//              if (size == 1) // for zero-rank datasets
166//                      return getAbs(offset) == other.getAbs(other.offset);
167
168                IndexIterator iter = getIterator();
169                IndexIterator oiter = other.getIterator();
170                while (iter.hasNext() && oiter.hasNext()) {
171                        if (data[iter.index] != other.data[oiter.index]) // OBJECT_UNEQUAL
172                                return false;
173                }
174                return true;
175        }
176
177        @Override
178        public int hashCode() {
179                return super.hashCode();
180        }
181
182        @Override
183        public DoubleDataset clone() {
184                return new DoubleDataset(this);
185        }
186
187        /**
188         * Create a dataset from an object which could be a Java list, array (of arrays...) or Number. Ragged
189         * sequences or arrays are padded with zeros.
190         * 
191         * @param obj
192         * @return dataset with contents given by input
193         */
194        static DoubleDataset createFromObject(final Object obj) {
195                DoubleDataset result = new DoubleDataset();
196
197                if (obj != null) {
198                        result.shape = ShapeUtils.getShapeFromObject(obj);
199                        result.size = ShapeUtils.calcSize(result.shape);
200        
201                        try {
202                                result.odata = result.data = createArray(result.size);
203                        } catch (Throwable t) {
204                                logger.error("Could not create a dataset of shape {}", Arrays.toString(result.shape), t);
205                                throw new IllegalArgumentException(t);
206                        }
207        
208                        int[] pos = new int[result.shape.length];
209                        result.fillData(obj, 0, pos);
210                }
211
212                return result;
213        }
214         // NAN_OMIT
215        /** // NAN_OMIT
216         * // NAN_OMIT
217         * @param stop // NAN_OMIT
218         * @return a new 1D dataset, filled with values determined by parameters // NAN_OMIT
219         */ // NAN_OMIT
220        static DoubleDataset createRange(final double stop) { // NAN_OMIT
221                return createRange(0, stop, 1); // NAN_OMIT
222        } // NAN_OMIT
223         // NAN_OMIT
224        /** // NAN_OMIT
225         * // NAN_OMIT
226         * @param start // NAN_OMIT
227         * @param stop // NAN_OMIT
228         * @param step // NAN_OMIT
229         * @return a new 1D dataset, filled with values determined by parameters // NAN_OMIT
230         */ // NAN_OMIT
231        static DoubleDataset createRange(final double start, final double stop, final double step) { // NAN_OMIT
232                int size = calcSteps(start, stop, step); // NAN_OMIT
233                DoubleDataset result = new DoubleDataset(size); // NAN_OMIT
234                for (int i = 0; i < size; i++) { // NAN_OMIT
235                        result.data[i] = (start + i * step); // PRIM_TYPE // NAN_OMIT // ADD_CAST
236                } // NAN_OMIT
237                return result; // NAN_OMIT
238        } // NAN_OMIT
239
240        /**
241         * @param shape
242         * @return a dataset filled with ones
243         */
244        static DoubleDataset ones(final int... shape) {
245                return new DoubleDataset(shape).fill(1);
246        }
247
248        @Override
249        public DoubleDataset fill(final Object obj) {
250                setDirty();
251                double dv = DTypeUtils.toReal(obj); // PRIM_TYPE // FROM_OBJECT
252                IndexIterator iter = getIterator();
253                while (iter.hasNext()) {
254                        data[iter.index] = dv;
255                }
256
257                return this;
258        }
259
260        /**
261         * This is a typed version of {@link #getBuffer()}
262         * @return data buffer as linear array
263         */
264        public double[] getData() { // PRIM_TYPE
265                return data;
266        }
267
268        @Override
269        protected int getBufferLength() {
270                if (data == null)
271                        return 0;
272                return data.length;
273        }
274
275        @Override
276        public DoubleDataset getView(boolean deepCopyMetadata) {
277                DoubleDataset view = new DoubleDataset();
278                copyToView(this, view, true, deepCopyMetadata);
279                view.setData();
280                return view;
281        }
282
283        /**
284         * Get a value from an absolute index of the internal array. This is an internal method with no checks so can be
285         * dangerous. Use with care or ideally with an iterator.
286         * 
287         * @param index
288         *            absolute index
289         * @return value
290         */
291        public double getAbs(final int index) { // PRIM_TYPE
292                return data[index];
293        }
294
295        @Override
296        public boolean getElementBooleanAbs(final int index) {
297                return data[index] != 0; // BOOLEAN_FALSE
298        }
299
300        @Override
301        public double getElementDoubleAbs(final int index) {
302                return data[index]; // BOOLEAN_ZERO
303        }
304
305        @Override
306        public long getElementLongAbs(final int index) {
307                return (long) data[index]; // BOOLEAN_ZERO // OMIT_CAST_INT
308        }
309
310        @Override
311        public Object getObjectAbs(final int index) {
312                return data[index];
313        }
314
315        @Override
316        public String getStringAbs(final int index) {
317                return stringFormat == null ? String.format("%.8g", data[index]) : // FORMAT_STRING
318                        stringFormat.format(data[index]);
319        }
320
321        /**
322         * Set a value at absolute index in the internal array. This is an internal method with no checks so can be
323         * dangerous. Use with care or ideally with an iterator.
324         * 
325         * @param index
326         *            absolute index
327         * @param val
328         *            new value
329         */
330        public void setAbs(final int index, final double val) { // PRIM_TYPE
331                setDirty();
332                data[index] = val;
333        }
334
335        @Override
336        protected void setItemDirect(final int dindex, final int sindex, final Object src) {
337                setDirty();
338                double[] dsrc = (double[]) src; // PRIM_TYPE
339                data[dindex] = dsrc[sindex];
340        }
341
342        @Override
343        public void setObjectAbs(final int index, final Object obj) {
344                if (index < 0 || index > data.length) {
345                        throw new IndexOutOfBoundsException("Index given is outside dataset");
346                }
347
348                setAbs(index, DTypeUtils.toReal(obj)); // FROM_OBJECT
349        }
350
351        /**
352         * @return item in first position
353         * @since 2.0
354         */
355        public double get() { // PRIM_TYPE
356                return data[getFirst1DIndex()];
357        }
358
359        /**
360         * @param i
361         * @return item in given position
362         */
363        public double get(final int i) { // PRIM_TYPE
364                return data[get1DIndex(i)];
365        }
366
367        /**
368         * @param i
369         * @param j
370         * @return item in given position
371         */
372        public double get(final int i, final int j) { // PRIM_TYPE
373                return data[get1DIndex(i, j)];
374        }
375
376        /**
377         * @param pos
378         * @return item in given position
379         */
380        public double get(final int... pos) { // PRIM_TYPE
381                return data[get1DIndex(pos)];
382        }
383
384        @Override
385        public Object getObject() {
386                return Double.valueOf(get()); // CLASS_TYPE
387        }
388
389        @Override
390        public Object getObject(final int i) {
391                return Double.valueOf(get(i)); // CLASS_TYPE
392        }
393
394        @Override
395        public Object getObject(final int i, final int j) {
396                return Double.valueOf(get(i, j)); // CLASS_TYPE
397        }
398
399        @Override
400        public Object getObject(final int... pos) {
401                return Double.valueOf(get(pos)); // CLASS_TYPE
402        }
403
404        @Override
405        public String getString() {
406                return getStringAbs(getFirst1DIndex());
407        }
408
409        @Override
410        public String getString(final int i) {
411                return getStringAbs(get1DIndex(i));
412        }
413
414        @Override
415        public String getString(final int i, final int j) {
416                return getStringAbs(get1DIndex(i, j));
417        }
418
419        @Override
420        public String getString(final int... pos) {
421                return getStringAbs(get1DIndex(pos));
422        }
423
424        @Override
425        public double getDouble() {
426                return get(); // BOOLEAN_ZERO
427        }
428
429        @Override
430        public double getDouble(final int i) {
431                return get(i); // BOOLEAN_ZERO
432        }
433
434        @Override
435        public double getDouble(final int i, final int j) {
436                return get(i, j); // BOOLEAN_ZERO
437        }
438
439        @Override
440        public double getDouble(final int... pos) {
441                return get(pos); // BOOLEAN_ZERO
442        }
443
444        @Override
445        public float getFloat() {
446                return (float) get(); // BOOLEAN_ZERO // OMIT_REAL_CAST
447        }
448
449        @Override
450        public float getFloat(final int i) {
451                return (float) get(i); // BOOLEAN_ZERO // OMIT_REAL_CAST
452        }
453
454        @Override
455        public float getFloat(final int i, final int j) {
456                return (float) get(i, j); // BOOLEAN_ZERO // OMIT_REAL_CAST
457        }
458
459        @Override
460        public float getFloat(final int... pos) {
461                return (float) get(pos); // BOOLEAN_ZERO // OMIT_REAL_CAST
462        }
463
464        @Override
465        public long getLong() {
466                return (long) get(); // BOOLEAN_ZERO // OMIT_UPCAST
467        }
468
469        @Override
470        public long getLong(final int i) {
471                return (long) get(i); // BOOLEAN_ZERO // OMIT_UPCAST
472        }
473
474        @Override
475        public long getLong(final int i, final int j) {
476                return (long) get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
477        }
478
479        @Override
480        public long getLong(final int... pos) {
481                return (long) get(pos); // BOOLEAN_ZERO // OMIT_UPCAST
482        }
483
484        @Override
485        public int getInt() {
486                return (int) get(); // BOOLEAN_ZERO // OMIT_UPCAST
487        }
488
489        @Override
490        public int getInt(final int i) {
491                return (int) get(i); // BOOLEAN_ZERO // OMIT_UPCAST
492        }
493
494        @Override
495        public int getInt(final int i, final int j) {
496                return (int) get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
497        }
498
499        @Override
500        public int getInt(final int... pos) {
501                return (int) get(pos); // BOOLEAN_ZERO // OMIT_UPCAST
502        }
503
504        @Override
505        public short getShort() {
506                return (short) get(); // BOOLEAN_ZERO // OMIT_UPCAST
507        }
508
509        @Override
510        public short getShort(final int i) {
511                return (short) get(i); // BOOLEAN_ZERO // OMIT_UPCAST
512        }
513
514        @Override
515        public short getShort(final int i, final int j) {
516                return (short) get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
517        }
518
519        @Override
520        public short getShort(final int... pos) {
521                return (short) get(pos); // BOOLEAN_ZERO // OMIT_UPCAST
522        }
523
524        @Override
525        public byte getByte() {
526                return (byte) get(); // BOOLEAN_ZERO // OMIT_UPCAST
527        }
528
529        @Override
530        public byte getByte(final int i) {
531                return (byte) get(i); // BOOLEAN_ZERO // OMIT_UPCAST
532        }
533
534        @Override
535        public byte getByte(final int i, final int j) {
536                return (byte) get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
537        }
538
539        @Override
540        public byte getByte(final int... pos) {
541                return (byte) get(pos); // BOOLEAN_ZERO // OMIT_UPCAST
542        }
543
544        @Override
545        public boolean getBoolean() {
546                return get() != 0; // BOOLEAN_FALSE
547        }
548
549        @Override
550        public boolean getBoolean(final int i) {
551                return get(i) != 0; // BOOLEAN_FALSE
552        }
553
554        @Override
555        public boolean getBoolean(final int i, final int j) {
556                return get(i, j) != 0; // BOOLEAN_FALSE
557        }
558
559        @Override
560        public boolean getBoolean(final int... pos) {
561                return get(pos) != 0; // BOOLEAN_FALSE
562        }
563
564        /**
565         * Sets the value at first point to the passed value. The dataset must not be null
566         * 
567         * @param value
568         * @since 2.0
569         */
570        public void setItem(final double value) { // PRIM_TYPE
571                setAbs(getFirst1DIndex(), value);
572        }
573
574        /**
575         * Sets the value at a particular point to the passed value. The dataset must be 1D
576         * 
577         * @param value
578         * @param i
579         */
580        public void setItem(final double value, final int i) { // PRIM_TYPE
581                setAbs(get1DIndex(i), value);
582        }
583
584        /**
585         * Sets the value at a particular point to the passed value. The dataset must be 2D
586         * 
587         * @param value
588         * @param i
589         * @param j
590         */
591        public void setItem(final double value, final int i, final int j) { // PRIM_TYPE
592                setAbs(get1DIndex(i, j), value);
593        }
594
595        /**
596         * Sets the value at a particular point to the passed value
597         * 
598         * @param value
599         * @param pos
600         */
601        public void setItem(final double value, final int... pos) { // PRIM_TYPE
602                setAbs(get1DIndex(pos), value);
603        }
604
605        @Override
606        public void set(final Object obj) {
607                setItem(DTypeUtils.toReal(obj)); // FROM_OBJECT
608        }
609
610        @Override
611        public void set(final Object obj, final int i) {
612                setItem(DTypeUtils.toReal(obj), i); // FROM_OBJECT
613        }
614
615        @Override
616        public void set(final Object obj, final int i, final int j) {
617                setItem(DTypeUtils.toReal(obj), i, j); // FROM_OBJECT
618        }
619
620        @Override
621        public void set(final Object obj, int... pos) {
622                if (pos == null || (pos.length == 0 && shape.length > 0)) {
623                        pos = new int[shape.length];
624                }
625
626                setItem(DTypeUtils.toReal(obj), pos); // FROM_OBJECT
627        }
628
629
630        @Override
631        public void resize(int... newShape) {
632                setDirty();
633                final IndexIterator iter = getIterator();
634                final int nsize = ShapeUtils.calcSize(newShape);
635                final double[] ndata; // PRIM_TYPE
636                try {
637                        ndata = createArray(nsize);
638                } catch (Throwable t) {
639                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
640                        throw new IllegalArgumentException(t);
641                }
642                for (int i = 0; iter.hasNext() && i < nsize; i++) {
643                        ndata[i] = data[iter.index];
644                }
645
646                odata = data = ndata;
647                size = nsize;
648                shape = newShape;
649                stride = null;
650                offset = 0;
651                base = null;
652        }
653
654        @Override
655        public DoubleDataset sort(Integer axis) {
656                setDirty(); // BOOLEAN_OMIT
657                if (axis == null) { // BOOLEAN_OMIT
658                        if (stride == null) { // BOOLEAN_OMIT
659                                Arrays.sort(data); // BOOLEAN_OMIT
660                        } else { // BOOLEAN_OMIT
661                                DoubleDataset ads = clone().sort(null); // BOOLEAN_OMIT
662                                setSlicedView(getView(false), ads); // BOOLEAN_OMIT
663                        } // BOOLEAN_OMIT
664                } else { // BOOLEAN_OMIT
665                        axis = checkAxis(axis); // BOOLEAN_OMIT
666                         // BOOLEAN_OMIT 
667                        DoubleDataset ads = new DoubleDataset(shape[axis]); // BOOLEAN_OMIT
668                        PositionIterator pi = getPositionIterator(axis); // BOOLEAN_OMIT
669                        int[] pos = pi.getPos(); // BOOLEAN_OMIT
670                        boolean[] hit = pi.getOmit(); // BOOLEAN_OMIT
671                        while (pi.hasNext()) { // BOOLEAN_OMIT
672                                copyItemsFromAxes(pos, hit, ads); // BOOLEAN_OMIT
673                                Arrays.sort(ads.data); // BOOLEAN_OMIT
674                                setItemsOnAxes(pos, hit, ads.data); // BOOLEAN_OMIT
675                        } // BOOLEAN_OMIT
676                } // BOOLEAN_OMIT
677                return this; // BOOLEAN_OMIT
678                // throw new UnsupportedOperationException("Cannot sort dataset"); // BOOLEAN_USE
679        }
680
681        @Override
682        public DoubleDataset getUniqueItems() {
683                Set<Double> set = new TreeSet<Double>(); // CLASS_TYPE
684                IndexIterator it = getIterator();
685                while (it.hasNext()) {
686                        set.add(data[it.index]);
687                }
688
689                DoubleDataset u = new DoubleDataset(set.size()); // CLASS_TYPE
690                int i = 0;
691                double[] udata = u.getData(); // PRIM_TYPE
692                for (Double v : set) { // CLASS_TYPE
693                        udata[i++] = v;
694                }
695                return u;
696        }
697
698        @Override
699        public DoubleDataset getSlice(final SliceIterator siter) {
700                DoubleDataset result = new DoubleDataset(siter.getShape());
701                double[] rdata = result.data; // PRIM_TYPE
702
703                for (int i = 0; siter.hasNext(); i++)
704                        rdata[i] = data[siter.index];
705
706                result.setName(name + BLOCK_OPEN + Slice.createString(siter.shape, siter.start, siter.stop, siter.step) + BLOCK_CLOSE);
707                return result;
708        }
709
710        @Override
711        public void fillDataset(Dataset result, IndexIterator iter) {
712                setDirty();
713                IndexIterator riter = result.getIterator();
714
715                double[] rdata = ((DoubleDataset) result).data; // PRIM_TYPE
716
717                while (riter.hasNext() && iter.hasNext()) {
718                        rdata[riter.index] = data[iter.index];
719                }
720        }
721
722        @Override
723        public DoubleDataset setByBoolean(final Object obj, Dataset selection) {
724                setDirty();
725                if (obj instanceof Dataset) {
726                        final Dataset ds = (Dataset) obj;
727                        final int length = ((Number) selection.sum()).intValue();
728                        if (length != ds.getSize()) {
729                                throw new IllegalArgumentException(
730                                                "Number of true items in selection does not match number of items in dataset");
731                        }
732
733                        final IndexIterator oiter = ds.getIterator();
734                        final BooleanIterator biter = getBooleanIterator(selection);
735
736                        while (biter.hasNext() && oiter.hasNext()) {
737                                data[biter.index] = ds.getElementDoubleAbs(oiter.index); // GET_ELEMENT_WITH_CAST
738                        }
739                } else {
740                        final double dv = DTypeUtils.toReal(obj); // PRIM_TYPE // FROM_OBJECT
741                        final BooleanIterator biter = getBooleanIterator(selection);
742
743                        while (biter.hasNext()) {
744                                data[biter.index] = dv;
745                        }
746                }
747                return this;
748        }
749
750        @Override
751        public DoubleDataset setBy1DIndex(final Object obj, final Dataset index) {
752                setDirty();
753                if (obj instanceof Dataset) {
754                        final Dataset ds = (Dataset) obj;
755                        if (index.getSize() != ds.getSize()) {
756                                throw new IllegalArgumentException(
757                                                "Number of items in index dataset does not match number of items in dataset");
758                        }
759
760                        final IndexIterator oiter = ds.getIterator();
761                        final IntegerIterator iter = new IntegerIterator(index, size);
762
763                        while (iter.hasNext() && oiter.hasNext()) {
764                                data[iter.index] = ds.getElementDoubleAbs(oiter.index); // GET_ELEMENT_WITH_CAST
765                        }
766                } else {
767                        final double dv = DTypeUtils.toReal(obj); // PRIM_TYPE // FROM_OBJECT
768                        IntegerIterator iter = new IntegerIterator(index, size);
769
770                        while (iter.hasNext()) {
771                                data[iter.index] = dv;
772                        }
773                }
774                return this;
775        }
776
777        @Override
778        public DoubleDataset setByIndexes(final Object obj, final Object... indexes) {
779                setDirty();
780                final IntegersIterator iter = new IntegersIterator(shape, indexes);
781                final int[] pos = iter.getPos();
782
783                if (obj instanceof Dataset) {
784                        final Dataset ds = (Dataset) obj;
785                        if (ShapeUtils.calcSize(iter.getShape()) != ds.getSize()) {
786                                throw new IllegalArgumentException(
787                                                "Number of items in index datasets does not match number of items in dataset");
788                        }
789
790                        final IndexIterator oiter = ds.getIterator();
791
792                        while (iter.hasNext() && oiter.hasNext()) {
793                                setItem(ds.getElementDoubleAbs(oiter.index), pos); // GET_ELEMENT_WITH_CAST
794                        }
795                } else {
796                        final double dv = DTypeUtils.toReal(obj); // PRIM_TYPE // FROM_OBJECT
797
798                        while (iter.hasNext()) {
799                                setItem(dv, pos);
800                        }
801                }
802                return this;
803        }
804
805        @Override
806        DoubleDataset setSlicedView(Dataset view, Dataset d) {
807                setDirty();
808                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(view, d);
809
810                while (it.hasNext()) {
811                        data[it.aIndex] = it.bDouble; // BCAST_WITH_CAST d.getElementDoubleAbs(it.bIndex);
812                }
813                return this;
814        }
815
816        @Override
817        public DoubleDataset setSlice(final Object obj, final IndexIterator siter) {
818                setDirty();
819
820                if (obj instanceof IDataset) {
821                        final IDataset ds = (IDataset) obj;
822                        final int[] oshape = ds.getShape();
823
824                        if (!ShapeUtils.areShapesCompatible(siter.getShape(), oshape)) {
825                                throw new IllegalArgumentException(String.format(
826                                                "Input dataset is not compatible with slice: %s cf %s", Arrays.toString(oshape),
827                                                Arrays.toString(siter.getShape())));
828                        }
829
830                        if (ds instanceof Dataset) {
831                                final Dataset ads = (Dataset) ds;
832                                final IndexIterator oiter = ads.getIterator();
833
834                                while (siter.hasNext() && oiter.hasNext())
835                                        data[siter.index] = ads.getElementDoubleAbs(oiter.index); // GET_ELEMENT_WITH_CAST
836                        } else {
837                                final IndexIterator oiter = new PositionIterator(oshape);
838                                final int[] pos = oiter.getPos();
839
840                                while (siter.hasNext() && oiter.hasNext())
841                                        data[siter.index] = ds.getDouble(pos); // PRIM_TYPE
842                        }
843                } else {
844                        try {
845                                double v = DTypeUtils.toReal(obj); // PRIM_TYPE // FROM_OBJECT
846
847                                while (siter.hasNext())
848                                        data[siter.index] = v;
849                        } catch (IllegalArgumentException e) {
850                                throw new IllegalArgumentException("Object for setting slice is not a dataset or number");
851                        }
852                }
853                return this;
854        }
855
856        @Override
857        public void copyItemsFromAxes(final int[] pos, final boolean[] axes, final Dataset dest) {
858                double[] ddata = (double[]) dest.getBuffer(); // PRIM_TYPE
859
860                SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
861                int[] sshape = ShapeUtils.squeezeShape(siter.getShape(), false);
862
863                IndexIterator diter = dest.getSliceIterator(null, sshape, null);
864
865                if (ddata.length < ShapeUtils.calcSize(sshape)) {
866                        throw new IllegalArgumentException("destination array is not large enough");
867                }
868
869                dest.setDirty();
870                while (siter.hasNext() && diter.hasNext()) {
871                        ddata[diter.index] = data[siter.index];
872                }
873        }
874
875        @Override
876        public void setItemsOnAxes(final int[] pos, final boolean[] axes, final Object src) {
877                setDirty();
878                double[] sdata = (double[]) src; // PRIM_TYPE
879
880                SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
881
882                if (sdata.length < ShapeUtils.calcSize(siter.getShape())) {
883                        throw new IllegalArgumentException("destination array is not large enough");
884                }
885
886                for (int i = 0; siter.hasNext(); i++) {
887                        data[siter.index] = sdata[i];
888                }
889        }
890
891        private List<int[]> findPositions(final double value) { // PRIM_TYPE
892                IndexIterator iter = getIterator(true);
893                List<int[]> posns = new ArrayList<int[]>();
894                int[] pos = iter.getPos();
895
896                if (Double.isNaN(value)) { // CLASS_TYPE // REAL_ONLY
897                        while (iter.hasNext()) { // REAL_ONLY
898                                if (Double.isNaN(data[iter.index])) { // REAL_ONLY
899                                        posns.add(pos.clone()); // REAL_ONLY
900                                } // REAL_ONLY
901                        } // REAL_ONLY
902                } else // REAL_ONLY
903                {
904                        while (iter.hasNext()) {
905                                if (data[iter.index] == value) {
906                                        posns.add(pos.clone());
907                                }
908                        }
909                }
910                return posns;
911        }
912
913        @Override
914        public int[] maxPos(boolean... ignoreInvalids) {
915                StatisticsMetadata<Number> md = getStats(); // PRIM_TYPE // NAN_OMIT
916                // StatisticsMetadata<Number> md = getStats(); // BOOLEAN_USE
917                // StatisticsMetadata<String> md = getStringStats(); // OBJECT_USE
918                List<int[]> max = md.getMaximumPositions(ignoreInvalids);
919
920                if (max == null) {
921                        max = findPositions(md.getMaximum(ignoreInvalids).doubleValue()); // PRIM_TYPE // NAN_OMIT
922                        // max = findPositions(md.getMaximum(ignoreInvalids).intValue() != 0); // BOOLEAN_USE
923                        // max = findPositions(md.getMaximum(ignoreInvalids).toString()); // OBJECT_USE
924
925                        md.setMaximumPositions(max);
926                }
927
928                return max.get(0); // first maximum
929        }
930
931        @Override
932        public int[] minPos(boolean... ignoreInvalids) {
933                StatisticsMetadata<Number> md = getStats(); // PRIM_TYPE // NAN_OMIT
934                // StatisticsMetadata<Number> md = getStats(); // BOOLEAN_USE
935                // StatisticsMetadata<String> md = getStringStats(); // OBJECT_USE
936                List<int[]> min = md.getMinimumPositions(ignoreInvalids);
937
938                if (min == null) {
939                        min = findPositions(md.getMinimum(ignoreInvalids).doubleValue()); // PRIM_TYPE // NAN_OMIT
940                        // min = findPositions(md.getMinimum(ignoreInvalids).intValue() != 0); // BOOLEAN_USE
941                        // min = findPositions(md.getMinimum(ignoreInvalids).toString()); // OBJECT_USE
942
943                        md.setMinimumPositions(min);
944                }
945
946                return min.get(0); // first minimum
947        }
948
949        @Override
950        public boolean containsNans() {
951                IndexIterator iter = getIterator(); // REAL_ONLY
952                while (iter.hasNext()) { // REAL_ONLY
953                        if (Double.isNaN(data[iter.index])) // CLASS_TYPE // REAL_ONLY
954                                return true; // REAL_ONLY
955                } // REAL_ONLY
956                return false;
957        }
958
959        @Override
960        public boolean containsInfs() {
961                IndexIterator iter = getIterator(); // REAL_ONLY
962                while (iter.hasNext()) { // REAL_ONLY
963                        if (Double.isInfinite(data[iter.index])) // CLASS_TYPE // REAL_ONLY
964                                return true; // REAL_ONLY
965                } // REAL_ONLY
966                return false;
967        }
968
969        @Override
970        public boolean containsInvalidNumbers() {
971                IndexIterator iter = getIterator(); // REAL_ONLY
972                while (iter.hasNext()) { // REAL_ONLY
973                        double x = data[iter.index]; // PRIM_TYPE // REAL_ONLY
974                        if (Double.isNaN(x) || Double.isInfinite(x)) // CLASS_TYPE // REAL_ONLY
975                                return true; // REAL_ONLY
976                } // REAL_ONLY
977                return false;
978        }
979
980        @Override
981        public DoubleDataset iadd(final Object b) {
982                setDirty(); // NAN_OMIT
983                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
984                boolean useLong = bds.getElementClass().equals(Long.class); // NAN_OMIT
985                if (bds.getSize() == 1) { // NAN_OMIT
986                        final IndexIterator it = getIterator(); // NAN_OMIT
987                        if (useLong) { // NAN_OMIT
988                                final long lb = bds.getElementLongAbs(0); // NAN_OMIT
989                                while (it.hasNext()) { // NAN_OMIT
990                                        data[it.index] += lb; // NAN_OMIT
991                                } // NAN_OMIT
992                        } else { // NAN_OMIT
993                                final double db = bds.getElementDoubleAbs(0); // NAN_OMIT
994                                while (it.hasNext()) { // NAN_OMIT
995                                        data[it.index] += db; // NAN_OMIT
996                                } // NAN_OMIT
997                        } // NAN_OMIT
998                } else { // NAN_OMIT
999                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); // NAN_OMIT
1000                        it.setOutputDouble(!useLong); // NAN_OMIT
1001                        if (useLong) { // NAN_OMIT
1002                                while (it.hasNext()) { // NAN_OMIT
1003                                        data[it.aIndex] += it.bLong; // NAN_OMIT
1004                                } // NAN_OMIT
1005                        } else { // NAN_OMIT
1006                                while (it.hasNext()) { // NAN_OMIT
1007                                        data[it.aIndex] += it.bDouble; // NAN_OMIT
1008                                } // NAN_OMIT
1009                        } // NAN_OMIT
1010                } // NAN_OMIT
1011                return this;
1012        }
1013
1014        @Override
1015        public DoubleDataset isubtract(final Object b) {
1016                setDirty(); // NAN_OMIT
1017                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
1018                boolean useLong = bds.getElementClass().equals(Long.class); // NAN_OMIT
1019                if (bds.getSize() == 1) { // NAN_OMIT
1020                        final IndexIterator it = getIterator(); // NAN_OMIT
1021                        if (useLong) { // NAN_OMIT
1022                                final long lb = bds.getElementLongAbs(0); // NAN_OMIT
1023                                while (it.hasNext()) { // NAN_OMIT
1024                                        data[it.index] -= lb; // NAN_OMIT
1025                                } // NAN_OMIT
1026                        } else { // NAN_OMIT
1027                                final double db = bds.getElementDoubleAbs(0); // NAN_OMIT
1028                                while (it.hasNext()) { // NAN_OMIT
1029                                        data[it.index] -= db; // NAN_OMIT
1030                                } // NAN_OMIT
1031                        } // NAN_OMIT
1032                } else { // NAN_OMIT
1033                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); // NAN_OMIT
1034                        if (useLong) { // NAN_OMIT
1035                                it.setOutputDouble(false); // NAN_OMIT
1036                                while (it.hasNext()) { // NAN_OMIT
1037                                        data[it.aIndex] -= it.bLong; // NAN_OMIT
1038                                } // NAN_OMIT
1039                        } else { // NAN_OMIT
1040                                it.setOutputDouble(true); // NAN_OMIT
1041                                while (it.hasNext()) { // NAN_OMIT
1042                                        data[it.aIndex] -= it.bDouble; // NAN_OMIT
1043                                } // NAN_OMIT
1044                        } // NAN_OMIT
1045                } // NAN_OMIT
1046                return this;
1047        }
1048
1049        @Override
1050        public DoubleDataset imultiply(final Object b) {
1051                setDirty(); // NAN_OMIT
1052                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
1053                boolean useLong = bds.getElementClass().equals(Long.class); // NAN_OMIT
1054                if (bds.getSize() == 1) { // NAN_OMIT
1055                        final IndexIterator it = getIterator(); // NAN_OMIT
1056                        if (useLong) { // NAN_OMIT
1057                                final long lb = bds.getElementLongAbs(0); // NAN_OMIT
1058                                while (it.hasNext()) { // NAN_OMIT
1059                                        data[it.index] *= lb; // NAN_OMIT
1060                                } // NAN_OMIT
1061                        } else { // NAN_OMIT
1062                                final double db = bds.getElementDoubleAbs(0); // NAN_OMIT
1063                                while (it.hasNext()) { // NAN_OMIT
1064                                        data[it.index] *= db; // NAN_OMIT
1065                                } // NAN_OMIT
1066                        } // NAN_OMIT
1067                } else { // NAN_OMIT
1068                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); // NAN_OMIT
1069                        it.setOutputDouble(!useLong); // NAN_OMIT
1070                        if (useLong) { // NAN_OMIT
1071                                while (it.hasNext()) { // NAN_OMIT
1072                                        data[it.aIndex] *= it.bLong; // NAN_OMIT
1073                                } // NAN_OMIT
1074                        } else { // NAN_OMIT
1075                                while (it.hasNext()) { // NAN_OMIT
1076                                        data[it.aIndex] *= it.bDouble; // NAN_OMIT
1077                                } // NAN_OMIT
1078                        } // NAN_OMIT
1079                } // NAN_OMIT
1080                return this;
1081        }
1082
1083        @Override
1084        public DoubleDataset idivide(final Object b) {
1085                setDirty(); // NAN_OMIT
1086                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
1087                boolean useLong = bds.getElementClass().equals(Long.class); // NAN_OMIT
1088                if (bds.getSize() == 1) { // NAN_OMIT
1089                        if (useLong) { // NAN_OMIT
1090                                final long lb = bds.getElementLongAbs(0); // NAN_OMIT
1091                                // if (lb == 0) { // INT_USE // NAN_OMIT
1092                                //      fill(0); // INT_USE // NAN_OMIT
1093                                // } else { // INT_USE // NAN_OMIT
1094                                final IndexIterator it = getIterator(); // NAN_OMIT
1095                                while (it.hasNext()) { // NAN_OMIT
1096                                        data[it.index] /= lb; // NAN_OMIT
1097                                } // NAN_OMIT
1098                                // } // INT_USE // NAN_OMIT
1099                        } else { // NAN_OMIT
1100                                final double db = bds.getElementDoubleAbs(0); // NAN_OMIT
1101                                // if (db == 0) { // INT_USE // NAN_OMIT
1102                                //      fill(0); // INT_USE // NAN_OMIT
1103                                // } else { // INT_USE // NAN_OMIT
1104                                final IndexIterator it = getIterator(); // NAN_OMIT
1105                                while (it.hasNext()) { // NAN_OMIT
1106                                        data[it.index] /= db; // NAN_OMIT
1107                                } // NAN_OMIT
1108                                // } // INT_USE // NAN_OMIT
1109                        } // NAN_OMIT
1110                } else { // NAN_OMIT
1111                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); // NAN_OMIT
1112                        it.setOutputDouble(!useLong); // NAN_OMIT
1113                        if (useLong) { // NAN_OMIT
1114                                while (it.hasNext()) { // NAN_OMIT
1115                                        // if (it.bLong == 0) { // INT_USE // NAN_OMIT
1116                                        //      data[it.aIndex] = 0; // INT_USE // NAN_OMIT
1117                                        // } else { // INT_USE // NAN_OMIT
1118                                        data[it.aIndex] /= it.bLong; // NAN_OMIT
1119                                        // } // INT_USE // NAN_OMIT
1120                                } // NAN_OMIT
1121                        } else { // NAN_OMIT
1122                                while (it.hasNext()) { // NAN_OMIT
1123                                        // if (it.bDouble == 0) { // INT_USE // NAN_OMIT
1124                                        //      data[it.aIndex] = 0; // INT_USE // NAN_OMIT
1125                                        // } else { // INT_USE // NAN_OMIT
1126                                        data[it.aIndex] /= it.bDouble; // NAN_OMIT
1127                                        // } // INT_USE // NAN_OMIT
1128                                } // NAN_OMIT
1129                        } // NAN_OMIT
1130                } // NAN_OMIT
1131                return this;
1132        }
1133
1134        @Override
1135        public DoubleDataset ifloor() {
1136                setDirty(); // REAL_ONLY
1137                IndexIterator it = getIterator(); // REAL_ONLY
1138                while (it.hasNext()) { // REAL_ONLY
1139                        data[it.index] = Math.floor(data[it.index]); // PRIM_TYPE // REAL_ONLY // ADD_CAST
1140                } // REAL_ONLY
1141                return this;
1142        }
1143
1144        @Override
1145        public DoubleDataset iremainder(final Object b) {
1146                setDirty(); // NAN_OMIT
1147                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
1148                boolean useLong = bds.getElementClass().equals(Long.class); // NAN_OMIT
1149                if (bds.getSize() == 1) { // NAN_OMIT
1150                        if (useLong) { // NAN_OMIT
1151                                final long lb = bds.getElementLongAbs(0); // NAN_OMIT
1152                                // if (lb == 0) { // INT_USE // NAN_OMIT
1153                                //      fill(0); // INT_USE // NAN_OMIT
1154                                // } else { // INT_USE // NAN_OMIT
1155                                final IndexIterator it = getIterator(); // NAN_OMIT
1156                                while (it.hasNext()) { // NAN_OMIT
1157                                        data[it.index] %= lb; // NAN_OMIT
1158                                } // NAN_OMIT
1159                                // } // INT_USE // NAN_OMIT
1160                        } else { // NAN_OMIT
1161                                final long lb = bds.getElementLongAbs(0); // NAN_OMIT
1162                                // if (lb == 0) { // INT_USE // NAN_OMIT
1163                                //      fill(0); // INT_USE // NAN_OMIT
1164                                // } else { // INT_USE // NAN_OMIT
1165                                final IndexIterator it = getIterator(); // NAN_OMIT
1166                                while (it.hasNext()) { // NAN_OMIT
1167                                        data[it.index] %= lb; // NAN_OMIT
1168                                } // NAN_OMIT
1169                                // } // INT_USE // NAN_OMIT
1170                        } // NAN_OMIT
1171                } else { // NAN_OMIT
1172                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); // NAN_OMIT
1173                        it.setOutputDouble(!useLong); // NAN_OMIT
1174                        if (useLong) { // NAN_OMIT
1175                                while (it.hasNext()) { // NAN_OMIT
1176                                        data[it.aIndex] %= it.bLong; // NAN_OMIT // INT_EXCEPTION
1177                                } // NAN_OMIT
1178                        } else { // NAN_OMIT
1179                                while (it.hasNext()) { // NAN_OMIT
1180                                        data[it.aIndex] %= it.bDouble; // NAN_OMIT // INT_EXCEPTION
1181                                } // NAN_OMIT
1182                        } // NAN_OMIT
1183                } // NAN_OMIT
1184                return this;
1185        }
1186
1187        @Override
1188        public DoubleDataset ipower(final Object b) {
1189                setDirty(); // NAN_OMIT
1190                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
1191                if (bds.getSize() == 1) { // NAN_OMIT
1192                        final double vr = bds.getElementDoubleAbs(0); // NAN_OMIT
1193                        final IndexIterator it = getIterator(); // NAN_OMIT
1194                        if (bds.isComplex()) { // NAN_OMIT
1195                                final double vi = bds.getElementDoubleAbs(1); // NAN_OMIT
1196                                if (vi == 0) { // NAN_OMIT
1197                                        while (it.hasNext()) { // NAN_OMIT
1198                                                final double v = Math.pow(data[it.index], vr); // NAN_OMIT
1199                                                // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE // NAN_OMIT
1200                                                //      data[it.index] = 0; // INT_USE // NAN_OMIT
1201                                                // } else { // INT_USE // NAN_OMIT
1202                                                data[it.index] = v; // PRIM_TYPE_LONG // NAN_OMIT // ADD_CAST
1203                                                // } // INT_USE // NAN_OMIT
1204                                        } // NAN_OMIT
1205                                } else { // NAN_OMIT
1206                                        final Complex zv = new Complex(vr, vi); // NAN_OMIT
1207                                        while (it.hasNext()) { // NAN_OMIT
1208                                                Complex zd = new Complex(data[it.index], 0); // NAN_OMIT
1209                                                final double v = zd.pow(zv).getReal(); // NAN_OMIT
1210                                                // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE // NAN_OMIT
1211                                                //      data[it.index] = 0; // INT_USE // NAN_OMIT
1212                                                // } else { // INT_USE // NAN_OMIT
1213                                                data[it.index] = v; // PRIM_TYPE_LONG // NAN_OMIT // ADD_CAST
1214                                                // } // INT_USE // NAN_OMIT
1215                                        } // NAN_OMIT
1216                                } // NAN_OMIT
1217                        } else {// NAN_OMIT
1218                                while (it.hasNext()) { // NAN_OMIT
1219                                        final double v = Math.pow(data[it.index], vr); // NAN_OMIT
1220                                        // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE // NAN_OMIT
1221                                        //      data[it.index] = 0; // INT_USE // NAN_OMIT
1222                                        // } else { // INT_USE // NAN_OMIT
1223                                        data[it.index] = v; // PRIM_TYPE_LONG // NAN_OMIT // ADD_CAST
1224                                        // } // INT_USE // NAN_OMIT
1225                                } // NAN_OMIT
1226                        } // NAN_OMIT
1227                } else { // NAN_OMIT
1228                        final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); // NAN_OMIT
1229                        it.setOutputDouble(true); // NAN_OMIT
1230                        if (bds.isComplex()) { // NAN_OMIT
1231                                while (it.hasNext()) { // NAN_OMIT
1232                                        final Complex zv = new Complex(it.bDouble, bds.getElementDoubleAbs(it.bIndex + 1)); // NAN_OMIT
1233                                        final double v = new Complex(it.aDouble, 0).pow(zv).getReal(); // NAN_OMIT
1234                                        // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE // NAN_OMIT
1235                                        //      data[it.aIndex] = 0; // INT_USE // NAN_OMIT
1236                                        // } else { // INT_USE // NAN_OMIT
1237                                        data[it.aIndex] = v; // PRIM_TYPE_LONG // NAN_OMIT // ADD_CAST
1238                                        // } // INT_USE // NAN_OMIT
1239                                } // NAN_OMIT
1240                        } else {// NAN_OMIT
1241                                while (it.hasNext()) { // NAN_OMIT
1242                                        final double v = Math.pow(it.aDouble, it.bDouble); // NAN_OMIT
1243                                        // if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE // NAN_OMIT
1244                                        //      data[it.aIndex] = 0; // INT_USE // NAN_OMIT
1245                                        // } else { // INT_USE // NAN_OMIT
1246                                        data[it.aIndex] = v; // PRIM_TYPE_LONG // NAN_OMIT // ADD_CAST
1247                                        // } // INT_USE // NAN_OMIT
1248                                } // NAN_OMIT
1249                        } // NAN_OMIT
1250                } // NAN_OMIT
1251                return this;
1252        }
1253
1254        @Override
1255        public double residual(final Object b, final Dataset w, boolean ignoreNaNs) {
1256                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); // NAN_OMIT
1257                final BroadcastIterator it = BroadcastIterator.createIterator(this, bds); // NAN_OMIT
1258                it.setOutputDouble(true); // NAN_OMIT
1259                double sum = 0;
1260                double comp = 0; // NAN_OMIT
1261                if (ignoreNaNs) { // REAL_ONLY // NAN_OMIT
1262                        if (w == null) { // REAL_ONLY // NAN_OMIT
1263                                while (it.hasNext()) { // REAL_ONLY // NAN_OMIT
1264                                        final double diff = it.aDouble - it.bDouble; // REAL_ONLY // NAN_OMIT
1265                                        if (Double.isNaN(diff)) // REAL_ONLY // NAN_OMIT
1266                                                continue; // REAL_ONLY // NAN_OMIT
1267                                        final double err = diff * diff - comp; // REAL_ONLY // NAN_OMIT
1268                                        final double temp = sum + err; // REAL_ONLY // NAN_OMIT
1269                                        comp = (temp - sum) - err; // REAL_ONLY // NAN_OMIT
1270                                        sum = temp; // REAL_ONLY // NAN_OMIT
1271                                } // REAL_ONLY // NAN_OMIT
1272                        } else { // REAL_ONLY // NAN_OMIT
1273                                IndexIterator itw = w.getIterator(); // REAL_ONLY // NAN_OMIT
1274                                while (it.hasNext() && itw.hasNext()) { // REAL_ONLY // NAN_OMIT
1275                                        final double diff = it.aDouble - it.bDouble; // REAL_ONLY // NAN_OMIT
1276                                        if (Double.isNaN(diff)) // REAL_ONLY // NAN_OMIT
1277                                                continue; // REAL_ONLY // NAN_OMIT
1278                                        final double err = diff * diff * w.getElementDoubleAbs(itw.index) - comp; // REAL_ONLY // NAN_OMIT
1279                                        final double temp = sum + err; // REAL_ONLY // NAN_OMIT
1280                                        comp = (temp - sum) - err; // REAL_ONLY // NAN_OMIT
1281                                        sum = temp; // REAL_ONLY // NAN_OMIT
1282                                } // REAL_ONLY // NAN_OMIT
1283                        } // REAL_ONLY // NAN_OMIT
1284                } else // REAL_ONLY // NAN_OMIT
1285                { // NAN_OMIT
1286                        if (w == null) { // NAN_OMIT
1287                                while (it.hasNext()) { // NAN_OMIT
1288                                        final double diff = it.aDouble - it.bDouble; // NAN_OMIT
1289                                        final double err = diff * diff - comp; // NAN_OMIT
1290                                        final double temp = sum + err; // NAN_OMIT
1291                                        comp = (temp - sum) - err; // NAN_OMIT
1292                                        sum = temp; // NAN_OMIT
1293                                } // NAN_OMIT
1294                        } else { // NAN_OMIT
1295                                IndexIterator itw = w.getIterator(); // NAN_OMIT
1296                                while (it.hasNext() && itw.hasNext()) { // NAN_OMIT
1297                                        final double diff = it.aDouble - it.bDouble; // NAN_OMIT
1298                                        final double err = diff * diff * w.getElementDoubleAbs(itw.index) - comp; // NAN_OMIT
1299                                        final double temp = sum + err; // NAN_OMIT
1300                                        comp = (temp - sum) - err; // NAN_OMIT
1301                                        sum = temp; // NAN_OMIT
1302                                } // NAN_OMIT
1303                        } // NAN_OMIT
1304                } // NAN_OMIT
1305                return sum;
1306        }
1307}