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); } }
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)); } }
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); }
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); }
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)); } } }
/// <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]); } }
public MultiRange(int[] lowerBounds, int[] lengths) { LowerBounds = lowerBounds; Lengths = lengths; Strides = StringUtil.ArrayStrides(lengths); }