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}