/// <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 <![CDATA[ILArray<>]]> with result</returns> /// <remarks> the values of inArray will not be altered.</remarks> private static ILLogicalArray LogicalUnaryComplexOperator (ILArray< complex > inArray, ILLogicalFunctionComplex 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 ( complex * pInArr = inArray.m_data) { byte* tmpOut = pOutArr; complex * 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 ( complex * pInArr = inArray.m_data) { byte* tmpOut = pOutArr; complex * 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 ( complex * pInArr = inArray.m_data) { byte* tmpOut = pOutArr; byte* tmpOutEnd = tmpOut + retByteArr.Length; // init lesezeiger: add alle Dimensionen mit 0 (auer leadDim) complex * 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 ( complex * pInArr = inArray.m_data) { byte* lastElement = pOutArr + retByteArr.Length; byte* tmpOut = pOutArr; complex * 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 <![CDATA[ILArray<>]]> with result</returns> /// <remarks> the values of inArray will not be altered.</remarks> private static ILLogicalArray LogicalUnaryComplexOperator (ILArray< complex > inArray, ILLogicalFunctionComplex operation) { ILDimension inDim = inArray.Dimensions; byte [] retByteArr; // build ILDimension int newLength = inDim.NumberOfElements; retByteArr = new byte [newLength]; int leadDimLen = inDim [0]; // physical -> pointer arithmetic unsafe { fixed (byte* pOutArr = retByteArr) { fixed ( complex * pInArr = inArray.m_data) { byte* lastElement = pOutArr + retByteArr.Length; byte* tmpOut = pOutArr; complex * tmpIn = pInArr; while (tmpOut < lastElement) *tmpOut++ = operation ( *tmpIn++ ); } } } return new ILLogicalArray ( retByteArr, inDim.ToIntArray () ); }