/// <summary> /// Applys the function (delegate) given to all elements of the storage /// </summary> /// <param name="inArray">storage array to be apply the function to</param> /// <param name="operation">operation to apply to the elements of inArray. This /// acts like a function pointer.</param> /// <returns>new ILArray<double> with result</returns> /// <remarks> the values of inArray will not be altered.</remarks> private static ILLogicalArray LogicalUnaryDoubleOperator(ILArray <double> inArray, ILApplyLogical_Double operation) { ILDimension inDim = inArray.Dimensions; byte[] retByteArr; // build ILDimension int newLength = inDim.NumberOfElements; retByteArr = new byte[newLength]; int leadDim = 0; int leadDimLen = inDim[0]; if (inArray.IsReference) { #region Reference storage // walk along the longest dimension (for performance reasons) for (int i = 1; i < inDim.NumberOfDimensions; i++) { if (leadDimLen < inDim[i]) { leadDimLen = inDim[i]; leadDim = i; } } ILIndexOffset idxOffset = inArray.m_indexOffset; int incOut = inDim.SequentialIndexDistance(leadDim); // ======================== REFERENCE double Storage =========== if (inArray.IsMatrix) { #region Matrix //////////////////////////// MATRIX //////////////////// int secDim = (leadDim + 1) % 2; unsafe { fixed(int *leadDimStart = idxOffset[leadDim], secDimStart = idxOffset[secDim]) { fixed(byte *pOutArr = retByteArr) { fixed(double *pInArr = inArray.m_data) { byte * tmpOut = pOutArr; double *tmpIn = pInArr; byte * tmpOutEnd = pOutArr + inDim.NumberOfElements - 1; int * secDimEnd = secDimStart + idxOffset[secDim].Length; int * secDimIdx = secDimStart; int * leadDimIdx = leadDimStart; int * leadDimEnd = leadDimStart + idxOffset[secDim].Length;; while (secDimIdx < secDimEnd) { tmpIn = pInArr + *secDimIdx++; leadDimIdx = leadDimStart; while (leadDimIdx < leadDimEnd) { *tmpOut = operation(*(tmpIn + *leadDimIdx++)); tmpOut += incOut; } if (tmpOut > tmpOutEnd) { tmpOut = pOutArr + (tmpOutEnd - tmpOut); } } } } } } #endregion } else if (inArray.IsVector) { #region Vector //////////////////////////// VECTOR /////////////////////// unsafe { fixed(int *leadDimStart = idxOffset[leadDim]) { fixed(byte *pOutArr = retByteArr) { fixed(double *pInArr = inArray.m_data) { byte * tmpOut = pOutArr; double *tmpIn = pInArr + idxOffset[((leadDim + 1) % 2), 0]; int * leadDimIdx = leadDimStart; int * leadDimEnd = leadDimStart + leadDimLen; // start at first element while (leadDimIdx < leadDimEnd) { *tmpOut++ = operation(*(tmpIn + *leadDimIdx++)); } } } } } #endregion } else { ///////////////////////////// ARBITRARY DIMENSIONS ////////// #region arbitrary size unsafe { int[] curPosition = new int[inArray.Dimensions.NumberOfDimensions]; fixed(int *leadDimStart = idxOffset[leadDim]) { fixed(byte *pOutArr = retByteArr) { fixed(double *pInArr = inArray.m_data) { byte *tmpOut = pOutArr; byte *tmpOutEnd = tmpOut + retByteArr.Length; // init lesezeiger: add alle Dimensionen mit 0 (außer leadDim) double *tmpIn = pInArr + inArray.getBaseIndex(0, 0); tmpIn -= idxOffset[leadDim, 0]; int *leadDimIdx = leadDimStart; int *leadDimEnd = leadDimStart + leadDimLen; int dimLen = curPosition.Length; int d, curD; // start at first element while (tmpOut < tmpOutEnd) { leadDimIdx = leadDimStart; while (leadDimIdx < leadDimEnd) { *tmpOut = operation(*(tmpIn + *leadDimIdx++)); tmpOut += incOut; } if (tmpOut > tmpOutEnd) { tmpOut = pOutArr + (tmpOutEnd - tmpOut); } // increment higher dimensions d = 1; while (d < dimLen) { curD = (d + leadDim) % dimLen; tmpIn -= idxOffset[curD, curPosition[curD]]; curPosition[curD]++; if (curPosition[curD] < idxOffset[curD].Length) { tmpIn += idxOffset[curD, curPosition[curD]]; break; } curPosition[curD] = 0; tmpIn += idxOffset[curD, 0]; d++; } } } } } } #endregion } // ============================================================== #endregion } else { // physical -> pointer arithmetic #region physical storage unsafe { fixed(byte *pOutArr = retByteArr) { fixed(double *pInArr = inArray.m_data) { byte * lastElement = pOutArr + retByteArr.Length; byte * tmpOut = pOutArr; double *tmpIn = pInArr; while (tmpOut < lastElement) { *tmpOut++ = operation(*tmpIn++); } } } } #endregion } return(new ILLogicalArray(retByteArr, inDim.ToIntArray())); }
/// <summary> /// Applys the function (delegate) given to all elements of the storage /// </summary> /// <param name="inArray">storage array to be apply the function to</param> /// <param name="operation">operation to apply to the elements of inArray. This /// acts like a function pointer.</param> /// <returns>new ILArray<double> with result</returns> /// <remarks> the values of inArray will not be altered.</remarks> private static ILLogicalArray LogicalUnaryDoubleOperator(ILArray<double> inArray, ILApplyLogical_Double operation) { ILDimension inDim = inArray.Dimensions; byte[] retByteArr; // build ILDimension int newLength = inDim.NumberOfElements; retByteArr = new byte[newLength]; int leadDim = 0; int leadDimLen = inDim[0]; if (inArray.IsReference) { #region Reference storage // walk along the longest dimension (for performance reasons) for (int i = 1; i < inDim.NumberOfDimensions; i++) { if (leadDimLen < inDim[i]) { leadDimLen = inDim[i]; leadDim = i; } } ILIndexOffset idxOffset = inArray.m_indexOffset; int incOut = inDim.SequentialIndexDistance(leadDim); // ======================== REFERENCE double Storage =========== if (inArray.IsMatrix) { #region Matrix //////////////////////////// MATRIX //////////////////// int secDim = (leadDim + 1) % 2; unsafe { fixed (int* leadDimStart = idxOffset[leadDim], secDimStart = idxOffset[secDim]) { fixed (byte* pOutArr = retByteArr) { fixed (double* pInArr = inArray.m_data) { byte* tmpOut = pOutArr; double* tmpIn = pInArr; byte* tmpOutEnd = pOutArr + inDim.NumberOfElements - 1; int* secDimEnd = secDimStart + idxOffset[secDim].Length; int* secDimIdx = secDimStart; int* leadDimIdx = leadDimStart; int* leadDimEnd = leadDimStart + idxOffset[secDim].Length; ; while (secDimIdx < secDimEnd) { tmpIn = pInArr + *secDimIdx++; leadDimIdx = leadDimStart; while (leadDimIdx < leadDimEnd) { *tmpOut = operation(*(tmpIn + *leadDimIdx++)); tmpOut += incOut; } if (tmpOut > tmpOutEnd) tmpOut = pOutArr + (tmpOutEnd - tmpOut); } } } } } #endregion } else if (inArray.IsVector) { #region Vector //////////////////////////// VECTOR /////////////////////// unsafe { fixed (int* leadDimStart = idxOffset[leadDim]) { fixed (byte* pOutArr = retByteArr) { fixed (double* pInArr = inArray.m_data) { byte* tmpOut = pOutArr; double* tmpIn = pInArr + idxOffset[((leadDim + 1) % 2), 0]; int* leadDimIdx = leadDimStart; int* leadDimEnd = leadDimStart + leadDimLen; // start at first element while (leadDimIdx < leadDimEnd) *tmpOut++ = operation(*(tmpIn + *leadDimIdx++)); } } } } #endregion } else { ///////////////////////////// ARBITRARY DIMENSIONS ////////// #region arbitrary size unsafe { int[] curPosition = new int[inArray.Dimensions.NumberOfDimensions]; fixed (int* leadDimStart = idxOffset[leadDim]) { fixed (byte* pOutArr = retByteArr) { fixed (double* pInArr = inArray.m_data) { byte* tmpOut = pOutArr; byte* tmpOutEnd = tmpOut + retByteArr.Length; // init lesezeiger: add alle Dimensionen mit 0 (außer leadDim) double* tmpIn = pInArr + inArray.getBaseIndex(0, 0); tmpIn -= idxOffset[leadDim, 0]; int* leadDimIdx = leadDimStart; int* leadDimEnd = leadDimStart + leadDimLen; int dimLen = curPosition.Length; int d, curD; // start at first element while (tmpOut < tmpOutEnd) { leadDimIdx = leadDimStart; while (leadDimIdx < leadDimEnd) { *tmpOut = operation(*(tmpIn + *leadDimIdx++)); tmpOut += incOut; } if (tmpOut > tmpOutEnd) tmpOut = pOutArr + (tmpOutEnd - tmpOut); // increment higher dimensions d = 1; while (d < dimLen) { curD = (d + leadDim) % dimLen; tmpIn -= idxOffset[curD, curPosition[curD]]; curPosition[curD]++; if (curPosition[curD] < idxOffset[curD].Length) { tmpIn += idxOffset[curD, curPosition[curD]]; break; } curPosition[curD] = 0; tmpIn += idxOffset[curD, 0]; d++; } } } } } } #endregion } // ============================================================== #endregion } else { // physical -> pointer arithmetic #region physical storage unsafe { fixed (byte* pOutArr = retByteArr) { fixed (double* pInArr = inArray.m_data) { byte* lastElement = pOutArr + retByteArr.Length; byte* tmpOut = pOutArr; double* tmpIn = pInArr; while (tmpOut < lastElement) *tmpOut++ = operation(*tmpIn++); } } } #endregion } return new ILLogicalArray(retByteArr, inDim.ToIntArray()); }