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.eclipse.january.metadata.StatisticsMetadata;
024
025
026/**
027 * Extend dataset for Object values // PRIM_TYPE
028 */
029public class ObjectDatasetBase extends AbstractDataset {
030        // pin UID to base class
031        private static final long serialVersionUID = Dataset.serialVersionUID;
032
033        protected Object[] data; // subclass alias // PRIM_TYPE
034
035        @Override
036        protected void setData() {
037                data = (Object[]) odata; // PRIM_TYPE
038        }
039
040        protected static Object[] createArray(final int size) { // PRIM_TYPE
041                Object[] array = null; // PRIM_TYPE
042
043                try {
044                        array = new Object[size]; // PRIM_TYPE
045                } catch (OutOfMemoryError e) {
046                        logger.error("The size of the dataset ({}) that is being created is too large "
047                                        + "and there is not enough memory to hold it.", size);
048                        throw new OutOfMemoryError("The dimensions given are too large, and there is "
049                                        + "not enough memory available in the Java Virtual Machine");
050                }
051                return array;
052        }
053
054        @Override
055        public int getDType() {
056                return OBJECT; // DATA_TYPE
057        }
058
059        /**
060         * Create a null dataset
061         */
062        ObjectDatasetBase() {
063        }
064
065        /**
066         * Create a zero-filled dataset of given shape
067         * @param shape
068         */
069        ObjectDatasetBase(final int... shape) {
070                if (shape != null) {
071                        size = ShapeUtils.calcSize(shape);
072                        this.shape = shape.clone();
073
074                        try {
075                                odata = data = createArray(size);
076                        } catch (Throwable t) {
077                                logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
078                                throw new IllegalArgumentException(t);
079                        }
080                }
081        }
082
083        /**
084         * Create a dataset using given data
085         * @param data
086         * @param shape
087         *            (can be null to create 1D dataset)
088         */
089        ObjectDatasetBase(final Object[] data, int... shape) { // PRIM_TYPE
090                if (data == null) {
091                        throw new IllegalArgumentException("Data must not be null");
092                }
093                if (shape == null || shape.length == 0) {
094                        shape = new int[] { data.length };
095                }
096                size = ShapeUtils.calcSize(shape);
097                if (size != data.length) {
098                        throw new IllegalArgumentException(String.format("Shape %s is not compatible with size of data array, %d",
099                                        Arrays.toString(shape), data.length));
100                }
101                this.shape = size == 0 ? null : shape.clone();
102
103                odata = this.data = data;
104        }
105
106        /**
107         * Copy a dataset
108         * @param dataset
109         */
110        ObjectDatasetBase(final ObjectDatasetBase dataset) {
111                copyToView(dataset, this, true, true);
112
113                try {
114                        if (dataset.stride == null) {
115                                if (dataset.data != null) {
116                                        odata = data = dataset.data.clone();
117                                }
118                        } else {
119                                offset = 0;
120                                stride = null;
121                                base = null;
122                                odata = data = createArray(size);
123
124                                IndexIterator iter = dataset.getIterator();
125                                for (int i = 0; iter.hasNext(); i++) {
126                                        data[i] = dataset.data[iter.index];
127                                }
128                        }
129                } catch (Throwable t) {
130                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
131                        throw new IllegalArgumentException(t);
132                }
133        }
134
135        /**
136         * Copy and cast a dataset to this class type
137         * @param dataset
138         */
139        ObjectDatasetBase(final Dataset dataset) {
140                copyToView(dataset, this, true, false);
141                offset = 0;
142                stride = null;
143                base = null;
144                try {
145                        odata = data = createArray(size);
146                } catch (Throwable t) {
147                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
148                        throw new IllegalArgumentException(t);
149                }
150                IndexIterator iter = dataset.getIterator();
151                for (int i = 0; iter.hasNext(); i++) {
152                        data[i] = dataset.getObjectAbs(iter.index); // GET_ELEMENT_WITH_CAST
153                }
154        }
155
156        @Override
157        public boolean equals(Object obj) {
158                if (this == obj) {
159                        return true;
160                }
161
162                if (obj == null) {
163                        return false;
164                }
165
166                if (!getClass().equals(obj.getClass())) {
167                        if (getRank() == 0) { // for zero-rank datasets
168                                return obj.equals(getObjectAbs(offset));
169                        }
170                        return false;
171                }
172
173                ObjectDatasetBase other = (ObjectDatasetBase) obj;
174                if (size != other.size) {
175                        return false;
176                }
177                if (!Arrays.equals(shape, other.shape)) {
178                        return false;
179                }
180                if (data == other.data && stride == null && other.stride == null) {
181                        return true;
182                }
183
184                IndexIterator iter = getIterator();
185                IndexIterator oiter = other.getIterator();
186                while (iter.hasNext() && oiter.hasNext()) {
187                        if (!data[iter.index].equals(other.data[oiter.index])) { // OBJECT_UNEQUAL
188                                return false;
189                        }
190                }
191                return true;
192        }
193
194        @Override
195        public int hashCode() {
196                return super.hashCode();
197        }
198
199        @Override
200        public ObjectDatasetBase clone() {
201                return new ObjectDatasetBase(this);
202        }
203
204        /**
205         * Create a dataset from an object which could be a Java list, array (of arrays...) or Number. Ragged
206         * sequences or arrays are padded with zeros.
207         *
208         * @param obj
209         * @return dataset with contents given by input
210         */
211        static ObjectDatasetBase createFromObject(final Object obj) {
212                ObjectDatasetBase result = new ObjectDatasetBase();
213
214                if (obj != null) {
215                        result.shape = ShapeUtils.getShapeFromObject(obj);
216                        result.size = ShapeUtils.calcSize(result.shape);
217
218                        try {
219                                result.odata = result.data = createArray(result.size);
220                        } catch (Throwable t) {
221                                logger.error("Could not create a dataset of shape {}", Arrays.toString(result.shape), t);
222                                throw new IllegalArgumentException(t);
223                        }
224
225                        int[] pos = new int[result.shape.length];
226                        result.fillData(obj, 0, pos);
227                }
228
229                return result;
230        }
231
232        /**
233         * @param shape
234         * @return a dataset filled with ones
235         */
236        static ObjectDatasetBase ones(final int... shape) {
237                return new ObjectDatasetBase(shape).fill(1);
238        }
239
240        @Override
241        public ObjectDatasetBase fill(final Object obj) {
242                setDirty();
243                Object dv = obj; // PRIM_TYPE // FROM_OBJECT
244                IndexIterator iter = getIterator();
245                while (iter.hasNext()) {
246                        data[iter.index] = dv;
247                }
248
249                return this;
250        }
251
252        /**
253         * This is a typed version of {@link #getBuffer()}
254         * @return data buffer as linear array
255         */
256        public Object[] getData() { // PRIM_TYPE
257                return data;
258        }
259
260        @Override
261        protected int getBufferLength() {
262                if (data == null)
263                        return 0;
264                return data.length;
265        }
266
267        @Override
268        public ObjectDatasetBase getView(boolean deepCopyMetadata) {
269                ObjectDatasetBase view = new ObjectDatasetBase();
270                copyToView(this, view, true, deepCopyMetadata);
271                view.setData();
272                return view;
273        }
274
275        /**
276         * Get a value from an absolute index of the internal array. This is an internal method with no checks so can be
277         * dangerous. Use with care or ideally with an iterator.
278         *
279         * @param index
280         *            absolute index
281         * @return value
282         */
283        public Object getAbs(final int index) { // PRIM_TYPE
284                return data[index];
285        }
286
287        @Override
288        public boolean getElementBooleanAbs(final int index) {
289                return false;
290        }
291
292        @Override
293        public double getElementDoubleAbs(final int index) {
294                return 0;
295        }
296
297        @Override
298        public long getElementLongAbs(final int index) {
299                return 0;
300        }
301
302        @Override
303        public Object getObjectAbs(final int index) {
304                return data[index];
305        }
306
307        @Override
308        public String getStringAbs(final int index) {
309                return stringFormat == null ? String.format("%s", data[index]) : // FORMAT_STRING
310                        stringFormat.format(data[index]);
311        }
312
313        /**
314         * Set a value at absolute index in the internal array. This is an internal method with no checks so can be
315         * dangerous. Use with care or ideally with an iterator.
316         *
317         * @param index
318         *            absolute index
319         * @param val
320         *            new value
321         */
322        public void setAbs(final int index, final Object val) { // PRIM_TYPE
323                setDirty();
324                data[index] = val;
325        }
326
327        @Override
328        protected void setItemDirect(final int dindex, final int sindex, final Object src) {
329                setDirty();
330                Object[] dsrc = (Object[]) src; // PRIM_TYPE
331                data[dindex] = dsrc[sindex];
332        }
333
334        @Override
335        public void setObjectAbs(final int index, final Object obj) {
336                if (index < 0 || index > data.length) {
337                        throw new IndexOutOfBoundsException("Index given is outside dataset");
338                }
339
340                setAbs(index, obj); // FROM_OBJECT
341        }
342
343        /**
344         * @return item in first position
345         * @since 2.0
346         */
347        public Object get() { // PRIM_TYPE
348                return data[getFirst1DIndex()];
349        }
350
351        /**
352         * @param i
353         * @return item in given position
354         */
355        public Object get(final int i) { // PRIM_TYPE
356                return data[get1DIndex(i)];
357        }
358
359        /**
360         * @param i
361         * @param j
362         * @return item in given position
363         */
364        public Object get(final int i, final int j) { // PRIM_TYPE
365                return data[get1DIndex(i, j)];
366        }
367
368        /**
369         * @param pos
370         * @return item in given position
371         */
372        public Object get(final int... pos) { // PRIM_TYPE
373                return data[get1DIndex(pos)];
374        }
375
376        @Override
377        public Object getObject() {
378                return get(); // CLASS_TYPE
379        }
380
381        @Override
382        public Object getObject(final int i) {
383                return get(i); // CLASS_TYPE
384        }
385
386        @Override
387        public Object getObject(final int i, final int j) {
388                return get(i, j); // CLASS_TYPE
389        }
390
391        @Override
392        public Object getObject(final int... pos) {
393                return get(pos); // CLASS_TYPE
394        }
395
396        @Override
397        public String getString() {
398                return getStringAbs(getFirst1DIndex());
399        }
400
401        @Override
402        public String getString(final int i) {
403                return getStringAbs(get1DIndex(i));
404        }
405
406        @Override
407        public String getString(final int i, final int j) {
408                return getStringAbs(get1DIndex(i, j));
409        }
410
411        @Override
412        public String getString(final int... pos) {
413                return getStringAbs(get1DIndex(pos));
414        }
415
416        @Override
417        public double getDouble() {
418                return 0;
419        }
420
421        @Override
422        public double getDouble(final int i) {
423                return 0;
424        }
425
426        @Override
427        public double getDouble(final int i, final int j) {
428                return 0;
429        }
430
431        @Override
432        public double getDouble(final int... pos) {
433                return 0;
434        }
435
436        @Override
437        public float getFloat() {
438                return 0;
439        }
440
441        @Override
442        public float getFloat(final int i) {
443                return 0;
444        }
445
446        @Override
447        public float getFloat(final int i, final int j) {
448                return 0;
449        }
450
451        @Override
452        public float getFloat(final int... pos) {
453                return 0;
454        }
455
456        @Override
457        public long getLong() {
458                return 0;
459        }
460
461        @Override
462        public long getLong(final int i) {
463                return 0;
464        }
465
466        @Override
467        public long getLong(final int i, final int j) {
468                return 0;
469        }
470
471        @Override
472        public long getLong(final int... pos) {
473                return 0;
474        }
475
476        @Override
477        public int getInt() {
478                return 0;
479        }
480
481        @Override
482        public int getInt(final int i) {
483                return 0;
484        }
485
486        @Override
487        public int getInt(final int i, final int j) {
488                return 0;
489        }
490
491        @Override
492        public int getInt(final int... pos) {
493                return 0;
494        }
495
496        @Override
497        public short getShort() {
498                return 0;
499        }
500
501        @Override
502        public short getShort(final int i) {
503                return 0;
504        }
505
506        @Override
507        public short getShort(final int i, final int j) {
508                return 0;
509        }
510
511        @Override
512        public short getShort(final int... pos) {
513                return 0;
514        }
515
516        @Override
517        public byte getByte() {
518                return 0;
519        }
520
521        @Override
522        public byte getByte(final int i) {
523                return 0;
524        }
525
526        @Override
527        public byte getByte(final int i, final int j) {
528                return 0;
529        }
530
531        @Override
532        public byte getByte(final int... pos) {
533                return 0;
534        }
535
536        @Override
537        public boolean getBoolean() {
538                return false;
539        }
540
541        @Override
542        public boolean getBoolean(final int i) {
543                return false;
544        }
545
546        @Override
547        public boolean getBoolean(final int i, final int j) {
548                return false;
549        }
550
551        @Override
552        public boolean getBoolean(final int... pos) {
553                return false;
554        }
555
556        /**
557         * Sets the value at first point to the passed value. The dataset must not be null
558         *
559         * @param value
560         * @since 2.0
561         */
562        public void setItem(final Object value) { // PRIM_TYPE
563                setAbs(getFirst1DIndex(), value);
564        }
565
566        /**
567         * Sets the value at a particular point to the passed value. The dataset must be 1D
568         *
569         * @param value
570         * @param i
571         */
572        public void setItem(final Object value, final int i) { // PRIM_TYPE
573                setAbs(get1DIndex(i), value);
574        }
575
576        /**
577         * Sets the value at a particular point to the passed value. The dataset must be 2D
578         *
579         * @param value
580         * @param i
581         * @param j
582         */
583        public void setItem(final Object value, final int i, final int j) { // PRIM_TYPE
584                setAbs(get1DIndex(i, j), value);
585        }
586
587        /**
588         * Sets the value at a particular point to the passed value
589         *
590         * @param value
591         * @param pos
592         */
593        public void setItem(final Object value, final int... pos) { // PRIM_TYPE
594                setAbs(get1DIndex(pos), value);
595        }
596
597        @Override
598        public void set(final Object obj) {
599                setItem(obj); // FROM_OBJECT
600        }
601
602        @Override
603        public void set(final Object obj, final int i) {
604                setItem(obj, i); // FROM_OBJECT
605        }
606
607        @Override
608        public void set(final Object obj, final int i, final int j) {
609                setItem(obj, i, j); // FROM_OBJECT
610        }
611
612        @Override
613        public void set(final Object obj, int... pos) {
614                if (pos == null || (pos.length == 0 && shape.length > 0)) {
615                        pos = new int[shape.length];
616                }
617
618                setItem(obj, pos); // FROM_OBJECT
619        }
620
621        @Override
622        public void resize(int... newShape) {
623                setDirty();
624                final IndexIterator iter = getIterator();
625                final int nsize = ShapeUtils.calcSize(newShape);
626                final Object[] ndata; // PRIM_TYPE
627                try {
628                        ndata = createArray(nsize);
629                } catch (Throwable t) {
630                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
631                        throw new IllegalArgumentException(t);
632                }
633                for (int i = 0; iter.hasNext() && i < nsize; i++) {
634                        ndata[i] = data[iter.index];
635                }
636
637                odata = data = ndata;
638                size = nsize;
639                shape = newShape;
640                stride = null;
641                offset = 0;
642                base = null;
643        }
644
645        @Override
646        public ObjectDatasetBase sort(Integer axis) {
647                setDirty();
648                if (axis == null) {
649                        if (stride == null) {
650                                Arrays.sort(data);
651                        } else {
652                                ObjectDatasetBase ads = clone().sort(null);
653                                setSlicedView(getView(false), ads);
654                        }
655                } else {
656                        axis = checkAxis(axis);
657                        
658                        ObjectDatasetBase ads = new ObjectDatasetBase(shape[axis]);
659                        PositionIterator pi = getPositionIterator(axis);
660                        int[] pos = pi.getPos();
661                        boolean[] hit = pi.getOmit();
662                        while (pi.hasNext()) {
663                                copyItemsFromAxes(pos, hit, ads);
664                                Arrays.sort(ads.data);
665                                setItemsOnAxes(pos, hit, ads.data);
666                        }
667                }
668                return this;
669                // throw new UnsupportedOperationException("Cannot sort dataset"); // BOOLEAN_USE
670        }
671
672        @Override
673        public ObjectDatasetBase getUniqueItems() {
674                Set<Object> set = new TreeSet<Object>(); // CLASS_TYPE
675                IndexIterator it = getIterator();
676                while (it.hasNext()) {
677                        set.add(data[it.index]);
678                }
679
680                ObjectDataset u = new ObjectDataset(set.size()); // CLASS_TYPE
681                int i = 0;
682                Object[] udata = u.getData(); // PRIM_TYPE
683                for (Object v : set) { // CLASS_TYPE
684                        udata[i++] = v;
685                }
686                return u;
687        }
688
689        @Override
690        public ObjectDatasetBase getSlice(final SliceIterator siter) {
691                ObjectDatasetBase result = new ObjectDatasetBase(siter.getShape());
692                Object[] rdata = result.data; // PRIM_TYPE
693
694                for (int i = 0; siter.hasNext(); i++)
695                        rdata[i] = data[siter.index];
696
697                result.setName(name + BLOCK_OPEN + Slice.createString(siter.shape, siter.start, siter.stop, siter.step) + BLOCK_CLOSE);
698                return result;
699        }
700
701        @Override
702        public void fillDataset(Dataset result, IndexIterator iter) {
703                IndexIterator riter = result.getIterator();
704                result.setDirty();
705
706                Object[] rdata = ((ObjectDatasetBase) result).data; // PRIM_TYPE
707
708                while (riter.hasNext() && iter.hasNext()) {
709                        rdata[riter.index] = data[iter.index];
710                }
711        }
712
713        @Override
714        public ObjectDatasetBase setByBoolean(final Object obj, Dataset selection) {
715                setDirty();
716                if (obj instanceof Dataset) {
717                        final Dataset ds = (Dataset) obj;
718                        final int length = ((Number) selection.sum()).intValue();
719                        if (length != ds.getSize()) {
720                                throw new IllegalArgumentException(
721                                                "Number of true items in selection does not match number of items in dataset");
722                        }
723
724                        final IndexIterator oiter = ds.getIterator();
725                        final BooleanIterator biter = getBooleanIterator(selection);
726
727                        while (biter.hasNext() && oiter.hasNext()) {
728                                data[biter.index] = ds.getObjectAbs(oiter.index); // GET_ELEMENT_WITH_CAST
729                        }
730                } else {
731                        final Object dv = obj; // PRIM_TYPE // FROM_OBJECT
732                        final BooleanIterator biter = getBooleanIterator(selection);
733
734                        while (biter.hasNext()) {
735                                data[biter.index] = dv;
736                        }
737                }
738                return this;
739        }
740
741        @Override
742        public ObjectDatasetBase setBy1DIndex(final Object obj, final Dataset index) {
743                setDirty();
744                if (obj instanceof Dataset) {
745                        final Dataset ds = (Dataset) obj;
746                        if (index.getSize() != ds.getSize()) {
747                                throw new IllegalArgumentException(
748                                                "Number of items in index dataset does not match number of items in dataset");
749                        }
750
751                        final IndexIterator oiter = ds.getIterator();
752                        final IntegerIterator iter = new IntegerIterator(index, size);
753
754                        while (iter.hasNext() && oiter.hasNext()) {
755                                data[iter.index] = ds.getObjectAbs(oiter.index); // GET_ELEMENT_WITH_CAST
756                        }
757                } else {
758                        final Object dv = obj; // PRIM_TYPE // FROM_OBJECT
759                        IntegerIterator iter = new IntegerIterator(index, size);
760
761                        while (iter.hasNext()) {
762                                data[iter.index] = dv;
763                        }
764                }
765                return this;
766        }
767
768        @Override
769        public ObjectDatasetBase setByIndexes(final Object obj, final Object... indexes) {
770                setDirty();
771                final IntegersIterator iter = new IntegersIterator(shape, indexes);
772                final int[] pos = iter.getPos();
773
774                if (obj instanceof Dataset) {
775                        final Dataset ds = (Dataset) obj;
776                        if (ShapeUtils.calcSize(iter.getShape()) != ds.getSize()) {
777                                throw new IllegalArgumentException(
778                                                "Number of items in index datasets does not match number of items in dataset");
779                        }
780
781                        final IndexIterator oiter = ds.getIterator();
782
783                        while (iter.hasNext() && oiter.hasNext()) {
784                                setItem(ds.getObjectAbs(oiter.index), pos); // GET_ELEMENT_WITH_CAST
785                        }
786                } else {
787                        final Object dv = obj; // PRIM_TYPE // FROM_OBJECT
788
789                        while (iter.hasNext()) {
790                                setItem(dv, pos);
791                        }
792                }
793                return this;
794        }
795
796        @Override
797        ObjectDatasetBase setSlicedView(Dataset view, Dataset d) {
798                setDirty();
799                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(view, d);
800
801                while (it.hasNext()) {
802                        data[it.aIndex] = d.getObjectAbs(it.bIndex);
803                }
804                return this;
805        }
806
807        @Override
808        public ObjectDatasetBase setSlice(final Object obj, final IndexIterator siter) {
809                setDirty();
810
811                if (obj instanceof IDataset) {
812                        final IDataset ds = (IDataset) obj;
813                        final int[] oshape = ds.getShape();
814
815                        if (!ShapeUtils.areShapesCompatible(siter.getShape(), oshape)) {
816                                throw new IllegalArgumentException(String.format(
817                                                "Input dataset is not compatible with slice: %s cf %s", Arrays.toString(oshape),
818                                                Arrays.toString(siter.getShape())));
819                        }
820
821                        if (ds instanceof Dataset) {
822                                final Dataset ads = (Dataset) ds;
823                                final IndexIterator oiter = ads.getIterator();
824
825                                while (siter.hasNext() && oiter.hasNext())
826                                        data[siter.index] = ads.getObjectAbs(oiter.index); // GET_ELEMENT_WITH_CAST
827                        } else {
828                                final IndexIterator oiter = new PositionIterator(oshape);
829                                final int[] pos = oiter.getPos();
830
831                                while (siter.hasNext() && oiter.hasNext())
832                                        data[siter.index] = ds.getObject(pos); // PRIM_TYPE
833                        }
834                } else {
835                        try {
836                                Object v = obj; // PRIM_TYPE // FROM_OBJECT
837
838                                while (siter.hasNext())
839                                        data[siter.index] = v;
840                        } catch (IllegalArgumentException e) {
841                                throw new IllegalArgumentException("Object for setting slice is not a dataset or number");
842                        }
843                }
844                return this;
845        }
846
847        @Override
848        public void copyItemsFromAxes(final int[] pos, final boolean[] axes, final Dataset dest) {
849                Object[] ddata = (Object[]) dest.getBuffer(); // PRIM_TYPE
850
851                SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
852                int[] sshape = ShapeUtils.squeezeShape(siter.getShape(), false);
853
854                IndexIterator diter = dest.getSliceIterator(null, sshape, null);
855
856                if (ddata.length < ShapeUtils.calcSize(sshape)) {
857                        throw new IllegalArgumentException("destination array is not large enough");
858                }
859
860                dest.setDirty();
861                while (siter.hasNext() && diter.hasNext()) {
862                        ddata[diter.index] = data[siter.index];
863                }
864        }
865
866        @Override
867        public void setItemsOnAxes(final int[] pos, final boolean[] axes, final Object src) {
868                setDirty();
869                Object[] sdata = (Object[]) src; // PRIM_TYPE
870
871                SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
872
873                if (sdata.length < ShapeUtils.calcSize(siter.getShape())) {
874                        throw new IllegalArgumentException("destination array is not large enough");
875                }
876
877                for (int i = 0; siter.hasNext(); i++) {
878                        data[siter.index] = sdata[i];
879                }
880        }
881
882        private List<int[]> findPositions(final Object value) { // PRIM_TYPE
883                IndexIterator iter = getIterator(true);
884                List<int[]> posns = new ArrayList<int[]>();
885                int[] pos = iter.getPos();
886
887                {
888                        while (iter.hasNext()) {
889                                if (data[iter.index] == value) {
890                                        posns.add(pos.clone());
891                                }
892                        }
893                }
894                return posns;
895        }
896
897        @Override
898        public int[] maxPos(boolean... ignoreInvalids) {
899                // StatisticsMetadata<Number> md = getStats(); // BOOLEAN_USE
900                StatisticsMetadata<String> md = getStringStats(); // OBJECT_USE
901                List<int[]> max = md.getMaximumPositions(ignoreInvalids);
902
903                if (max == null) {
904                        // max = findPositions(md.getMaximum(ignoreInvalids).intValue() != 0); // BOOLEAN_USE
905                        max = findPositions(md.getMaximum(ignoreInvalids).toString()); // OBJECT_USE
906
907                        md.setMaximumPositions(max);
908                }
909
910                return max.get(0); // first maximum
911        }
912
913        @Override
914        public int[] minPos(boolean... ignoreInvalids) {
915                // StatisticsMetadata<Number> md = getStats(); // BOOLEAN_USE
916                StatisticsMetadata<String> md = getStringStats(); // OBJECT_USE
917                List<int[]> min = md.getMinimumPositions(ignoreInvalids);
918
919                if (min == null) {
920                        // min = findPositions(md.getMinimum(ignoreInvalids).intValue() != 0); // BOOLEAN_USE
921                        min = findPositions(md.getMinimum(ignoreInvalids).toString()); // OBJECT_USE
922
923                        md.setMinimumPositions(min);
924                }
925
926                return min.get(0); // first minimum
927        }
928
929        @Override
930        public boolean containsNans() {
931                return false;
932        }
933
934        @Override
935        public boolean containsInfs() {
936                return false;
937        }
938
939        @Override
940        public boolean containsInvalidNumbers() {
941                return false;
942        }
943
944        @Override
945        public ObjectDatasetBase iadd(final Object b) {
946                return this;
947        }
948
949        @Override
950        public ObjectDatasetBase isubtract(final Object b) {
951                return this;
952        }
953
954        @Override
955        public ObjectDatasetBase imultiply(final Object b) {
956                return this;
957        }
958
959        @Override
960        public ObjectDatasetBase idivide(final Object b) {
961                return this;
962        }
963
964        @Override
965        public ObjectDatasetBase ifloor() {
966                return this;
967        }
968
969        @Override
970        public ObjectDatasetBase iremainder(final Object b) {
971                return this;
972        }
973
974        @Override
975        public ObjectDatasetBase ipower(final Object b) {
976                return this;
977        }
978
979        @Override
980        public double residual(final Object b, final Dataset w, boolean ignoreNaNs) {
981                double sum = 0;
982                return sum;
983        }
984}