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