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