    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
    013package org.eclipse.january.dataset;
    014
    015import java.text.MessageFormat;
    016
    017
    018/**
    019 * Extend boolean base dataset for boolean values
    020 */
    021public class BooleanDataset extends BooleanDatasetBase {
    022        // pin UID to base class
    023        private static final long serialVersionUID = Dataset.serialVersionUID;
    024
    025        /**
    026         * Create a null dataset
    027         */
    028        BooleanDataset() {
    029                super();
    030        }
    031
    032        /**
    033         * Create a false-filled dataset of given shape
    034         * @param shape
    035         */
    036        BooleanDataset(final int... shape) {
    037                super(shape);
    038        }
    039
    040        /**
    041         * Create a dataset using given data
    042         * @param data
    043         * @param shape (can be null to create 1D dataset)
    044         */
    045        BooleanDataset(final boolean[] data, int... shape) {
    046                super(data, shape);
    047        }
    048
    049        /**
    050         * Copy a dataset
    051         * @param dataset
    052         */
    053        BooleanDataset(final BooleanDataset dataset) {
    054                super(dataset);
    055        }
    056
    057        /**
    058         * Cast a dataset to this class type
    059         * @param dataset
    060         */
    061        BooleanDataset(final Dataset dataset) {
    062                super(dataset);
    063        }
    064
    065        @Override
    066        public BooleanDataset getView(boolean deepCopyMetadata) {
    067                BooleanDataset view = new BooleanDataset();
    068                copyToView(this, view, true, deepCopyMetadata);
    069                view.setData();
    070                return view;
    071        }
    072
    073        @Override
    074        public BooleanDataset clone() {
    075                return new BooleanDataset(this);
    076        }
    077
    078        /**
    079         * Create a dataset from an object which could be a Java list, array (of arrays...)
    080         * or Number. Ragged sequences or arrays are padded with zeros.
    081         *
    082         * @param obj
    083         * @return dataset with contents given by input
    084         */
    085        static BooleanDataset createFromObject(final Object obj) {
    086                BooleanDatasetBase result = BooleanDatasetBase.createFromObject(obj);
    087                return new BooleanDataset(result.data, result.shape);
    088        }
    089
    090        /**
    091         * @param shape
    092         * @return a dataset filled with trues
    093         */
    094        static BooleanDataset ones(final int... shape) {
    095                BooleanDatasetBase result = BooleanDatasetBase.ones(shape);
    096                return new BooleanDataset(result.data, result.shape);
    097        }
    098
    099        @Override
    100        public boolean getElementBooleanAbs(final int index) {
    101                return data[index];
    102        }
    103
    104        @Override
    105        public double getElementDoubleAbs(final int index) {
    106                return data[index] ? 1 : 0;
    107        }
    108
    109        @Override
    110        public long getElementLongAbs(final int index) {
    111                return data[index] ? 1 : 0;
    112        }
    113
    114        @Override
    115        public double getDouble() {
    116                return getInt();
    117        }
    118
    119        @Override
    120        public double getDouble(final int i) {
    121                return getInt(i);
    122        }
    123
    124        @Override
    125        public double getDouble(final int i, final int j) {
    126                return getInt(i, j);
    127        }
    128
    129        @Override
    130        public double getDouble(final int... pos) {
    131                return getInt(pos);
    132        }
    133
    134        @Override
    135        public float getFloat() {
    136                return getInt();
    137        }
    138
    139        @Override
    140        public float getFloat(final int i) {
    141                return getInt(i);
    142        }
    143
    144        @Override
    145        public float getFloat(final int i, final int j) {
    146                return getInt(i, j);
    147        }
    148
    149        @Override
    150        public float getFloat(final int... pos) {
    151                return getInt(pos);
    152        }
    153
    154        @Override
    155        public long getLong() {
    156                return getInt();
    157        }
    158
    159        @Override
    160        public long getLong(final int i) {
    161                return getInt(i);
    162        }
    163
    164        @Override
    165        public long getLong(final int i, final int j) {
    166                return getInt(i, j);
    167        }
    168
    169        @Override
    170        public long getLong(final int... pos) {
    171                return getInt(pos);
    172        }
    173
    174        @Override
    175        public int getInt() {
    176                return get() ? 1 : 0;
    177        }
    178
    179        @Override
    180        public int getInt(final int i) {
    181                return get(i) ? 1 : 0;
    182        }
    183
    184        @Override
    185        public int getInt(final int i, final int j) {
    186                return get(i, j) ? 1 : 0;
    187        }
    188
    189        @Override
    190        public int getInt(final int... pos) {
    191                return get(pos) ? 1 : 0;
    192        }
    193
    194        @Override
    195        public short getShort() {
    196                return (short) getInt();
    197        }
    198
    199        @Override
    200        public short getShort(final int i) {
    201                return (short) getInt(i);
    202        }
    203
    204        @Override
    205        public short getShort(final int i, final int j) {
    206                return (short) getInt(i, j);
    207        }
    208
    209        @Override
    210        public short getShort(final int... pos) {
    211                return (short) getInt(pos);
    212        }
    213
    214        @Override
    215        public byte getByte() {
    216                return (byte) getInt();
    217        }
    218
    219        @Override
    220        public byte getByte(final int i) {
    221                return (byte) getInt(i);
    222        }
    223
    224        @Override
    225        public byte getByte(final int i, final int j) {
    226                return (byte) getInt(i, j);
    227        }
    228
    229        @Override
    230        public byte getByte(final int... pos) {
    231                return (byte) getInt(pos);
    232        }
    233
    234        @Override
    235        public boolean getBoolean() {
    236                return get();
    237        }
    238
    239        @Override
    240        public boolean getBoolean(final int i) {
    241                return get(i);
    242        }
    243
    244        @Override
    245        public boolean getBoolean(final int i, final int j) {
    246                return get(i, j);
    247        }
    248
    249        @Override
    250        public boolean getBoolean(final int... pos) {
    251                return get(pos);
    252        }
    253
    254        @Override
    255        public String getStringAbs(final int index) {
    256                return stringFormat instanceof MessageFormat ? stringFormat.format(data[index]) :
    257                                String.format("%b", data[index]);
    258        }
    259
    260        @Override
    261        public BooleanDataset getSlice(SliceIterator siter) {
    262                BooleanDatasetBase base = super.getSlice(siter);
    263
    264                BooleanDataset slice = new BooleanDataset();
    265                copyToView(base, slice, false, false);
    266                slice.setData();
    267                return slice;
    268        }
    269
    270        /**
    271         * OR
    272         */
    273        @Override
    274        public BooleanDataset iadd(final Object b) {
    275                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    276                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
    277                while (it.hasNext()) {
    278                        data[it.aIndex] |= bds.getElementBooleanAbs(it.bIndex);
    279                }
    280                setDirty();
    281                return this;
    282        }
    283
    284        /**
    285         * XOR
    286         */
    287        @Override
    288        public BooleanDataset isubtract(final Object b) {
    289                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    290                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
    291                while (it.hasNext()) {
    292                        data[it.aIndex] ^= bds.getElementBooleanAbs(it.bIndex);
    293                }
    294                setDirty();
    295                return this;
    296        }
    297
    298        /**
    299         * AND
    300         */
    301        @Override
    302        public BooleanDataset imultiply(final Object b) {
    303                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    304                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
    305                while (it.hasNext()) {
    306                        data[it.aIndex] &= bds.getElementBooleanAbs(it.bIndex);
    307                }
    308                setDirty();
    309                return this;
    310        }
    311
    312        @Override
    313        public BooleanDataset idivide(final Object b) {
    314                return imultiply(b);
    315        }
    316
    317        @Override
    318        public BooleanDataset iremainder(final Object b) {
    319                logger.error("Unsupported method for class");
    320                throw new UnsupportedOperationException("Unsupported method for class");
    321        }
    322
    323        @Override
    324        public BooleanDataset ipower(final Object b) {
    325                logger.error("Unsupported method for class");
    326                throw new UnsupportedOperationException("Unsupported method for class");
    327        }
    328
    329        @Override
    330        public double residual(final Object b, final Dataset w, boolean ignoreNaNs) {
    331                Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b);
    332                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds);
    333                double sum = 0;
    334                {
    335                        if (w == null) {
    336                                while (it.hasNext()) {
    337                                        if (data[it.aIndex] ^ bds.getElementBooleanAbs(it.bIndex))
    338                                                sum++;
    339                                }
    340                        } else {
    341                                IndexIterator itw = w.getIterator();
    342                                double comp = 0;
    343                                while (it.hasNext() && itw.hasNext()) {
    344                                        if (data[it.aIndex] ^ bds.getElementBooleanAbs(it.bIndex)) {
    345                                                final double err = w.getElementDoubleAbs(itw.index) - comp;
    346                                                final double temp = sum + err;
    347                                                comp = (temp - sum) - err;
    348                                                sum = temp;
    349                                        }
    350                                }
    351                        }
    352                }
    353                return sum;
    354        }
    355}