/// <summary> /// operate on elements of both storages by the given function -> relational operations /// </summary> /// <param name="inArray1">First storage array</param> /// <param name="inArray2">Second storage array</param> /// <param name="operation">operation to apply to the elements of inArray. This /// acts like a function pointer.</param> /// <returns>new ILLogicalArray with result of operation for corresponding /// elements of both arrays.</returns> /// <remarks>The values of inArray2 nor inArray2 will not be altered.The dimensions /// of both arrays must match.</remarks> private static ILArray <double> DoubleBinaryDoubleOperator(ILArray <double> inArray1, ILArray <double> inArray2, ILApplyDouble_DoubleDouble operation) { ILDimension inDim = inArray1.Dimensions; if (!inDim.IsSameSize(inArray2.Dimensions)) { throw new Exception("Array dimensions must match."); } double[] retBoolArr; // build ILDimension int newLength = inDim.NumberOfElements; retBoolArr = new double[newLength]; int leadDim = 0; int leadDimLen = inDim[0]; if (inArray1.IsReference || inArray2.IsReference) { // this will most probably be not very fast, but .... :| #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; } } ILIterator <double> it1 = inArray1.CreateIterator(ILIteratorPositions.ILEnd, leadDim); ILIterator <double> it2 = inArray2.CreateIterator(ILIteratorPositions.ILEnd, leadDim); unsafe { fixed(double *pOutArr = retBoolArr) { double *poutarr = pOutArr; double *outEnd = poutarr + newLength; while (poutarr < outEnd) { *poutarr++ = operation(it1.Increment(), it2.Increment()); } } } // ============================================================== #endregion } else { // physical -> pointer arithmetic #region physical storage unsafe { fixed(double *pInArr1 = inArray1.m_data, pInArr2 = inArray2.m_data) { fixed(double *pOutArr = retBoolArr) { double *poutarr = pOutArr; double *poutend = poutarr + newLength; double *pIn1 = pInArr1; double *pIn2 = pInArr2; while (poutarr < poutend) { *poutarr++ = operation(*pIn1++, *pIn2++); } } } } #endregion } return(new ILArray <double>(retBoolArr, inDim.ToIntArray())); }
/// <summary> /// operate on elements of both storages by the given function -> relational operations /// </summary> /// <param name="inArray1">First storage array</param> /// <param name="inArray2">Second storage array</param> /// <param name="operation">operation to apply to the elements of inArray. This /// acts like a function pointer.</param> /// <returns>new ILLogicalArray with result of operation for corresponding /// elements of both arrays.</returns> /// <remarks>The values of inArray2 nor inArray2 will not be altered.The dimensions /// of both arrays must match.</remarks> private static ILArray<double> DoubleBinaryDoubleOperator(ILArray<double> inArray1, ILArray<double> inArray2, ILApplyDouble_DoubleDouble operation) { ILDimension inDim = inArray1.Dimensions; if (!inDim.IsSameSize(inArray2.Dimensions)) throw new Exception("Array dimensions must match."); double[] retBoolArr; // build ILDimension int newLength = inDim.NumberOfElements; retBoolArr = new double[newLength]; int leadDim = 0; int leadDimLen = inDim[0]; if (inArray1.IsReference || inArray2.IsReference) { // this will most probably be not very fast, but .... :| #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; } } ILIterator<double> it1 = inArray1.CreateIterator(ILIteratorPositions.ILEnd, leadDim); ILIterator<double> it2 = inArray2.CreateIterator(ILIteratorPositions.ILEnd, leadDim); unsafe { fixed (double* pOutArr = retBoolArr) { double* poutarr = pOutArr; double* outEnd = poutarr + newLength; while (poutarr < outEnd) { *poutarr++ = operation(it1.Increment(), it2.Increment()); } } } // ============================================================== #endregion } else { // physical -> pointer arithmetic #region physical storage unsafe { fixed (double* pInArr1 = inArray1.m_data, pInArr2 = inArray2.m_data) { fixed (double* pOutArr = retBoolArr) { double* poutarr = pOutArr; double* poutend = poutarr + newLength; double* pIn1 = pInArr1; double* pIn2 = pInArr2; while (poutarr < poutend) *poutarr++ = operation(*pIn1++, *pIn2++); } } } #endregion } return new ILArray<double>(retBoolArr, inDim.ToIntArray()); }