Ejemplo n.º 1
0
        /// <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));
        }
Ejemplo n.º 2
0
        /// <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()));
        }
Ejemplo n.º 3
0
// 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
                }
            }
        }
Ejemplo n.º 4
0
        /// <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));;
        }