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}