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