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