예제 #1
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
                }
            }
        }