private static void ForEachLiteralIndex(int[] sizes, Action <int[]> action)
        {
            int[] strides     = StringUtil.ArrayStrides(sizes);
            int   arrayLength = strides[0] * sizes[0];

            int[] mIndex = new int[sizes.Length];
            for (int i = 0; i < arrayLength; i++)
            {
                StringUtil.LinearIndexToMultidimensionalIndex(i, strides, mIndex);
                action(mIndex);
            }
        }
Пример #2
0
 public ArrayAsList(Array array)
 {
     this.array = array;
     if (array.Rank == 1)
     {
         array1D = (T[])array;
     }
     else if (array.Rank == 2)
     {
         array2D = (T[, ])array;
     }
     else
     {
         strides = StringUtil.ArrayStrides(StringUtil.ArrayDimensions(array));
     }
 }
Пример #3
0
        protected Array ReadCellArray(int[] sizes)
        {
            Array cellArray = Array.CreateInstance(typeof(object), sizes);
            int   numElts   = cellArray.Length;

            Reverse(sizes);
            int[] strides = StringUtil.ArrayStrides(sizes);
            Reverse(sizes);
            int[] index      = new int[sizes.Length];
            bool  allStrings = true;

            for (int i = 0; i < numElts; i++)
            {
                string  dummyName;
                MatType cellValueType = (MatType)ReadInt();
                int     cellValueSize = ReadInt();
                object  value         = (cellValueSize == 0) ? null : Parse(cellValueType, out dummyName);
                StringUtil.LinearIndexToMultidimensionalIndex(i, strides, index);
                Reverse(index);
                cellArray.SetValue(value, index);
                if (!(value is string))
                {
                    allStrings = false;
                }
            }
            if (numElts > 0 && allStrings && sizes.Length == 2 && sizes[1] == 1)
            {
                string[] stringArray = new string[numElts];
                for (int i = 0; i < numElts; i++)
                {
                    StringUtil.LinearIndexToMultidimensionalIndex(i, strides, index);
                    Reverse(index);
                    object value = cellArray.GetValue(index);
                    stringArray[i] = (string)value;
                }
                return(stringArray);
            }
            return(cellArray);
        }
Пример #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
        protected override IExpression ConvertArrayCreate(IArrayCreateExpression iace)
        {
            IArrayCreateExpression ace = (IArrayCreateExpression)base.ConvertArrayCreate(iace);
            IAssignExpression      iae = context.FindAncestor <IAssignExpression>();

            if (iae == null)
            {
                return(ace);
            }
            if (iae.Expression != iace)
            {
                return(ace);
            }
            if (iace.Initializer != null)
            {
                var  exprs             = iace.Initializer.Expressions;
                bool expandInitializer = !AllElementsAreLiteral(exprs);
                if (expandInitializer)
                {
                    // convert the initializer to a list of assignment statements to literal indices
                    bool wasConvertingArrayCreate = convertingArrayCreate;
                    if (!wasConvertingArrayCreate)
                    {
                        arrayCreateStmts.Clear();
                    }
                    convertingArrayCreate = true;
                    IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(iae.Target);
                    // Sets the size of this variable at this array depth
                    int           depth    = Recognizer.GetIndexingDepth(iae.Target);
                    IExpression[] dimExprs = new IExpression[ace.Dimensions.Count];
                    for (int i = 0; i < dimExprs.Length; i++)
                    {
                        dimExprs[i] = ace.Dimensions[i];
                    }
                    List <IList <IExpression> > indices = Recognizer.GetIndices(iae.Target);
                    // for a multi-dimensional array, exprs will contain IBlockExpressions
                    // dimExprs must be ILiteralExpressions
                    int[] dims         = Util.ArrayInit(dimExprs.Length, i => (int)((ILiteralExpression)dimExprs[i]).Value);
                    int[] strides      = StringUtil.ArrayStrides(dims);
                    int   elementCount = strides[0] * dims[0];
                    var   target       = Builder.JaggedArrayIndex(Builder.VarRefExpr(ivd), indices);
                    int[] mIndex       = new int[dims.Length];
                    for (int linearIndex = elementCount - 1; linearIndex >= 0; linearIndex--)
                    {
                        StringUtil.LinearIndexToMultidimensionalIndex(linearIndex, strides, mIndex);
                        var indexExprs = Util.ArrayInit(mIndex.Length, i => Builder.LiteralExpr(mIndex[i]));
                        var lhs        = Builder.ArrayIndex(target, indexExprs);
                        var expr       = GetInitializerElement(exprs, mIndex);
                        var assignStmt = Builder.AssignStmt(lhs, expr);
                        var st         = ConvertStatement(assignStmt);
                        arrayCreateStmts.Push(st);
                    }
                    ace.Initializer       = null;
                    convertingArrayCreate = wasConvertingArrayCreate;
                    if (!wasConvertingArrayCreate)
                    {
                        context.AddStatementsAfterCurrent(arrayCreateStmts);
                    }
                }
            }
            return(ace);

            bool AllElementsAreLiteral(IList <IExpression> exprs)
            {
                foreach (var expr in exprs)
                {
                    if (expr is IBlockExpression ibe)
                    {
                        if (!AllElementsAreLiteral(ibe.Expressions))
                        {
                            return(false);
                        }
                    }
                    else if (!(expr is ILiteralExpression))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            IExpression GetInitializerElement(IList <IExpression> exprs, int[] mIndex, int dim = 0)
            {
                var expr = exprs[mIndex[dim]];

                if (dim == mIndex.Length - 1)
                {
                    return(expr);
                }
                else
                {
                    var blockExpr = (IBlockExpression)expr;
                    return(GetInitializerElement(blockExpr.Expressions, mIndex, dim + 1));
                }
            }
        }
Пример #6
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]);
            }
        }
Пример #7
0
 public MultiRange(int[] lowerBounds, int[] lengths)
 {
     LowerBounds = lowerBounds;
     Lengths     = lengths;
     Strides     = StringUtil.ArrayStrides(lengths);
 }