/// <summary> /// create shifted physical subarray of ILArray specified by range and shift /// </summary> /// <param name="range">must be valid range</param> /// <param name="shift">may be any integer - will be handled modulus ranges dimensions</param> /// <returns>physical array specified by range / shift</returns> private ILArray <BaseT> CreatePhysicalSubarrayFromPhysicalShifted(int shift, ILRange range) { if (range == null) { throw new ILArgumentException("ILArray (construct): Range specified must not be null!"); } int rangeDimLen = range.NumberOfDimensions, higherDimSum = 0; int intshift = shift % rangeDimLen; shift = shift % ((rangeDimLen > 1)? rangeDimLen : 2); int curPosOut = 0, d; BaseT[] retArr = ILMemoryPool.Pool.New <BaseT> (range.NumberOfElements); int leadDimNr = intshift, leadDimLenRange = range[intshift].Length, leadDimLen = m_dimensions[intshift]; int leadDimInc = m_dimensions.SequentialIndexDistance(intshift), tmpI = 0; int outElemCount = range.NumberOfElements, curPosIn; int[] idxArr = new int[rangeDimLen]; // used to store current position inside higher dims bool[] isFullDim = new bool[rangeDimLen]; int[][] r = range.RangeArray; int[] rleadDim = r[leadDimNr]; // faster access int[] seqDistances = m_dimensions.GetSequentialIndexDistances(range.NumberOfDimensions); if (rleadDim[0] < 0) { #region LeadDim is full (specified as ':') // leading dimension is a "full" dimension: only its largest // index is (negative) given in range[d] leadDimLenRange = -rleadDim[0] + 1; for (int i = 1; i < idxArr.Length; i++) { tmpI = (leadDimNr + i) % rangeDimLen; if (r[tmpI][0] < 0) { // full dimension //higherDimSum += m_dimensions.SequentialIndexDistance(tmpI) * idxArr[i]; // always 0! isFullDim[tmpI] = true; } else { higherDimSum += seqDistances[tmpI] * (r[tmpI][0]); } } curPosIn = higherDimSum; // todo: might be implemented more efficient... for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++, curPosIn += leadDimInc) { retArr[curPosOut++] = m_data[curPosIn]; } while (curPosOut < outElemCount) { // increase higher dims d = (leadDimNr + 1) % rangeDimLen; while (d != leadDimNr) { if (!isFullDim[d]) { if (idxArr[d] >= range[d].Length - 1) { idxArr[d] = 0; d = (d + 1) % rangeDimLen; } else { break; } } else { if (idxArr[d] >= -r[d][0]) { idxArr[d] = 0; d = (d + 1) % rangeDimLen; } else { break; } } } System.Diagnostics.Debug.Assert(d != leadDimNr); idxArr[d] += 1; higherDimSum = 0; for (int i = 1; i < idxArr.Length; i++) { tmpI = (i + leadDimNr) % rangeDimLen; if (isFullDim[tmpI]) { higherDimSum += seqDistances[tmpI] * idxArr[tmpI]; } else { higherDimSum += seqDistances[tmpI] * (r[tmpI][idxArr[tmpI]]); } } // do the copy! curPosIn = higherDimSum; // todo: might be implemented more efficient... tmpI = leadDimLenRange; while (tmpI-- > 0) { retArr[curPosOut++] = m_data[curPosIn]; curPosIn += leadDimInc; } } #endregion } else { #region LeadDim is explicitly declared for (int i = 1; i < idxArr.Length; i++) { tmpI = (leadDimNr + i) % rangeDimLen; if (r[tmpI][0] < 0) { // full dimension //higherDimSum += m_dimensions.SequentialIndexDistance(tmpI) * idxArr[i]; // always 0! isFullDim[tmpI] = true; } else { higherDimSum += seqDistances[tmpI] * (r[tmpI][0]); } } curPosIn = higherDimSum; // todo: might be implemented more efficient... for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++) { curPosIn = higherDimSum + rleadDim[lIdx] * leadDimInc; retArr[curPosOut++] = m_data[curPosIn]; } while (curPosOut < outElemCount) { // increase higher dims d = (leadDimNr + 1) % rangeDimLen; while (d != leadDimNr) { if (!isFullDim[d]) { if (idxArr[d] >= range[d].Length - 1) { idxArr[d] = 0; d = (d + 1) % rangeDimLen; } else { break; } } else { if (idxArr[d] >= -r[d][0]) { idxArr[d] = 0; d = (d + 1) % rangeDimLen; } else { break; } } } System.Diagnostics.Debug.Assert(d != leadDimNr); // reached the end idxArr[d] += 1; higherDimSum = 0; for (int i = 1; i < idxArr.Length; i++) { tmpI = (i + leadDimNr) % rangeDimLen; if (isFullDim[tmpI]) { higherDimSum += seqDistances[tmpI] * idxArr[tmpI]; } else { higherDimSum += seqDistances[tmpI] * (r[tmpI][idxArr[tmpI]]); } } // do the copy! curPosIn = higherDimSum; // todo: might be implemented more efficient... for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++) { curPosIn = higherDimSum + rleadDim[lIdx] * leadDimInc; retArr[curPosOut++] = m_data[curPosIn]; } } #endregion } return(new ILArray <BaseT> (retArr, range.GetDimensions().GetShifted(shift))); }
/// <summary> /// create physical subarray from physical ILArray /// </summary> /// <param name="range"></param> /// <returns></returns> private ILArray <BaseT> CreatePhysicalSubarrayFromPhysical(ILRange range) { if (range == null) { throw new ILArgumentException("range specified must not be null!"); } int rangeDimLen = range.NumberOfDimensions, higherDimSum = 0; int leadDimLenRange = range[0].Length, leadDimLen = m_dimensions[0]; int curPosOut = 0, d, outElemCount = range.NumberOfElements; BaseT[] retArr = ILMemoryPool.Pool.New <BaseT>(outElemCount); int[] idxArr = new int[rangeDimLen]; // used to store current position inside higher dims bool[] isFullDim = new bool[rangeDimLen]; int[][] r = range.RangeArray; int[] seqDistances = m_dimensions.GetSequentialIndexDistances(range.NumberOfDimensions); int[] rleadDim = range[0]; if (rleadDim[0] < 0) { #region LeadDim is full (specified as ':') // leading dimension is a "full" dimension: only its largest index is (negative) given in range[d] for (int i = 1; i < idxArr.Length; i++) { if (r[i][0] < 0) { // full dimension //higherDimSum += m_dimensions.SequentialIndexDistance(i) * idxArr[i]; isFullDim[i] = true; } else { higherDimSum += seqDistances[i] * (r[i][idxArr[i]]); } } leadDimLenRange = -rleadDim[0] + 1; for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++) { retArr[curPosOut++] = m_data[higherDimSum + lIdx]; } while (curPosOut < outElemCount) { // increase higher dims d = 1; while (d < rangeDimLen) { if (!isFullDim[d]) { if (idxArr[d] >= r[d].Length - 1) { idxArr[d] = 0; d++; } else { break; } } else { if (idxArr[d] >= -r[d][0]) { idxArr[d] = 0; d++; } else { break; } } } System.Diagnostics.Debug.Assert(d != idxArr.Length); idxArr[d] += 1; higherDimSum = 0; for (int i = 1; i < idxArr.Length; i++) { if (isFullDim[i]) { higherDimSum += seqDistances[i] * idxArr[i]; } else { higherDimSum += seqDistances[i] * (r[i][idxArr[i]]); } } // do the copy! for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++) { retArr[curPosOut++] = m_data[higherDimSum++]; } } #endregion } else { #region LeadDim is explicitly declared for (int i = 1; i < idxArr.Length; i++) { // ... not sure for higher dimensions... if (r[i][0] < 0) { // full dimension // higherDimSum += m_dimensions.SequentialIndexDistance(i) * idxArr[i]; isFullDim[i] = true; } else { higherDimSum += seqDistances[i] * (r[i][0]); } } for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++) { retArr[curPosOut++] = m_data[higherDimSum + rleadDim[lIdx]]; } while (curPosOut < outElemCount) { // increase higher dims d = 1; while (d < idxArr.Length) { if (!isFullDim[d]) { if (idxArr[d] >= r[d].Length - 1) { idxArr[d] = 0; d++; } else { break; } } else { if (idxArr[d] >= -r[d][0]) { idxArr[d] = 0; d++; } else { break; } } System.Diagnostics.Debug.Assert(d < idxArr.Length); } System.Diagnostics.Debug.Assert(d != idxArr.Length); idxArr[d] += 1; higherDimSum = 0; for (int i = 1; i < idxArr.Length; i++) { if (isFullDim[i]) { higherDimSum += seqDistances[i] * idxArr[i]; } else { higherDimSum += seqDistances[i] * (r[i][idxArr[i]]); } } // do the copy! for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++) { retArr[curPosOut++] = m_data[higherDimSum + rleadDim[lIdx]]; } } #endregion } return(new ILArray <BaseT>(retArr, range.GetDimensions())); }