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// This is generated from DoubleDataset.java by fromdouble.py
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;
024import org.eclipse.january.metadata.StatisticsMetadata;
025
026
027/**
028 * Extend dataset for int values // PRIM_TYPE
029 */
030public class IntegerDataset extends AbstractDataset {
031        // pin UID to base class
032        private static final long serialVersionUID = Dataset.serialVersionUID;
033
034        protected int[] data; // subclass alias // PRIM_TYPE
035
036        @Override
037        protected void setData() {
038                data = (int[]) odata; // PRIM_TYPE
039        }
040
041        protected static int[] createArray(final int size) { // PRIM_TYPE
042                int[] array = null; // PRIM_TYPE
043
044                try {
045                        array = new int[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 INT32; // DATA_TYPE
058        }
059
060        /**
061         * Create a null dataset
062         */
063        IntegerDataset() {
064        }
065
066        /**
067         * Create a zero-filled dataset of given shape
068         * @param shape
069         */
070        IntegerDataset(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        IntegerDataset(final int[] 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        IntegerDataset(final IntegerDataset 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        IntegerDataset(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] = (int) dataset.getElementLongAbs(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                IntegerDataset other = (IntegerDataset) 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 IntegerDataset clone() {
184                return new IntegerDataset(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 IntegerDataset createFromObject(final Object obj) {
195                IntegerDataset result = new IntegerDataset();
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        
215        /**
216         *
217         * @param stop
218         * @return a new 1D dataset, filled with values determined by parameters
219         */
220        static IntegerDataset createRange(final double stop) {
221                return createRange(0, stop, 1);
222        }
223        
224        /**
225         *
226         * @param start
227         * @param stop
228         * @param step
229         * @return a new 1D dataset, filled with values determined by parameters
230         */
231        static IntegerDataset createRange(final double start, final double stop, final double step) {
232                int size = calcSteps(start, stop, step);
233                IntegerDataset result = new IntegerDataset(size);
234                for (int i = 0; i < size; i++) {
235                        result.data[i] = (int) (start + i * step); // PRIM_TYPE // ADD_CAST
236                }
237                return result;
238        }
239
240        /**
241         * @param shape
242         * @return a dataset filled with ones
243         */
244        static IntegerDataset ones(final int... shape) {
245                return new IntegerDataset(shape).fill(1);
246        }
247
248        @Override
249        public IntegerDataset fill(final Object obj) {
250                setDirty();
251                int dv = (int) DTypeUtils.toLong(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 int[] 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 IntegerDataset getView(boolean deepCopyMetadata) {
277                IntegerDataset view = new IntegerDataset();
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 int 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 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("%d", 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 int 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                int[] dsrc = (int[]) 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, (int) DTypeUtils.toLong(obj)); // FROM_OBJECT
349        }
350
351        /**
352         * @return item in first position
353         * @since 2.0
354         */
355        public int get() { // PRIM_TYPE
356                return data[getFirst1DIndex()];
357        }
358
359        /**
360         * @param i
361         * @return item in given position
362         */
363        public int 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 int 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 int get(final int... pos) { // PRIM_TYPE
381                return data[get1DIndex(pos)];
382        }
383
384        @Override
385        public Object getObject() {
386                return Integer.valueOf(get()); // CLASS_TYPE
387        }
388
389        @Override
390        public Object getObject(final int i) {
391                return Integer.valueOf(get(i)); // CLASS_TYPE
392        }
393
394        @Override
395        public Object getObject(final int i, final int j) {
396                return Integer.valueOf(get(i, j)); // CLASS_TYPE
397        }
398
399        @Override
400        public Object getObject(final int... pos) {
401                return Integer.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 get(); // BOOLEAN_ZERO // OMIT_REAL_CAST
447        }
448
449        @Override
450        public float getFloat(final int i) {
451                return get(i); // BOOLEAN_ZERO // OMIT_REAL_CAST
452        }
453
454        @Override
455        public float getFloat(final int i, final int j) {
456                return get(i, j); // BOOLEAN_ZERO // OMIT_REAL_CAST
457        }
458
459        @Override
460        public float getFloat(final int... pos) {
461                return get(pos); // BOOLEAN_ZERO // OMIT_REAL_CAST
462        }
463
464        @Override
465        public long getLong() {
466                return get(); // BOOLEAN_ZERO // OMIT_UPCAST
467        }
468
469        @Override
470        public long getLong(final int i) {
471                return get(i); // BOOLEAN_ZERO // OMIT_UPCAST
472        }
473
474        @Override
475        public long getLong(final int i, final int j) {
476                return get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
477        }
478
479        @Override
480        public long getLong(final int... pos) {
481                return get(pos); // BOOLEAN_ZERO // OMIT_UPCAST
482        }
483
484        @Override
485        public int getInt() {
486                return get(); // BOOLEAN_ZERO // OMIT_UPCAST
487        }
488
489        @Override
490        public int getInt(final int i) {
491                return get(i); // BOOLEAN_ZERO // OMIT_UPCAST
492        }
493
494        @Override
495        public int getInt(final int i, final int j) {
496                return get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
497        }
498
499        @Override
500        public int getInt(final int... pos) {
501                return 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 int 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 int 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 int 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 int value, final int... pos) { // PRIM_TYPE
602                setAbs(get1DIndex(pos), value);
603        }
604
605        @Override
606        public void set(final Object obj) {
607                setItem((int) DTypeUtils.toLong(obj)); // FROM_OBJECT
608        }
609
610        @Override
611        public void set(final Object obj, final int i) {
612                setItem((int) DTypeUtils.toLong(obj), i); // FROM_OBJECT
613        }
614
615        @Override
616        public void set(final Object obj, final int i, final int j) {
617                setItem((int) DTypeUtils.toLong(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((int) DTypeUtils.toLong(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 int[] 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 IntegerDataset sort(Integer axis) {
656                setDirty();
657                if (axis == null) {
658                        if (stride == null) {
659                                Arrays.sort(data);
660                        } else {
661                                IntegerDataset ads = clone().sort(null);
662                                setSlicedView(getView(false), ads);
663                        }
664                } else {
665                        axis = checkAxis(axis);
666                        
667                        IntegerDataset ads = new IntegerDataset(shape[axis]);
668                        PositionIterator pi = getPositionIterator(axis);
669                        int[] pos = pi.getPos();
670                        boolean[] hit = pi.getOmit();
671                        while (pi.hasNext()) {
672                                copyItemsFromAxes(pos, hit, ads);
673                                Arrays.sort(ads.data);
674                                setItemsOnAxes(pos, hit, ads.data);
675                        }
676                }
677                return this;
678                // throw new UnsupportedOperationException("Cannot sort dataset"); // BOOLEAN_USE
679        }
680
681        @Override
682        public IntegerDataset getUniqueItems() {
683                Set<Integer> set = new TreeSet<Integer>(); // CLASS_TYPE
684                IndexIterator it = getIterator();
685                while (it.hasNext()) {
686                        set.add(data[it.index]);
687                }
688
689                IntegerDataset u = new IntegerDataset(set.size()); // CLASS_TYPE
690                int i = 0;
691                int[] udata = u.getData(); // PRIM_TYPE
692                for (Integer v : set) { // CLASS_TYPE
693                        udata[i++] = v;
694                }
695                return u;
696        }
697
698        @Override
699        public IntegerDataset getSlice(final SliceIterator siter) {
700                IntegerDataset result = new IntegerDataset(siter.getShape());
701                int[] 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                int[] rdata = ((IntegerDataset) 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 IntegerDataset 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] = (int) ds.getElementLongAbs(oiter.index); // GET_ELEMENT_WITH_CAST
738                        }
739                } else {
740                        final int dv = (int) DTypeUtils.toLong(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 IntegerDataset 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] = (int) ds.getElementLongAbs(oiter.index); // GET_ELEMENT_WITH_CAST
765                        }
766                } else {
767                        final int dv = (int) DTypeUtils.toLong(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 IntegerDataset 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((int) ds.getElementLongAbs(oiter.index), pos); // GET_ELEMENT_WITH_CAST
794                        }
795                } else {
796                        final int dv = (int) DTypeUtils.toLong(obj); // PRIM_TYPE // FROM_OBJECT
797
798                        while (iter.hasNext()) {
799                                setItem(dv, pos);
800                        }
801                }
802                return this;
803        }
804
805        @Override
806        IntegerDataset setSlicedView(Dataset view, Dataset d) {
807                setDirty();
808                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(view, d);
809
810                while (it.hasNext()) {
811                        data[it.aIndex] = (int) it.bLong; // BCAST_WITH_CAST d.getElementLongAbs(it.bIndex);
812                }
813                return this;
814        }
815
816        @Override
817        public IntegerDataset 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] = (int) ads.getElementLongAbs(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.getInt(pos); // PRIM_TYPE
842                        }
843                } else {
844                        try {
845                                int v = (int) DTypeUtils.toLong(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                int[] ddata = (int[]) 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                int[] sdata = (int[]) 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 int value) { // PRIM_TYPE
892                IndexIterator iter = getIterator(true);
893                List<int[]> posns = new ArrayList<int[]>();
894                int[] pos = iter.getPos();
895
896                {
897                        while (iter.hasNext()) {
898                                if (data[iter.index] == value) {
899                                        posns.add(pos.clone());
900                                }
901                        }
902                }
903                return posns;
904        }
905
906        @Override
907        public int[] maxPos(boolean... ignoreInvalids) {
908                StatisticsMetadata<Number> md = getStats(); // PRIM_TYPE
909                // StatisticsMetadata<Number> md = getStats(); // BOOLEAN_USE
910                // StatisticsMetadata<String> md = getStringStats(); // OBJECT_USE
911                List<int[]> max = md.getMaximumPositions(ignoreInvalids);
912
913                if (max == null) {
914                        max = findPositions(md.getMaximum(ignoreInvalids).intValue()); // PRIM_TYPE
915                        // max = findPositions(md.getMaximum(ignoreInvalids).intValue() != 0); // BOOLEAN_USE
916                        // max = findPositions(md.getMaximum(ignoreInvalids).toString()); // OBJECT_USE
917
918                        md.setMaximumPositions(max);
919                }
920
921                return max.get(0); // first maximum
922        }
923
924        @Override
925        public int[] minPos(boolean... ignoreInvalids) {
926                StatisticsMetadata<Number> md = getStats(); // PRIM_TYPE
927                // StatisticsMetadata<Number> md = getStats(); // BOOLEAN_USE
928                // StatisticsMetadata<String> md = getStringStats(); // OBJECT_USE
929                List<int[]> min = md.getMinimumPositions(ignoreInvalids);
930
931                if (min == null) {
932                        min = findPositions(md.getMinimum(ignoreInvalids).intValue()); // PRIM_TYPE
933                        // min = findPositions(md.getMinimum(ignoreInvalids).intValue() != 0); // BOOLEAN_USE
934                        // min = findPositions(md.getMinimum(ignoreInvalids).toString()); // OBJECT_USE
935
936                        md.setMinimumPositions(min);
937                }
938
939                return min.get(0); // first minimum
940        }
941
942        @Override
943        public boolean containsNans() {
944                return false;
945        }
946
947        @Override
948        public boolean containsInfs() {
949                return false;
950        }
951
952        @Override
953        public boolean containsInvalidNumbers() {
954                return false;
955        }
956
957        @Override
958        public IntegerDataset iadd(final Object b) {
959                setDirty();
960                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
961                boolean useLong = bds.getElementClass().equals(Long.class);
962                if (bds.getSize() == 1) {
963                        final IndexIterator it = getIterator();
964                        if (useLong) {
965                                final long lb = bds.getElementLongAbs(0);
966                                while (it.hasNext()) {
967                                        data[it.index] += lb;
968                                }
969                        } else {
970                                final double db = bds.getElementDoubleAbs(0);
971                                while (it.hasNext()) {
972                                        data[it.index] += db;
973                                }
974                        }
975                } else {
976                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
977                        it.setOutputDouble(!useLong);
978                        if (useLong) {
979                                while (it.hasNext()) {
980                                        data[it.aIndex] += it.bLong;
981                                }
982                        } else {
983                                while (it.hasNext()) {
984                                        data[it.aIndex] += it.bDouble;
985                                }
986                        }
987                }
988                return this;
989        }
990
991        @Override
992        public IntegerDataset isubtract(final Object b) {
993                setDirty();
994                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
995                boolean useLong = bds.getElementClass().equals(Long.class);
996                if (bds.getSize() == 1) {
997                        final IndexIterator it = getIterator();
998                        if (useLong) {
999                                final long lb = bds.getElementLongAbs(0);
1000                                while (it.hasNext()) {
1001                                        data[it.index] -= lb;
1002                                }
1003                        } else {
1004                                final double db = bds.getElementDoubleAbs(0);
1005                                while (it.hasNext()) {
1006                                        data[it.index] -= db;
1007                                }
1008                        }
1009                } else {
1010                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
1011                        if (useLong) {
1012                                it.setOutputDouble(false);
1013                                while (it.hasNext()) {
1014                                        data[it.aIndex] -= it.bLong;
1015                                }
1016                        } else {
1017                                it.setOutputDouble(true);
1018                                while (it.hasNext()) {
1019                                        data[it.aIndex] -= it.bDouble;
1020                                }
1021                        }
1022                }
1023                return this;
1024        }
1025
1026        @Override
1027        public IntegerDataset imultiply(final Object b) {
1028                setDirty();
1029                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
1030                boolean useLong = bds.getElementClass().equals(Long.class);
1031                if (bds.getSize() == 1) {
1032                        final IndexIterator it = getIterator();
1033                        if (useLong) {
1034                                final long lb = bds.getElementLongAbs(0);
1035                                while (it.hasNext()) {
1036                                        data[it.index] *= lb;
1037                                }
1038                        } else {
1039                                final double db = bds.getElementDoubleAbs(0);
1040                                while (it.hasNext()) {
1041                                        data[it.index] *= db;
1042                                }
1043                        }
1044                } else {
1045                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
1046                        it.setOutputDouble(!useLong);
1047                        if (useLong) {
1048                                while (it.hasNext()) {
1049                                        data[it.aIndex] *= it.bLong;
1050                                }
1051                        } else {
1052                                while (it.hasNext()) {
1053                                        data[it.aIndex] *= it.bDouble;
1054                                }
1055                        }
1056                }
1057                return this;
1058        }
1059
1060        @Override
1061        public IntegerDataset idivide(final Object b) {
1062                setDirty();
1063                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
1064                boolean useLong = bds.getElementClass().equals(Long.class);
1065                if (bds.getSize() == 1) {
1066                        if (useLong) {
1067                                final long lb = bds.getElementLongAbs(0);
1068                                if (lb == 0) { // INT_USE
1069                                        fill(0); // INT_USE
1070                                } else { // INT_USE
1071                                final IndexIterator it = getIterator();
1072                                while (it.hasNext()) {
1073                                        data[it.index] /= lb;
1074                                }
1075                                } // INT_USE
1076                        } else {
1077                                final double db = bds.getElementDoubleAbs(0);
1078                                if (db == 0) { // INT_USE
1079                                        fill(0); // INT_USE
1080                                } else { // INT_USE
1081                                final IndexIterator it = getIterator();
1082                                while (it.hasNext()) {
1083                                        data[it.index] /= db;
1084                                }
1085                                } // INT_USE
1086                        }
1087                } else {
1088                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
1089                        it.setOutputDouble(!useLong);
1090                        if (useLong) {
1091                                while (it.hasNext()) {
1092                                        if (it.bLong == 0) { // INT_USE
1093                                                data[it.aIndex] = 0; // INT_USE
1094                                        } else { // INT_USE
1095                                        data[it.aIndex] /= it.bLong;
1096                                        } // INT_USE
1097                                }
1098                        } else {
1099                                while (it.hasNext()) {
1100                                        if (it.bDouble == 0) { // INT_USE
1101                                                data[it.aIndex] = 0; // INT_USE
1102                                        } else { // INT_USE
1103                                        data[it.aIndex] /= it.bDouble;
1104                                        } // INT_USE
1105                                }
1106                        }
1107                }
1108                return this;
1109        }
1110
1111        @Override
1112        public IntegerDataset ifloor() {
1113                return this;
1114        }
1115
1116        @Override
1117        public IntegerDataset iremainder(final Object b) {
1118                setDirty();
1119                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
1120                boolean useLong = bds.getElementClass().equals(Long.class);
1121                if (bds.getSize() == 1) {
1122                        if (useLong) {
1123                                final long lb = bds.getElementLongAbs(0);
1124                                if (lb == 0) { // INT_USE
1125                                        fill(0); // INT_USE
1126                                } else { // INT_USE
1127                                final IndexIterator it = getIterator();
1128                                while (it.hasNext()) {
1129                                        data[it.index] %= lb;
1130                                }
1131                                } // INT_USE
1132                        } else {
1133                                final long lb = bds.getElementLongAbs(0);
1134                                if (lb == 0) { // INT_USE
1135                                        fill(0); // INT_USE
1136                                } else { // INT_USE
1137                                final IndexIterator it = getIterator();
1138                                while (it.hasNext()) {
1139                                        data[it.index] %= lb;
1140                                }
1141                                } // INT_USE
1142                        }
1143                } else {
1144                        final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
1145                        it.setOutputDouble(!useLong);
1146                        if (useLong) {
1147                                while (it.hasNext()) {
1148                                try {
1149                                                data[it.aIndex] %= it.bLong; // INT_EXCEPTION
1150                                } catch (ArithmeticException e) {
1151                                        data[it.aIndex] = 0;
1152                                }
1153                                }
1154                        } else {
1155                                while (it.hasNext()) {
1156                                try {
1157                                                data[it.aIndex] %= it.bDouble; // INT_EXCEPTION
1158                                } catch (ArithmeticException e) {
1159                                        data[it.aIndex] = 0;
1160                                }
1161                                }
1162                        }
1163                }
1164                return this;
1165        }
1166
1167        @Override
1168        public IntegerDataset ipower(final Object b) {
1169                setDirty();
1170                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
1171                if (bds.getSize() == 1) {
1172                        final double vr = bds.getElementDoubleAbs(0);
1173                        final IndexIterator it = getIterator();
1174                        if (bds.isComplex()) {
1175                                final double vi = bds.getElementDoubleAbs(1);
1176                                if (vi == 0) {
1177                                        while (it.hasNext()) {
1178                                                final double v = Math.pow(data[it.index], vr);
1179                                                if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
1180                                                        data[it.index] = 0; // INT_USE
1181                                                } else { // INT_USE
1182                                                data[it.index] = (int) (long) v; // PRIM_TYPE_LONG // ADD_CAST
1183                                                } // INT_USE
1184                                        }
1185                                } else {
1186                                        final Complex zv = new Complex(vr, vi);
1187                                        while (it.hasNext()) {
1188                                                Complex zd = new Complex(data[it.index], 0);
1189                                                final double v = zd.pow(zv).getReal();
1190                                                if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
1191                                                        data[it.index] = 0; // INT_USE
1192                                                } else { // INT_USE
1193                                                data[it.index] = (int) (long) v; // PRIM_TYPE_LONG // ADD_CAST
1194                                                } // INT_USE
1195                                        }
1196                                }
1197                        } else {// NAN_OMIT
1198                                while (it.hasNext()) {
1199                                        final double v = Math.pow(data[it.index], vr);
1200                                        if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
1201                                                data[it.index] = 0; // INT_USE
1202                                        } else { // INT_USE
1203                                        data[it.index] = (int) (long) v; // PRIM_TYPE_LONG // ADD_CAST
1204                                        } // INT_USE
1205                                }
1206                        }
1207                } else {
1208                        final BroadcastIterator it = BroadcastIterator.createIterator(this, bds);
1209                        it.setOutputDouble(true);
1210                        if (bds.isComplex()) {
1211                                while (it.hasNext()) {
1212                                        final Complex zv = new Complex(it.bDouble, bds.getElementDoubleAbs(it.bIndex + 1));
1213                                        final double v = new Complex(it.aDouble, 0).pow(zv).getReal();
1214                                        if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
1215                                                data[it.aIndex] = 0; // INT_USE
1216                                        } else { // INT_USE
1217                                        data[it.aIndex] = (int) (long) v; // PRIM_TYPE_LONG // ADD_CAST
1218                                        } // INT_USE
1219                                }
1220                        } else {// NAN_OMIT
1221                                while (it.hasNext()) {
1222                                        final double v = Math.pow(it.aDouble, it.bDouble);
1223                                        if (Double.isInfinite(v) || Double.isNaN(v)) { // INT_USE
1224                                                data[it.aIndex] = 0; // INT_USE
1225                                        } else { // INT_USE
1226                                        data[it.aIndex] = (int) (long) v; // PRIM_TYPE_LONG // ADD_CAST
1227                                        } // INT_USE
1228                                }
1229                        }
1230                }
1231                return this;
1232        }
1233
1234        @Override
1235        public double residual(final Object b, final Dataset w, boolean ignoreNaNs) {
1236                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
1237                final BroadcastIterator it = BroadcastIterator.createIterator(this, bds);
1238                it.setOutputDouble(true);
1239                double sum = 0;
1240                double comp = 0;
1241                {
1242                        if (w == null) {
1243                                while (it.hasNext()) {
1244                                        final double diff = it.aDouble - it.bDouble;
1245                                        final double err = diff * diff - comp;
1246                                        final double temp = sum + err;
1247                                        comp = (temp - sum) - err;
1248                                        sum = temp;
1249                                }
1250                        } else {
1251                                IndexIterator itw = w.getIterator();
1252                                while (it.hasNext() && itw.hasNext()) {
1253                                        final double diff = it.aDouble - it.bDouble;
1254                                        final double err = diff * diff * w.getElementDoubleAbs(itw.index) - comp;
1255                                        final double temp = sum + err;
1256                                        comp = (temp - sum) - err;
1257                                        sum = temp;
1258                                }
1259                        }
1260                }
1261                return sum;
1262        }
1263}