예제 #1
0
        /// <summary>
        /// Read the next data element from the stream
        /// </summary>
        /// <param name="name">On exit, the variable name</param>
        /// <returns>The data value, as a .NET object</returns>
        protected object Matlab5DataElement(out string name)
        {
            MatType dataType = (MatType)ReadInt();
            int     numBytes = ReadInt();

            byte[] bytes = new byte[numBytes];
            if (reader.Read(bytes, 0, numBytes) < numBytes)
            {
                throw new EndOfStreamException();
            }
            if (dataType == MatType.COMPRESSED)
            {
                // MAT file compression uses Zlib format, which is the same as Deflate but with an extra header and footer.
                // To use DeflateStream, we must first remove this header.
                bytes = RemoveRfc1950Header(bytes);
                var          stream      = new DeflateStream(new MemoryStream(bytes), CompressionMode.Decompress);
                MatlabReader unzipReader = new MatlabReader(stream);
                return(unzipReader.Matlab5DataElement(out name));
            }
            else
            {
                MatlabReader eltReader = new MatlabReader(new MemoryStream(bytes));
                var          result    = eltReader.Parse(dataType, out name);
                return(result);
            }
        }
예제 #2
0
 /// <summary>
 /// Read all variables from a file and store them in a dictionary
 /// </summary>
 /// <param name="fileName">The name of a MAT file</param>
 /// <returns>A dictionary that maps variable names into values</returns>
 public static Dictionary <string, object> Read(string fileName)
 {
     using (MatlabReader r = new MatlabReader(fileName))
     {
         return(r.ReadAll());
     }
 }
예제 #3
0
        /// <summary>
        /// Write a named struct whose fields are the columns of a csv file
        /// </summary>
        /// <param name="name"></param>
        /// <param name="path"></param>
        public void WriteFromCsv(string name, string path)
        {
            Dictionary <string, List <string> > dict = MatlabReader.ReadCsv(path);
            // try to convert strings into numbers
            Dictionary <string, object> dict2 = new Dictionary <string, object>();

            foreach (var entry in dict)
            {
                bool          isDouble = true;
                List <double> doubles  = new List <double>();
                foreach (string s in entry.Value)
                {
                    double d;
                    if (s.Length == 0)
                    {
                        d = double.NaN;
                        doubles.Add(d);
                    }
                    else if (double.TryParse(s, out d))
                    {
                        doubles.Add(d);
                    }
                    else
                    {
                        isDouble = false;
                        break;
                    }
                }
                if (isDouble)
                {
                    dict2.Add(entry.Key, doubles);
                }
                else
                {
                    dict2.Add(entry.Key, entry.Value);
                }
            }
            Write(name, dict2);
        }
예제 #4
0
        /// <summary>
        /// Write a named array to the stream
        /// </summary>
        /// <param name="name"></param>
        /// <param name="array"></param>
        public void WriteArray(string name, Array array)
        {
            Type    eltType   = array.GetType().GetElementType();
            mxClass dataClass = GetDataClass(eltType);

            // convert to a valid variable name
            name = MakeValidVariableName(name);

            // pad the name to an 8-byte boundary
            int numNameBytes = ((name.Length + 7) / 8) * 8;

            // precompute the cell bytes
            int numDataBytes = 0;
            int numDims      = array.Rank;
            int numElts      = array.Length;

            int[] sizes = new int[numDims];
            for (int i = 0; i < numDims; i++)
            {
                sizes[i] = array.GetLength(i);
            }
            MatlabReader.Reverse(sizes);
            int[] strides = StringUtil.ArrayStrides(sizes);
            MatlabReader.Reverse(sizes);
            int[]         index     = new int[numDims];
            List <byte[]> bytes     = new List <byte[]>();
            Stream        oldWriter = writer;

            try
            {
                for (int i = 0; i < numElts; i++)
                {
                    StringUtil.LinearIndexToMultidimensionalIndex(i, strides, index);
                    MatlabReader.Reverse(index);
                    object       cell = array.GetValue(index);
                    MemoryStream ms   = new MemoryStream(128);
                    writer = ms;
                    if (dataClass == mxClass.CELL)
                    {
                        Write("", cell);
                    }
                    else if (dataClass == mxClass.DOUBLE)
                    {
                        Write((double)cell);
                    }
                    else if (dataClass == mxClass.SINGLE)
                    {
                        Write((Single)cell);
                    }
                    else if (dataClass == mxClass.INT8)
                    {
                        Write((byte)cell);
                    }
                    else if (dataClass == mxClass.INT16)
                    {
                        Write((short)cell);
                    }
                    else if (dataClass == mxClass.UINT16)
                    {
                        Write((ushort)cell);
                    }
                    else if (dataClass == mxClass.INT32)
                    {
                        Write((int)cell);
                    }
                    else if (dataClass == mxClass.UINT32)
                    {
                        Write((uint)cell);
                    }
                    else if (dataClass == mxClass.INT64)
                    {
                        Write((long)cell);
                    }
                    else if (dataClass == mxClass.UINT64)
                    {
                        Write((ulong)cell);
                    }
                    else
                    {
                        throw new NotImplementedException(dataClass.ToString());
                    }
                    byte[] valueBytes = ms.ToArray();
                    bytes.Add(valueBytes);
                    numDataBytes += valueBytes.Length;
                }
            }
            finally
            {
                writer = oldWriter;
            }

            // compute total size of buffer
            int sizeBytes = numDims * 4;

            if (numDims % 2 == 1)
            {
                sizeBytes += 4;
            }
            int numBytes = 32 + sizeBytes + numNameBytes + numDataBytes;

            if (dataClass != mxClass.CELL)
            {
                numBytes += 8;
            }

            // write the data type field
            Write(MatType.MATRIX);
            Write(numBytes); // number of bytes

            // write the array flags
            Write(MatType.UINT32);
            Write(8); // 8 bytes to follow
            Write((int)dataClass);
            Write(0); // reserved

            // write the dimension field
            Write(MatType.INT32);
            if (numDims == 1)
            {
                Write(8); // 8 bytes to follow
                Write(sizes[0]);
                Write(1);
            }
            else
            {
                Write(numDims * 4);
                for (int i = 0; i < numDims; i++)
                {
                    Write(sizes[i]);
                }
                if (numDims % 2 == 1)
                {
                    Write(0);
                }
            }

            // write the name
            Write(MatType.INT8);
            Write(name.Length); // length of name in bytes
            Write(name, numNameBytes);

            if (dataClass != mxClass.CELL)
            {
                MatType elementClass = GetElementClass(eltType);
                Write((int)elementClass);
                Write(numDataBytes);
            }
            // write the cell values
            for (int i = 0; i < bytes.Count; i++)
            {
                Write(bytes[i]);
            }
        }