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