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