    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                                        }
    285                                        d = DatasetUtils.cast(d, dtype);
    286                                }
    287                        } else {
    288                                switch (dtype) {
    289                                case Dataset.BOOL:
    290                                        d = BooleanDataset.createFromObject(obj);
    291                                        break;
    292                                case Dataset.INT8:
    293                                        d = ByteDataset.createFromObject(obj);
    294                                        break;
    295                                case Dataset.INT16:
    296                                        d = ShortDataset.createFromObject(obj);
    297                                        break;
    298                                case Dataset.INT32:
    299                                        d = IntegerDataset.createFromObject(obj);
    300                                        break;
    301                                case Dataset.INT64:
    302                                        d = LongDataset.createFromObject(obj);
    303                                        break;
    304                                case Dataset.ARRAYINT8:
    305                                        d = CompoundByteDataset.createFromObject(itemSize, obj);
    306                                        break;
    307                                case Dataset.ARRAYINT16:
    308                                        d = CompoundShortDataset.createFromObject(itemSize, obj);
    309                                        break;
    310                                case Dataset.ARRAYINT32:
    311                                        d = CompoundIntegerDataset.createFromObject(itemSize, obj);
    312                                        break;
    313                                case Dataset.ARRAYINT64:
    314                                        d = CompoundLongDataset.createFromObject(itemSize, obj);
    315                                        break;
    316                                case Dataset.FLOAT32:
    317                                        d = FloatDataset.createFromObject(obj);
    318                                        break;
    319                                case Dataset.FLOAT64:
    320                                        d = DoubleDataset.createFromObject(obj);
    321                                        break;
    322                                case Dataset.ARRAYFLOAT32:
    323                                        d = CompoundFloatDataset.createFromObject(itemSize, obj);
    324                                        break;
    325                                case Dataset.ARRAYFLOAT64:
    326                                        d = CompoundDoubleDataset.createFromObject(itemSize, obj);
    327                                        break;
    328                                case Dataset.COMPLEX64:
    329                                        d = ComplexFloatDataset.createFromObject(obj);
    330                                        break;
    331                                case Dataset.COMPLEX128:
    332                                        d = ComplexDoubleDataset.createFromObject(obj);
    333                                        break;
    334                                case Dataset.DATE:
    335                                        d = DateDatasetImpl.createFromObject(obj);
    336                                        break;
    337                                case Dataset.STRING:
    338                                        d = StringDataset.createFromObject(obj);
    339                                        break;
    340                                case Dataset.OBJECT:
    341                                        d = ObjectDataset.createFromObject(obj);
    342                                        break;
    343                                case Dataset.RGB:
    344                                        d = RGBDataset.createFromObject(obj);
    345                                        break;
    346                                default:
    347                                        throw new IllegalArgumentException("Dataset type is not known");
    348                                }
    349                        }
    350                }
    351
    352                if (shape != null && !(shape.length == 0 && d.getSize() > 1)) { // allow zero-rank datasets
    353                        d.setShape(shape);
    354                }
    355                return d;
    356        }
    357
    358        private static Dataset createFromPrimitiveArray(final int dtype, final Object array) {
    359                switch (dtype) {
    360                case Dataset.BOOL:
    361                        return new BooleanDataset((boolean []) array);
    362                case Dataset.INT8:
    363                        return new ByteDataset((byte []) array);
    364                case Dataset.INT16:
    365                        return new ShortDataset((short []) array);
    366                case Dataset.INT32:
    367                        return new IntegerDataset((int []) array, null);
    368                case Dataset.INT64:
    369                        return new LongDataset((long []) array);
    370                case Dataset.FLOAT32:
    371                        return new FloatDataset((float []) array);
    372                case Dataset.FLOAT64:
    373                        return new DoubleDataset((double []) array);
    374                case Dataset.STRING:
    375                        return new StringDataset((String []) array);
    376                case Dataset.DATE:
    377                        return new DateDatasetImpl((Date []) array);
    378                default:
    379                        return null;
    380                }
    381        }
    382
    383        /**
    384         * Create dataset of appropriate type from list
    385         *
    386         * @param objectList
    387         * @return dataset filled with values from list
    388         */
    389        public static Dataset createFromList(List<?> objectList) {
    390                if (objectList == null || objectList.size() == 0) {
    391                        throw new IllegalArgumentException("No list or zero-length list given");
    392                }
    393
    394                Object obj = null;
    395                for (Object o : objectList) {
    396                        if (o != null) {
    397                                obj = o;
    398                                break;
    399                        }
    400                }
    401                if (obj == null) {
    402                        return zeros(new int[objectList.size()], Dataset.OBJECT);
    403                }
    404
    405                Class<? extends Object> clazz = obj.getClass();
    406                if (!DTypeUtils.isClassSupportedAsElement(clazz)) {
    407                        throw new IllegalArgumentException("Class of list element not supported");
    408                }
    409
    410                int dtype = DTypeUtils.getDTypeFromClass(clazz);
    411                return createFromList(dtype, objectList);
    412        }
    413
    414        /**
    415         * Create dataset of given type from list
    416         *
    417         * @param dtype
    418         * @param objectList
    419         * @return dataset filled with values from list
    420         *
    421         * @deprecated Please use the class-based methods in DatasetFactory,
    422         *             such as {@link #createFromList(Class, List)}
    423         */
    424        @Deprecated
    425        public static Dataset createFromList(final int dtype, List<?> objectList) {
    426                int len = objectList.size();
    427                Dataset result = zeros(new int[] { len }, dtype);
    428
    429                for (int i = 0; i < len; i++) {
    430                        result.setObjectAbs(i, objectList.get(i));
    431                }
    432                return result;
    433        }
    434
    435        /**
    436         * Create compound dataset of given type from given parts
    437         *
    438         * @param objects
    439         * @return compound dataset
    440         */
    441        public static CompoundDataset createCompoundDataset(Object... objects) {
    442                Dataset[] datasets = new Dataset[objects.length];
    443                for (int i = 0; i < objects.length; i++) {
    444                        datasets[i] = createFromObject(objects[i]);
    445                }
    446                return DatasetUtils.createCompoundDataset(datasets);
    447        }
    448
    449        /**
    450         * Create compound dataset of given type from given parts
    451         *
    452         * @param dtype
    453         * @param objects
    454         * @return compound dataset
    455         *
    456         * @deprecated Please use the class-based methods in DatasetFactory,
    457         *             such as {@link #createCompoundDataset(Class, Object...)}
    458         */
    459        @Deprecated
    460        public static CompoundDataset createCompoundDataset(final int dtype, Object... objects) {
    461                Dataset[] datasets = new Dataset[objects.length];
    462                for (int i = 0; i < objects.length; i++) {
    463                        datasets[i] = createFromObject(objects[i]);
    464                }
    465                return DatasetUtils.createCompoundDataset(dtype, datasets);
    466        }
    467
    468        /**
    469         * Create complex dataset of given type from real and imaginary parts
    470         *
    471         * @param dtype
    472         * @param real
    473         * @param imag
    474         * @return complex dataset
    475         *
    476         * @deprecated Please use the class-based methods in DatasetFactory,
    477         *             such as {@link #createComplexDataset(Class, Object, Object)}
    478         */
    479        @Deprecated
    480        public static CompoundDataset createComplexDataset(final int dtype, Object real, Object imag) {
    481                switch (dtype) {
    482                case Dataset.COMPLEX64:
    483                        return new ComplexFloatDataset(createFromObject(real), createFromObject(imag));
    484                case Dataset.COMPLEX128:
    485                        return new ComplexDoubleDataset(createFromObject(real), createFromObject(imag));
    486                default:
    487                        throw new IllegalArgumentException("Dataset class must be a complex one");
    488                }
    489        }
    490
    491        /**
    492         * @param shape
    493         * @return a new double dataset of given shape, filled with zeros
    494         */
    495        public static DoubleDataset zeros(final int... shape) {
    496                return zeros(DoubleDataset.class, shape);
    497        }
    498
    499        /**
    500         * @param shape
    501         * @param dtype
    502         * @return a new dataset of given shape and type, filled with zeros
    503         *
    504         * @deprecated Please use the class-based methods in DatasetFactory,
    505         *             such as {@link #zeros(Class, int...)}
    506         */
    507        @Deprecated
    508        public static Dataset zeros(final int[] shape, final int dtype) {
    509                switch (dtype) {
    510                case Dataset.BOOL:
    511                        return new BooleanDataset(shape);
    512                case Dataset.INT8:
    513                case Dataset.ARRAYINT8:
    514                        return new ByteDataset(shape);
    515                case Dataset.INT16:
    516                case Dataset.ARRAYINT16:
    517                        return new ShortDataset(shape);
    518                case Dataset.RGB:
    519                        return new RGBDataset(shape);
    520                case Dataset.INT32:
    521                case Dataset.ARRAYINT32:
    522                        return new IntegerDataset(shape);
    523                case Dataset.INT64:
    524                case Dataset.ARRAYINT64:
    525                        return new LongDataset(shape);
    526                case Dataset.FLOAT32:
    527                case Dataset.ARRAYFLOAT32:
    528                        return new FloatDataset(shape);
    529                case Dataset.FLOAT64:
    530                case Dataset.ARRAYFLOAT64:
    531                        return new DoubleDataset(shape);
    532                case Dataset.COMPLEX64:
    533                        return new ComplexFloatDataset(shape);
    534                case Dataset.COMPLEX128:
    535                        return new ComplexDoubleDataset(shape);
    536                case Dataset.STRING:
    537                        return new StringDataset(shape);
    538                case Dataset.DATE:
    539                        return new DateDatasetImpl(shape);
    540                case Dataset.OBJECT:
    541                        return new ObjectDataset(shape);
    542                }
    543                throw new IllegalArgumentException("dtype not known or unsupported");
    544        }
    545
    546        /**
    547         * @param itemSize
    548         *            if equal to 1, then non-compound dataset is returned
    549         * @param shape
    550         * @param dtype
    551         * @return a new dataset of given item size, shape and type, filled with zeros
    552         *
    553         * @deprecated Please use the class-based methods in DatasetFactory,
    554         *             such as {@link #zeros(int, Class, int...)}
    555         */
    556        @Deprecated
    557        public static Dataset zeros(final int itemSize, final int[] shape, final int dtype) {
    558                if (itemSize == 1) {
    559                        return zeros(shape, dtype);
    560                }
    561                return compoundZeros(itemSize, shape, dtype);
    562        }
    563
    564        /**
    565         * @param itemSize
    566         * @param shape
    567         * @param dtype
    568         * @return a new dataset of given item size, shape and type, filled with zeros
    569         * @since 2.0
    570         *
    571         * @deprecated Please use the class-based methods in DatasetFactory,
    572         *             such as {@link #compoundZeros(int, Class, int...)}
    573         */
    574        @Deprecated
    575        public static CompoundDataset compoundZeros(final int itemSize, final int[] shape, final int dtype) {
    576                switch (dtype) {
    577                case Dataset.INT8:
    578                case Dataset.ARRAYINT8:
    579                        return new CompoundByteDataset(itemSize, shape);
    580                case Dataset.INT16:
    581                case Dataset.ARRAYINT16:
    582                        return new CompoundShortDataset(itemSize, shape);
    583                case Dataset.RGB:
    584                        if (itemSize != 3) {
    585                                throw new IllegalArgumentException("Number of elements not compatible with RGB type");
    586                        }
    587                        return new RGBDataset(shape);
    588                case Dataset.INT32:
    589                case Dataset.ARRAYINT32:
    590                        return new CompoundIntegerDataset(itemSize, shape);
    591                case Dataset.INT64:
    592                case Dataset.ARRAYINT64:
    593                        return new CompoundLongDataset(itemSize, shape);
    594                case Dataset.FLOAT32:
    595                case Dataset.ARRAYFLOAT32:
    596                        return new CompoundFloatDataset(itemSize, shape);
    597                case Dataset.FLOAT64:
    598                case Dataset.ARRAYFLOAT64:
    599                        return new CompoundDoubleDataset(itemSize, shape);
    600                case Dataset.COMPLEX64:
    601                        if (itemSize != 2) {
    602                                throw new IllegalArgumentException("Number of elements not compatible with complex type");
    603                        }
    604                        return new ComplexFloatDataset(shape);
    605                case Dataset.COMPLEX128:
    606                        if (itemSize != 2) {
    607                                throw new IllegalArgumentException("Number of elements not compatible with complex type");
    608                        }
    609                        return new ComplexDoubleDataset(shape);
    610                }
    611                throw new IllegalArgumentException("dtype not a known compound type");
    612        }
    613
    614        /**
    615         * @param dataset
    616         * @return a new dataset of same shape and type as input dataset, filled with zeros
    617         */
    618        @SuppressWarnings("unchecked")
    619        public static <T extends Dataset> T zeros(final T dataset) {
    620                int dtype = dataset.getDType();
    621                return (T) (DTypeUtils.isDTypeElemental(dtype) ? zeros(dataset, dtype) :
    622                        compoundZeros(dataset.getElementsPerItem(),  dataset.getShapeRef(), dtype));
    623        }
    624
    625        /**
    626         * Create a new dataset of same shape as input dataset, filled with zeros. If dtype is not
    627         * explicitly compound then an elemental dataset is created
    628         * @param dataset
    629         * @param dtype
    630         * @return a new dataset
    631         *
    632         * @deprecated Please use the class-based methods in DatasetFactory,
    633         *             such as {@link #zeros(Dataset, Class)}
    634         */
    635        @Deprecated
    636        public static Dataset zeros(final Dataset dataset, final int dtype) {
    637                final int[] shape = dataset.getShapeRef();
    638                final int isize = DTypeUtils.isDTypeElemental(dtype) ? 1 :dataset.getElementsPerItem();
    639
    640                return zeros(isize, shape, dtype);
    641        }
    642
    643        /**
    644         * @param dataset
    645         * @return a new dataset of same shape and type as input dataset, filled with ones
    646         */
    647        @SuppressWarnings("unchecked")
    648        public static <T extends Dataset> T ones(final T dataset) {
    649                return (T) ones(dataset, dataset.getDType());
    650        }
    651
    652        /**
    653         * Create a new dataset of same shape as input dataset, filled with ones. If dtype is not
    654         * explicitly compound then an elemental dataset is created
    655         * @param dataset
    656         * @param dtype
    657         * @return a new dataset
    658         *
    659         * @deprecated Please use the class-based methods in DatasetFactory,
    660         *             such as {@link #createRange(Class, double, double, double)}
    661         */
    662        @Deprecated
    663        public static Dataset ones(final Dataset dataset, final int dtype) {
    664                final int[] shape = dataset.getShapeRef();
    665                final int isize = DTypeUtils.isDTypeElemental(dtype) ? 1 :dataset.getElementsPerItem();
    666
    667                return ones(isize, shape, dtype);
    668        }
    669
    670        /**
    671         * @param shape
    672         * @return a new double dataset of given shape, filled with ones
    673         */
    674        public static DoubleDataset ones(final int... shape) {
    675                return ones(DoubleDataset.class, shape);
    676        }
    677
    678        /**
    679         * @param shape
    680         * @param dtype
    681         * @return a new dataset of given shape and type, filled with ones
    682         *
    683         * @deprecated Please use the class-based methods in DatasetFactory,
    684         *             such as {@link #ones(Class, int...)}
    685         */
    686        @Deprecated
    687        public static Dataset ones(final int[] shape, final int dtype) {
    688                switch (dtype) {
    689                case Dataset.BOOL:
    690                        return BooleanDataset.ones(shape);
    691                case Dataset.INT8:
    692                        return ByteDataset.ones(shape);
    693                case Dataset.INT16:
    694                        return ShortDataset.ones(shape);
    695                case Dataset.RGB:
    696                        return new RGBDataset(shape).fill(1);
    697                case Dataset.INT32:
    698                        return IntegerDataset.ones(shape);
    699                case Dataset.INT64:
    700                        return LongDataset.ones(shape);
    701                case Dataset.FLOAT32:
    702                        return FloatDataset.ones(shape);
    703                case Dataset.FLOAT64:
    704                        return DoubleDataset.ones(shape);
    705                case Dataset.COMPLEX64:
    706                        return ComplexFloatDataset.ones(shape);
    707                case Dataset.COMPLEX128:
    708                        return ComplexDoubleDataset.ones(shape);
    709                }
    710                throw new IllegalArgumentException("dtype not known");
    711        }
    712
    713        /**
    714         * @param itemSize
    715         *            if equal to 1, then non-compound dataset is returned
    716         * @param shape
    717         * @param dtype
    718         * @return a new dataset of given item size, shape and type, filled with ones
    719         *
    720         * @deprecated Please use the class-based methods in DatasetFactory,
    721         *             such as {@link #ones(Class, int...)}
    722         */
    723        @Deprecated
    724        public static Dataset ones(final int itemSize, final int[] shape, final int dtype) {
    725                if (itemSize == 1) {
    726                        return ones(shape, dtype);
    727                }
    728                switch (dtype) {
    729                case Dataset.INT8:
    730                case Dataset.ARRAYINT8:
    731                        return CompoundByteDataset.ones(itemSize, shape);
    732                case Dataset.INT16:
    733                case Dataset.ARRAYINT16:
    734                        return CompoundShortDataset.ones(itemSize, shape);
    735                case Dataset.RGB:
    736                        if (itemSize != 3) {
    737                                throw new IllegalArgumentException("Number of elements not compatible with RGB type");
    738                        }
    739                        return new RGBDataset(shape).fill(1);
    740                case Dataset.INT32:
    741                case Dataset.ARRAYINT32:
    742                        return CompoundIntegerDataset.ones(itemSize, shape);
    743                case Dataset.INT64:
    744                case Dataset.ARRAYINT64:
    745                        return CompoundLongDataset.ones(itemSize, shape);
    746                case Dataset.FLOAT32:
    747                case Dataset.ARRAYFLOAT32:
    748                        return CompoundFloatDataset.ones(itemSize, shape);
    749                case Dataset.FLOAT64:
    750                case Dataset.ARRAYFLOAT64:
    751                        return CompoundDoubleDataset.ones(itemSize, shape);
    752                case Dataset.COMPLEX64:
    753                        if (itemSize != 2) {
    754                                throw new IllegalArgumentException("Number of elements not compatible with complex type");
    755                        }
    756                        return ComplexFloatDataset.ones(shape);
    757                case Dataset.COMPLEX128:
    758                        if (itemSize != 2) {
    759                                throw new IllegalArgumentException("Number of elements not compatible with complex type");
    760                        }
    761                        return ComplexDoubleDataset.ones(shape);
    762                }
    763                throw new IllegalArgumentException("dtype not a known compound type");
    764        }
    765
    766        /**
    767         * Create a 1D dataset of linearly spaced values in closed interval
    768         *
    769         * @param start
    770         * @param stop stop value is included
    771         * @param length number of points
    772         * @param dtype
    773         * @return dataset with linearly spaced values
    774         *
    775         * @deprecated Please use the class-based methods in DatasetFactory,
    776         *             such as {@link #createLinearSpace(Class, double, double, int)}
    777         */
    778        @Deprecated
    779        public static Dataset createLinearSpace(final double start, final double stop, final int length, final int dtype) {
    780                if (length < 1) {
    781                        throw new IllegalArgumentException("Length is less than one");
    782                } else if (length == 1) {
    783                        return createFromObject(dtype, start);
    784                } else {
    785                        Dataset ds = zeros(new int[] {length}, dtype);
    786                        double num = stop - start;
    787                        double den = length - 1;
    788                        double value;
    789
    790                        for (int i = 0; i < length; i++) {
    791                                value = start + (num * i) / den;
    792                                ds.setObjectAbs(i, value);
    793                        }
    794
    795                        return ds;
    796                }
    797        }
    798
    799        /**
    800         * Create a 1D dataset of logarithmically spaced values in closed interval. The base value is used to
    801         * determine the factor between values: factor = base ** step, where step is the interval between linearly
    802         * spaced sequence of points
    803         *
    804         * @param start
    805         * @param stop stop value is included
    806         * @param length number of points
    807         * @param base
    808         * @param dtype
    809         * @return dataset with logarithmically spaced values
    810         *
    811         * @deprecated Please use the class-based methods in DatasetFactory,
    812         *             such as {@link #createLogSpace(Class, double, double, int, double)}
    813         */
    814        @Deprecated
    815        public static Dataset createLogSpace(final double start, final double stop, final int length, final double base, final int dtype) {
    816                if (length < 1) {
    817                        throw new IllegalArgumentException("Length is less than one");
    818                } else if (length == 1) {
    819                        return createFromObject(dtype, Math.pow(base, start));
    820                } else {
    821                        Dataset ds = zeros(new int[] {length}, dtype);
    822                        double step = (stop - start) / (length - 1);
    823                        double value;
    824
    825                        for (int i = 0; i < length; i++) {
    826                                value = start + i * step;
    827                                ds.setObjectAbs(i, Math.pow(base, value));
    828                        }
    829
    830                        return ds;
    831                }
    832        }
    833
    834        /**
    835         * Create dataset with items ranging from 0 up to given stop in steps of 1
    836         * @param clazz
    837         * @param stop stop value is <strong>not</strong> included
    838         * @return a new dataset of given shape and type, filled with values determined by parameters
    839         */
    840        @SuppressWarnings("unchecked")
    841        public static <T extends Dataset> T createRange(Class<T> clazz, final double stop) {
    842                return (T) createRange(0, stop, 1, DTypeUtils.getDType(clazz));
    843        }
    844
    845        /**
    846         * Create dataset with items ranging from given start up to given stop in given steps
    847         * @param clazz dataset class
    848         * @param start
    849         * @param stop stop value is <strong>not</strong> included
    850         * @param step spacing between items
    851         * @return a new 1D dataset of given class, filled with values determined by parameters
    852         */
    853        @SuppressWarnings("unchecked")
    854        public static <T extends Dataset> T createRange(Class<T> clazz, final double start, final double stop, final double step) {
    855                return (T) createRange(start, stop, step, DTypeUtils.getDType(clazz));
    856        }
    857
    858        /**
    859         * Create compound dataset with items ranging from 0 up to given stop in steps of 1
    860         * @param itemSize
    861         * @param clazz compound dataset class
    862         * @param stop stop value is <strong>not</strong> included
    863         * @return a new 1D dataset of given class, filled with values determined by parameters
    864         * @since 2.1
    865         */
    866        @SuppressWarnings("unchecked")
    867        public static <T extends CompoundDataset> T createRange(final int itemSize, Class<T> clazz, final double stop) {
    868                return (T) createRange(itemSize, 0, stop, 1, DTypeUtils.getDType(clazz));
    869        }
    870
    871        /**
    872         * Create compound dataset with items ranging from given start up to given stop in given steps
    873         * @param itemSize
    874         * @param clazz compound dataset class
    875         * @param start
    876         * @param stop stop value is <strong>not</strong> included
    877         * @param step spacing between items
    878         * @return a new 1D dataset of given class, filled with values determined by parameters
    879         * @since 2.1
    880         */
    881        @SuppressWarnings("unchecked")
    882        public static <T extends CompoundDataset> T createRange(final int itemSize, Class<T> clazz, final double start, final double stop, final double step) {
    883                return (T) createRange(itemSize, start, stop, step, DTypeUtils.getDType(clazz));
    884        }
    885
    886        /**
    887         * Create a dataset from object
    888         * @param clazz dataset class
    889         * @param obj
    890         *            can be a Java list, array or Number
    891         * @return dataset
    892         * @throws IllegalArgumentException if dataset class is not known
    893         * @since 2.1
    894         */
    895        @SuppressWarnings("unchecked")
    896        public static <T extends Dataset> T createFromObject(Class<T> clazz, Object obj) {
    897                return (T) createFromObject(1, DTypeUtils.getDType(clazz), obj, null);
    898        }
    899
    900
    901        /**
    902         * Create a dataset from object
    903         * @param clazz dataset class
    904         * @param obj
    905         *            can be a Java list, array or Number
    906         * @param shape can be null
    907         * @return dataset
    908         * @throws IllegalArgumentException if dataset type is not known
    909         */
    910        @SuppressWarnings("unchecked")
    911        public static <T extends Dataset> T createFromObject(Class<T> clazz, Object obj, int... shape) {
    912                return (T) createFromObject(1, DTypeUtils.getDType(clazz), obj, shape);
    913        }
    914
    915        /**
    916         * Create a compound dataset from object
    917         * @param itemSize
    918         * @param clazz dataset class
    919         * @param obj
    920         *            can be a Java list, array or Number
    921         * @param shape can be null
    922         * @return dataset
    923         * @throws IllegalArgumentException if dataset type is not known
    924         */
    925        @SuppressWarnings("unchecked")
    926        public static <T extends Dataset> T createFromObject(final int itemSize, Class<T> clazz, Object obj, int... shape) {
    927                return (T) createFromObject(itemSize, DTypeUtils.getDType(clazz), obj, shape);
    928        }
    929
    930        /**
    931         * Create dataset of given class from list
    932         *
    933         * @param clazz dataset class
    934         * @param objectList
    935         * @return dataset filled with values from list
    936         */
    937        @SuppressWarnings("unchecked")
    938        public static <T extends Dataset> T createFromList(Class<T> clazz, List<?> objectList) {
    939                return (T) createFromList(DTypeUtils.getDType(clazz), objectList);
    940        }
    941
    942        /**
    943         * Create compound dataset of given class from given parts
    944         *
    945         * @param clazz
    946         * @param objects
    947         * @return compound dataset
    948         */
    949        @SuppressWarnings("unchecked")
    950        public static <T extends Dataset> T createCompoundDataset(Class<T> clazz, Object... objects) {
    951                return (T) createCompoundDataset(DTypeUtils.getDType(clazz), objects);
    952        }
    953
    954        /**
    955         * Create complex dataset of given class from real and imaginary parts
    956         *
    957         * @param clazz dataset class
    958         * @param real
    959         * @param imag
    960         * @return complex dataset
    961         */
    962        @SuppressWarnings("unchecked")
    963        public static <T extends Dataset> T createComplexDataset(Class<T> clazz, Object real, Object imag) {
    964                return (T) createComplexDataset(DTypeUtils.getDType(clazz), real, imag);
    965        }
    966
    967        /**
    968         * @param clazz dataset class
    969         * @param shape
    970         * @return a new dataset of given shape and class, filled with zeros
    971         */
    972        @SuppressWarnings("unchecked")
    973        public static <T extends Dataset> T zeros(Class<T> clazz, int... shape) {
    974                return (T) zeros(shape, DTypeUtils.getDType(clazz));
    975        }
    976
    977        /**
    978         * @param itemSize
    979         *            if equal to 1, then non-compound dataset is returned
    980         * @param clazz dataset class
    981         * @param shape
    982         * @return a new dataset of given item size, shape and class, filled with zeros
    983         */
    984        @SuppressWarnings("unchecked")
    985        public static <T extends Dataset> T zeros(int itemSize, Class<T> clazz, int... shape) {
    986                return (T) zeros(itemSize, shape, DTypeUtils.getDType(clazz));
    987        }
    988
    989        /**
    990         * @param dataset
    991         * @param clazz dataset class
    992         * @return a new dataset of given class with same shape as input dataset, filled with zeros
    993         */
    994        @SuppressWarnings("unchecked")
    995        public static <T extends Dataset> T zeros(Dataset dataset, Class<T> clazz) {
    996                return (T) zeros(dataset, DTypeUtils.getDType(clazz));
    997        }
    998
    999        /**
    1000         * @param itemSize
    1001         * @param clazz compound dataset class
    1002         * @param shape
    1003         * @return a new compound dataset of given item size, shape and class, filled with zeros
    1004         * @since 2.0
    1005         */
    1006        @SuppressWarnings("unchecked")
    1007        public static <T extends CompoundDataset> T compoundZeros(int itemSize, Class<T> clazz, int... shape) {
    1008                return (T) compoundZeros(itemSize, shape, DTypeUtils.getDType(clazz));
    1009        }
    1010
    1011        /**
    1012         * @param clazz dataset class
    1013         * @param shape
    1014         * @return a new dataset of given shape and class, filled with ones
    1015         */
    1016        @SuppressWarnings("unchecked")
    1017        public static <T extends Dataset> T ones(Class<T> clazz, int... shape) {
    1018                return (T) ones(shape, DTypeUtils.getDType(clazz));
    1019        }
    1020
    1021        /**
    1022         * @param itemSize
    1023         *            if equal to 1, then non-compound dataset is returned
    1024         * @param clazz dataset class
    1025         * @param shape
    1026         * @return a new dataset of given item size, shape and class, filled with ones
    1027         */
    1028        @SuppressWarnings("unchecked")
    1029        public static <T extends Dataset> T ones(int itemSize, Class<T> clazz, int... shape) {
    1030                return (T) ones(itemSize, shape, DTypeUtils.getDType(clazz));
    1031        }
    1032
    1033        /**
    1034         * @param dataset
    1035         * @param clazz dataset class
    1036         * @return a new dataset of given class with same shape as input dataset, filled with ones
    1037         */
    1038        @SuppressWarnings("unchecked")
    1039        public static <T extends Dataset> T ones(Dataset dataset, Class<T> clazz) {
    1040                return (T) ones(dataset, DTypeUtils.getDType(clazz));
    1041        }
    1042
    1043        /**
    1044         * Create a 1D dataset of linearly spaced values in closed interval
    1045         *
    1046         * @param clazz dataset class
    1047         * @param start
    1048         * @param stop stop value is included
    1049         * @param length number of points
    1050         * @return dataset with linearly spaced values
    1051         */
    1052        @SuppressWarnings("unchecked")
    1053        public static <T extends Dataset> T createLinearSpace(Class<T> clazz, final double start, final double stop, final int length) {
    1054                return (T) createLinearSpace(start, stop, length, DTypeUtils.getDType(clazz));
    1055        }
    1056
    1057        /**
    1058         * Create a 1D dataset of logarithmically spaced values in closed interval. The base value is used to
    1059         * determine the factor between values: factor = base ** step, where step is the interval between linearly
    1060         * spaced sequence of points
    1061         *
    1062         * @param start
    1063         * @param stop stop value is included
    1064         * @param length number of points
    1065         * @param base
    1066         * @return dataset with logarithmically spaced values
    1067         */
    1068        @SuppressWarnings("unchecked")
    1069        public static <T extends Dataset> T createLogSpace(Class<T> clazz, final double start, final double stop, final int length, final double base) {
    1070                return (T) createLogSpace(start, stop, length, base, DTypeUtils.getDType(clazz));
    1071        }
    1072}