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