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}