예제 #1
0
        protected Type GetType(mxClass dataClass)
        {
            switch (dataClass)
            {
            case mxClass.DOUBLE:
                return(typeof(double));

            case mxClass.SINGLE:
                return(typeof(Single));

            case mxClass.INT8:
                return(typeof(byte));

            case mxClass.INT32:
                return(typeof(int));

            case mxClass.UINT32:
                return(typeof(uint));

            case mxClass.INT64:
                return(typeof(long));

            case mxClass.UINT64:
                return(typeof(ulong));

            default:
                throw new ArgumentException("Cannot convert mxClass " + dataClass + " to Type");
            }
        }
예제 #2
0
        protected void WriteMatrixHeader(string name, int rows, int cols, mxClass dataClass, int elementSize, bool isComplex = false, bool isLogical = false)
        {
            // convert to a valid variable name
            name = MakeValidVariableName(name);

            int numNameBytes = ((name.Length + 7) / 8) * 8;

            // compute total size of buffer
            int numericBytes = 8 + elementSize * rows * cols;

            numericBytes = ((numericBytes + 7) / 8) * 8;
            int numBytes = 48 + numNameBytes + numericBytes;

            if (isComplex)
            {
                numBytes += numericBytes;
            }

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

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

            if (isComplex)
            {
                flags |= 0x0800;
            }
            if (isLogical)
            {
                flags |= 0x0200;
            }
            Write(flags);
            Write(0);

            // write the dimension field
            Write(MatType.INT32);
            Write(8);    // 8 bytes to follow
            Write(rows); // number of rows
            Write(cols); // number of columns

            // write the matrix name
            Write(MatType.INT8);
            Write(name.Length); // length of name in bytes
            Write(name, numNameBytes);
        }
예제 #3
0
        protected Matrix ReadMatrix(mxClass dataClass, int rows, int cols)
        {
            Matrix  result = new Matrix(rows, cols);
            MatType elementClass;
            int     numDataBytes;
            bool    isSmallFormat = ReadTypeAndSize(out elementClass, out numDataBytes);

            for (int j = 0; j < result.Cols; j++)
            {
                for (int i = 0; i < result.Rows; i++)
                {
                    result[i, j] = (double)Convert.ChangeType(ReadElement(elementClass), typeof(double));
                }
            }
            ReadPadding(numDataBytes, isSmallFormat);
            return(result);
        }
예제 #4
0
        protected Array ReadArray(mxClass dataClass, int[] sizes)
        {
            Array result  = Array.CreateInstance(GetType(dataClass), sizes);
            int   numElts = result.Length;

            Reverse(sizes);
            int[] strides = StringUtil.ArrayStrides(sizes);
            Reverse(sizes);
            int[]   index = new int[sizes.Length];
            MatType elementClass;
            int     numDataBytes;
            bool    isSmallFormat = ReadTypeAndSize(out elementClass, out numDataBytes);

            for (int i = 0; i < numElts; i++)
            {
                StringUtil.LinearIndexToMultidimensionalIndex(i, strides, index);
                Reverse(index);
                object value = ReadElement(elementClass);
                result.SetValue(value, index);
            }
            ReadPadding(numDataBytes, isSmallFormat);
            return(result);
        }
예제 #5
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]);
            }
        }
예제 #6
0
        /// <summary>
        /// Read a specific data type from the stream
        /// </summary>
        /// <param name="dataType">The type number as documented by the MAT format</param>
        /// <param name="name">On exit, the variable name</param>
        /// <returns>The data value, as a .NET object</returns>
        protected object Parse(MatType dataType, out string name)
        {
            if (dataType == MatType.COMPRESSED)
            {
                throw new NotImplementedException();
            }
            if (dataType != MatType.MATRIX)
            {
                throw new NotImplementedException("dataType = " + dataType + " not implemented");
            }
            // Flags
            MatType flagsType = (MatType)ReadInt();

            if (flagsType != MatType.UINT32)
            {
                throw new NotImplementedException("flagsType = " + flagsType + " not recognized");
            }
            int numFlagsBytes = ReadInt();

            if (numFlagsBytes != 8)
            {
                throw new NotImplementedException("numFlagsBytes = " + numFlagsBytes + " not recognized");
            }
            int     flags     = ReadInt();
            bool    isLogical = (flags & 0x0200) > 0;
            bool    isComplex = (flags & 0x0800) > 0;
            mxClass dataClass = (mxClass)(flags & 0xff);

            if (dataClass > mxClass.UINT64)
            {
                throw new NotImplementedException("dataClass = " + dataClass + " not recognized");
            }
            ReadInt(); // ignored

            // Size
            MatType sizeType = (MatType)ReadInt();

            if (sizeType != MatType.INT32)
            {
                throw new NotImplementedException("sizeType = " + sizeType + " not recognized");
            }
            int numSizeBytes = ReadInt();
            int numDims      = numSizeBytes / 4;

            int[] sizes = new int[numDims];
            int   numDimsGreaterThanOne = 0;

            for (int i = 0; i < numDims; i++)
            {
                sizes[i] = ReadInt();
                if (sizes[i] > 1)
                {
                    numDimsGreaterThanOne++;
                }
            }
            ReadPadding(numSizeBytes, false);
            bool isVector = (numDimsGreaterThanOne <= 1);
            int  length   = sizes[0] * sizes[1];

            // Name
            name = ReadString();

            if (dataClass == mxClass.CHAR)
            {
                return(ReadString());
            }
            else if (dataClass == mxClass.CELL)
            {
                return(ReadCellArray(sizes));
            }
            else if (dataClass == mxClass.STRUCT)
            {
                return(ReadStruct());
            }
            else if (dataClass == mxClass.OBJECT || dataClass == mxClass.SPARSE)
            {
                throw new NotImplementedException("dataClass = " + dataClass + " not implemented");
            }
            else if (isVector && dataClass == mxClass.INT32)
            {
                return(ReadIntArray(length));
            }
            else if (isVector && dataClass == mxClass.UINT32)
            {
                return(ReadUIntArray(length));
            }
            else if (isVector && dataClass == mxClass.INT64)
            {
                return(ReadLongArray(length));
            }
            else if (isVector && dataClass == mxClass.UINT64)
            {
                return(ReadULongArray(length));
            }
            else if (isVector && isLogical)
            {
                return(ReadBoolArray(length));
            }
            else if (numDims == 2)
            {
                // Elements
                int    rows = sizes[0];
                int    cols = sizes[1];
                object real = ReadMatrix(dataClass, rows, cols);
                if (isComplex)
                {
                    object        imaginary = ReadMatrix(dataClass, rows, cols);
                    ComplexMatrix cm        = new ComplexMatrix();
                    cm.Real      = (Matrix)real;
                    cm.Imaginary = (Matrix)imaginary;
                    return(cm);
                }
                else
                {
                    return(real);
                }
            }
            else
            {
                if (isComplex)
                {
                    throw new NotSupportedException("complex multi-dimensional arrays are not supported");
                }
                // multi-dimensional array
                return(ReadArray(dataClass, sizes));
            }
        }