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