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}