/// <summary>Finds finite value elements</summary> /// <param name="A">input array</param> /// <returns>Logical array with 1 if the corresponding elements of input array is finite, 0 else.</returns> /// <remarks><para>If the input array is empty, an empty array will be returned.</para> /// <para>The array returned will be a dense array.</para></remarks> public static ILLogicalArray isfinite(ILArray <complex> A) { if (A.IsEmpty) { return(ILLogicalArray.empty(A.Dimensions)); } ILDimension inDim = A.Dimensions; byte [] retDblArr; // build ILDimension int newLength = inDim.NumberOfElements; //retDblArr = new byte [newLength]; retDblArr = ILMemoryPool.Pool.New <byte> (newLength); int leadDimLen = inDim [0]; // physical -> pointer arithmetic unsafe { fixed(byte *pOutArr = retDblArr) fixed(complex * pInArr = A.m_data) { byte * lastElement = pOutArr + retDblArr.Length; byte * tmpOut = pOutArr; complex *tmpIn = pInArr; while (tmpOut < lastElement) // HC02 { *tmpOut++ = complex.IsFinite(*tmpIn++) ?(byte)1:(byte)0; } } } return(new ILLogicalArray(retDblArr, inDim)); }
/// <summary>Locate infinite value elements</summary> /// <param name="A">input array</param> /// <returns>Logical array with 1 if the corresponding elements of input array is infinite, 0 else.</returns> /// <remarks><para>If the input array is empty, an empty array will be returned.</para> /// <para>The array returned will be a dense array.</para></remarks> public static ILLogicalArray isinf(ILArray <complex> A) { if (A.IsEmpty) { return(ILLogicalArray.empty(A.Dimensions)); } ILDimension inDim = A.Dimensions; byte [] retDblArr; // build ILDimension int newLength = inDim.NumberOfElements; //retDblArr = new byte [newLength]; retDblArr = ILMemoryPool.Pool.New <byte> (newLength); int leadDim = 0; int leadDimLen = inDim [0]; if (A.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 = A.m_indexOffset; int incOut = inDim.SequentialIndexDistance(leadDim); System.Diagnostics.Debug.Assert(!A.IsVector, "Reference arrays of vector size should not exist!"); if (A.IsMatrix) { #region Matrix //////////////////////////// MATRIX //////////////////// int secDim = (leadDim + 1) % 2; unsafe { fixed(int *leadDimStart = idxOffset [leadDim], secDimStart = idxOffset [secDim]) { fixed(byte *pOutArr = retDblArr) fixed(complex * pInArr = A.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 + leadDimLen; while (secDimIdx < secDimEnd) { if (tmpOut > tmpOutEnd) { tmpOut = pOutArr + (tmpOut - tmpOutEnd); } tmpIn = pInArr + *secDimIdx++; leadDimIdx = leadDimStart; while (leadDimIdx < leadDimEnd) // HC00 { *tmpOut = complex.IsInfinity(*(tmpIn + *leadDimIdx++)) ?(byte)1:(byte)0; tmpOut += incOut; } } } } } #endregion } else { #region arbitrary size unsafe { int [] curPosition = new int [A.Dimensions.NumberOfDimensions]; fixed(int *leadDimStart = idxOffset [leadDim]) { fixed(byte *pOutArr = retDblArr) fixed(complex * pInArr = A.m_data) { byte * tmpOut = pOutArr; byte * tmpOutEnd = tmpOut + retDblArr.Length - 1; complex *tmpIn = pInArr + A.getBaseIndex(0, 0); tmpIn -= idxOffset [leadDim, 0]; // if the first index of leaddim is not 0, it will be added later anyway. so we subtract it here int *leadDimIdx = leadDimStart; int *leadDimEnd = leadDimStart + leadDimLen; int dimLen = curPosition.Length; int d, curD, count = retDblArr.Length / leadDimLen; // start at first element while (count-- > 0) { leadDimIdx = leadDimStart; while (leadDimIdx < leadDimEnd) //HC01 { *tmpOut = complex.IsInfinity(*(tmpIn + *leadDimIdx++)) ?(byte)1:(byte)0; tmpOut += incOut; } if (tmpOut > tmpOutEnd) { tmpOut -= retDblArr.Length - 1; } // 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 = retDblArr) fixed(complex * pInArr = A.m_data) { byte * lastElement = pOutArr + retDblArr.Length; byte * tmpOut = pOutArr; complex *tmpIn = pInArr; while (tmpOut < lastElement) // HC02 { *tmpOut++ = complex.IsInfinity(*tmpIn++) ?(byte)1:(byte)0; } } } #endregion } return(new ILLogicalArray(retDblArr, inDim)); }
/// <summary>determine, if any elements are nonzero</summary> /// <param name="A">N-dimensional array</param> /// <param name="leadDim">index of dimension to operate along</param> /// <returns><para>array of same size as A, having the 'leadDim's dimension reduced to 1, if any elements along that dimension are non-zero, '0' else. </para></returns> public static ILLogicalArray any(ILArray <complex> A, int leadDim) { if (A.IsEmpty) { return(ILLogicalArray.empty(A.Dimensions)); } if (A.IsScalar) { return(new ILLogicalArray(new byte [1] { (A.GetValue(0).iszero())?(byte)0:(byte)1 }, 1, 1)); } if (leadDim >= A.Dimensions.NumberOfDimensions) { throw new ILArgumentException("dimension parameter out of range!"); } ILDimension inDim = A.Dimensions; int[] newDims = inDim.ToIntArray(); int tmpCount = 0; int newLength; byte [] retDblArr; // build ILDimension newLength = inDim.NumberOfElements / newDims[leadDim]; newDims[leadDim] = 1; retDblArr = ILMemoryPool.Pool.New <byte>(newLength); ILDimension newDimension = new ILDimension(newDims); int incOut = newDimension.SequentialIndexDistance(leadDim); int leadDimLen = inDim[leadDim]; int nrHigherDims = inDim.NumberOfElements / leadDimLen; // physical -> pointer arithmetic if (leadDim == 0) { #region physical along 1st leading dimension unsafe { fixed(byte *pOutArr = retDblArr) fixed(complex * pInArr = A.m_data) { complex *lastElement; byte * tmpOut = pOutArr; complex *tmpIn = pInArr; for (int h = nrHigherDims; h-- > 0;) { lastElement = tmpIn + leadDimLen; while (tmpIn < lastElement) { tmpCount += ((*tmpIn++).iszero())?0:1; } *tmpOut = (tmpCount == 0)? (byte)0:(byte)1; tmpCount = 0; tmpOut++; } } } #endregion } else { #region physical along abitrary dimension // sum along abitrary dimension unsafe { fixed(byte *pOutArr = retDblArr) fixed(complex * pInArr = A.m_data) { byte * lastElementOut = newLength + pOutArr - 1; int inLength = inDim.NumberOfElements - 1; complex *lastElementIn = pInArr + inLength; int inc = inDim.SequentialIndexDistance(leadDim); byte * tmpOut = pOutArr; int outLength = newLength - 1; complex *leadEnd; complex *tmpIn = pInArr; for (int h = nrHigherDims; h-- > 0;) { leadEnd = tmpIn + leadDimLen * inc; while (tmpIn < leadEnd) { tmpCount += ((*tmpIn).iszero())?0:1; tmpIn += inc; } *tmpOut = (tmpCount == 0)? (byte)0:(byte)1; tmpCount = 0; tmpOut += inc; if (tmpOut > lastElementOut) { tmpOut = pOutArr + ((tmpOut - pOutArr) - outLength); } if (tmpIn > lastElementIn) { tmpIn = pInArr + ((tmpIn - pInArr) - inLength); } } } } #endregion } return(new ILLogicalArray(retDblArr, newDims));; }