/// <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> /// 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())); }
// DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !! /// <summary> sum two arrays elementwise</summary> /// <param name="A">input 1</param> /// <param name="B">input 2</param> /// <returns> Array with elementwise sum of A and B </returns> /// <remarks><para>On empty input - empty array will be returned.</para> /// <para>A and / or B may be scalar. The scalar value will operate on all elements of the /// other array in this case.</para> /// <para>If neither of A or B is scalar or empty, the dimensions of both arrays must match. /// </para></remarks> public static ILArray <double> atan2(ILArray <double> A, ILArray <double> B) { if (A.IsEmpty && B.IsEmpty) { if (!A.Dimensions.IsSameShape(B.Dimensions)) { throw new ILDimensionMismatchException(); } return(ILArray <double> .empty(A.Dimensions)); } if (A.IsScalar) { if (B.IsScalar) { return(new ILArray <double> (new double [1] { Math.Atan2(A.GetValue(0), B.GetValue(0)) }, A.Dimensions)); } else { if (B.IsEmpty) { return(ILArray <double> .empty(B.Dimensions)); } #region scalar + array ILDimension inDim = B.Dimensions; // double [] retArr = new double [inDim.NumberOfElements]; double [] retArr = ILMemoryPool.Pool.New <double> (inDim.NumberOfElements); double scalarValue = A.GetValue(0); double tmpValue2; int leadDim = 0, leadDimLen = inDim [0]; if (B.IsReference) { #region Reference storage // walk along the longest dimension (for performance reasons) ILIndexOffset idxOffset = B.m_indexOffset; int incOut = inDim.SequentialIndexDistance(leadDim); System.Diagnostics.Debug.Assert(!B.IsVector, "Reference arrays of vector size should not exist!"); for (int i = 1; i < inDim.NumberOfDimensions; i++) { if (leadDimLen < inDim [i]) { leadDimLen = inDim [i]; leadDim = i; incOut = inDim.SequentialIndexDistance(leadDim); } } if (B.IsMatrix) { #region Matrix //////////////////////////// MATRIX //////////////////// int secDim = (leadDim + 1) % 2; unsafe { fixed(int *leadDimStart = idxOffset [leadDim], secDimStart = idxOffset [secDim]) fixed(double *pOutArr = retArr) fixed(double *pInArr = B.m_data) { double *tmpOut = pOutArr; double *tmpIn = pInArr; double *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) { *tmpOut = Math.Atan2(scalarValue, (*(tmpIn + *leadDimIdx++))); tmpOut += incOut; } } } } #endregion } else { #region arbitrary size unsafe { int [] curPosition = new int [B.Dimensions.NumberOfDimensions]; fixed(int *leadDimStart = idxOffset [leadDim]) { fixed(double *pOutArr = retArr) fixed(double *pInArr = B.m_data) { double *tmpOut = pOutArr; double *tmpOutEnd = tmpOut + retArr.Length; // init lesezeiger: add alle Dimensionen mit 0 (auer leadDim) double *tmpIn = pInArr + B.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 = Math.Atan2(scalarValue, (*(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(double *pOutArr = retArr) fixed(double *pInArr = B.m_data) { double *lastElement = pOutArr + retArr.Length; double *tmpOut = pOutArr; double *tmpIn = pInArr; while (tmpOut < lastElement) //HC03 { *tmpOut++ = Math.Atan2(scalarValue, (*tmpIn++)); } } } #endregion } return(new ILArray <double> (retArr, inDim)); #endregion scalar + array } } else { if (B.IsScalar) { if (A.IsEmpty) { return(ILArray <double> .empty(A.Dimensions)); } #region array + scalar ILDimension inDim = A.Dimensions; // double [] retArr = new double [inDim.NumberOfElements]; double [] retArr = ILMemoryPool.Pool.New <double> (inDim.NumberOfElements); double scalarValue = B.GetValue(0); double tmpValue1; int leadDim = 0, leadDimLen = inDim [0]; if (A.IsReference) { #region Reference storage // walk along the longest dimension (for performance reasons) ILIndexOffset idxOffset = A.m_indexOffset; int incOut = inDim.SequentialIndexDistance(leadDim); System.Diagnostics.Debug.Assert(!A.IsVector, "Reference arrays of vector size should not exist!"); for (int i = 1; i < inDim.NumberOfDimensions; i++) { if (leadDimLen < inDim [i]) { leadDimLen = inDim [i]; leadDim = i; incOut = inDim.SequentialIndexDistance(leadDim); } } if (A.IsMatrix) { #region Matrix //////////////////////////// MATRIX //////////////////// int secDim = (leadDim + 1) % 2; unsafe { fixed(int *leadDimStart = idxOffset [leadDim], secDimStart = idxOffset [secDim]) fixed(double *pOutArr = retArr) fixed(double *pInArr = A.m_data) { double *tmpOut = pOutArr; double *tmpIn = pInArr; double *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) //HC04 { *tmpOut = Math.Atan2(*(tmpIn + *leadDimIdx++), scalarValue); tmpOut += incOut; } } } } #endregion } else { #region arbitrary size unsafe { int [] curPosition = new int [A.Dimensions.NumberOfDimensions]; fixed(int *leadDimStart = idxOffset [leadDim]) { fixed(double *pOutArr = retArr) fixed(double *pInArr = A.m_data) { double *tmpOut = pOutArr; double *tmpOutEnd = tmpOut + retArr.Length; // init readpointer: add all Dimensions with 0 (except leadDim) double *tmpIn = pInArr + A.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) //HC05 { *tmpOut = Math.Atan2(*(tmpIn + *leadDimIdx++), scalarValue); 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(double *pOutArr = retArr) fixed(double *pInArr = A.m_data) { double *lastElement = pOutArr + retArr.Length; double *tmpOut = pOutArr; double *tmpIn = pInArr; while (tmpOut < lastElement) //HC06 { *tmpOut++ = Math.Atan2(*tmpIn++, scalarValue); } } } #endregion //tmpValue1 = 0; } return(new ILArray <double> (retArr, inDim)); #endregion array + scalar } else { #region array + array ILDimension inDim = A.Dimensions; if (!inDim.IsSameShape(B.Dimensions)) { throw new ILDimensionMismatchException(); } double [] retSystemArr; double tmpValue1; double tmpValue2; // retSystemArr = new double [inDim.NumberOfElements]; retSystemArr = ILMemoryPool.Pool.New <double> (inDim.NumberOfElements); int leadDim = 0, leadDimLen = inDim [0]; // this will most probably be not very fast, but .... :| // 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; } } unsafe { fixed(double *pOutArr = retSystemArr) fixed(double *inA1 = A.m_data) fixed(double *inA2 = B.m_data) { double *pInA1 = inA1; double *pInA2 = inA2; int c = 0; double *poutarr = pOutArr; double *outEnd = poutarr + retSystemArr.Length; if (A.IsReference) { if (!B.IsReference) { while (poutarr < outEnd) //HC07 { *poutarr++ = Math.Atan2(*(pInA1 + A.getBaseIndex(c++)), (*pInA2++)); } } else { // optimization for matrix if (inDim.NumberOfDimensions < 3) { fixed(int *pA1idx0 = A.m_indexOffset[0]) fixed(int *pA1idx1 = A.m_indexOffset[1]) fixed(int *pA2idx0 = B.m_indexOffset[0]) fixed(int *pA2idx1 = B.m_indexOffset[1]) { int r = 0, rLen = A.m_dimensions[0]; int cLen = A.m_dimensions[1]; while (poutarr < outEnd) //HC08 { *poutarr++ = Math.Atan2(*(pInA1 + (*(pA1idx0 + r)) + (*(pA1idx1 + c))), (*(pInA2 + (*(pA2idx0 + r)) + (*(pA2idx1 + c))))); if (++r == rLen) { r = 0; c++; } } } } else { while (poutarr < outEnd) //HC09 { *poutarr++ = Math.Atan2(*(pInA1 + A.getBaseIndex(c)), (*(pInA2 + B.getBaseIndex(c++)))); } } // tmpValue1 = 0; tmpValue2 = 0; } } else { if (B.IsReference) { while (poutarr < outEnd) //HC10 { *poutarr++ = Math.Atan2(*pInA1++, (*(pInA2 + B.getBaseIndex(c++)))); } } else { while (poutarr < outEnd) //HC11 { *poutarr++ = Math.Atan2(*pInA1++ /*HC:*/, (*pInA2++)); } } } } } return(new ILArray <double> (retSystemArr, inDim)); #endregion array + array } } }
/// <summary> /// Multiply elements of inArray along specified dimension. /// </summary> /// <param name="inArray">N-dimensional double array</param> /// <param name="leadDim">index of dimension to multiply elements along</param> /// <returns>array having the 'leadDim's dimension /// reduced to the length of 1 with the result of the product of /// corresponding elements of inArray of that dimension.</returns> public static ILArray <double> prod(ILArray <double> inArray, int leadDim) { ILDimension inDim = inArray.Dimensions; int[] newDims = inDim.ToIntArray(); if (leadDim == newDims.Length || inDim[leadDim] == 1) { // scalar or sum over singleton -> return copy return((ILArray <double>)inArray.Clone()); } int newLength; double[] retDblArr; // build ILDimension newLength = inDim.NumberOfElements / newDims[leadDim]; newDims[leadDim] = 1; retDblArr = ILMemoryPool.Pool.New <double>(newLength); int leadDimLen = inDim[leadDim]; int nrHigherDims = inDim.NumberOfElements / leadDimLen; if (inArray.IsReference) { #region Reference storage // ======================== REFERENCE double Storage =========== if (inArray.IsMatrix) { #region Matrix //////////////////////////// MATRIX /////////////////////// unsafe { ILIndexOffset idxOffset = inArray.m_indexOffset; int secDim = (leadDim + 1) % 2; fixed(int *leadDimStart = idxOffset[leadDim], secDimStart = idxOffset[secDim]) { fixed(double *pOutArr = retDblArr, pInArr = inArray.m_data) { double *tmpOut = pOutArr; double *lastElementOut = tmpOut + retDblArr.Length; double *tmpIn = pInArr; int * secDimEnd = secDimStart + idxOffset[secDim].Length - 1; int * secDimIdx = secDimStart; int * leadDimIdx = leadDimStart; int * leadDimEnd = leadDimStart + leadDimLen - 1; // start at first element while (secDimIdx <= secDimEnd) { tmpIn = pInArr + *secDimIdx++; leadDimIdx = leadDimStart; *tmpOut = 1.0; while (leadDimIdx <= leadDimEnd) { *tmpOut *= *(tmpIn + *leadDimIdx++); } tmpOut++; } } } } #endregion } else if (inArray.IsVector) { #region Vector //////////////////////////// VECTOR /////////////////////// unsafe { ILIndexOffset idxOffset = inArray.m_indexOffset; int[] curPosition = new int[2]; int secDim = (leadDim + 1) % 2; fixed(int *leadDimStart = idxOffset[leadDim]) { fixed(double *pOutArr = retDblArr, pInArr = inArray.m_data) { double *tmpOut = pOutArr; double *tmpIn = pInArr; int * leadDimIdx = leadDimStart; int * leadDimEnd = leadDimStart + leadDimLen; // start at first element *tmpOut = 1.0; while (leadDimIdx < leadDimEnd) { *tmpOut *= *(tmpIn + *leadDimIdx++); } } } } #endregion } else { ///////////////////////////// ARBITRARY DIMENSIONS ////////// #region arbitrary size unsafe { ILIndexOffset idxOffset = inArray.m_indexOffset; int[] curPosition = new int[inArray.Dimensions.NumberOfDimensions]; fixed(int *leadDimStart = idxOffset[leadDim]) { fixed(double *pOutArr = retDblArr, pInArr = inArray.m_data) { double *tmpOut = pOutArr; double *lastElementOut = tmpOut + retDblArr.Length; double *tmpIn = pInArr; int * leadDimIdx = leadDimStart; int * leadDimEnd = leadDimStart + leadDimLen; int dimLen = curPosition.Length; int d, curD; // start at first element while (tmpOut < lastElementOut) { leadDimIdx = leadDimStart; *tmpOut = 1.0; while (leadDimIdx < leadDimEnd) { *tmpOut *= *(tmpIn + *leadDimIdx++); } 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, curPosition[curD]]; d++; } } } } } #endregion } // ============================================================== #endregion } else { // physical -> pointer arithmetic if (leadDim == 0) { #region physical along 1st leading dimension unsafe { fixed(double *pOutArr = retDblArr, pInArr = inArray.m_data) { double *lastElement; double *tmpOut = pOutArr; double *tmpIn = pInArr; for (int h = nrHigherDims; h-- > 0;) { lastElement = tmpIn + leadDimLen; *tmpOut = 1.0; while (tmpIn < lastElement) { *tmpOut *= *tmpIn++; } tmpOut++; } } } #endregion } else { #region physical along abitrary dimension // sum along abitrary dimension unsafe { fixed(double *pOutArr = retDblArr, pInArr = inArray.m_data) { double *lastElementOut = newLength + pOutArr - 1; int inLength = inDim.NumberOfElements - 1; double *lastElementIn = pInArr + inLength; int inc = inDim.SequentialIndexDistance(leadDim); double *tmpOut = pOutArr; int outLength = newLength - 1; double *leadEnd; double *tmpIn = pInArr; for (int h = nrHigherDims; h-- > 0;) { leadEnd = tmpIn + leadDimLen * inc; *tmpOut = 1.0; while (tmpIn < leadEnd) { *tmpOut *= *tmpIn; tmpIn += inc; } tmpOut += inc; if (tmpOut > lastElementOut) { tmpOut = pOutArr + ((tmpOut - pOutArr) - outLength); } if (tmpIn > lastElementIn) { tmpIn = pInArr + ((tmpIn - pInArr) - inLength); } } } } #endregion } } return(new ILArray <double>(retDblArr, newDims));; }