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 if (obj == null) { 087 return new BooleanDataset(); 088 } 089 BooleanDatasetBase result = BooleanDatasetBase.createFromObject(obj); 090 BooleanDataset ds = new BooleanDataset(result.data, result.shape); 091 if (result.shape.length == 0) { 092 ds.setShape(result.shape); // special case of single item 093 } 094 return ds; 095 } 096 097 /** 098 * @param shape 099 * @return a dataset filled with trues 100 */ 101 static BooleanDataset ones(final int... shape) { 102 BooleanDatasetBase result = BooleanDatasetBase.ones(shape); 103 return new BooleanDataset(result.data, result.shape); 104 } 105 106 @Override 107 public boolean getElementBooleanAbs(final int index) { 108 return data[index]; 109 } 110 111 @Override 112 public double getElementDoubleAbs(final int index) { 113 return data[index] ? 1 : 0; 114 } 115 116 @Override 117 public long getElementLongAbs(final int index) { 118 return data[index] ? 1 : 0; 119 } 120 121 @Override 122 public double getDouble() { 123 return getInt(); 124 } 125 126 @Override 127 public double getDouble(final int i) { 128 return getInt(i); 129 } 130 131 @Override 132 public double getDouble(final int i, final int j) { 133 return getInt(i, j); 134 } 135 136 @Override 137 public double getDouble(final int... pos) { 138 return getInt(pos); 139 } 140 141 @Override 142 public float getFloat() { 143 return getInt(); 144 } 145 146 @Override 147 public float getFloat(final int i) { 148 return getInt(i); 149 } 150 151 @Override 152 public float getFloat(final int i, final int j) { 153 return getInt(i, j); 154 } 155 156 @Override 157 public float getFloat(final int... pos) { 158 return getInt(pos); 159 } 160 161 @Override 162 public long getLong() { 163 return getInt(); 164 } 165 166 @Override 167 public long getLong(final int i) { 168 return getInt(i); 169 } 170 171 @Override 172 public long getLong(final int i, final int j) { 173 return getInt(i, j); 174 } 175 176 @Override 177 public long getLong(final int... pos) { 178 return getInt(pos); 179 } 180 181 @Override 182 public int getInt() { 183 return get() ? 1 : 0; 184 } 185 186 @Override 187 public int getInt(final int i) { 188 return get(i) ? 1 : 0; 189 } 190 191 @Override 192 public int getInt(final int i, final int j) { 193 return get(i, j) ? 1 : 0; 194 } 195 196 @Override 197 public int getInt(final int... pos) { 198 return get(pos) ? 1 : 0; 199 } 200 201 @Override 202 public short getShort() { 203 return (short) getInt(); 204 } 205 206 @Override 207 public short getShort(final int i) { 208 return (short) getInt(i); 209 } 210 211 @Override 212 public short getShort(final int i, final int j) { 213 return (short) getInt(i, j); 214 } 215 216 @Override 217 public short getShort(final int... pos) { 218 return (short) getInt(pos); 219 } 220 221 @Override 222 public byte getByte() { 223 return (byte) getInt(); 224 } 225 226 @Override 227 public byte getByte(final int i) { 228 return (byte) getInt(i); 229 } 230 231 @Override 232 public byte getByte(final int i, final int j) { 233 return (byte) getInt(i, j); 234 } 235 236 @Override 237 public byte getByte(final int... pos) { 238 return (byte) getInt(pos); 239 } 240 241 @Override 242 public boolean getBoolean() { 243 return get(); 244 } 245 246 @Override 247 public boolean getBoolean(final int i) { 248 return get(i); 249 } 250 251 @Override 252 public boolean getBoolean(final int i, final int j) { 253 return get(i, j); 254 } 255 256 @Override 257 public boolean getBoolean(final int... pos) { 258 return get(pos); 259 } 260 261 @Override 262 public String getStringAbs(final int index) { 263 return stringFormat instanceof MessageFormat ? stringFormat.format(data[index]) : 264 String.format("%b", data[index]); 265 } 266 267 @Override 268 public BooleanDataset getSlice(SliceIterator siter) { 269 BooleanDatasetBase base = super.getSlice(siter); 270 271 BooleanDataset slice = new BooleanDataset(); 272 copyToView(base, slice, false, false); 273 slice.setData(); 274 return slice; 275 } 276 277 /** 278 * OR 279 */ 280 @Override 281 public BooleanDataset iadd(final Object b) { 282 Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); 283 final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); 284 while (it.hasNext()) { 285 data[it.aIndex] |= bds.getElementBooleanAbs(it.bIndex); 286 } 287 setDirty(); 288 return this; 289 } 290 291 /** 292 * XOR 293 */ 294 @Override 295 public BooleanDataset isubtract(final Object b) { 296 Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); 297 final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); 298 while (it.hasNext()) { 299 data[it.aIndex] ^= bds.getElementBooleanAbs(it.bIndex); 300 } 301 setDirty(); 302 return this; 303 } 304 305 /** 306 * AND 307 */ 308 @Override 309 public BooleanDataset imultiply(final Object b) { 310 Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); 311 final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); 312 while (it.hasNext()) { 313 data[it.aIndex] &= bds.getElementBooleanAbs(it.bIndex); 314 } 315 setDirty(); 316 return this; 317 } 318 319 @Override 320 public BooleanDataset idivide(final Object b) { 321 return imultiply(b); 322 } 323 324 @Override 325 public BooleanDataset iremainder(final Object b) { 326 logger.error("Unsupported method for class"); 327 throw new UnsupportedOperationException("Unsupported method for class"); 328 } 329 330 @Override 331 public BooleanDataset ipower(final Object b) { 332 logger.error("Unsupported method for class"); 333 throw new UnsupportedOperationException("Unsupported method for class"); 334 } 335 336 @Override 337 public double residual(final Object b, final Dataset w, boolean ignoreNaNs) { 338 Dataset bds = b instanceof Dataset ? (Dataset) b : DatasetFactory.createFromObject(b); 339 final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(this, bds); 340 double sum = 0; 341 { 342 if (w == null) { 343 while (it.hasNext()) { 344 if (data[it.aIndex] ^ bds.getElementBooleanAbs(it.bIndex)) 345 sum++; 346 } 347 } else { 348 IndexIterator itw = w.getIterator(); 349 double comp = 0; 350 while (it.hasNext() && itw.hasNext()) { 351 if (data[it.aIndex] ^ bds.getElementBooleanAbs(it.bIndex)) { 352 final double err = w.getElementDoubleAbs(itw.index) - comp; 353 final double temp = sum + err; 354 comp = (temp - sum) - err; 355 sum = temp; 356 } 357 } 358 } 359 } 360 return sum; 361 } 362}