    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 byte values // PRIM_TYPE
    029 */
    030public class ByteDataset extends AbstractDataset {
    031        // pin UID to base class
    032        private static final long serialVersionUID = Dataset.serialVersionUID;
    033
    034        protected byte[] data; // subclass alias // PRIM_TYPE
    035
    036        @Override
    037        protected void setData() {
    038                data = (byte[]) odata; // PRIM_TYPE
    039        }
    040
    041        protected static byte[] createArray(final int size) { // PRIM_TYPE
    042                byte[] array = null; // PRIM_TYPE
    043
    044                try {
    045                        array = new byte[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 INT8; // DATA_TYPE
    058        }
    059
    060        /**
    061         * Create a null dataset
    062         */
    063        ByteDataset() {
    064        }
    065
    066        /**
    067         * Create a zero-filled dataset of given shape
    068         * @param shape
    069         */
    070        ByteDataset(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        ByteDataset(final byte[] 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        ByteDataset(final ByteDataset 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        ByteDataset(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] = (byte) 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                ByteDataset other = (ByteDataset) 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 ByteDataset clone() {
    186                return new ByteDataset(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 ByteDataset createFromObject(final Object obj) {
    197                ByteDataset result = new ByteDataset();
    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 ByteDataset 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 ByteDataset createRange(final double start, final double stop, final double step) {
    234                int size = calcSteps(start, stop, step);
    235                ByteDataset result = new ByteDataset(size);
    236                for (int i = 0; i < size; i++) {
    237                        result.data[i] = (byte) (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 ByteDataset ones(final int... shape) {
    247                return new ByteDataset(shape).fill(1);
    248        }
    249
    250        @Override
    251        public ByteDataset fill(final Object obj) {
    252                setDirty();
    253                byte dv = (byte) 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 byte[] 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 ByteDataset getView(boolean deepCopyMetadata) {
    279                ByteDataset view = new ByteDataset();
    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 byte 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 byte 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                byte[] dsrc = (byte[]) 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, (byte) DTypeUtils.toLong(obj)); // FROM_OBJECT
    351        }
    352
    353        /**
    354         * @return item in first position
    355         * @since 2.0
    356         */
    357        public byte get() { // PRIM_TYPE
    358                return data[getFirst1DIndex()];
    359        }
    360
    361        /**
    362         * @param i
    363         * @return item in given position
    364         */
    365        public byte 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 byte 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 byte get(final int... pos) { // PRIM_TYPE
    383                return data[get1DIndex(pos)];
    384        }
    385
    386        @Override
    387        public Object getObject() {
    388                return Byte.valueOf(get()); // CLASS_TYPE
    389        }
    390
    391        @Override
    392        public Object getObject(final int i) {
    393                return Byte.valueOf(get(i)); // CLASS_TYPE
    394        }
    395
    396        @Override
    397        public Object getObject(final int i, final int j) {
    398                return Byte.valueOf(get(i, j)); // CLASS_TYPE
    399        }
    400
    401        @Override
    402        public Object getObject(final int... pos) {
    403                return Byte.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 get(); // BOOLEAN_ZERO // OMIT_UPCAST
    529        }
    530
    531        @Override
    532        public byte getByte(final int i) {
    533                return get(i); // BOOLEAN_ZERO // OMIT_UPCAST
    534        }
    535
    536        @Override
    537        public byte getByte(final int i, final int j) {
    538                return get(i, j); // BOOLEAN_ZERO // OMIT_UPCAST
    539        }
    540
    541        @Override
    542        public byte getByte(final int... pos) {
    543                return 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 byte 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 byte 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 byte 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 byte value, final int... pos) { // PRIM_TYPE
    604                setAbs(get1DIndex(pos), value);
    605        }
    606
    607        @Override
    608        public void set(final Object obj) {
    609                setItem((byte) DTypeUtils.toLong(obj)); // FROM_OBJECT
    610        }
    611
    612        @Override
    613        public void set(final Object obj, final int i) {
    614                setItem((byte) 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((byte) 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((byte) 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 byte[] 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 ByteDataset sort(Integer axis) {
    657                setDirty();
    658                if (axis == null) {
    659                        if (stride == null) {
    660                                Arrays.sort(data);
    661                        } else {
    662                                ByteDataset ads = clone().sort(null);
    663                                setSlicedView(getView(false), ads);
    664                        }
    665                } else {
    666                        axis = checkAxis(axis);
    667
    668                        ByteDataset ads = new ByteDataset(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 ByteDataset getUniqueItems() {
    684                Set<Byte> set = new TreeSet<Byte>(); // CLASS_TYPE
    685                IndexIterator it = getIterator();
    686                while (it.hasNext()) {
    687                        set.add(data[it.index]);
    688                }
    689
    690                ByteDataset u = new ByteDataset(set.size()); // CLASS_TYPE
    691                int i = 0;
    692                byte[] udata = u.getData(); // PRIM_TYPE
    693                for (Byte v : set) { // CLASS_TYPE
    694                        udata[i++] = v;
    695                }
    696                return u;
    697        }
    698
    699        @Override
    700        public ByteDataset getSlice(final SliceIterator siter) {
    701                ByteDataset result = new ByteDataset(siter.getShape());
    702                byte[] 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                byte[] rdata = ((ByteDataset) 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 ByteDataset 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] = (byte) ds.getElementLongAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    739                        }
    740                } else {
    741                        final byte dv = (byte) 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 ByteDataset 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] = (byte) ds.getElementLongAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    766                        }
    767                } else {
    768                        final byte dv = (byte) 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 ByteDataset 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((byte) ds.getElementLongAbs(oiter.index), pos); // GET_ELEMENT_WITH_CAST
    795                        }
    796                } else {
    797                        final byte dv = (byte) 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        ByteDataset setSlicedView(Dataset view, Dataset d) {
    808                setDirty();
    809                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(view, d);
    810
    811                while (it.hasNext()) {
    812                        data[it.aIndex] = (byte) it.bLong; // BCAST_WITH_CAST d.getElementLongAbs(it.bIndex);
    813                }
    814                return this;
    815        }
    816
    817        @Override
    818        public ByteDataset 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] = (byte) 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.getByte(pos); // PRIM_TYPE
    843                        }
    844                } else {
    845                        try {
    846                                byte v = (byte) 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                byte[] ddata = (byte[]) 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                byte[] sdata = (byte[]) 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 byte 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).byteValue()); // 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).byteValue()); // 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 ByteDataset 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 ByteDataset 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 ByteDataset 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 ByteDataset 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 ByteDataset ifloor() {
    1118                return this;
    1119        }
    1120
    1121        @Override
    1122        public ByteDataset 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 ByteDataset 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] = (byte) (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] = (byte) (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] = (byte) (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] = (byte) (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] = (byte) (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}