Пример #1
0
        /// <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()));
        }
Пример #2
0
 /// <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());
 }