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.util.Date; 016import java.util.List; 017 018public class DatasetFactory { 019 020 /** 021 * Create dataset with items ranging from 0 up to given stop in steps of 1 022 * @param stop stop value is <strong>not</strong> included 023 * @param dtype dataset type 024 * @return a new dataset of given shape and type, filled with values determined by parameters 025 * 026 * @deprecated Please use the class-based methods in DatasetFactory, 027 * such as {@link #createRange(Class, double)} 028 */ 029 @Deprecated 030 public static Dataset createRange(final double stop, final int dtype) { 031 return createRange(0, stop, 1, dtype); 032 } 033 034 /** 035 * Create dataset with items ranging from given start up to given stop in given steps 036 * @param start start value start value 037 * @param stop stop value is <strong>not</strong> included 038 * @param step spacing between items 039 * @param dtype dataset type 040 * @return a new 1D dataset of given type, filled with values determined by parameters 041 * 042 * @deprecated Please use the class-based methods in DatasetFactory, 043 * such as {@link #createRange(Class, double, double, double)} 044 */ 045 @Deprecated 046 public static Dataset createRange(final double start, final double stop, final double step, final int dtype) { 047 return createRange(DTypeUtils.getInterface(dtype), start, stop, step); 048 } 049 050 /** 051 * Create compound dataset with items of given size ranging from 0 up to given stop in steps of 1 052 * @param itemSize item size 053 * @param stop stop value is <strong>not</strong> included 054 * @param dtype dataset type 055 * @return a new dataset of given shape and type, filled with values determined by parameters 056 * 057 * @deprecated Please use the class-based methods in DatasetFactory, 058 * such as {@link #createRange(int, Class, double)} 059 */ 060 @Deprecated 061 public static CompoundDataset createRange(final int itemSize, final double stop, final int dtype) { 062 return createRange(itemSize, 0, stop, 1, dtype); 063 } 064 065 /** 066 * Create compound dataset with items of given size ranging from given start up to given stop in given steps 067 * @param itemSize item size 068 * @param start start value 069 * @param stop stop value is <strong>not</strong> included 070 * @param step spacing between items 071 * @param dtype dataset type 072 * @return a new 1D dataset of given type, filled with values determined by parameters 073 * 074 * @deprecated Please use the class-based methods in DatasetFactory, 075 * such as {@link #createRange(int, Class, double, double, double)} 076 */ 077 @Deprecated 078 public static CompoundDataset createRange(final int itemSize, final double start, final double stop, final double step, final int dtype) { 079 Class<? extends CompoundDataset> clazz = InterfaceUtils.getCompoundInterface(DTypeUtils.getInterface(dtype)); 080 return createRange(itemSize, clazz, start, stop, step); 081 } 082 083 /** 084 * Create a dataset from object 085 * @param dtype dataset type 086 * @param obj 087 * can be a Java list, array or Number 088 * @return dataset 089 * @throws IllegalArgumentException if dataset type is not known 090 * 091 * @deprecated Please use the class-based methods in DatasetFactory, 092 * such as {@link #createFromObject(Class, Object, int...)} 093 */ 094 @Deprecated 095 public static Dataset createFromObject(final int dtype, final Object obj) { 096 return createFromObject(dtype, obj, null); 097 } 098 099 /** 100 * Create a dataset from object 101 * @param dtype dataset type 102 * @param obj 103 * can be a Java list, array or Number 104 * @param shape can be null 105 * @return dataset 106 * @throws IllegalArgumentException if dataset type is not known 107 * 108 * @deprecated Please use the class-based methods in DatasetFactory, 109 * such as {@link #createFromObject(Class, Object, int...)} 110 */ 111 @Deprecated 112 public static Dataset createFromObject(final int dtype, final Object obj, final int... shape) { 113 return createFromObject(1, dtype, obj, shape); 114 } 115 116 /** 117 * Create a dataset from object 118 * @param itemSize item size 119 * @param dtype dataset type 120 * @param obj 121 * can be a Java list, array or Number 122 * @param shape can be null 123 * @return dataset 124 * @throws IllegalArgumentException if dataset type is not known 125 * 126 * @deprecated Please use the class-based methods in DatasetFactory, 127 * such as {@link #createFromObject(int, Class, Object, int...)} 128 */ 129 @Deprecated 130 public static Dataset createFromObject(final int itemSize, final int dtype, final Object obj, final int... shape) { 131 return createFromObject(itemSize, DTypeUtils.getInterface(dtype), obj, shape); 132 } 133 134 /** 135 * Create dataset of given type from list 136 * 137 * @param dtype dataset type 138 * @param objectList inputs 139 * @return dataset filled with values from list 140 * 141 * @deprecated Please use the class-based methods in DatasetFactory, 142 * such as {@link #createFromList(Class, List)} 143 */ 144 @Deprecated 145 public static Dataset createFromList(final int dtype, List<?> objectList) { 146 return createFromList(DTypeUtils.getInterface(dtype), objectList); 147 } 148 149 /** 150 * Create compound dataset of given type from given parts 151 * 152 * @param dtype dataset type 153 * @param objects inputs 154 * @return compound dataset 155 * 156 * @deprecated Please use the class-based methods in DatasetFactory, 157 * such as {@link #createCompoundDataset(Class, Object...)} 158 */ 159 @Deprecated 160 public static CompoundDataset createCompoundDataset(final int dtype, Object... objects) { 161 return (CompoundDataset) createCompoundDataset(DTypeUtils.getInterface(dtype), objects); 162 } 163 164 /** 165 * Create complex dataset of given type from real and imaginary parts 166 * 167 * @param dtype dataset type 168 * @param real real part 169 * @param imag imaginary part 170 * @return complex dataset 171 * 172 * @deprecated Please use the class-based methods in DatasetFactory, 173 * such as {@link #createComplexDataset(Class, Object, Object)} 174 */ 175 @Deprecated 176 public static CompoundDataset createComplexDataset(final int dtype, Object real, Object imag) { 177 return createComplexDataset(DTypeUtils.getInterface(dtype), real, imag); 178 } 179 180 /** 181 * @param shape output shape 182 * @param dtype dataset type 183 * @return a new dataset of given shape and type, filled with zeros 184 * 185 * @deprecated Please use the class-based methods in DatasetFactory, 186 * such as {@link #zeros(Class, int...)} 187 */ 188 @Deprecated 189 public static Dataset zeros(final int[] shape, final int dtype) { 190 return zeros(DTypeUtils.getInterface(dtype), shape); 191 } 192 193 /** 194 * @param itemSize item size 195 * if equal to 1, then non-compound dataset is returned 196 * @param shape output shape 197 * @param dtype dataset type 198 * @return a new dataset of given item size, shape and type, filled with zeros 199 * 200 * @deprecated Please use the class-based methods in DatasetFactory, 201 * such as {@link #zeros(int, Class, int...)} 202 */ 203 @Deprecated 204 public static Dataset zeros(final int itemSize, final int[] shape, final int dtype) { 205 if (itemSize == 1) { 206 return zeros(shape, dtype); 207 } 208 return compoundZeros(itemSize, shape, dtype); 209 } 210 211 /** 212 * @param itemSize item size 213 * @param shape output shape 214 * @param dtype dataset type 215 * @return a new dataset of given item size, shape and type, filled with zeros 216 * @since 2.0 217 * 218 * @deprecated Please use the class-based methods in DatasetFactory, 219 * such as {@link #compoundZeros(int, Class, int...)} 220 */ 221 @Deprecated 222 public static CompoundDataset compoundZeros(final int itemSize, final int[] shape, final int dtype) { 223 return compoundZeros(itemSize, InterfaceUtils.getCompoundInterface(DTypeUtils.getInterface(dtype)), shape); 224 } 225 226 /** 227 * Create a new dataset of same shape as input dataset, filled with zeros. If dtype is not 228 * explicitly compound then an elemental dataset is created 229 * @param dataset input 230 * @param dtype dataset type 231 * @return a new dataset 232 * 233 * @deprecated Please use the class-based methods in DatasetFactory, 234 * such as {@link #zeros(Dataset, Class)} 235 */ 236 @Deprecated 237 public static Dataset zeros(final Dataset dataset, final int dtype) { 238 Class<? extends Dataset> clazz = DTypeUtils.getInterface(dtype); 239 final int isize = InterfaceUtils.isElemental(clazz) ? 1 :dataset.getElementsPerItem(); 240 241 return zeros(isize, clazz, dataset.getShapeRef()); 242 } 243 244 /** 245 * Create a new dataset of same shape as input dataset, filled with ones. If dtype is not 246 * explicitly compound then an elemental dataset is created 247 * @param dataset input 248 * @param dtype dataset type 249 * @return a new dataset 250 * 251 * @deprecated Please use the class-based methods in DatasetFactory, 252 * such as {@link #ones(Dataset, Class)} 253 */ 254 @Deprecated 255 public static Dataset ones(final Dataset dataset, final int dtype) { 256 Class<? extends Dataset> clazz = DTypeUtils.getInterface(dtype); 257 final int isize = InterfaceUtils.isElemental(clazz) ? 1 :dataset.getElementsPerItem(); 258 259 return ones(isize, clazz, dataset.getShapeRef()); 260 } 261 262 /** 263 * @param shape output shape 264 * @param dtype dataset type 265 * @return a new dataset of given shape and type, filled with ones 266 * 267 * @deprecated Please use the class-based methods in DatasetFactory, 268 * such as {@link #ones(Class, int...)} 269 */ 270 @Deprecated 271 public static Dataset ones(final int[] shape, final int dtype) { 272 return ones(DTypeUtils.getInterface(dtype), shape); 273 } 274 275 /** 276 * @param itemSize item size 277 * if equal to 1, then non-compound dataset is returned 278 * @param shape output shape 279 * @param dtype dataset type 280 * @return a new dataset of given item size, shape and type, filled with ones 281 * 282 * @deprecated Please use the class-based methods in DatasetFactory, 283 * such as {@link #ones(Class, int...)} 284 */ 285 @Deprecated 286 public static Dataset ones(final int itemSize, final int[] shape, final int dtype) { 287 return ones(itemSize, DTypeUtils.getInterface(dtype), shape); 288 } 289 290 /** 291 * Create a 1D dataset of linearly spaced values in closed interval 292 * 293 * @param start start value 294 * @param stop stop value is included 295 * @param length number of points 296 * @param dtype dataset type 297 * @return dataset with linearly spaced values 298 * 299 * @deprecated Please use the class-based methods in DatasetFactory, 300 * such as {@link #createLinearSpace(Class, double, double, int)} 301 */ 302 @Deprecated 303 public static Dataset createLinearSpace(final double start, final double stop, final int length, final int dtype) { 304 return createLinearSpace(DTypeUtils.getInterface(dtype), start, stop, length); 305 } 306 307 /** 308 * Create a 1D dataset of logarithmically spaced values in closed interval. The base value is used to 309 * determine the factor between values: factor = base ** step, where step is the interval between linearly 310 * spaced sequence of points 311 * 312 * @param start start value 313 * @param stop stop value is included 314 * @param length number of points 315 * @param base for exponentiation 316 * @param dtype dataset type 317 * @return dataset with logarithmically spaced values 318 * 319 * @deprecated Please use the class-based methods in DatasetFactory, 320 * such as {@link #createLogSpace(Class, double, double, int, double)} 321 */ 322 @Deprecated 323 public static Dataset createLogSpace(final double start, final double stop, final int length, final double base, final int dtype) { 324 return createLogSpace(DTypeUtils.getInterface(dtype), start, stop, length, base); 325 } 326 327 /** 328 * Create a 1D dataset of linearly spaced values in closed interval 329 * 330 * @param <T> dataset sub-interface 331 * @param clazz dataset sub-interface 332 * @param start start value 333 * @param stop stop value is included 334 * @param length number of points 335 * @return dataset with linearly spaced values 336 */ 337 public static <T extends Dataset> T createLinearSpace(Class<T> clazz, final double start, final double stop, final int length) { 338 if (length < 1) { 339 throw new IllegalArgumentException("Length is less than one"); 340 } else if (length == 1) { 341 return createFromObject(clazz, start); 342 } else { 343 T ds = zeros(clazz, length); 344 double num = stop - start; 345 double den = length - 1; 346 double value; 347 348 for (int i = 0; i < length; i++) { 349 value = start + (num * i) / den; 350 ds.setObjectAbs(i, value); 351 } 352 353 return ds; 354 } 355 } 356 357 /** 358 * Create a 1D dataset of logarithmically spaced values in closed interval. The base value is used to 359 * determine the factor between values: factor = base ** step, where step is the interval between linearly 360 * spaced sequence of points 361 * 362 * @param <T> dataset sub-interface 363 * @param clazz dataset sub-interface 364 * @param start start value 365 * @param stop stop value is included 366 * @param length number of points 367 * @param base for exponentiation 368 * @return dataset with logarithmically spaced values 369 */ 370 public static <T extends Dataset> T createLogSpace(Class<T> clazz, final double start, final double stop, final int length, final double base) { 371 if (length < 1) { 372 throw new IllegalArgumentException("Length is less than one"); 373 } else if (length == 1) { 374 return createFromObject(clazz, Math.pow(base, start)); 375 } else { 376 T ds = zeros(clazz, length); 377 double step = (stop - start) / (length - 1); 378 double value; 379 380 for (int i = 0; i < length; i++) { 381 value = start + i * step; 382 ds.setObjectAbs(i, Math.pow(base, value)); 383 } 384 385 return ds; 386 } 387 } 388 389 /** 390 * Create dataset with items ranging from 0 up to given stop in steps of 1 391 * @param stop stop value is <strong>not</strong> included 392 * @return a new double dataset of given shape and type, filled with values determined by parameters 393 */ 394 public static DoubleDataset createRange(final double stop) { 395 return createRange(DoubleDataset.class, 0, stop, 1); 396 } 397 398 /** 399 * Create dataset with items ranging from given start up to given stop in given steps 400 * @param start start value 401 * @param stop stop value is <strong>not</strong> included 402 * @param step spacing between items 403 * @return a new 1D dataset of given type, filled with values determined by parameters 404 * @since 2.1 405 */ 406 public static DoubleDataset createRange(final double start, final double stop, final double step) { 407 return createRange(DoubleDataset.class, start, stop, step); 408 } 409 410 /** 411 * Create dataset with items ranging from 0 up to given stop in steps of 1 412 * @param <T> dataset sub-interface 413 * @param clazz dataset sub-interface 414 * @param stop stop value is <strong>not</strong> included 415 * @return a new dataset of given shape and class, filled with values determined by parameters 416 */ 417 public static <T extends Dataset> T createRange(Class<T> clazz, final double stop) { 418 return createRange(clazz, 0, stop, 1); 419 } 420 421 /** 422 * Create dataset with items ranging from given start up to given stop in given steps 423 * @param <T> dataset sub-interface 424 * @param clazz dataset sub-interface 425 * @param start start value 426 * @param stop stop value is <strong>not</strong> included 427 * @param step spacing between items 428 * @return a new 1D dataset of given class, filled with values determined by parameters 429 */ 430 @SuppressWarnings("unchecked") 431 public static <T extends Dataset> T createRange(Class<T> clazz, final double start, final double stop, final double step) { 432 if ((step > 0) != (start <= stop)) { 433 throw new IllegalArgumentException("Invalid parameters: start and stop must be in correct order for step"); 434 } 435 436 Dataset d = null; 437 if (ByteDataset.class.isAssignableFrom(clazz)) { 438 d = ByteDataset.createRange(start, stop, step); 439 } else if (ShortDataset.class.isAssignableFrom(clazz)) { 440 d = ShortDataset.createRange(start, stop, step); 441 } else if (IntegerDataset.class.isAssignableFrom(clazz)) { 442 d = IntegerDataset.createRange(start, stop, step); 443 } else if (LongDataset.class.isAssignableFrom(clazz)) { 444 d = LongDataset.createRange(start, stop, step); 445 } else if (FloatDataset.class.isAssignableFrom(clazz)) { 446 d = FloatDataset.createRange(start, stop, step); 447 } else if (DoubleDataset.class.isAssignableFrom(clazz)) { 448 d = DoubleDataset.createRange(start, stop, step); 449 } else if (ComplexFloatDataset.class.isAssignableFrom(clazz)) { 450 d = ComplexFloatDataset.createRange(start, stop, step); 451 } else if (ComplexDoubleDataset.class.isAssignableFrom(clazz)) { 452 d = ComplexDoubleDataset.createRange(start, stop, step); 453 } else { 454 throw new IllegalArgumentException("Dataset interface not supported"); 455 } 456 457 return (T) d; 458 } 459 460 /** 461 * Create compound dataset with items ranging from 0 up to given stop in steps of 1 462 * @param <T> compound dataset sub-interface 463 * @param itemSize item size 464 * @param clazz compound dataset sub-interface 465 * @param stop stop value is <strong>not</strong> included 466 * @return a new 1D dataset of given class, filled with values determined by parameters 467 * @since 2.1 468 */ 469 public static <T extends CompoundDataset> T createRange(final int itemSize, Class<T> clazz, final double stop) { 470 return createRange(itemSize, clazz, 0, stop, 1); 471 } 472 473 /** 474 * Create compound dataset with items ranging from given start up to given stop in given steps 475 * @param <T> compound dataset sub-interface 476 * @param itemSize item size 477 * @param clazz compound dataset sub-interface 478 * @param start start value 479 * @param stop stop value is <strong>not</strong> included 480 * @param step spacing between items 481 * @return a new 1D dataset of given class, filled with values determined by parameters 482 * @since 2.1 483 */ 484 @SuppressWarnings("unchecked") 485 public static <T extends CompoundDataset> T createRange(final int itemSize, Class<T> clazz, final double start, final double stop, final double step) { 486 if (itemSize < 1) { 487 throw new IllegalArgumentException("Item size must be greater or equal to 1"); 488 } 489 if ((step > 0) != (start <= stop)) { 490 throw new IllegalArgumentException("Invalid parameters: start and stop must be in correct order for step"); 491 } 492 493 CompoundDataset c = null; 494 if (CompoundByteDataset.class.isAssignableFrom(clazz)) { 495 c = CompoundIntegerDataset.createRange(itemSize, start, stop, step); 496 } else if (CompoundShortDataset.class.isAssignableFrom(clazz)) { 497 c = CompoundShortDataset.createRange(itemSize, start, stop, step); 498 } else if (CompoundIntegerDataset.class.isAssignableFrom(clazz)) { 499 c = CompoundIntegerDataset.createRange(itemSize, start, stop, step); 500 } else if (CompoundLongDataset.class.isAssignableFrom(clazz)) { 501 c = CompoundLongDataset.createRange(itemSize, start, stop, step); 502 } else if (ComplexFloatDataset.class.isAssignableFrom(clazz)) { 503 if (itemSize != 2) { 504 throw new IllegalArgumentException("Item size must be equal to 2"); 505 } 506 c = ComplexFloatDataset.createRange(start, stop, step); 507 } else if (ComplexDoubleDataset.class.isAssignableFrom(clazz)) { 508 if (itemSize != 2) { 509 throw new IllegalArgumentException("Item size must be equal to 2"); 510 } 511 c = ComplexDoubleDataset.createRange(start, stop, step); 512 } else if (CompoundFloatDataset.class.isAssignableFrom(clazz)) { 513 c = CompoundFloatDataset.createRange(itemSize, start, stop, step); 514 } else if (CompoundDoubleDataset.class.isAssignableFrom(clazz)) { 515 c = CompoundDoubleDataset.createRange(itemSize, start, stop, step); 516 } else { 517 throw new IllegalArgumentException("dtype not known"); 518 } 519 return (T) c; 520 } 521 522 /** 523 * Create a dataset from object (automatically detect dataset type) 524 * 525 * @param obj 526 * can be Java list, array or Number 527 * @return dataset 528 */ 529 public static Dataset createFromObject(Object obj) { 530 return createFromObject(obj, null); 531 } 532 533 /** 534 * Create a dataset from object (automatically detect dataset type) 535 * 536 * @param obj 537 * can be Java list, array or Number 538 * @param shape can be null 539 * @return dataset 540 */ 541 public static Dataset createFromObject(Object obj, int... shape) { 542 if (obj instanceof IDataset) { 543 Dataset d = DatasetUtils.convertToDataset((IDataset) obj); 544 if (shape != null) { 545 d.setShape(shape); 546 } 547 return d; 548 } 549 550 return createFromObject(InterfaceUtils.getInterface(obj), obj, shape); 551 } 552 553 /** 554 * Create a dataset from object (automatically detect dataset type) 555 * @param isUnsigned 556 * if true, interpret integer values as unsigned by increasing element bit width if required 557 * @param obj 558 * can be a Java list, array or Number 559 * @return dataset 560 */ 561 public static Dataset createFromObject(boolean isUnsigned, final Object obj) { 562 Dataset a = createFromObject(obj); 563 if (isUnsigned) { 564 a = DatasetUtils.makeUnsigned(a, true); 565 } 566 return a; 567 } 568 569 /** 570 * Create dataset of appropriate type from list 571 * 572 * @param objectList inputs for each item 573 * @return dataset filled with values from list 574 */ 575 public static Dataset createFromList(List<?> objectList) { 576 if (objectList == null || objectList.size() == 0) { 577 throw new IllegalArgumentException("No list or zero-length list given"); 578 } 579 580 Object obj = null; 581 for (Object o : objectList) { 582 if (o != null) { 583 obj = o; 584 break; 585 } 586 } 587 if (obj == null) { 588 return zeros(ObjectDataset.class, objectList.size()); 589 } 590 591 Class<? extends Object> clazz = obj.getClass(); 592 if (InterfaceUtils.isElementSupported(clazz)) { 593 return createFromList(InterfaceUtils.getInterface(obj), objectList); 594 } 595 596 return createFromObject(objectList); 597 } 598 599 /** 600 * Create compound dataset of given type from given parts 601 * 602 * @param objects inputs across dataset for each element 603 * @return compound dataset 604 */ 605 public static CompoundDataset createCompoundDataset(Object... objects) { 606 Dataset[] datasets = new Dataset[objects.length]; 607 for (int i = 0; i < objects.length; i++) { 608 datasets[i] = createFromObject(objects[i]); 609 } 610 return DatasetUtils.createCompoundDataset(datasets); 611 } 612 613 /** 614 * Create a dataset from object 615 * @param <T> dataset sub-interface 616 * @param clazz dataset sub-interface 617 * @param obj 618 * can be a Java list, array or Number 619 * @return dataset 620 * @throws IllegalArgumentException if dataset class is not known 621 * @since 2.1 622 */ 623 public static <T extends Dataset> T createFromObject(Class<T> clazz, Object obj) { 624 return createFromObject(1, clazz, obj, null); 625 } 626 627 628 /** 629 * Create a dataset from object 630 * @param <T> dataset sub-interface 631 * @param clazz dataset sub-interface 632 * @param obj 633 * can be a Java list, array or Number 634 * @param shape can be null 635 * @return dataset 636 */ 637 public static <T extends Dataset> T createFromObject(Class<T> clazz, Object obj, int... shape) { 638 return createFromObject(1, clazz, obj, shape); 639 } 640 641 /** 642 * Create a compound dataset from object 643 * @param <T> compound dataset sub-interface 644 * @param itemSize item size 645 * @param clazz compound dataset sub-interface 646 * @param obj 647 * can be a Java list, array or Number 648 * @param shape can be null 649 * @return dataset 650 */ 651 @SuppressWarnings("unchecked") 652 public static <T extends Dataset> T createFromObject(final int itemSize, Class<T> clazz, Object obj, int... shape) { 653 Dataset d = null; 654 655 if (obj instanceof IDataset) { 656 d = itemSize == 1 ? DatasetUtils.cast(clazz, (IDataset) obj) : 657 DatasetUtils.cast(itemSize, clazz, (IDataset) obj, false); 658 } else { 659 // primitive arrays 660 Class<? extends Object> ca = obj == null ? null : obj.getClass().getComponentType(); 661 if (ca != null && (ca.isPrimitive() || ca.equals(String.class))) { 662 if (ComplexFloatDataset.class.isAssignableFrom(clazz)) { 663 return (T) new ComplexFloatDataset(DTypeUtils.toFloatArray(obj, DTypeUtils.getLength(obj)), shape); 664 } else if (ComplexDoubleDataset.class.isAssignableFrom(clazz)) { 665 return (T) new ComplexDoubleDataset(DTypeUtils.toDoubleArray(obj, DTypeUtils.getLength(obj)), shape); 666 } else { 667 d = createFromPrimitiveArray(InterfaceUtils.getInterfaceFromClass(1, ca), obj); 668 if (!InterfaceUtils.isElemental(clazz)) { 669 if (RGBByteDataset.class.isAssignableFrom(clazz) || RGBDataset.class.isAssignableFrom(clazz)) { 670 d = DatasetUtils.createCompoundDataset(d, 3); 671 if (d.getSize() == 1) { // special case of allowing a zero-rank RGB dataset 672 d.setShape(); 673 } 674 } else { 675 d = DatasetUtils.createCompoundDataset(d, itemSize); 676 } 677 } 678 d = d.cast(clazz); 679 } 680 } else { 681// if (itemSize != 1 && !InterfaceUtils.isElemental(clazz)) { 682// throw new IllegalArgumentException("Compound dataset interface needed for itemSize > 1"); 683// } 684 if (BooleanDataset.class.isAssignableFrom(clazz)) { 685 d = BooleanDataset.createFromObject(obj); 686 } else if (ByteDataset.class.isAssignableFrom(clazz)) { 687 d = ByteDataset.createFromObject(obj); 688 } else if (ShortDataset.class.isAssignableFrom(clazz)) { 689 d = ShortDataset.createFromObject(obj); 690 } else if (IntegerDataset.class.isAssignableFrom(clazz)) { 691 d = IntegerDataset.createFromObject(obj); 692 } else if (LongDataset.class.isAssignableFrom(clazz)) { 693 d = LongDataset.createFromObject(obj); 694 } else if (RGBByteDataset.class.isAssignableFrom(clazz)) { 695 d = RGBByteDataset.createFromObject(obj); 696 } else if (CompoundByteDataset.class.isAssignableFrom(clazz)) { 697 d = CompoundByteDataset.createFromObject(itemSize, obj); 698 } else if (RGBDataset.class.isAssignableFrom(clazz)) { 699 d = RGBDataset.createFromObject(obj); 700 } else if (CompoundShortDataset.class.isAssignableFrom(clazz)) { 701 d = CompoundShortDataset.createFromObject(itemSize, obj); 702 } else if (CompoundIntegerDataset.class.isAssignableFrom(clazz)) { 703 d = CompoundIntegerDataset.createFromObject(itemSize, obj); 704 } else if (CompoundLongDataset.class.isAssignableFrom(clazz)) { 705 d = CompoundLongDataset.createFromObject(itemSize, obj); 706 } else if (FloatDataset.class.isAssignableFrom(clazz)) { 707 d = FloatDataset.createFromObject(obj); 708 } else if (DoubleDataset.class.isAssignableFrom(clazz)) { 709 d = DoubleDataset.createFromObject(obj); 710 } else if (ComplexFloatDataset.class.isAssignableFrom(clazz)) { 711 d = ComplexFloatDataset.createFromObject(obj); 712 } else if (ComplexDoubleDataset.class.isAssignableFrom(clazz)) { 713 d = ComplexDoubleDataset.createFromObject(obj); 714 } else if (CompoundFloatDataset.class.isAssignableFrom(clazz)) { 715 d = CompoundFloatDataset.createFromObject(itemSize, obj); 716 } else if (CompoundDoubleDataset.class.isAssignableFrom(clazz)) { 717 d = CompoundDoubleDataset.createFromObject(itemSize, obj); 718 } else if (DateDataset.class.isAssignableFrom(clazz)) { 719 d = DateDatasetImpl.createFromObject(obj); 720 } else if (StringDataset.class.isAssignableFrom(clazz)) { 721 d = StringDataset.createFromObject(obj); 722 } else if (ObjectDataset.class.isAssignableFrom(clazz)) { 723 d = ObjectDataset.createFromObject(obj); 724 } else { 725 throw new IllegalArgumentException("Dataset interface is not unsupported"); 726 } 727 } 728 } 729 730 if (shape != null && !(shape.length == 0 && d.getSize() > 1)) { // allow zero-rank datasets 731 d.setShape(shape); 732 } 733 return (T) d; 734 } 735 736 private static Dataset createFromPrimitiveArray(Class<? extends Dataset> clazz, final Object array) { 737 if (BooleanDataset.class.isAssignableFrom(clazz)) { 738 return new BooleanDataset((boolean[]) array); 739 } else if (ByteDataset.class.isAssignableFrom(clazz)) { 740 return new ByteDataset((byte[]) array); 741 } else if (ShortDataset.class.isAssignableFrom(clazz)) { 742 return new ShortDataset((short[]) array); 743 } else if (IntegerDataset.class.isAssignableFrom(clazz)) { 744 return new IntegerDataset((int[]) array, null); 745 } else if (LongDataset.class.isAssignableFrom(clazz)) { 746 return new LongDataset((long[]) array); 747 } else if (FloatDataset.class.isAssignableFrom(clazz)) { 748 return new FloatDataset((float[]) array); 749 } else if (DoubleDataset.class.isAssignableFrom(clazz)) { 750 return new DoubleDataset((double[]) array); 751 } else if (StringDataset.class.isAssignableFrom(clazz)) { 752 return new StringDataset((String[]) array); 753 } else if (DateDataset.class.isAssignableFrom(clazz)) { 754 return new DateDatasetImpl((Date[]) array); 755 } 756 return null; 757 } 758 759 /** 760 * Create dataset of given class from list 761 * 762 * @param <T> dataset sub-interface 763 * @param clazz dataset sub-interface 764 * @param objectList inputs for each item 765 * @return dataset filled with values from list 766 */ 767 public static <T extends Dataset> T createFromList(Class<T> clazz, List<?> objectList) { 768 int len = objectList.size(); 769 T result = zeros(clazz, len); 770 771 for (int i = 0; i < len; i++) { 772 result.setObjectAbs(i, objectList.get(i)); 773 } 774 return result; 775 } 776 777 /** 778 * Create compound dataset of given class from given parts 779 * 780 * @param <T> compound dataset sub-interface 781 * @param clazz compound dataset sub-interface 782 * @param objects inputs across dataset for each element 783 * @return compound dataset 784 * @since 2.3 785 */ 786 public static <T extends CompoundDataset> T createCompoundDataset(Class<T> clazz, Object... objects) { 787 Dataset[] datasets = new Dataset[objects.length]; 788 for (int i = 0; i < objects.length; i++) { 789 datasets[i] = createFromObject(objects[i]); 790 } 791 return DatasetUtils.createCompoundDataset(clazz, datasets); 792 } 793 794 /** 795 * Create complex dataset of given class from real and imaginary parts 796 * 797 * @param <T> complex dataset sub-interface 798 * @param clazz complex dataset sub-interface 799 * @param real real part 800 * @param imag imaginary part 801 * @return complex dataset 802 * @since 2.3 803 */ 804 @SuppressWarnings("unchecked") 805 public static <T extends CompoundDataset> T createComplexDataset(Class<? extends Dataset> clazz, Object real, Object imag) { 806 if (ComplexFloatDataset.class.isAssignableFrom(clazz)) { 807 return (T) new ComplexFloatDataset(createFromObject(real), createFromObject(imag)); 808 } else if (ComplexDoubleDataset.class.isAssignableFrom(clazz)) { 809 return (T) new ComplexDoubleDataset(createFromObject(real), createFromObject(imag)); 810 } else { 811 throw new IllegalArgumentException("Dataset class must be a complex one"); 812 } 813 } 814 815 /** 816 * @param shape output shape 817 * @return a new double dataset of given shape, filled with zeros 818 */ 819 public static DoubleDataset zeros(final int... shape) { 820 return zeros(DoubleDataset.class, shape); 821 } 822 823 /** 824 * @param <T> dataset subclass 825 * @param dataset input 826 * @return a new dataset of same shape and class as input dataset, filled with zeros 827 */ 828 public static <T extends Dataset> T zeros(final T dataset) { 829 return zeros(dataset, dataset.getShapeRef()); 830 } 831 832 /** 833 * @param <T> dataset subclass 834 * @param dataset input 835 * @param shape output shape 836 * @return a new dataset of same class as input dataset and given shape, filled with zeros 837 * @since 2.3 838 */ 839 @SuppressWarnings("unchecked") 840 public static <T extends Dataset> T zeros(final T dataset, int... shape) { 841 Class<? extends Dataset> clazz = dataset.getClass(); 842 return (T) (InterfaceUtils.isElemental(dataset.getClass()) ? zeros(clazz, shape) : 843 compoundZeros(dataset.getElementsPerItem(), InterfaceUtils.getCompoundInterface(clazz), shape)); 844 } 845 846 /** 847 * @param <T> dataset sub-interface 848 * @param clazz dataset sub-interface 849 * @param shape output shape 850 * @return a new dataset of given shape and class, filled with zeros 851 */ 852 @SuppressWarnings("unchecked") 853 public static <T extends Dataset> T zeros(Class<T> clazz, int... shape) { 854 if (BooleanDataset.class.isAssignableFrom(clazz)) { 855 return (T) new BooleanDataset(shape); 856 } else if (ByteDataset.class.isAssignableFrom(clazz)) { 857 return (T) new ByteDataset(shape); 858 } else if (ShortDataset.class.isAssignableFrom(clazz)) { 859 return (T) new ShortDataset(shape); 860 } else if (IntegerDataset.class.isAssignableFrom(clazz)) { 861 return (T) new IntegerDataset(shape); 862 } else if (LongDataset.class.isAssignableFrom(clazz)) { 863 return (T) new LongDataset(shape); 864 } else if (FloatDataset.class.isAssignableFrom(clazz)) { 865 return (T) new FloatDataset(shape); 866 } else if (DoubleDataset.class.isAssignableFrom(clazz)) { 867 return (T) new DoubleDataset(shape); 868 } else if (RGBByteDataset.class.isAssignableFrom(clazz)) { 869 return (T) new RGBByteDataset(shape); 870 } else if (RGBDataset.class.isAssignableFrom(clazz)) { 871 return (T) new RGBDataset(shape); 872 } else if (ComplexFloatDataset.class.isAssignableFrom(clazz)) { 873 return (T) new ComplexFloatDataset(shape); 874 } else if (ComplexDoubleDataset.class.isAssignableFrom(clazz)) { 875 return (T) new ComplexDoubleDataset(shape); 876 } else if (StringDataset.class.isAssignableFrom(clazz)) { 877 return (T) new StringDataset(shape); 878 } else if (DateDataset.class.isAssignableFrom(clazz)) { 879 return (T) new DateDatasetImpl(shape); 880 } else if (ObjectDataset.class.isAssignableFrom(clazz)) { 881 return (T) new ObjectDataset(shape); 882 } 883 884 throw new IllegalArgumentException("Interface not known or unsupported"); 885 } 886 887 /** 888 * @param <T> dataset sub-interface 889 * @param itemSize item size. If equal to 1, then non-compound dataset is returned 890 * @param clazz dataset sub-interface 891 * @param shape output shape 892 * @return a new dataset of given item size, shape and class, filled with zeros 893 */ 894 @SuppressWarnings("unchecked") 895 public static <T extends Dataset> T zeros(int itemSize, Class<T> clazz, int... shape) { 896 if (itemSize == 1 && InterfaceUtils.isElemental(clazz)) { 897 return zeros(clazz, shape); 898 } 899 return (T) compoundZeros(itemSize, InterfaceUtils.getCompoundInterface(clazz), shape); 900 } 901 902 /** 903 * @param <T> dataset subclass 904 * @param dataset input 905 * @param clazz dataset class 906 * @return a new dataset of given class with same shape as input dataset, filled with zeros 907 */ 908 public static <T extends Dataset> T zeros(Dataset dataset, Class<T> clazz) { 909 return (T) zeros(dataset.getElementsPerItem(), clazz, dataset.getShapeRef()); 910 } 911 912 /** 913 * @param <T> compound dataset sub-interface 914 * @param itemSize item size 915 * @param clazz compound dataset sub-interface 916 * @param shape output shape 917 * @return a new compound dataset of given item size, shape and class, filled with zeros 918 * @since 2.0 919 */ 920 @SuppressWarnings("unchecked") 921 public static <T extends CompoundDataset> T compoundZeros(int itemSize, Class<T> clazz, int... shape) { 922 if (RGBByteDataset.class.isAssignableFrom(clazz)) { 923 if (itemSize != 3) { 924 throw new IllegalArgumentException("Number of elements not compatible with RGB type"); 925 } 926 return (T) new RGBByteDataset(shape); 927 } else if (CompoundByteDataset.class.isAssignableFrom(clazz)) { 928 return (T) new CompoundByteDataset(itemSize, shape); 929 } else if (RGBDataset.class.isAssignableFrom(clazz)) { 930 if (itemSize != 3) { 931 throw new IllegalArgumentException("Number of elements not compatible with RGB type"); 932 } 933 return (T) new RGBDataset(shape); 934 } else if (CompoundShortDataset.class.isAssignableFrom(clazz)) { 935 return (T) new CompoundShortDataset(itemSize, shape); 936 } else if (CompoundIntegerDataset.class.isAssignableFrom(clazz)) { 937 return (T) new CompoundIntegerDataset(itemSize, shape); 938 } else if (CompoundLongDataset.class.isAssignableFrom(clazz)) { 939 return (T) new CompoundLongDataset(itemSize, shape); 940 } else if (ComplexFloatDataset.class.isAssignableFrom(clazz)) { 941 if (itemSize != 2) { 942 throw new IllegalArgumentException("Number of elements not compatible with complex type"); 943 } 944 return (T) new ComplexFloatDataset(shape); 945 } else if (CompoundFloatDataset.class.isAssignableFrom(clazz)) { 946 return (T) new CompoundFloatDataset(itemSize, shape); 947 } else if (ComplexDoubleDataset.class.isAssignableFrom(clazz)) { 948 if (itemSize != 2) { 949 throw new IllegalArgumentException("Number of elements not compatible with complex type"); 950 } 951 return (T) new ComplexDoubleDataset(shape); 952 } else if (CompoundDoubleDataset.class.isAssignableFrom(clazz)) { 953 return (T) new CompoundDoubleDataset(itemSize, shape); 954 } 955 throw new IllegalArgumentException("Class not a known compound interface"); 956 } 957 958 /** 959 * @param shape output shape 960 * @return a new double dataset of given shape, filled with ones 961 */ 962 public static DoubleDataset ones(final int... shape) { 963 return ones(DoubleDataset.class, shape); 964 } 965 966 /** 967 * @param <T> dataset subclass 968 * @param dataset input 969 * @return a new dataset of same shape and class as input dataset, filled with ones 970 */ 971 @SuppressWarnings("unchecked") 972 public static <T extends Dataset> T ones(final T dataset) { 973 return (T) ones(dataset, dataset.getClass()); 974 } 975 976 /** 977 * @param <T> dataset sub-interface 978 * @param clazz dataset sub-interface 979 * @param shape output shape 980 * @return a new dataset of given shape and class, filled with ones 981 */ 982 @SuppressWarnings("unchecked") 983 public static <T extends Dataset> T ones(Class<T> clazz, int... shape) { 984 if (BooleanDataset.class.isAssignableFrom(clazz)) { 985 return (T) BooleanDataset.ones(shape); 986 } else if (ByteDataset.class.isAssignableFrom(clazz)) { 987 return (T) ByteDataset.ones(shape); 988 } else if (ShortDataset.class.isAssignableFrom(clazz)) { 989 return (T) ShortDataset.ones(shape); 990 } else if (IntegerDataset.class.isAssignableFrom(clazz)) { 991 return (T) IntegerDataset.ones(shape); 992 } else if (LongDataset.class.isAssignableFrom(clazz)) { 993 return (T) LongDataset.ones(shape); 994 } else if (FloatDataset.class.isAssignableFrom(clazz)) { 995 return (T) FloatDataset.ones(shape); 996 } else if (DoubleDataset.class.isAssignableFrom(clazz)) { 997 return (T) DoubleDataset.ones(shape); 998 } else if (RGBByteDataset.class.isAssignableFrom(clazz)) { 999 return (T) new RGBByteDataset(shape).fill(1); 1000 } else if (RGBDataset.class.isAssignableFrom(clazz)) { 1001 return (T) new RGBDataset(shape).fill(1); 1002 } else if (ComplexFloatDataset.class.isAssignableFrom(clazz)) { 1003 return (T) ComplexFloatDataset.ones(shape); 1004 } else if (ComplexDoubleDataset.class.isAssignableFrom(clazz)) { 1005 return (T) ComplexDoubleDataset.ones(shape); 1006 } else if (StringDataset.class.isAssignableFrom(clazz)) { 1007 return (T) StringDataset.ones(shape); 1008 } else if (DateDataset.class.isAssignableFrom(clazz)) { 1009 return (T) DateDatasetImpl.ones(shape); 1010 } else if (ObjectDataset.class.isAssignableFrom(clazz)) { 1011 return (T) ObjectDataset.ones(shape); 1012 } 1013 throw new IllegalArgumentException("Interface not known or unsupported"); 1014 } 1015 1016 /** 1017 * @param <T> dataset sub-interface 1018 * @param itemSize item size. If equal to 1, then non-compound dataset is returned 1019 * @param clazz dataset sub-interface 1020 * @param shape output shape 1021 * @return a new dataset of given item size, shape and class, filled with ones 1022 */ 1023 @SuppressWarnings("unchecked") 1024 public static <T extends Dataset> T ones(int itemSize, Class<T> clazz, int... shape) { 1025 if (InterfaceUtils.isElemental(clazz)) { 1026 return ones(clazz, shape); 1027 } 1028 1029 if (RGBByteDataset.class.isAssignableFrom(clazz)) { 1030 if (itemSize != 3) { 1031 throw new IllegalArgumentException("Number of elements not compatible with RGB type"); 1032 } 1033 return (T) new RGBByteDataset(shape).fill(1); 1034 } else if (CompoundByteDataset.class.isAssignableFrom(clazz)) { 1035 return (T) CompoundByteDataset.ones(itemSize, shape); 1036 } else if (RGBDataset.class.isAssignableFrom(clazz)) { 1037 if (itemSize != 3) { 1038 throw new IllegalArgumentException("Number of elements not compatible with RGB type"); 1039 } 1040 return (T) new RGBDataset(shape).fill(1); 1041 } else if (CompoundShortDataset.class.isAssignableFrom(clazz)) { 1042 return (T) CompoundShortDataset.ones(itemSize, shape); 1043 } else if (CompoundIntegerDataset.class.isAssignableFrom(clazz)) { 1044 return (T) CompoundIntegerDataset.ones(itemSize, shape); 1045 } else if (CompoundLongDataset.class.isAssignableFrom(clazz)) { 1046 return (T) CompoundLongDataset.ones(itemSize, shape); 1047 } else if (CompoundFloatDataset.class.isAssignableFrom(clazz)) { 1048 return (T) CompoundFloatDataset.ones(itemSize, shape); 1049 } else if (CompoundDoubleDataset.class.isAssignableFrom(clazz)) { 1050 return (T) CompoundDoubleDataset.ones(itemSize, shape); 1051 } 1052 throw new IllegalArgumentException("Class not a known compound interface"); 1053 } 1054 1055 /** 1056 * @param <T> dataset subclass 1057 * @param dataset input 1058 * @param clazz dataset class 1059 * @return a new dataset of given class with same shape as input dataset, filled with ones 1060 */ 1061 public static <T extends Dataset> T ones(Dataset dataset, Class<T> clazz) { 1062 return (T) ones(dataset.getElementsPerItem(), clazz, dataset.getShapeRef()); 1063 } 1064}