Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Misc/ILMatFile5.cs @ 11219

Last change on this file since 11219 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 101.4 KB
Line 
1///
2///    This file is part of ILNumerics Community Edition.
3///
4///    ILNumerics Community Edition - high performance computing for applications.
5///    Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
6///
7///    ILNumerics Community Edition is free software: you can redistribute it and/or modify
8///    it under the terms of the GNU General Public License version 3 as published by
9///    the Free Software Foundation.
10///
11///    ILNumerics Community Edition is distributed in the hope that it will be useful,
12///    but WITHOUT ANY WARRANTY; without even the implied warranty of
13///    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14///    GNU General Public License for more details.
15///
16///    You should have received a copy of the GNU General Public License
17///    along with ILNumerics Community Edition. See the file License.txt in the root
18///    of your distribution package. If not, see <http://www.gnu.org/licenses/>.
19///
20///    In addition this software uses the following components and/or licenses:
21///
22///    =================================================================================
23///    The Open Toolkit Library License
24///   
25///    Copyright (c) 2006 - 2009 the Open Toolkit library.
26///   
27///    Permission is hereby granted, free of charge, to any person obtaining a copy
28///    of this software and associated documentation files (the "Software"), to deal
29///    in the Software without restriction, including without limitation the rights to
30///    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
31///    the Software, and to permit persons to whom the Software is furnished to do
32///    so, subject to the following conditions:
33///
34///    The above copyright notice and this permission notice shall be included in all
35///    copies or substantial portions of the Software.
36///
37///    =================================================================================
38///   
39
40using System;
41using System.Collections.Generic;
42using System.Text;
43using System.IO;
44using System.IO.Compression;
45using ILNumerics;
46using ILNumerics.Storage;
47using ILNumerics.Misc;
48using ILNumerics.Exceptions;
49
50
51namespace ILNumerics {
52   
53    /// <summary>
54    /// Matlab .mat file wrapper class
55    /// </summary>
56    /// <remarks>This class reads and writes Matlab .mat files version 6! !
57    /// All numeric array types are supported. The reading and writing of
58    /// Matlab cell arrays is not supported yet.</remarks>
59    public sealed class ILMatFile : IDisposable {
60
61        #region attributes
62        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
63        private string m_filename = "(unknown)";
64        /// <summary>
65        /// Path to mat file, if this object was created from an existing mat file.
66        /// </summary>
67        public string Filelocation {
68            get {
69                return m_filename;
70            }
71        }
72        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
73        private ILCell m_data = ILMath.cell();
74        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
75        private string headerFromFile;
76        #endregion
77                     
78        #region constants
79        /// <summary>
80        /// Inner types for MATLAB data elements
81        /// </summary>
82        public enum MatFileType : int {
83            /// <summary>
84            /// unknown
85            /// </summary>
86            miUNKNOWN = 0,
87            /// <summary>
88            /// Int8
89            /// </summary>
90            miINT8 = 1,
91            /// <summary>
92            /// UInt8
93            /// </summary>
94            miUINT8 = 2,
95            /// <summary>
96            /// Int16
97            /// </summary>
98            miINT16 = 3,
99            /// <summary>
100            /// UInt16
101            /// </summary>
102            miUINT16 = 4,
103            /// <summary>
104            /// int32
105            /// </summary>
106            miINT32 = 5,
107            /// <summary>
108            /// UInt32
109            /// </summary>
110            miUINT32 = 6,
111            /// <summary>
112            /// float
113            /// </summary>
114            miSINGLE = 7,
115            /// <summary>
116            /// double
117            /// </summary>
118            miDOUBLE = 9,
119            /// <summary>
120            /// Int64
121            /// </summary>
122            miINT64 = 12,
123            /// <summary>
124            /// UInt64
125            /// </summary>
126            miUINT64 = 13,
127            /// <summary>
128            /// matrix type (general)
129            /// </summary>
130            miMATRIX = 14,
131            /// <summary>
132            /// compressed
133            /// </summary>
134            miCOMPRESSED = 15,
135            /// <summary>
136            /// utf8 encoded
137            /// </summary>
138            miUTF8 = 16,
139            /// <summary>
140            /// utf16 encoded
141            /// </summary>
142            miUTF16 = 17,
143            /// <summary>
144            /// utf32 encoded
145            /// </summary>
146            miUTF32 = 18
147        }
148        /// <summary>
149        /// Types for matrix chunks
150        /// </summary>
151        public enum MatFileArrayClass {
152            /// <summary>
153            /// cell
154            /// </summary>
155            mxCELL_CLASS = 1,
156            /// <summary>
157            /// struct
158            /// </summary>
159            mxSTRUCT_CLASS = 2,
160            /// <summary>
161            /// object
162            /// </summary>
163            mxOBJECT_CLASS = 3,
164            /// <summary>
165            /// char
166            /// </summary>
167            mxCHAR_CLASS = 4,
168            /// <summary>
169            /// sparse
170            /// </summary>
171            mxSPARSE_CLASS = 5,
172            /// <summary>
173            /// double
174            /// </summary>
175            mxDOUBLE_CLASS = 6,
176            /// <summary>
177            /// float
178            /// </summary>
179            mxSINGLE_CLASS = 7,
180            /// <summary>
181            /// Int8
182            /// </summary>
183            mxINT8_CLASS = 8,
184            /// <summary>
185            /// UInt8
186            /// </summary>
187            mxUINT8_CLASS = 9,
188            /// <summary>
189            /// Int16
190            /// </summary>
191            mxINT16_CLASS = 10,
192            /// <summary>
193            /// UInt16
194            /// </summary>
195            mxUINT16_CLASS = 11,
196            /// <summary>
197            /// Int32
198            /// </summary>
199            mxINT32_CLASS = 12,
200            /// <summary>
201            /// UInt32
202            /// </summary>
203            mxUINT32_CLASS = 13,
204            /// <summary>
205            /// Int32
206            /// </summary>
207            mxINT64_CLASS = 14,
208            /// <summary>
209            /// UInt32
210            /// </summary>
211            mxUINT64_CLASS = 15
212        }
213
214        /// <summary>
215        /// List of keywords which Matlab disallows for variable names
216        /// </summary>
217        public static readonly string[] ReservedKeywords = new string[] {
218            "break",
219            "case"  ,
220            "catch"  ,
221            "continue",
222            "else"    ,
223            "elseif"  ,
224            "end"     ,
225            "for"     ,
226            "function",
227            "global"  ,
228            "if"      ,
229            "otherwise",
230            "persistent",
231            "return"    ,
232            "switch"    ,
233            "try"       ,
234            "while"               
235        };
236
237        private static int miSIZE_INT32    = 4;
238        private static int miSIZE_INT16    = 2;
239        private static int miSIZE_INT8     = 1;
240        private static int miSIZE_UINT32   = 4;
241        private static int miSIZE_UINT16   = 2;
242        private static int miSIZE_UINT8    = 1;
243        private static int miSIZE_DOUBLE   = 8;
244        private static int miSIZE_SINGLE   = 4;
245        private static int miSIZE_UTF32    = 4;
246        private static int miSIZE_INT64    = 8;
247        private static int miSIZE_UINT64   = 8;
248
249
250        /* Matlab Array Types (Classes) */
251        private static int mxUNKNOWN_CLASS = 0;
252        private static int mxCELL_CLASS    = 1;
253        private static int mxSTRUCT_CLASS  = 2;
254        private static int mxOBJECT_CLASS  = 3;
255        private static int mxCHAR_CLASS    = 4;
256        private static int mxSPARSE_CLASS  = 5;
257        private static int mxDOUBLE_CLASS  = 6;
258        private static int mxSINGLE_CLASS  = 7;
259        private static int mxINT8_CLASS    = 8;
260        private static int mxUINT8_CLASS   = 9;
261        private static int mxINT16_CLASS   = 10;
262        private static int mxUINT16_CLASS  = 11;
263        private static int mxINT32_CLASS   = 12;
264        private static int mxUINT32_CLASS  = 13;
265        private static int mxINT64_CLASS   = 14;
266        private static int mxUINT64_CLASS  = 15;
267        private static int mxFUNCTION_CLASS= 16;
268        private static int mxOPAQUE_CLASS  = 17;
269       
270        private static int mtFLAG_COMPLEX  = 0x0800;
271        private static int mtFLAG_GLOBAL   = 0x0400;
272        private static int mtFLAG_LOGICAL  = 0x0200;
273        private static int mtFLAG_TYPE     = 0xff;
274        #endregion
275
276        #region private helper
277        /// <summary>
278        /// size of single elements stored in Matlab's *.mat files
279        /// </summary>
280        /// <param name="type">one of Matlab's inner element types</param>
281        /// <returns>size in bytes </returns>
282        private static int sizeOf(MatFileType type)
283        {
284            switch ( type )
285            {
286                case MatFileType.miINT8:
287                    return miSIZE_INT8;
288                case MatFileType.miUINT8:
289                    return miSIZE_UINT8;
290                case MatFileType.miINT16:
291                    return miSIZE_INT16;
292                case MatFileType.miUINT16:
293                    return miSIZE_UINT16;
294                case MatFileType.miINT32:
295                    return miSIZE_INT32;
296                case MatFileType.miUINT32:
297                    return miSIZE_UINT32;
298                case MatFileType.miINT64:
299                    return miSIZE_INT64;
300                case MatFileType.miUINT64:
301                    return miSIZE_UINT64;
302                case MatFileType.miDOUBLE:
303                    return miSIZE_DOUBLE;
304                case MatFileType.miSINGLE:
305                    return miSIZE_SINGLE;
306                case MatFileType.miUTF32:
307                    return miSIZE_UTF32;
308                default:
309                    throw new ILArgumentException("Invalid MatFileType specified: " + type.ToString());
310            }
311        }
312        private ILBaseArray read_compressed(BinaryReader br, int len) {
313            throw new NotImplementedException("Compressed matfile format is not supported yet! Use '-v6' option in Matlab to create the matfile!");
314            //long startpos = br.BaseStream.Position;
315            ////ZOutputStream zstream = new ZOutputStream(br.BaseStream);
316            //GZipStream str = new GZipStream(br.BaseStream,CompressionMode.Decompress);
317            //BinaryReader bread = new BinaryReader(str);
318            //MatFileType dataType = (MatFileType)Enum.Parse(typeof(MatFileType), bread.ReadInt32().ToString());
319            //int elementLength = bread.ReadInt32();
320            //ILBaseArray ret = null;
321            //if (dataType == MatFileType.miMATRIX) {
322            //    ret = read_miMATRIX(bread);     
323            //}
324            //return ret;
325        }
326        private void read_header(BinaryReader br) {
327            headerFromFile = br.ReadBytes(116).ToString();
328            // skip subsystem data
329            br.ReadBytes(8);
330            // version
331            int version = br.ReadInt16();
332            if (br.ReadChar() != 'I' || br.ReadByte() != 'M')
333                throw new Exception("This file eventually was written on a machine, which is not compatible " +
334                    " to this one due to an endian type issue!");
335        }
336        /// <summary>
337        /// read ONE array (arbitrary dimensions/type) from MAT file
338        /// </summary>
339        /// <param name="br">binary reader initialized and pointing to the beginning of the subarray element.</param>
340        /// <returns>ILBaseArray of size and type originally stored into the mat file.</returns>
341        private ILBaseArray read_miMATRIX(BinaryReader br) {
342            long entryPositionInStream = br.BaseStream.Position;
343            bool complex = false;
344            bool logical = false;
345            int mxClass = 0;
346            int[] dimensions = new int[0];
347            MatFileType storageType = MatFileType.miUNKNOWN;
348            int nrElements = 1;
349            string name;
350            ILBaseArray ret;
351            // read array flags
352            Int32 readInt = br.ReadInt32();
353            if (readInt != 6)
354                throw new Exception("found invalid datatype in array flag! currently only 'mxArray' types are supported!");
355            readInt = br.ReadInt32();
356            if (readInt != 8)
357                throw new Exception("unexpected array flag length. expected: 8 /found: " + readInt);
358            readInt = br.ReadInt32();
359            complex = (readInt & mtFLAG_COMPLEX) != 0;
360            logical = (readInt & mtFLAG_LOGICAL) != 0;
361            mxClass = readInt & 0x00ff;
362            // unknown
363            br.ReadInt32();
364            // Read dimensions array
365            readInt = br.ReadInt32();
366            if (readInt != 5)
367                throw new Exception("found invalid datatype in dimension flag!");
368            readInt = br.ReadInt32();
369            if (readInt < 2)
370                throw new Exception("Invalid number of dimensions found: " + readInt);
371            dimensions = new int[(int)readInt / 4];
372            for (int i = 0; i < dimensions.Length; i++) {
373                dimensions[i] = br.ReadInt32();
374                nrElements *= dimensions[i];
375            }
376            // padidng if needed
377            if ((dimensions.Length % 2) != 0)
378                br.ReadInt32();
379            // read Name - check for small data element format
380            readInt = br.ReadInt32();
381            int nrSmallBytes = (int)((readInt & 0xffff0000) >> 16);
382            if (nrSmallBytes != 0) {
383                // process small element format
384                if ((readInt & 0xffff) != 1)
385                    throw new Exception("Invalid datype for (compressed) name element found: " + (readInt & 0x00ff));
386                StringBuilder nameBuild = new StringBuilder();
387                nameBuild.Append(br.ReadChars(nrSmallBytes));
388                // padding if needed
389                while (nrSmallBytes < 4) {
390                    br.ReadByte();
391                    nrSmallBytes++;
392                }
393                name = nameBuild.ToString();
394            } else {
395                // process 'long' format
396                if (readInt != 1)
397                    throw new Exception("Invalid datype for name element found: " + readInt);
398                readInt = br.ReadInt32();
399                StringBuilder nameBuild = new StringBuilder();
400                nameBuild.Append(br.ReadChars(readInt));
401                while (readInt % 8 != 0) {
402                    readInt++;
403                    br.ReadByte();
404                }
405                name = nameBuild.ToString();
406            }
407            // read data flags + check if small format
408            readInt = br.ReadInt32();
409            nrSmallBytes = (Int16)((readInt & 0xffff0000) >> 16);
410            System.Array realData = null;
411            System.Array imagData = null;
412            int len;
413            if (nrSmallBytes != 0 && nrElements <= 4) {
414                // small data element format for scalars only!
415                // process small format -> real part
416                storageType = (MatFileType)(readInt & 0xffff);
417                len = nrSmallBytes;
418                readElementGeneric(br, storageType, out realData, ref len, 4);
419                // padding
420                //while (nrSmallBytes < 4 && br.BaseStream.Position < br.BaseStream.Length) {
421                //    br.ReadByte();
422                //    nrSmallBytes++;
423                //}
424            } else {
425                // read regular data : real part
426                storageType = (MatFileType)Enum.Parse(typeof(MatFileType), readInt.ToString());
427                len = br.ReadInt32();
428                nrSmallBytes = len;
429                readElementGeneric(br, storageType, out realData, ref len);
430                // (padding is done in readElementGeneric)
431            }
432
433            // read imag part + check if small format
434            if (complex) {
435                readInt = br.ReadInt32();
436                nrSmallBytes = (Int16)((readInt & 0xffff0000) >> 16);
437                if (nrSmallBytes != 0 && nrElements <= 4) {
438                    // process small format -> imag part
439                    storageType = (MatFileType)(readInt & 0xffff);
440                    len = nrSmallBytes;
441                    readElementGeneric(br, storageType, out imagData, ref len, 4);
442                    // padding
443                    //while (nrSmallBytes < 4 && br.BaseStream.Position < br.BaseStream.Length) {
444                    //    br.ReadByte();
445                    //    nrSmallBytes++;
446                    //}
447                } else {
448                    // read regular data : image part
449                    storageType = (MatFileType)Enum.Parse(typeof(MatFileType), readInt.ToString()); ;
450                    len = br.ReadInt32();
451                    nrSmallBytes = len;
452                    readElementGeneric(br, storageType, out imagData, ref len);
453                    // (padding's done in readElementGeneric)
454                }
455            }
456            // convert to original data type
457            if (complex) {
458                if (mxClass == mxSINGLE_CLASS) {
459                    fcomplex[] retArr = new fcomplex[nrElements];
460                    float[] realPart = Convert2SingleArray(realData);
461                    float[] imagPart = Convert2SingleArray(imagData);
462                    for (int i = 0; i < nrElements; i++) {
463                        retArr[i] = new fcomplex(realPart[i], imagPart[i]);
464                    }
465                    ret = new ILRetArray<fcomplex>(retArr, dimensions);
466                } else {
467                    complex[] retArr = new complex[nrElements];
468                    double[] realPart = Convert2DoubleArray(realData);
469                    double[] imagPart = Convert2DoubleArray(imagData);
470                    for (int i = 0; i < nrElements; i++) {
471                        retArr[i] = new complex(realPart[i], imagPart[i]);
472                    }
473                    ret = new ILRetArray<complex>(retArr, dimensions);
474                }
475            } else if (logical) {
476                int numNonzero = 0;
477                byte[] retArr = Convert2Logical(realData, out numNonzero);
478                ret = new ILRetLogical(retArr, new ILSize(dimensions), numNonzero);
479            } else {
480                if (false) {
481
482                   
483                } else if (mxClass ==  mxDOUBLE_CLASS) {
484                   
485                    double[] dataArr =   Convert2DoubleArray(realData);
486                    ret = new ILRetArray<double>(dataArr, dimensions);
487
488#region HYCALPER AUTO GENERATED CODE
489
490                   
491                } else if (mxClass ==  mxUINT8_CLASS) {
492                   
493                    byte[] dataArr =  Convert2ByteArray(realData);
494                    ret = new ILRetArray<byte>(dataArr, dimensions);
495                   
496                } else if (mxClass ==  mxUINT64_CLASS) {
497                   
498                    UInt64[] dataArr =  Convert2UInt64Array(realData);
499                    ret = new ILRetArray<UInt64>(dataArr, dimensions);
500                   
501                } else if (mxClass ==  mxINT64_CLASS) {
502                   
503                    Int64[] dataArr =  Convert2Int64Array(realData);
504                    ret = new ILRetArray<Int64>(dataArr, dimensions);
505                   
506                } else if (mxClass ==  mxUINT32_CLASS) {
507                   
508                    UInt32[] dataArr =  Convert2UInt32Array(realData);
509                    ret = new ILRetArray<UInt32>(dataArr, dimensions);
510                   
511                } else if (mxClass ==  mxINT32_CLASS) {
512                   
513                    Int32[] dataArr =  Convert2Int32Array(realData);
514                    ret = new ILRetArray<Int32>(dataArr, dimensions);
515                   
516                } else if (mxClass ==  mxUINT16_CLASS) {
517                   
518                    UInt16[] dataArr =  Convert2UInt16Array(realData);
519                    ret = new ILRetArray<UInt16>(dataArr, dimensions);
520                   
521                } else if (mxClass ==  mxINT16_CLASS) {
522                   
523                    Int16[] dataArr =  Convert2Int16Array(realData);
524                    ret = new ILRetArray<Int16>(dataArr, dimensions);
525                   
526                } else if (mxClass ==  mxUINT8_CLASS) {
527                   
528                    char[] dataArr =  Convert2CharArray(realData);
529                    ret = new ILRetArray<char>(dataArr, dimensions);
530                   
531                } else if (mxClass ==  mxINT8_CLASS) {
532                   
533                    byte[] dataArr =  Convert2ByteArray(realData);
534                    ret = new ILRetArray<byte>(dataArr, dimensions);
535                   
536                } else if (mxClass ==  mxSINGLE_CLASS) {
537                   
538                    float[] dataArr =  Convert2SingleArray(realData);
539                    ret = new ILRetArray<float>(dataArr, dimensions);
540                   
541                } else if (mxClass ==  mxCHAR_CLASS) {
542                   
543                    char[] dataArr =  Convert2CharArray(realData);
544                    ret = new ILRetArray<char>(dataArr, dimensions);
545
546#endregion HYCALPER AUTO GENERATED CODE
547               } else {
548                    throw new Exception("element data type is not supported");
549                }
550            }
551            // set name       
552            ret.Name = name;
553            return ret;
554        }
555
556
557       
558
559        private  double[]  Convert2DoubleArray(System.Array input) {
560            // keep track of type matches ! No checks will be made!
561           
562            double[] ret = new  double[input.Length];
563            switch (input.GetType().Name.ToLower()) {
564                case "char[]":
565                    for (int i = 0; i < input.Length; i++) {
566                        ret[i] = ( double)(char)input.GetValue(i);
567                    }
568                    break;
569
570                case "uint64[]":
571                    for (int i = 0; i < input.Length; i++) {
572                        ret[i] = ( double)(UInt64)input.GetValue(i);
573                    }
574                    break;
575
576                case "uint32[]":
577                    for (int i = 0; i < input.Length; i++) {
578                        ret[i] = ( double)(UInt32)input.GetValue(i);
579                    }
580                    break;
581
582                case "uint16[]":
583                    for (int i = 0; i < input.Length; i++) {
584                        ret[i] = ( double)(UInt16)input.GetValue(i);
585                    }
586                    break;
587
588                case "int64[]":
589                    for (int i = 0; i < input.Length; i++) {
590                        ret[i] = ( double)(Int64)input.GetValue(i);
591                    }
592                    break;
593
594                case "int32[]":
595                    for (int i = 0; i < input.Length; i++) {
596                        ret[i] = ( double)(Int32)input.GetValue(i);
597                    }
598                    break;
599
600                case "int16[]":
601                    for (int i = 0; i < input.Length; i++) {
602                        ret[i] = ( double)(Int16)input.GetValue(i);
603                    }
604                    break;
605
606                case "single[]":
607                    for (int i = 0; i < input.Length; i++) {
608                        ret[i] = ( double)(float)input.GetValue(i);
609                    }
610                    break;
611
612                case "double[]":
613                    for (int i = 0; i < input.Length; i++) {
614                        ret[i] = ( double)(double)input.GetValue(i);
615                    }
616                    break;
617
618                case "byte[]":
619                    for (int i = 0; i < input.Length; i++) {
620                        ret[i] = ( double)(byte)input.GetValue(i);
621                    }
622                    break;
623                case "sbyte[]":
624                    for (int i = 0; i < input.Length; i++) {
625                        ret[i] = ( double)(sbyte)input.GetValue(i);
626                    }
627                    break;
628                default:
629                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
630            }
631            return ret;
632        }
633
634#region HYCALPER AUTO GENERATED CODE
635
636       
637
638        private  sbyte[]  Convert2SByteArray(System.Array input) {
639            // keep track of type matches ! No checks will be made!
640           
641            sbyte[] ret = new  sbyte[input.Length];
642            switch (input.GetType().Name.ToLower()) {
643                case "char[]":
644                    for (int i = 0; i < input.Length; i++) {
645                        ret[i] = ( sbyte)(char)input.GetValue(i);
646                    }
647                    break;
648
649                case "uint64[]":
650                    for (int i = 0; i < input.Length; i++) {
651                        ret[i] = ( sbyte)(UInt64)input.GetValue(i);
652                    }
653                    break;
654
655                case "uint32[]":
656                    for (int i = 0; i < input.Length; i++) {
657                        ret[i] = ( sbyte)(UInt32)input.GetValue(i);
658                    }
659                    break;
660
661                case "uint16[]":
662                    for (int i = 0; i < input.Length; i++) {
663                        ret[i] = ( sbyte)(UInt16)input.GetValue(i);
664                    }
665                    break;
666
667                case "int64[]":
668                    for (int i = 0; i < input.Length; i++) {
669                        ret[i] = ( sbyte)(Int64)input.GetValue(i);
670                    }
671                    break;
672
673                case "int32[]":
674                    for (int i = 0; i < input.Length; i++) {
675                        ret[i] = ( sbyte)(Int32)input.GetValue(i);
676                    }
677                    break;
678
679                case "int16[]":
680                    for (int i = 0; i < input.Length; i++) {
681                        ret[i] = ( sbyte)(Int16)input.GetValue(i);
682                    }
683                    break;
684
685                case "single[]":
686                    for (int i = 0; i < input.Length; i++) {
687                        ret[i] = ( sbyte)(float)input.GetValue(i);
688                    }
689                    break;
690
691                case "double[]":
692                    for (int i = 0; i < input.Length; i++) {
693                        ret[i] = ( sbyte)(double)input.GetValue(i);
694                    }
695                    break;
696
697                case "byte[]":
698                    for (int i = 0; i < input.Length; i++) {
699                        ret[i] = ( sbyte)(byte)input.GetValue(i);
700                    }
701                    break;
702                case "sbyte[]":
703                    for (int i = 0; i < input.Length; i++) {
704                        ret[i] = ( sbyte)(sbyte)input.GetValue(i);
705                    }
706                    break;
707                default:
708                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
709            }
710            return ret;
711        }
712       
713
714        private  byte[]  Convert2ByteArray(System.Array input) {
715            // keep track of type matches ! No checks will be made!
716           
717            byte[] ret = new  byte[input.Length];
718            switch (input.GetType().Name.ToLower()) {
719                case "char[]":
720                    for (int i = 0; i < input.Length; i++) {
721                        ret[i] = ( byte)(char)input.GetValue(i);
722                    }
723                    break;
724
725                case "uint64[]":
726                    for (int i = 0; i < input.Length; i++) {
727                        ret[i] = ( byte)(UInt64)input.GetValue(i);
728                    }
729                    break;
730
731                case "uint32[]":
732                    for (int i = 0; i < input.Length; i++) {
733                        ret[i] = ( byte)(UInt32)input.GetValue(i);
734                    }
735                    break;
736
737                case "uint16[]":
738                    for (int i = 0; i < input.Length; i++) {
739                        ret[i] = ( byte)(UInt16)input.GetValue(i);
740                    }
741                    break;
742
743                case "int64[]":
744                    for (int i = 0; i < input.Length; i++) {
745                        ret[i] = ( byte)(Int64)input.GetValue(i);
746                    }
747                    break;
748
749                case "int32[]":
750                    for (int i = 0; i < input.Length; i++) {
751                        ret[i] = ( byte)(Int32)input.GetValue(i);
752                    }
753                    break;
754
755                case "int16[]":
756                    for (int i = 0; i < input.Length; i++) {
757                        ret[i] = ( byte)(Int16)input.GetValue(i);
758                    }
759                    break;
760
761                case "single[]":
762                    for (int i = 0; i < input.Length; i++) {
763                        ret[i] = ( byte)(float)input.GetValue(i);
764                    }
765                    break;
766
767                case "double[]":
768                    for (int i = 0; i < input.Length; i++) {
769                        ret[i] = ( byte)(double)input.GetValue(i);
770                    }
771                    break;
772
773                case "byte[]":
774                    for (int i = 0; i < input.Length; i++) {
775                        ret[i] = ( byte)(byte)input.GetValue(i);
776                    }
777                    break;
778                case "sbyte[]":
779                    for (int i = 0; i < input.Length; i++) {
780                        ret[i] = ( byte)(sbyte)input.GetValue(i);
781                    }
782                    break;
783                default:
784                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
785            }
786            return ret;
787        }
788       
789
790        private  UInt64[]  Convert2UInt64Array(System.Array input) {
791            // keep track of type matches ! No checks will be made!
792           
793            UInt64[] ret = new  UInt64[input.Length];
794            switch (input.GetType().Name.ToLower()) {
795                case "char[]":
796                    for (int i = 0; i < input.Length; i++) {
797                        ret[i] = ( UInt64)(char)input.GetValue(i);
798                    }
799                    break;
800
801                case "uint64[]":
802                    for (int i = 0; i < input.Length; i++) {
803                        ret[i] = ( UInt64)(UInt64)input.GetValue(i);
804                    }
805                    break;
806
807                case "uint32[]":
808                    for (int i = 0; i < input.Length; i++) {
809                        ret[i] = ( UInt64)(UInt32)input.GetValue(i);
810                    }
811                    break;
812
813                case "uint16[]":
814                    for (int i = 0; i < input.Length; i++) {
815                        ret[i] = ( UInt64)(UInt16)input.GetValue(i);
816                    }
817                    break;
818
819                case "int64[]":
820                    for (int i = 0; i < input.Length; i++) {
821                        ret[i] = ( UInt64)(Int64)input.GetValue(i);
822                    }
823                    break;
824
825                case "int32[]":
826                    for (int i = 0; i < input.Length; i++) {
827                        ret[i] = ( UInt64)(Int32)input.GetValue(i);
828                    }
829                    break;
830
831                case "int16[]":
832                    for (int i = 0; i < input.Length; i++) {
833                        ret[i] = ( UInt64)(Int16)input.GetValue(i);
834                    }
835                    break;
836
837                case "single[]":
838                    for (int i = 0; i < input.Length; i++) {
839                        ret[i] = ( UInt64)(float)input.GetValue(i);
840                    }
841                    break;
842
843                case "double[]":
844                    for (int i = 0; i < input.Length; i++) {
845                        ret[i] = ( UInt64)(double)input.GetValue(i);
846                    }
847                    break;
848
849                case "byte[]":
850                    for (int i = 0; i < input.Length; i++) {
851                        ret[i] = ( UInt64)(byte)input.GetValue(i);
852                    }
853                    break;
854                case "sbyte[]":
855                    for (int i = 0; i < input.Length; i++) {
856                        ret[i] = ( UInt64)(sbyte)input.GetValue(i);
857                    }
858                    break;
859                default:
860                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
861            }
862            return ret;
863        }
864       
865
866        private  UInt32[]  Convert2UInt32Array(System.Array input) {
867            // keep track of type matches ! No checks will be made!
868           
869            UInt32[] ret = new  UInt32[input.Length];
870            switch (input.GetType().Name.ToLower()) {
871                case "char[]":
872                    for (int i = 0; i < input.Length; i++) {
873                        ret[i] = ( UInt32)(char)input.GetValue(i);
874                    }
875                    break;
876
877                case "uint64[]":
878                    for (int i = 0; i < input.Length; i++) {
879                        ret[i] = ( UInt32)(UInt64)input.GetValue(i);
880                    }
881                    break;
882
883                case "uint32[]":
884                    for (int i = 0; i < input.Length; i++) {
885                        ret[i] = ( UInt32)(UInt32)input.GetValue(i);
886                    }
887                    break;
888
889                case "uint16[]":
890                    for (int i = 0; i < input.Length; i++) {
891                        ret[i] = ( UInt32)(UInt16)input.GetValue(i);
892                    }
893                    break;
894
895                case "int64[]":
896                    for (int i = 0; i < input.Length; i++) {
897                        ret[i] = ( UInt32)(Int64)input.GetValue(i);
898                    }
899                    break;
900
901                case "int32[]":
902                    for (int i = 0; i < input.Length; i++) {
903                        ret[i] = ( UInt32)(Int32)input.GetValue(i);
904                    }
905                    break;
906
907                case "int16[]":
908                    for (int i = 0; i < input.Length; i++) {
909                        ret[i] = ( UInt32)(Int16)input.GetValue(i);
910                    }
911                    break;
912
913                case "single[]":
914                    for (int i = 0; i < input.Length; i++) {
915                        ret[i] = ( UInt32)(float)input.GetValue(i);
916                    }
917                    break;
918
919                case "double[]":
920                    for (int i = 0; i < input.Length; i++) {
921                        ret[i] = ( UInt32)(double)input.GetValue(i);
922                    }
923                    break;
924
925                case "byte[]":
926                    for (int i = 0; i < input.Length; i++) {
927                        ret[i] = ( UInt32)(byte)input.GetValue(i);
928                    }
929                    break;
930                case "sbyte[]":
931                    for (int i = 0; i < input.Length; i++) {
932                        ret[i] = ( UInt32)(sbyte)input.GetValue(i);
933                    }
934                    break;
935                default:
936                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
937            }
938            return ret;
939        }
940       
941
942        private  UInt16[]  Convert2UInt16Array(System.Array input) {
943            // keep track of type matches ! No checks will be made!
944           
945            UInt16[] ret = new  UInt16[input.Length];
946            switch (input.GetType().Name.ToLower()) {
947                case "char[]":
948                    for (int i = 0; i < input.Length; i++) {
949                        ret[i] = ( UInt16)(char)input.GetValue(i);
950                    }
951                    break;
952
953                case "uint64[]":
954                    for (int i = 0; i < input.Length; i++) {
955                        ret[i] = ( UInt16)(UInt64)input.GetValue(i);
956                    }
957                    break;
958
959                case "uint32[]":
960                    for (int i = 0; i < input.Length; i++) {
961                        ret[i] = ( UInt16)(UInt32)input.GetValue(i);
962                    }
963                    break;
964
965                case "uint16[]":
966                    for (int i = 0; i < input.Length; i++) {
967                        ret[i] = ( UInt16)(UInt16)input.GetValue(i);
968                    }
969                    break;
970
971                case "int64[]":
972                    for (int i = 0; i < input.Length; i++) {
973                        ret[i] = ( UInt16)(Int64)input.GetValue(i);
974                    }
975                    break;
976
977                case "int32[]":
978                    for (int i = 0; i < input.Length; i++) {
979                        ret[i] = ( UInt16)(Int32)input.GetValue(i);
980                    }
981                    break;
982
983                case "int16[]":
984                    for (int i = 0; i < input.Length; i++) {
985                        ret[i] = ( UInt16)(Int16)input.GetValue(i);
986                    }
987                    break;
988
989                case "single[]":
990                    for (int i = 0; i < input.Length; i++) {
991                        ret[i] = ( UInt16)(float)input.GetValue(i);
992                    }
993                    break;
994
995                case "double[]":
996                    for (int i = 0; i < input.Length; i++) {
997                        ret[i] = ( UInt16)(double)input.GetValue(i);
998                    }
999                    break;
1000
1001                case "byte[]":
1002                    for (int i = 0; i < input.Length; i++) {
1003                        ret[i] = ( UInt16)(byte)input.GetValue(i);
1004                    }
1005                    break;
1006                case "sbyte[]":
1007                    for (int i = 0; i < input.Length; i++) {
1008                        ret[i] = ( UInt16)(sbyte)input.GetValue(i);
1009                    }
1010                    break;
1011                default:
1012                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
1013            }
1014            return ret;
1015        }
1016       
1017
1018        private  Int64[]  Convert2Int64Array(System.Array input) {
1019            // keep track of type matches ! No checks will be made!
1020           
1021            Int64[] ret = new  Int64[input.Length];
1022            switch (input.GetType().Name.ToLower()) {
1023                case "char[]":
1024                    for (int i = 0; i < input.Length; i++) {
1025                        ret[i] = ( Int64)(char)input.GetValue(i);
1026                    }
1027                    break;
1028
1029                case "uint64[]":
1030                    for (int i = 0; i < input.Length; i++) {
1031                        ret[i] = ( Int64)(UInt64)input.GetValue(i);
1032                    }
1033                    break;
1034
1035                case "uint32[]":
1036                    for (int i = 0; i < input.Length; i++) {
1037                        ret[i] = ( Int64)(UInt32)input.GetValue(i);
1038                    }
1039                    break;
1040
1041                case "uint16[]":
1042                    for (int i = 0; i < input.Length; i++) {
1043                        ret[i] = ( Int64)(UInt16)input.GetValue(i);
1044                    }
1045                    break;
1046
1047                case "int64[]":
1048                    for (int i = 0; i < input.Length; i++) {
1049                        ret[i] = ( Int64)(Int64)input.GetValue(i);
1050                    }
1051                    break;
1052
1053                case "int32[]":
1054                    for (int i = 0; i < input.Length; i++) {
1055                        ret[i] = ( Int64)(Int32)input.GetValue(i);
1056                    }
1057                    break;
1058
1059                case "int16[]":
1060                    for (int i = 0; i < input.Length; i++) {
1061                        ret[i] = ( Int64)(Int16)input.GetValue(i);
1062                    }
1063                    break;
1064
1065                case "single[]":
1066                    for (int i = 0; i < input.Length; i++) {
1067                        ret[i] = ( Int64)(float)input.GetValue(i);
1068                    }
1069                    break;
1070
1071                case "double[]":
1072                    for (int i = 0; i < input.Length; i++) {
1073                        ret[i] = ( Int64)(double)input.GetValue(i);
1074                    }
1075                    break;
1076
1077                case "byte[]":
1078                    for (int i = 0; i < input.Length; i++) {
1079                        ret[i] = ( Int64)(byte)input.GetValue(i);
1080                    }
1081                    break;
1082                case "sbyte[]":
1083                    for (int i = 0; i < input.Length; i++) {
1084                        ret[i] = ( Int64)(sbyte)input.GetValue(i);
1085                    }
1086                    break;
1087                default:
1088                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
1089            }
1090            return ret;
1091        }
1092       
1093
1094        private  Int32[]  Convert2Int32Array(System.Array input) {
1095            // keep track of type matches ! No checks will be made!
1096           
1097            Int32[] ret = new  Int32[input.Length];
1098            switch (input.GetType().Name.ToLower()) {
1099                case "char[]":
1100                    for (int i = 0; i < input.Length; i++) {
1101                        ret[i] = ( Int32)(char)input.GetValue(i);
1102                    }
1103                    break;
1104
1105                case "uint64[]":
1106                    for (int i = 0; i < input.Length; i++) {
1107                        ret[i] = ( Int32)(UInt64)input.GetValue(i);
1108                    }
1109                    break;
1110
1111                case "uint32[]":
1112                    for (int i = 0; i < input.Length; i++) {
1113                        ret[i] = ( Int32)(UInt32)input.GetValue(i);
1114                    }
1115                    break;
1116
1117                case "uint16[]":
1118                    for (int i = 0; i < input.Length; i++) {
1119                        ret[i] = ( Int32)(UInt16)input.GetValue(i);
1120                    }
1121                    break;
1122
1123                case "int64[]":
1124                    for (int i = 0; i < input.Length; i++) {
1125                        ret[i] = ( Int32)(Int64)input.GetValue(i);
1126                    }
1127                    break;
1128
1129                case "int32[]":
1130                    for (int i = 0; i < input.Length; i++) {
1131                        ret[i] = ( Int32)(Int32)input.GetValue(i);
1132                    }
1133                    break;
1134
1135                case "int16[]":
1136                    for (int i = 0; i < input.Length; i++) {
1137                        ret[i] = ( Int32)(Int16)input.GetValue(i);
1138                    }
1139                    break;
1140
1141                case "single[]":
1142                    for (int i = 0; i < input.Length; i++) {
1143                        ret[i] = ( Int32)(float)input.GetValue(i);
1144                    }
1145                    break;
1146
1147                case "double[]":
1148                    for (int i = 0; i < input.Length; i++) {
1149                        ret[i] = ( Int32)(double)input.GetValue(i);
1150                    }
1151                    break;
1152
1153                case "byte[]":
1154                    for (int i = 0; i < input.Length; i++) {
1155                        ret[i] = ( Int32)(byte)input.GetValue(i);
1156                    }
1157                    break;
1158                case "sbyte[]":
1159                    for (int i = 0; i < input.Length; i++) {
1160                        ret[i] = ( Int32)(sbyte)input.GetValue(i);
1161                    }
1162                    break;
1163                default:
1164                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
1165            }
1166            return ret;
1167        }
1168       
1169
1170        private  Int16[]  Convert2Int16Array(System.Array input) {
1171            // keep track of type matches ! No checks will be made!
1172           
1173            Int16[] ret = new  Int16[input.Length];
1174            switch (input.GetType().Name.ToLower()) {
1175                case "char[]":
1176                    for (int i = 0; i < input.Length; i++) {
1177                        ret[i] = ( Int16)(char)input.GetValue(i);
1178                    }
1179                    break;
1180
1181                case "uint64[]":
1182                    for (int i = 0; i < input.Length; i++) {
1183                        ret[i] = ( Int16)(UInt64)input.GetValue(i);
1184                    }
1185                    break;
1186
1187                case "uint32[]":
1188                    for (int i = 0; i < input.Length; i++) {
1189                        ret[i] = ( Int16)(UInt32)input.GetValue(i);
1190                    }
1191                    break;
1192
1193                case "uint16[]":
1194                    for (int i = 0; i < input.Length; i++) {
1195                        ret[i] = ( Int16)(UInt16)input.GetValue(i);
1196                    }
1197                    break;
1198
1199                case "int64[]":
1200                    for (int i = 0; i < input.Length; i++) {
1201                        ret[i] = ( Int16)(Int64)input.GetValue(i);
1202                    }
1203                    break;
1204
1205                case "int32[]":
1206                    for (int i = 0; i < input.Length; i++) {
1207                        ret[i] = ( Int16)(Int32)input.GetValue(i);
1208                    }
1209                    break;
1210
1211                case "int16[]":
1212                    for (int i = 0; i < input.Length; i++) {
1213                        ret[i] = ( Int16)(Int16)input.GetValue(i);
1214                    }
1215                    break;
1216
1217                case "single[]":
1218                    for (int i = 0; i < input.Length; i++) {
1219                        ret[i] = ( Int16)(float)input.GetValue(i);
1220                    }
1221                    break;
1222
1223                case "double[]":
1224                    for (int i = 0; i < input.Length; i++) {
1225                        ret[i] = ( Int16)(double)input.GetValue(i);
1226                    }
1227                    break;
1228
1229                case "byte[]":
1230                    for (int i = 0; i < input.Length; i++) {
1231                        ret[i] = ( Int16)(byte)input.GetValue(i);
1232                    }
1233                    break;
1234                case "sbyte[]":
1235                    for (int i = 0; i < input.Length; i++) {
1236                        ret[i] = ( Int16)(sbyte)input.GetValue(i);
1237                    }
1238                    break;
1239                default:
1240                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
1241            }
1242            return ret;
1243        }
1244       
1245
1246        private  char[]  Convert2CharArray(System.Array input) {
1247            // keep track of type matches ! No checks will be made!
1248           
1249            char[] ret = new  char[input.Length];
1250            switch (input.GetType().Name.ToLower()) {
1251                case "char[]":
1252                    for (int i = 0; i < input.Length; i++) {
1253                        ret[i] = ( char)(char)input.GetValue(i);
1254                    }
1255                    break;
1256
1257                case "uint64[]":
1258                    for (int i = 0; i < input.Length; i++) {
1259                        ret[i] = ( char)(UInt64)input.GetValue(i);
1260                    }
1261                    break;
1262
1263                case "uint32[]":
1264                    for (int i = 0; i < input.Length; i++) {
1265                        ret[i] = ( char)(UInt32)input.GetValue(i);
1266                    }
1267                    break;
1268
1269                case "uint16[]":
1270                    for (int i = 0; i < input.Length; i++) {
1271                        ret[i] = ( char)(UInt16)input.GetValue(i);
1272                    }
1273                    break;
1274
1275                case "int64[]":
1276                    for (int i = 0; i < input.Length; i++) {
1277                        ret[i] = ( char)(Int64)input.GetValue(i);
1278                    }
1279                    break;
1280
1281                case "int32[]":
1282                    for (int i = 0; i < input.Length; i++) {
1283                        ret[i] = ( char)(Int32)input.GetValue(i);
1284                    }
1285                    break;
1286
1287                case "int16[]":
1288                    for (int i = 0; i < input.Length; i++) {
1289                        ret[i] = ( char)(Int16)input.GetValue(i);
1290                    }
1291                    break;
1292
1293                case "single[]":
1294                    for (int i = 0; i < input.Length; i++) {
1295                        ret[i] = ( char)(float)input.GetValue(i);
1296                    }
1297                    break;
1298
1299                case "double[]":
1300                    for (int i = 0; i < input.Length; i++) {
1301                        ret[i] = ( char)(double)input.GetValue(i);
1302                    }
1303                    break;
1304
1305                case "byte[]":
1306                    for (int i = 0; i < input.Length; i++) {
1307                        ret[i] = ( char)(byte)input.GetValue(i);
1308                    }
1309                    break;
1310                case "sbyte[]":
1311                    for (int i = 0; i < input.Length; i++) {
1312                        ret[i] = ( char)(sbyte)input.GetValue(i);
1313                    }
1314                    break;
1315                default:
1316                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
1317            }
1318            return ret;
1319        }
1320       
1321
1322        private  float[]  Convert2SingleArray(System.Array input) {
1323            // keep track of type matches ! No checks will be made!
1324           
1325            float[] ret = new  float[input.Length];
1326            switch (input.GetType().Name.ToLower()) {
1327                case "char[]":
1328                    for (int i = 0; i < input.Length; i++) {
1329                        ret[i] = ( float)(char)input.GetValue(i);
1330                    }
1331                    break;
1332
1333                case "uint64[]":
1334                    for (int i = 0; i < input.Length; i++) {
1335                        ret[i] = ( float)(UInt64)input.GetValue(i);
1336                    }
1337                    break;
1338
1339                case "uint32[]":
1340                    for (int i = 0; i < input.Length; i++) {
1341                        ret[i] = ( float)(UInt32)input.GetValue(i);
1342                    }
1343                    break;
1344
1345                case "uint16[]":
1346                    for (int i = 0; i < input.Length; i++) {
1347                        ret[i] = ( float)(UInt16)input.GetValue(i);
1348                    }
1349                    break;
1350
1351                case "int64[]":
1352                    for (int i = 0; i < input.Length; i++) {
1353                        ret[i] = ( float)(Int64)input.GetValue(i);
1354                    }
1355                    break;
1356
1357                case "int32[]":
1358                    for (int i = 0; i < input.Length; i++) {
1359                        ret[i] = ( float)(Int32)input.GetValue(i);
1360                    }
1361                    break;
1362
1363                case "int16[]":
1364                    for (int i = 0; i < input.Length; i++) {
1365                        ret[i] = ( float)(Int16)input.GetValue(i);
1366                    }
1367                    break;
1368
1369                case "single[]":
1370                    for (int i = 0; i < input.Length; i++) {
1371                        ret[i] = ( float)(float)input.GetValue(i);
1372                    }
1373                    break;
1374
1375                case "double[]":
1376                    for (int i = 0; i < input.Length; i++) {
1377                        ret[i] = ( float)(double)input.GetValue(i);
1378                    }
1379                    break;
1380
1381                case "byte[]":
1382                    for (int i = 0; i < input.Length; i++) {
1383                        ret[i] = ( float)(byte)input.GetValue(i);
1384                    }
1385                    break;
1386                case "sbyte[]":
1387                    for (int i = 0; i < input.Length; i++) {
1388                        ret[i] = ( float)(sbyte)input.GetValue(i);
1389                    }
1390                    break;
1391                default:
1392                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
1393            }
1394            return ret;
1395        }
1396
1397#endregion HYCALPER AUTO GENERATED CODE
1398
1399        private byte[] Convert2Logical(System.Array input, out int numNonzero) {
1400            // keep track of type matches ! No checks will be made!
1401            numNonzero = 0;
1402            byte[] ret = new byte[input.Length];
1403            switch (input.GetType().Name.ToLower()) {
1404                case "char[]":
1405                    for (int i = 0; i < input.Length; i++) {
1406                        if ((char)input.GetValue(i) == 0) {
1407                            ret[i] = 0;
1408                        } else {
1409                            ret[i] = 1;
1410                            numNonzero++;
1411                        }
1412                    }
1413                    break;
1414
1415                case "uint64[]":
1416                    for (int i = 0; i < input.Length; i++) {
1417                        if ((UInt64)input.GetValue(i) == 0) {
1418                            ret[i] = 0;
1419                        } else {
1420                            ret[i] = 1;
1421                            numNonzero++;
1422                        }
1423                    }
1424                    break;
1425
1426                case "uint32[]":
1427                    for (int i = 0; i < input.Length; i++) {
1428                        if ((UInt32)input.GetValue(i) == 0) {
1429                            ret[i] = 0;
1430                        } else {
1431                            ret[i] = 1;
1432                            numNonzero++;
1433                        }
1434                    }
1435                    break;
1436
1437                case "uint16[]":
1438                    for (int i = 0; i < input.Length; i++) {
1439                        if ((UInt16)input.GetValue(i) == 0) {
1440                            ret[i] = 0;
1441                        } else {
1442                            ret[i] = 1;
1443                            numNonzero++;
1444                        }
1445                    }
1446                    break;
1447
1448                case "int64[]":
1449                    for (int i = 0; i < input.Length; i++) {
1450                        if ((Int64)input.GetValue(i) == 0) {
1451                            ret[i] = 0;
1452                        } else {
1453                            ret[i] = 1;
1454                            numNonzero++;
1455                        }
1456                    }
1457                    break;
1458
1459                case "int32[]":
1460                    for (int i = 0; i < input.Length; i++) {
1461                        if ((Int32)input.GetValue(i) == 0) {
1462                            ret[i] = 0;
1463                        } else {
1464                            ret[i] = 1;
1465                            numNonzero++;
1466                        }
1467                    }
1468                    break;
1469
1470                case "int16[]":
1471                    for (int i = 0; i < input.Length; i++) {
1472                        if ((Int16)input.GetValue(i) == 0) {
1473                            ret[i] = 0;
1474                        } else {
1475                            ret[i] = 1;
1476                            numNonzero++;
1477                        }
1478                    }
1479                    break;
1480
1481                case "single[]":
1482                    for (int i = 0; i < input.Length; i++) {
1483                        if ((float)input.GetValue(i) == 0) {
1484                            ret[i] = 0;
1485                        } else {
1486                            ret[i] = 1;
1487                            numNonzero++;
1488                        }
1489                    }
1490                    break;
1491
1492                case "double[]":
1493                    for (int i = 0; i < input.Length; i++) {
1494                        if ((double)input.GetValue(i) == 0) {
1495                            ret[i] = 0;
1496                        } else {
1497                            ret[i] = 1;
1498                            numNonzero++;
1499                        }
1500                    }
1501                    break;
1502
1503                case "byte[]":
1504                    for (int i = 0; i < input.Length; i++) {
1505                        if ((byte)input.GetValue(i) == 0) {
1506                            ret[i] = 0;
1507                        } else {
1508                            ret[i] = 1;
1509                            numNonzero++;
1510                        }
1511                    }
1512                    break;
1513
1514                case "sbyte[]":
1515                    for (int i = 0; i < input.Length; i++) {
1516                        if ((sbyte)input.GetValue(i) == 0) {
1517                            ret[i] = 0;
1518                        } else {
1519                            ret[i] = 1;
1520                            numNonzero++;
1521                        }
1522                    }
1523                    break;
1524                default:
1525                    throw new InvalidCastException("cannot convert from '" + input.GetType().Name + "'!");
1526            }
1527            return ret;
1528        }
1529        private static void readElementGeneric(BinaryReader br, MatFileType storageType, out System.Array realData, ref Int32 len) {
1530            readElementGeneric(br, storageType, out realData, ref len, 8);
1531        }
1532        /// <summary>
1533        /// read array of supported matlab data types
1534        /// </summary>
1535        /// <param name="br">binary reader, opened and correctly positioned</param>
1536        /// <param name="storageType">actual storage type</param>
1537        /// <param name="realData">output: on return, the array read</param>
1538        /// <param name="len">input: number of bytes to read, on return: number of elements in array</param>
1539        /// <param name="paddBytes">padding border, the stream will be read to the next border of length 'paddBytes'.</param>
1540        private static void readElementGeneric(BinaryReader br, MatFileType storageType, out System.Array realData, ref Int32 len, int paddBytes) {
1541            Int32 readInt = len;
1542            switch (storageType) {
1543                case MatFileType.miINT8:
1544                    realData = System.Array.CreateInstance(typeof(sbyte), readInt / sizeOf(storageType));
1545                    len = realData.Length;
1546                    for (int i = 0; i < len; i++) {
1547                        realData.SetValue(br.ReadSByte(), i);
1548                    }
1549                    while (len % paddBytes != 0) {
1550                        br.ReadByte();
1551                        len++;
1552                    }
1553                    break;
1554                case MatFileType.miUINT8:
1555                    realData = System.Array.CreateInstance(typeof(byte), readInt / sizeOf(storageType));
1556                    len = realData.Length;
1557                    realData = br.ReadBytes(len);
1558                    while (len % paddBytes != 0) {
1559                        br.ReadByte();
1560                        len++;
1561                    }
1562                    break;
1563                case MatFileType.miINT16:
1564                    realData = System.Array.CreateInstance(typeof(short), readInt / sizeOf(storageType));
1565                    len = realData.Length;
1566                    for (int i = 0; i < len; i++) {
1567                        realData.SetValue(br.ReadInt16(), i);
1568                    }
1569                    while ((len * sizeOf(storageType) % paddBytes) != 0) {
1570                        len++;
1571                        br.ReadInt16();
1572                    }
1573                    break;
1574                case MatFileType.miUINT16:
1575                    realData = System.Array.CreateInstance(typeof(UInt16), readInt / sizeOf(storageType));
1576                    len = realData.Length;
1577                    for (int i = 0; i < len; i++) {
1578                        realData.SetValue(br.ReadUInt16(), i);
1579                    }
1580                    while ((len * sizeOf(storageType) % paddBytes) != 0) {
1581                        len++;
1582                        br.ReadUInt16();
1583                    }
1584                    break;
1585                case MatFileType.miINT32:
1586                    realData = System.Array.CreateInstance(typeof(Int32), readInt / sizeOf(storageType));
1587                    len = realData.Length;
1588                    for (int i = 0; i < len; i++) {
1589                        realData.SetValue(br.ReadInt32(), i);
1590                    }
1591                    while ((len * sizeOf(storageType) % paddBytes) != 0) {
1592                        len++;
1593                        br.ReadInt32();
1594                    }
1595                    break;
1596                case MatFileType.miUINT32:
1597                    realData = System.Array.CreateInstance(typeof(UInt32), readInt / sizeOf(storageType));
1598                    len = realData.Length;
1599                    for (int i = 0; i < len; i++) {
1600                        realData.SetValue(br.ReadUInt32(), i);
1601                    }
1602                    while ((len * sizeOf(storageType) % paddBytes) != 0) {
1603                        len++;
1604                        br.ReadUInt32();
1605                    }
1606                    break;
1607                case MatFileType.miSINGLE:
1608                    realData = System.Array.CreateInstance(typeof(float), readInt / sizeOf(storageType));
1609                    len = realData.Length;
1610                    for (int i = 0; i < len; i++) {
1611                        realData.SetValue(br.ReadSingle(), i);
1612                    }
1613                    while ((len * sizeOf(storageType) % paddBytes) != 0) {
1614                        len++;
1615                        br.ReadSingle();
1616                    }
1617                    break;
1618                case MatFileType.miDOUBLE:
1619                    realData = System.Array.CreateInstance(typeof(double), readInt / sizeOf(storageType));
1620                    len = realData.Length;
1621                    for (int i = 0; i < len; i++) {
1622                        realData.SetValue(br.ReadDouble(), i);
1623                    }
1624                    while ((len * sizeOf(storageType) % paddBytes) != 0) {
1625                        len++;
1626                        br.ReadDouble();
1627                    }
1628                    break;
1629                case MatFileType.miINT64:
1630                    realData = System.Array.CreateInstance(typeof(Int64), readInt / sizeOf(storageType));
1631                    len = realData.Length;
1632                    for (int i = 0; i < len; i++) {
1633                        realData.SetValue(br.ReadInt64(), i);
1634                    }
1635                    while ((len * sizeOf(storageType) % paddBytes) != 0) {
1636                        len++;
1637                        br.ReadInt64();
1638                    }
1639                    break;
1640                case MatFileType.miUINT64:
1641                    realData = System.Array.CreateInstance(typeof(UInt64), readInt / sizeOf(storageType));
1642                    len = realData.Length;
1643                    for (int i = 0; i < len; i++) {
1644                        realData.SetValue(br.ReadUInt64(), i);
1645                    }
1646                    while ((len * sizeOf(storageType) % paddBytes) != 0) {
1647                        len++;
1648                        br.ReadInt64();
1649                    }
1650                    break;
1651                case MatFileType.miMATRIX:
1652                    throw new NotSupportedException("matrix data type not expected as inner datatype!");
1653                case MatFileType.miCOMPRESSED:
1654                    throw new NotSupportedException("Compressed matrix are not supported (yet)! ");
1655                case MatFileType.miUTF8:
1656                    realData = System.Array.CreateInstance(typeof(UTF8Encoding), readInt / sizeOf(storageType));
1657                    len = realData.Length;
1658                    for (int i = 0; i < len; i++) {
1659                        realData.SetValue(br.ReadUInt16(), i);
1660                    }
1661                    while ((len * sizeOf(storageType) % paddBytes) != 0) {
1662                        len++;
1663                        br.ReadInt16();
1664                    }
1665                    break;
1666                case MatFileType.miUTF16:
1667                    throw new NotSupportedException("UTF16 data type not supported (yet)!");
1668                case MatFileType.miUTF32:
1669                    realData = System.Array.CreateInstance(typeof(UTF32Encoding), readInt / sizeOf(storageType));
1670                    len = realData.Length;
1671                    for (int i = 0; i < len; i++) {
1672                        realData.SetValue(br.ReadChars(2), i);
1673                    }
1674                    while ((len * sizeOf(storageType) % paddBytes) != 0) {
1675                        len++;
1676                        br.ReadChars(2);
1677                    }
1678                    break;
1679                default:
1680                    throw new Exception("Unknown element data type found! Cancelling...");
1681            }
1682        }
1683        private void write(BinaryWriter fileout) {
1684            try {
1685                // write MAT-header
1686                StringBuilder headerLine = new StringBuilder("vers. 5.0 MAT-FILE Creator: ILNumerics, 2011");
1687                while (headerLine.Length < 123)
1688                    headerLine.Append(' ');
1689                fileout.Write(headerLine.ToString());
1690                fileout.Write((short)0x0100);
1691                fileout.Write((short)0x4d49);
1692                int tmpInt = 0;
1693                foreach (string name in Keys) {
1694                    ILBaseArray arr = this[name];
1695                    using (ILScope.Enter(arr)) {
1696                        // determine overall length
1697                        int[] dimensionSubelement = createDimensionSubelement(arr);
1698                        byte[] nameElememData; int nameElemType;
1699                        createNameSubelement(name, out nameElemType, out nameElememData);
1700                        // write subarray header               
1701                        // mxarray subelement type
1702                        fileout.Write((int)MatFileType.miMATRIX);
1703                        // determine length of single array element
1704                        int elemLen = getElementLength(arr);
1705                        //System.Diagnostics.Debug.Assert(arr.IsMatrix,"TODO: n-dim. arrays are not implemented yet!");
1706                        // overall length of subarray container
1707                        int allLength = 16 // array flags
1708                                      + dimensionSubelement.Length * 4   // dimension element
1709                                      + nameElememData.Length + 8; // name element
1710                        int dataSubelemLen = elemLen * arr.Size.NumberOfElements + 8;
1711                        // recognize padding!
1712                        if (dataSubelemLen % 8 != 0)
1713                            dataSubelemLen += (8 - ((elemLen * arr.Size.NumberOfElements) % 8));
1714                        allLength += dataSubelemLen;
1715                        if (arr.IsComplex)
1716                            allLength += dataSubelemLen;
1717                        fileout.Write(allLength);
1718                        // subelement: array flags
1719                        // miUInt32 , length: 8
1720                        fileout.Write((int)MatFileType.miUINT32);
1721                        fileout.Write(8);
1722                        // write array flags 
1723                        int flag = getElementClass(arr);
1724                        if (arr.IsComplex)
1725                            flag |= mtFLAG_COMPLEX;
1726                        if (arr is ILBaseLogical)
1727                            flag |= mtFLAG_LOGICAL;
1728                        fileout.Write(flag);
1729                        fileout.Write(0);      // this is later used for sparse arrays
1730                        // write dimensions tag     
1731                        for (int i = 0; i < dimensionSubelement.Length; i++)
1732                            fileout.Write(dimensionSubelement[i]);
1733                        // write array name     
1734                        fileout.Write((int)MatFileType.miINT8);
1735                        fileout.Write(name.Length);
1736                        fileout.Write(nameElememData);
1737                        // write matrix elements     
1738                        allLength = arr.Size.NumberOfElements;
1739                        if (false) {
1740
1741                        } else if (arr is ILDenseArray<double>) {
1742                            // header of array subdata element     
1743                            fileout.Write((int) MatFileType.miDOUBLE);
1744                            fileout.Write(allLength * elemLen);
1745                            ILDenseArray<double> tmp = (arr as ILDenseArray<double>);
1746                           
1747                            double[] arrArray = tmp.GetArrayForRead();
1748                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1749                                fileout.Write( //
1750                                    arrArray[i]  //
1751                                );
1752                            }
1753
1754#region HYCALPER AUTO GENERATED CODE
1755
1756                        } else if (arr is ILDenseArray<fcomplex>) {
1757                            // header of array subdata element     
1758                            fileout.Write((int) MatFileType.miSINGLE);
1759                            fileout.Write(allLength * elemLen);
1760                            ILDenseArray<fcomplex> tmp = (arr as ILDenseArray<fcomplex>);
1761                           
1762                            fcomplex[] arrArray = tmp.GetArrayForRead();
1763                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1764                                fileout.Write(
1765                                    arrArray[i]  .real
1766                                );
1767                            }
1768                        } else if (arr is ILDenseArray<complex>) {
1769                            // header of array subdata element     
1770                            fileout.Write((int) MatFileType.miDOUBLE);
1771                            fileout.Write(allLength * elemLen);
1772                            ILDenseArray<complex> tmp = (arr as ILDenseArray<complex>);
1773                           
1774                            complex[] arrArray = tmp.GetArrayForRead();
1775                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1776                                fileout.Write(
1777                                    arrArray[i]  .real
1778                                );
1779                            }
1780                        } else if (arr is ILDenseArray<UInt32>) {
1781                            // header of array subdata element     
1782                            fileout.Write((int) MatFileType.miUINT32);
1783                            fileout.Write(allLength * elemLen);
1784                            ILDenseArray<UInt32> tmp = (arr as ILDenseArray<UInt32>);
1785                           
1786                            UInt32[] arrArray = tmp.GetArrayForRead();
1787                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1788                                fileout.Write(
1789                                    arrArray[i]   
1790                                );
1791                            }
1792                        } else if (arr is ILDenseArray<UInt16>) {
1793                            // header of array subdata element     
1794                            fileout.Write((int) MatFileType.miUINT16);
1795                            fileout.Write(allLength * elemLen);
1796                            ILDenseArray<UInt16> tmp = (arr as ILDenseArray<UInt16>);
1797                           
1798                            UInt16[] arrArray = tmp.GetArrayForRead();
1799                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1800                                fileout.Write(
1801                                    arrArray[i]   
1802                                );
1803                            }
1804                        } else if (arr is ILDenseArray<Int32>) {
1805                            // header of array subdata element     
1806                            fileout.Write((int) MatFileType.miINT32);
1807                            fileout.Write(allLength * elemLen);
1808                            ILDenseArray<Int32> tmp = (arr as ILDenseArray<Int32>);
1809                           
1810                            Int32[] arrArray = tmp.GetArrayForRead();
1811                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1812                                fileout.Write(
1813                                    arrArray[i]   
1814                                );
1815                            }
1816                        } else if (arr is ILDenseArray<Int16>) {
1817                            // header of array subdata element     
1818                            fileout.Write((int) MatFileType.miINT16);
1819                            fileout.Write(allLength * elemLen);
1820                            ILDenseArray<Int16> tmp = (arr as ILDenseArray<Int16>);
1821                           
1822                            Int16[] arrArray = tmp.GetArrayForRead();
1823                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1824                                fileout.Write(
1825                                    arrArray[i]   
1826                                );
1827                            }
1828                        } else if (arr is ILDenseArray<float>) {
1829                            // header of array subdata element     
1830                            fileout.Write((int) MatFileType.miSINGLE);
1831                            fileout.Write(allLength * elemLen);
1832                            ILDenseArray<float> tmp = (arr as ILDenseArray<float>);
1833                           
1834                            float[] arrArray = tmp.GetArrayForRead();
1835                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1836                                fileout.Write(
1837                                    arrArray[i]   
1838                                );
1839                            }
1840                        } else if (arr is ILDenseArray<char>) {
1841                            // header of array subdata element     
1842                            fileout.Write((int) MatFileType.miUINT16);
1843                            fileout.Write(allLength * elemLen);
1844                            ILDenseArray<char> tmp = (arr as ILDenseArray<char>);
1845                           
1846                            char[] arrArray = tmp.GetArrayForRead();
1847                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1848                                fileout.Write( (UInt16)
1849                                    arrArray[i]   
1850                                );
1851                            }
1852                        } else if (arr is ILDenseArray<byte>) {
1853                            // header of array subdata element     
1854                            fileout.Write((int) MatFileType.miUINT8);
1855                            fileout.Write(allLength * elemLen);
1856                            ILDenseArray<byte> tmp = (arr as ILDenseArray<byte>);
1857                           
1858                            byte[] arrArray = tmp.GetArrayForRead();
1859                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1860                                fileout.Write(
1861                                    arrArray[i]   
1862                                );
1863                            }
1864                        } else if (arr is ILDenseArray<UInt64>) {
1865                            // header of array subdata element     
1866                            fileout.Write((int) MatFileType.miUINT64);
1867                            fileout.Write(allLength * elemLen);
1868                            ILDenseArray<UInt64> tmp = (arr as ILDenseArray<UInt64>);
1869                           
1870                            UInt64[] arrArray = tmp.GetArrayForRead();
1871                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1872                                fileout.Write(
1873                                    arrArray[i]   
1874                                );
1875                            }
1876                        } else if (arr is ILDenseArray<Int64>) {
1877                            // header of array subdata element     
1878                            fileout.Write((int) MatFileType.miINT64);
1879                            fileout.Write(allLength * elemLen);
1880                            ILDenseArray<Int64> tmp = (arr as ILDenseArray<Int64>);
1881                           
1882                            Int64[] arrArray = tmp.GetArrayForRead();
1883                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1884                                fileout.Write(
1885                                    arrArray[i]   
1886                                );
1887                            }
1888                        } else if (arr is ILDenseArray<sbyte>) {
1889                            // header of array subdata element     
1890                            fileout.Write((int) MatFileType.miINT8);
1891                            fileout.Write(allLength * elemLen);
1892                            ILDenseArray<sbyte> tmp = (arr as ILDenseArray<sbyte>);
1893                           
1894                            sbyte[] arrArray = tmp.GetArrayForRead();
1895                            for (int i = 0; i < arr.Size.NumberOfElements; i++) {
1896                                fileout.Write(
1897                                    arrArray[i]   
1898                                );
1899                            }
1900
1901#endregion HYCALPER AUTO GENERATED CODE
1902                       } else {
1903                            throw new FormatException("The format of the array was not known!");
1904                        }
1905                        // pad to 8 byte border
1906                        tmpInt = allLength * elemLen;
1907                        byte dummy = 0;
1908                        while (tmpInt % 8 != 0) {
1909                            fileout.Write(dummy);
1910                            tmpInt++;
1911                        }
1912                        #region imaginary part
1913                        if (arr.IsComplex) {
1914                            if (arr is ILDenseArray<complex>) {
1915                                ILDenseArray<complex> tmp = (arr as ILDenseArray<complex>);
1916                                // header of array subdata element     
1917                                fileout.Write((int)MatFileType.miDOUBLE);
1918                                fileout.Write(allLength * elemLen);
1919                                complex[] arrArray = tmp.GetArrayForRead();
1920                                for (int i = 0; i < arrArray.Length; i++) {
1921                                    fileout.Write(arrArray[i].imag
1922                                    );
1923                                }
1924                            } else if (arr is ILDenseArray<fcomplex>) {
1925                                fileout.Write((int)MatFileType.miSINGLE);
1926                                fileout.Write(allLength * elemLen);
1927                                ILDenseArray<fcomplex> tmp = (arr as ILDenseArray<fcomplex>);
1928                                fcomplex[] arrArray = tmp.GetArrayForRead();
1929                                for (int i = 0; i < arrArray.Length; i++) {
1930                                    fileout.Write(arrArray[i].imag
1931                                    );
1932                                }
1933                            }
1934                            // pad to 8 byte border
1935                            tmpInt = allLength * elemLen;
1936                            dummy = 0;
1937                            while (tmpInt % 8 != 0) {
1938                                fileout.Write(dummy);
1939                                tmpInt++;
1940                            }
1941                        }
1942                        #endregion
1943                    }
1944                }
1945                fileout.Close();
1946            } catch (Exception e) {
1947                throw e;
1948            }
1949        }
1950        /// <summary>
1951        /// create name subelement for Matfile storage - padded to 8 byte border
1952        /// </summary>
1953        /// <param name="arrName">name property</param>
1954        /// <param name="type">will be 'miINT8' on return</param>
1955        /// <param name="data">return data array </param>
1956        private void createNameSubelement(string arrName, out int type, out byte[] data) {
1957            int len = arrName.Length;
1958            if (len % 8 != 0)
1959                len += (8 - len % 8);
1960            data = new byte[len];
1961            for (int i = 0; i < arrName.Length; i++) {
1962                data[i] = (byte)arrName[i];
1963            }
1964            type = (int)MatFileType.miINT8;
1965            return;
1966        }
1967        private int[] createDimensionSubelement(ILBaseArray arr) {
1968            int[] ret;
1969            int LengthInt;
1970            // determine length of dimensions array byte (padding to full 8 byte border)
1971            if (arr.Size.NumberOfDimensions % 2 == 0) {
1972                LengthInt = (arr.Size.NumberOfDimensions + 2);
1973            } else {
1974                // must pad to 8 byte border
1975                LengthInt = (arr.Size.NumberOfDimensions + 3);
1976            }
1977            ret = new int[LengthInt];
1978            ret[0] = (int)MatFileType.miINT32;
1979            ret[1] = arr.Size.NumberOfDimensions * 4;
1980            for (int i = 0; i < arr.Size.NumberOfDimensions; i++) {
1981                ret[i + 2] = arr.Size[i];
1982            }
1983            return ret;
1984        }
1985        private int IndexOf(string name) {
1986            for (int i = 0; i < Count; i++) {
1987                if (m_data.GetValue<string>(i, 1, 0) == name)
1988                    return i;
1989            }
1990            return -1;
1991        }
1992        private string findName(ILBaseArray value) {
1993            string elementType = string.Empty;
1994            Type type = value.GetType();
1995            if (type.GetGenericArguments() != null && type.GetGenericArguments().Length > 0) {
1996                elementType = type.GetGenericArguments()[0].Name;
1997            } else {
1998                elementType = type.Name;
1999            }
2000            string dimString = String.Join("x", value.Size.ToIntArray());
2001            string baseName = String.Format("{0}_{1}", elementType, dimString);
2002
2003            // make the new name unique
2004            string tempName = baseName;
2005            int postFix = 0;
2006            while (IndexOf(tempName) >= 0) {
2007                tempName = baseName + "_" + postFix.ToString();
2008                postFix++;
2009            }
2010            return tempName;
2011        }
2012        /// <summary>
2013        /// get mat file array class type corresponding to this arra element type
2014        /// </summary>
2015        /// <param name="arr">arra with generic system type or complex/fcomplex</param>
2016        /// <returns>mat file array class type code (int value)</returns>
2017        private static int getElementClass(ILBaseArray arr) {
2018            Type arrType = arr.GetType();
2019            if (arr is ILRetLogical || arr is ILLogical)
2020                return (int)MatFileArrayClass.mxINT8_CLASS;
2021            if (!arrType.IsGenericType)
2022                throw new ILInvalidOperationException("The array type to be saved is not applicable!");
2023            string innerType = arrType.GetGenericArguments()[0].Name;
2024            switch (innerType) {
2025                case "Double":
2026                    return (int)MatFileArrayClass.mxDOUBLE_CLASS;
2027                case "Single":
2028                    return (int)MatFileArrayClass.mxSINGLE_CLASS;
2029                case "Int16":
2030                    return (int)MatFileArrayClass.mxINT16_CLASS;
2031                case "Int32":
2032                    return (int)MatFileArrayClass.mxINT32_CLASS;
2033                case "Int64":
2034                    return (int)MatFileArrayClass.mxINT64_CLASS;
2035                case "UInt16":
2036                    return (int)MatFileArrayClass.mxUINT16_CLASS;
2037                case "UInt32":
2038                    return (int)MatFileArrayClass.mxUINT32_CLASS;
2039                case "UInt64":
2040                    return (int)MatFileArrayClass.mxUINT64_CLASS;
2041                case "complex":
2042                    return (int)MatFileArrayClass.mxDOUBLE_CLASS;
2043                case "fcomplex":
2044                    return (int)MatFileArrayClass.mxSINGLE_CLASS;
2045                case "Byte":
2046                    return (int)MatFileArrayClass.mxUINT8_CLASS;
2047                case "Char":
2048                    return (int)MatFileArrayClass.mxCHAR_CLASS;
2049                default:
2050                    throw new ILInvalidOperationException("Arrays of inner element type: '" + innerType + "' can not be written as Matfile!");
2051            }
2052        }
2053        /// <summary>
2054        /// get storage length of inner array elements
2055        /// </summary>
2056        /// <param name="arr">base array in question</param>
2057        /// <returns>storage length in bytes</returns>
2058        private static int getElementLength(ILBaseArray arr) {
2059            Type arrType = arr.GetType();
2060            string innerType;
2061            if (arr is ILRetLogical || arr is ILLogical)
2062                return 1;
2063            if (!arrType.IsGenericType)
2064                throw new ILInvalidOperationException("The array type to be saved is not applicable!");
2065            innerType = arrType.GetGenericArguments()[0].Name;
2066            switch (innerType) {
2067                case "Double":
2068                    return miSIZE_DOUBLE;
2069                case "Single":
2070                    return miSIZE_SINGLE;
2071                case "Int16":
2072                    return miSIZE_INT16;
2073                case "Int32":
2074                    return miSIZE_INT32;
2075                case "Int64":
2076                    return miSIZE_INT64;
2077                case "UInt16":
2078                    return miSIZE_UINT16;
2079                case "UInt32":
2080                    return miSIZE_UINT32;
2081                case "UInt64":
2082                    return miSIZE_UINT64;
2083                case "complex":
2084                    return miSIZE_DOUBLE;
2085                case "fcomplex":
2086                    return miSIZE_SINGLE;
2087                case "Byte":
2088                    return miSIZE_INT8;
2089                case "Char":
2090                    return miSIZE_UINT16;
2091                default:
2092                    throw new ILInvalidOperationException("Arrays of inner element type: '" + innerType + "' can not be written as Matfile!");
2093            }
2094        }
2095        #endregion
2096
2097        #region public interface
2098        /// <summary>
2099        /// Convert MatFileType enumeration member to string representation
2100        /// </summary>
2101        /// <param name="type">MatFileType enumeration member</param>
2102        /// <returns>String representing the Matlab's inner element type</returns>
2103        /// <remarks>This function is obsolete. You may directly use the enumeration's functionality instead.</remarks>
2104        public static String typeToString(MatFileType type)
2105        {
2106            String s;
2107            switch (type)
2108            {
2109                case MatFileType.miUNKNOWN:
2110                    s = "unknown";
2111                    break;
2112                case MatFileType.miINT8:
2113                    s = "int8";
2114                    break;
2115                case MatFileType.miUINT8:
2116                    s = "uint8";
2117                    break;
2118                case MatFileType.miINT16:
2119                    s = "int16";
2120                    break;
2121                case MatFileType.miUINT16:
2122                    s = "uint16";
2123                    break;
2124                case MatFileType.miINT32:
2125                    s = "int32";
2126                    break;
2127                case MatFileType.miUINT32:
2128                    s = "uint32";
2129                    break;
2130                case MatFileType.miSINGLE:
2131                    s = "single";
2132                    break;
2133                case MatFileType.miDOUBLE:
2134                    s = "double";
2135                    break;
2136                case MatFileType.miINT64:
2137                    s = "int64";
2138                    break;
2139                case MatFileType.miUINT64:
2140                    s = "uint64";
2141                    break;
2142                case MatFileType.miMATRIX:
2143                    s = "matrix";
2144                    break;
2145                case MatFileType.miCOMPRESSED:
2146                    s = "compressed";
2147                    break;
2148                case MatFileType.miUTF8:
2149                    s = "uft8";
2150                    break;
2151                case MatFileType.miUTF16:
2152                    s = "utf16";
2153                    break;
2154                case MatFileType.miUTF32:
2155                    s = "utf32";
2156                    break;
2157                default:
2158                    s = "unknown";
2159                    break;
2160            }
2161            return s;
2162        }
2163        /// <summary>
2164        /// Add array to collection of arrays in this ILMatFile container
2165        /// </summary>
2166        /// <param name="A">Array to be added to ILMatFile</param>
2167        /// <returns>String used to identify the array in the collection of arrays</returns>
2168        /// <remarks><para>The internal <c>Name</c> property of array given will be used as identification key.</para>
2169        /// <para>Note, the test if elements of A are supported by MatFile specification is done if the MatFile is to be written to stream ('write').</para></remarks>
2170        /// <exception cref="ILNumerics.Exceptions.ILInvalidOperationException">If the internal name of A does not fullfill the restrictions given by Matlab.</exception>
2171        public string AddArray(ILBaseArray A, string key = "") {
2172            using (ILScope.Enter(A)) {
2173                string name = key;
2174                if (String.IsNullOrEmpty(name)) {
2175                    name = A.Name;
2176                }
2177                if (String.IsNullOrEmpty(name)) {
2178                    name = findName(A);
2179                }
2180                this[name] = A;
2181                return name;
2182            }
2183        }
2184        /// <summary>
2185        /// List all key names currently stored with arrays
2186        /// </summary>
2187        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
2188        public IList<string> Keys {
2189            get {
2190                List<string> ret = new List<string>();
2191                for (int i = 0; i < m_data.S[0]; i++) {
2192                    ret.Add(m_data.GetValue<string>(i, 1, 0));
2193                }
2194                return ret;
2195            }
2196        }
2197        /// <summary>
2198        /// Retrieve a cell with all arrays stored in the mat file
2199        /// </summary>
2200        /// <remarks>The cell returned will be clone of the arrays stored in the mat file. Altering any cell
2201        /// elements will leave the arrays in the matfile (class/memory object) untouched.
2202        /// <para>The cell returned will be of size [n,2], where n is the number of arrays contained. The
2203        /// first row saved the arrays, the second row containes scalar string arrays with the name of
2204        /// the array in the corresponding row.</para>
2205        /// </remarks>
2206        public ILRetCell Arrays {
2207            get { return m_data.C; }
2208            protected set { m_data.a = value; }
2209        }
2210        /// <summary>
2211        /// Write this mat file into a binary stream
2212        /// </summary>
2213        /// <param name="stream">Stream to receive data. This will commonly be a FileStream object.</param>
2214        /// <remarks>
2215        /// <para>This method writes the full content of the current mat file into a binary stream. The file
2216        /// afterwards is suitable to be read again by ILNumerics.MatFile classes or by compatible *.mat file
2217        /// readers - including Matlab, e.g.</para>
2218        /// <example><code>
2219        /// MatFile m = new MatFile(myarrays);
2220        /// using (Stream s = new FileStream("test.mat",FileMode.Create)) {
2221        ///     m.Write(s);
2222        /// }
2223        /// </code></example></remarks>
2224        public void Write(Stream stream) {
2225            using (BinaryWriter fileout = new BinaryWriter(stream)) {
2226                write(fileout);
2227            }
2228        }
2229        /// <summary>
2230        /// Write all arrays to *.mat file
2231        /// </summary>
2232        /// <param name="filename">Filename of the file to write the mat file to</param>
2233        /// <remarks>
2234        /// <para>The method writes the full content of the matfile to the file specified. If the filename
2235        /// points to a file which already exists, that file will be overwritten. Otherwise a new file will
2236        /// be created. </para>
2237        /// <para>The file will be suitable for reading by ILNumerics.MatFile classes or by compatible *.mat file
2238        /// readers - including e.g. matlab</para>
2239        /// </remarks>
2240        public void Write(string filename) {
2241            using (FileStream fs = new FileStream(filename, FileMode.OpenOrCreate)) {
2242                Write(fs);
2243            }
2244        }
2245        /// <summary>
2246        /// Add/set arrays to the MatFile array container
2247        /// </summary>
2248        /// <param name="name">The name of the array for display in Matlab</param>
2249        /// <remarks><para>For get access the name must exist as key in the container. Use the MatFile.Keys property to get a list of all names if needed</para>
2250        /// <para>For set access, the name given must not be null or empty. It cannot be one of the <see cref="ReservedKeywords">ReservedKeywords</see>.
2251        /// If the name allready exist in the collection as name, the array currently assigned to it will be replaced. If the value is null, the current array will be removed from the list. If the name does
2252        /// not already exist, the new array will be added and assigned to this name.</para>
2253        /// <para>Restrictions on array names: Matlab allowes variables to have names of maximum length 63. Therefore, if the
2254        /// name given was larger than 63, it will be abbreviated. Names must start with a letter and contain only digits, (ASCII) letters or underscores '_'.</para></remarks>
2255        /// <exception cref="ILArgumentException">If the name does not fullfill the restrictions given from Matlab</exception>
2256        public ILBaseArray this[string name] {
2257            internal get {
2258                return m_data.GetBaseArray(IndexOf(name), 0);
2259            }
2260            set {
2261                using (ILScope.Enter(value)) {
2262                    #region test if name is valid
2263                    if (String.IsNullOrEmpty(name)) {
2264                        name = findName(value);
2265                    }
2266                    foreach (string nono in ReservedKeywords) {
2267                        if (name == nono)
2268                            throw new ILArgumentException("MatFile: the name " + nono + " is a reserved keyword in Matlab and may not be used as array name!");
2269                    }
2270                    if (name.Length > 63)
2271                        name = name.Substring(0, 63);
2272                    if (!Char.IsLetter(name[0]))
2273                        throw new ILArgumentException("MatFile: the name must start with a letter!");
2274                    int i;
2275                    for (i = 1; i < name.Length; i++) {
2276                        char c = name[i];
2277                        if (!Char.IsLetter(c) && !Char.IsDigit(c) && c != '_')
2278                            throw new ILArgumentException("MatFile: variable names must contain letters, digits or underscores only!");
2279                    }
2280                    #endregion
2281                    i = IndexOf(name);
2282                    if (i >= 0) {
2283                        // alter array
2284                        if (object.Equals(value, null))
2285                            // remove from
2286                            m_data[i, ILMath.full] = null;
2287                        else
2288                            m_data.SetValue(value, i, 0);
2289                    } else {
2290                        if (object.Equals(value, null))
2291                            return;
2292                        // add array
2293                        m_data.SetValue(name, m_data.S[0], 1);
2294                        m_data.SetValue(value, m_data.S[0] - 1, 0);
2295                    }
2296                }
2297            }
2298        }
2299        /// <summary>
2300        /// Number of arrays in the mat file container
2301        /// </summary>
2302        public int Count { get { return m_data.S[0]; } }
2303        /// <summary>
2304        /// Retrieve array by name
2305        /// </summary>
2306        /// <typeparam name="T">Expected type of the array</typeparam>
2307        /// <param name="name">Name of the array to retrieve</param>
2308        /// <returns>A clone of the array found or null, if no array with the given name exists</returns>
2309        public ILRetArray<T> GetArray<T>(string name) {
2310            int ind = IndexOf(name);
2311            if (ind >= 0)
2312                return m_data.GetArray<T>(ind, 0);
2313            throw new ILArgumentException("no array with name '" + name + "' found");
2314        }
2315        /// <summary>
2316        /// Retrieve array by index
2317        /// </summary>
2318        /// <typeparam name="T">Expected type of the array</typeparam>
2319        /// <param name="index">Index of the array</param>
2320        /// <returns>A clone of the array found or null, if no array at the given index exists</returns>
2321        public ILRetArray<T> GetArray<T>(ILBaseArray index) {
2322            using (ILScope.Enter(index)) {
2323                if (!index.IsScalar || !index.IsNumeric)
2324                    throw new ILArgumentException("index argument must be a numeric scalar");
2325                int ind = ILMath.toint32(index).GetValue(0);
2326                if (ind >= m_data.S[0])
2327                    throw new ILArgumentException("index argument must be in range 0..Count-1");
2328                return m_data.GetArray<T>(ind, 0);
2329            }
2330        }
2331        #endregion
2332
2333        #region constructors
2334        /// <summary>
2335        /// Create MatFile object from existing mat file
2336        /// </summary>
2337        /// <param name="file2open">Path to Matlab mat file to open</param>
2338        /// <remarks>Curently mat files up to Matlab version 6.5 are supported. Compressed mat file content is not supported yet.</remarks>
2339        public ILMatFile(string file2open) {
2340
2341            using (ILScope.Enter()) {
2342                m_filename = file2open;
2343                using (FileStream fs = File.OpenRead(file2open)) {
2344                    BinaryReader br = new BinaryReader(fs);
2345                    read_header(br);
2346                    // read elements
2347                    ILCell targetCell = ILMath.cell(new ILSize(0, 2), null);
2348                    while (br.BaseStream.Position < br.BaseStream.Length - 7) {
2349                        MatFileType dataType = (MatFileType)Enum.Parse(typeof(MatFileType), br.ReadInt32().ToString());
2350                        // the length of this chunk may be used for error checking, but....
2351                        int len = br.ReadInt32();
2352                        switch (dataType) {
2353                            case MatFileType.miCOMPRESSED:
2354                                ILBaseArray mat = read_compressed(br, len);
2355                                targetCell.SetValue(mat.Name, targetCell.S[0], 1);
2356                                targetCell.SetValue(mat, targetCell.S[0] - 1, 0);
2357                                break;
2358                            case MatFileType.miMATRIX:
2359                                mat = read_miMATRIX(br);
2360                                targetCell.SetValue(mat.Name, targetCell.S[0], 1);
2361                                targetCell.SetValue(mat, targetCell.S[0] - 1, 0);
2362                                break;
2363                            default:
2364                                // ignore all other elements, not supported yet
2365                                break;
2366                        }
2367                    }
2368                    m_data.a = targetCell;
2369                    br.Close();
2370                }
2371            }
2372        }
2373        /// <summary>
2374        /// Create MatFile object from ILBaseArray
2375        /// </summary>
2376        /// <param name="input">ILBaseArray of arbitrary size/type</param>
2377        /// <exception cref="ArgumentNullException">If input array was null or one of the names in the input arrays does not fullfill the restrictions made from Matlab</exception>
2378        public ILMatFile(params ILBaseArray[] input) {
2379            if (object.Equals(input,null))
2380                throw new ArgumentNullException ("input array may not be null!");
2381            //m_data = new ILCell(input.Length,2);
2382            for (int i=0; i < input.Length; i++) {
2383                if (String.IsNullOrWhiteSpace(input[i].Name)) {
2384                    this["ILArray" + i.ToString()] = input[i];
2385                } else {
2386                    this[input[i].Name] = input[i];
2387                }
2388            }
2389        }
2390        /// <summary>
2391        /// Create an empty MatFile object
2392        /// </summary>
2393        public ILMatFile() {
2394            m_data = new ILCell(0,2);
2395        }
2396        #endregion
2397
2398
2399        #region IDisposable Members
2400        /// <summary>
2401        /// Dispose all arrays of the matfile object
2402        /// </summary>
2403        /// <remarks>Calling dispose should be the last action for a matfile object. It is recommended to
2404        /// utilize the matfile class in using blocks (C#) only.</remarks>
2405        public void Dispose() {
2406            if (!object.Equals(m_data,null))
2407                m_data.Dispose();
2408        }
2409
2410        #endregion
2411    }
2412}
Note: See TracBrowser for help on using the repository browser.