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