Beispiel #1
0
        /// <summary>Hyperbolic tangent of array elements</summary>
        /// <param name="A">input array</param>
        /// <returns>Hyperbolic tangent of array elements</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 ILArray <float> tanh(ILArray <float> A)
        {
            if (A.IsEmpty)
            {
                return(ILArray <float> .empty(A.Dimensions));
            }
            ILDimension inDim = A.Dimensions;

            float [] retDblArr;
            // build ILDimension
            int newLength = inDim.NumberOfElements;

            //retDblArr = new  float [newLength];
            retDblArr = ILMemoryPool.Pool.New <float> (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(float *pOutArr = retDblArr)
                            fixed(float *pInArr = A.m_data)
                            {
                                float *tmpOut     = pOutArr;
                                float *tmpIn      = pInArr;
                                float *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 = (float)Math.Tanh(*(tmpIn + *leadDimIdx++));
                                        tmpOut += incOut;
                                    }
                                }
                            }
                        }
                    }
                    #endregion
                }
                else
                {
                    #region arbitrary size
                    unsafe {
                        int [] curPosition = new int [A.Dimensions.NumberOfDimensions];
                        fixed(int *leadDimStart = idxOffset [leadDim])
                        {
                            fixed(float *pOutArr = retDblArr)
                            fixed(float *pInArr = A.m_data)
                            {
                                float *tmpOut    = pOutArr;
                                float *tmpOutEnd = tmpOut + retDblArr.Length - 1;
                                float *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 = (float)Math.Tanh(*(tmpIn + *leadDimIdx++));
                                        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(float *pOutArr = retDblArr)
                    fixed(float *pInArr = A.m_data)
                    {
                        float *lastElement = pOutArr + retDblArr.Length;
                        float *tmpOut      = pOutArr;
                        float *tmpIn       = pInArr;

                        while (tmpOut < lastElement)   // HC02

                        {
                            *tmpOut++ = (float)Math.Tanh(*tmpIn++);
                        }
                    }
                }
                #endregion
            }
            return(new  ILArray <float> (retDblArr, inDim));
        }
Beispiel #2
0
        /// <summary>
        /// First derivative along specific dimension
        /// </summary>
        /// <param name="A">input array</param>
        /// <param name="leadDim">dimensions to create derivative along</param>
        /// <returns>array with first derivative of A along dimension <code>lieadDim</code></returns>
        private static ILArray <complex> diff(int leadDim, ILArray <complex> A)
        {
            if (A.IsEmpty)
            {
                return(ILArray <complex> .empty(A.Dimensions));
            }
            if (A.IsScalar)
            {
                return(ILArray <complex> .empty(0, 0));
            }
            if (leadDim < 0)
            {
                throw new ILArgumentException("dimension parameter out of range!");
            }
            if (leadDim >= A.Dimensions.NumberOfDimensions)
            {
                int[] outDims = A.Dimensions.ToIntArray(leadDim + 1);
                outDims[leadDim] = 0;
                return(ILArray <complex> .empty(outDims));
            }
            ILDimension inDim = A.Dimensions;

            int[] newDims = inDim.ToIntArray();

            if (inDim[leadDim] == 1)
            {
                return(ILArray <complex> .empty(0, 0));
            }
            int newLength;

            complex [] retDblArr;
            // build ILDimension
            newLength = inDim.NumberOfElements / newDims[leadDim];
            newDims[leadDim]--;
            newLength = newLength * newDims[leadDim];
            retDblArr = ILMemoryPool.Pool.New <complex>(newLength);
            ILDimension newDimension = new ILDimension(newDims);
            int         leadDimLen = inDim[leadDim];
            int         nrHigherDims = inDim.NumberOfElements / leadDimLen;
            int         incOut = newDimension.SequentialIndexDistance(leadDim);
            complex     firstVal, secVal;

            if (A.IsVector)
            {
                return(A["1:end"] - A[vector(0, A.Length - 2)]);
            }

            // physical -> pointer arithmetic
            if (leadDim == 0)
            {
                #region physical along 1st leading dimension
                unsafe
                {
                    fixed(complex *pOutArr = retDblArr)
                    fixed(complex * pInArr = A.m_data)
                    {
                        complex *lastElement;
                        complex *tmpOut = pOutArr;
                        complex *tmpIn  = pInArr;

                        for (int h = nrHigherDims; h-- > 0;)
                        {
                            lastElement = tmpIn + leadDimLen;

                            firstVal = *tmpIn++;
                            while (tmpIn < lastElement)
                            {
                                secVal      = *tmpIn++;
                                *(tmpOut++) = ( complex )(secVal - firstVal);
                                firstVal    = secVal;
                            }
                        }
                    }
                }
                #endregion
            }
            else
            {
                #region physical along abitrary dimension
                // sum along abitrary dimension
                unsafe
                {
                    fixed(complex *pOutArr = retDblArr)
                    fixed(complex * pInArr = A.m_data)
                    {
                        complex *lastElementOut = newLength + pOutArr - 1;
                        int      inLength       = inDim.NumberOfElements - 1;
                        complex *lastElementIn  = pInArr + inLength;
                        int      inc            = inDim.SequentialIndexDistance(leadDim);
                        complex *tmpOut         = pOutArr;
                        int      outLength      = newLength - 1;
                        complex *leadEnd;
                        complex *tmpIn = pInArr;

                        for (int h = nrHigherDims; h-- > 0;)
                        {
                            leadEnd  = tmpIn + leadDimLen * inc;
                            firstVal = *tmpIn;
                            tmpIn   += inc;
                            while (tmpIn < leadEnd)
                            {
                                secVal = *tmpIn;
                                *tmpOut = ( complex )(secVal - firstVal);
                                tmpIn   += inc;
                                tmpOut  += incOut;
                                firstVal = secVal;
                            }
                            if (tmpOut > lastElementOut)
                            {
                                tmpOut -= outLength;
                            }
                            if (tmpIn > lastElementIn)
                            {
                                tmpIn -= inLength;
                            }
                        }
                    }
                }
                #endregion
            }
            return(new  ILArray <complex> (retDblArr, newDimension));;
        }
Beispiel #3
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()));
        }
Beispiel #4
0
        /// <summary>
        /// this helper function is used from all constructors
        /// </summary>
        /// <param name="data">storage of source array</param>
        /// <param name="indexOffset">ILIndexOffset mapping for reference arrays</param>
        /// <param name="dimensions">Dimension specification</param>
        /// <param name="startPos">enumeration value where to set the initial element position </param>
        /// <param name="leadingDimension">the dimension, the iterator is going to walk along</param>
        private void commonConstruct(BaseT[] data, ILIndexOffset indexOffset,
                                     ILDimension dimensions, ILIteratorPositions startPos, int leadingDimension)
        {
            m_data             = data;
            m_leadDim          = leadingDimension % dimensions.NumberOfDimensions;
            m_dataLenghtMinus1 = m_data.Length - 1;
            if (indexOffset == null)
            {
                m_increment = dimensions.SequentialIndexDistance(leadingDimension);
                switch (startPos)
                {
                case ILIteratorPositions.ILStart:
                    m_pos = 0;
                    break;

                case ILIteratorPositions.ILMiddle:
                    m_pos = (int)(m_data.Length / 2);
                    break;

                case ILIteratorPositions.ILEnd:
                    m_pos = m_dataLenghtMinus1;
                    break;
                }
            }
            else
            {
                int nrDims    = indexOffset.Length;
                int curDim    = (m_leadDim + 1) % nrDims;
                int curDimLen = dimensions[curDim];
                m_indexOffset   = indexOffset;
                m_leadDimIdx    = indexOffset[curDim];
                m_higherDimsIdx = new int[dimensions.NumberOfElements / dimensions[m_leadDim]];
                int[] curPos = new int[dimensions.NumberOfDimensions];
                // create int vector holding presummed higher dimension indices
                unsafe
                {
                    fixed(int *tmpHighDims = m_higherDimsIdx, tmpLeadDim = m_leadDimIdx,
                          pCurPos          = curPos)
                    {
                        int *pHighDimsIdx  = tmpHighDims;
                        int *pHighDimsLast = pHighDimsIdx + m_higherDimsIdx.Length;
                        int *pLeadDimIdx   = tmpLeadDim;
                        int *pCurPosDim    = pCurPos;
                        int  curIdxSum     = 0;
                        int  d;

                        // sum all idxOffset[d,0] as start value
                        for (d = 2; d < nrDims; d++)
                        {
                            curIdxSum += indexOffset[(m_leadDim + d) % nrDims, 0];
                        }
                        do
                        {
                            // tmp leadDim is 1 dim larger than real leadDim
                            // sum leadDim
                            for (int i = 0; i < curDimLen; i++)
                            {
                                *pHighDimsIdx++ = curIdxSum + *pLeadDimIdx++;
                            }
                            // start increasing at 2 dims higher than lead dim
                            pLeadDimIdx = tmpLeadDim;
                            for (d = 2; pHighDimsIdx < pHighDimsLast && d < nrDims; d++)
                            {
                                curDim      = (d + m_leadDim) % nrDims;
                                pCurPosDim  = pCurPos + curDim;
                                curIdxSum  -= m_indexOffset[curDim, *pCurPosDim];
                                *pCurPosDim = *pCurPosDim + 1;
                                if (*pCurPosDim < dimensions[curDim])
                                {
                                    curIdxSum += m_indexOffset[curDim, *pCurPosDim];
                                    break;
                                }
                                *pCurPosDim = 0;
                                curIdxSum  += m_indexOffset[curDim, *pCurPosDim];
                            }
                        } while (pHighDimsIdx < pHighDimsLast && d < nrDims);
                    }
                }
                m_leadDimIdx = indexOffset[m_leadDim];
                // get start/ end positions
                switch (startPos)
                {
                case ILIteratorPositions.ILStart:
                    m_curLeadIdx = 0;
                    m_curHighDim = 0;
                    m_pos        = m_leadDimIdx[0] + m_higherDimsIdx[0];
                    break;

                case ILIteratorPositions.ILMiddle:
                    m_curLeadIdx = 0;
                    m_curHighDim = (int)(m_higherDimsIdx.Length / 2.0);
                    m_pos        = m_leadDimIdx[0] + m_higherDimsIdx[m_curHighDim];
                    break;

                case ILIteratorPositions.ILEnd:
                    m_curLeadIdx = m_leadDimIdx.Length - 1;
                    m_curHighDim = m_higherDimsIdx.Length - 1;
                    m_pos        = m_leadDimIdx[m_curLeadIdx]
                                   + m_higherDimsIdx[m_curHighDim];
                    break;
                }
            }
            // determine if this storage can be altered
            if (ILArray <BaseT> .GetNumberOfReferences(m_data) > 1)
            {
                m_readonly = true;
            }
            else
            {
                m_readonly = false;
            }
        }
Beispiel #5
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;

            // 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));;
        }
Beispiel #6
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));;
        }
Beispiel #7
0
        /// <summary>determine, if any elements are nonzero</summary>
        /// <param name="A">N-dimensional array</param>
        /// <param name="leadDim">index of dimension to operate along</param>
        /// <returns><para>array of same size as A, having the 'leadDim's dimension reduced to 1, if any elements along that dimension are non-zero, '0' else. </para></returns>
        public static ILLogicalArray  any(ILArray <complex> A, int leadDim)
        {
            if (A.IsEmpty)
            {
                return(ILLogicalArray.empty(A.Dimensions));
            }
            if (A.IsScalar)
            {
                return(new ILLogicalArray(new byte [1] {
                    (A.GetValue(0).iszero())?(byte)0:(byte)1
                }, 1, 1));
            }
            if (leadDim >= A.Dimensions.NumberOfDimensions)
            {
                throw new ILArgumentException("dimension parameter out of range!");
            }
            ILDimension inDim = A.Dimensions;

            int[] newDims  = inDim.ToIntArray();
            int   tmpCount = 0;
            int   newLength;

            byte [] retDblArr;
            // build ILDimension
            newLength        = inDim.NumberOfElements / newDims[leadDim];
            newDims[leadDim] = 1;
            retDblArr        = ILMemoryPool.Pool.New <byte>(newLength);
            ILDimension newDimension = new ILDimension(newDims);
            int         incOut       = newDimension.SequentialIndexDistance(leadDim);
            int         leadDimLen   = inDim[leadDim];
            int         nrHigherDims = inDim.NumberOfElements / leadDimLen;

            // physical -> pointer arithmetic
            if (leadDim == 0)
            {
                #region physical along 1st leading dimension
                unsafe
                {
                    fixed(byte *pOutArr = retDblArr)
                    fixed(complex * pInArr = A.m_data)
                    {
                        complex *lastElement;
                        byte *   tmpOut = pOutArr;
                        complex *tmpIn  = pInArr;

                        for (int h = nrHigherDims; h-- > 0;)
                        {
                            lastElement = tmpIn + leadDimLen;

                            while (tmpIn < lastElement)
                            {
                                tmpCount += ((*tmpIn++).iszero())?0:1;
                            }
                            *tmpOut = (tmpCount == 0)? (byte)0:(byte)1; tmpCount = 0;
                            tmpOut++;
                        }
                    }
                }
                #endregion
            }
            else
            {
                #region physical along abitrary dimension
                // sum along abitrary dimension
                unsafe
                {
                    fixed(byte *pOutArr = retDblArr)
                    fixed(complex * pInArr = A.m_data)
                    {
                        byte *   lastElementOut = newLength + pOutArr - 1;
                        int      inLength       = inDim.NumberOfElements - 1;
                        complex *lastElementIn  = pInArr + inLength;
                        int      inc            = inDim.SequentialIndexDistance(leadDim);
                        byte *   tmpOut         = pOutArr;
                        int      outLength      = newLength - 1;
                        complex *leadEnd;
                        complex *tmpIn = pInArr;

                        for (int h = nrHigherDims; h-- > 0;)
                        {
                            leadEnd = tmpIn + leadDimLen * inc;

                            while (tmpIn < leadEnd)
                            {
                                tmpCount += ((*tmpIn).iszero())?0:1;
                                tmpIn    += inc;
                            }
                            *tmpOut = (tmpCount == 0)? (byte)0:(byte)1; tmpCount = 0;
                            tmpOut += inc;
                            if (tmpOut > lastElementOut)
                            {
                                tmpOut = pOutArr + ((tmpOut - pOutArr) - outLength);
                            }
                            if (tmpIn > lastElementIn)
                            {
                                tmpIn = pInArr + ((tmpIn - pInArr) - inLength);
                            }
                        }
                    }
                }
                #endregion
            }

            return(new  ILLogicalArray(retDblArr, newDims));;
        }
Beispiel #8
0
        /// <summary>
        /// Sum elements of A along dimension specified.
        /// </summary>
        /// <param name="A">N-dimensional array</param>
        /// <param name="leadDim">index of dimension to operate along</param>
        /// <returns>array, same size as A, but having the 'leadDim's dimension
        /// reduced to the length 1 with the sum of all
        /// elements along that dimension.</returns>
        public static /*!HC:outCls1*/ ILArray <double> /*!HC:funcname*/ sum(/*!HC:inCls1*/ ILArray <double> A, int leadDim)
        {
            if (A.IsEmpty)
            {
                return /*!HC:outCls1*/ (ILArray <double> .empty(A.Dimensions));
            }
            if (A.IsScalar)
            {
                /*!HC:HCscalarOp*/
                return(new /*!HC:outCls1*/ ILArray <double> (new /*!HC:inArr1*/ double [] { A.GetValue(0) }, 1, 1));
            }
            if (leadDim >= A.Dimensions.NumberOfDimensions)
            {
                throw new ILArgumentException("dimension parameter out of range!");
            }
            ILDimension inDim = A.Dimensions;

            int[] newDims = inDim.ToIntArray();
            /*!HC:singletonDimOp*/
            if (inDim[leadDim] == 1)
            {
                return((/*!HC:outCls1*/ ILArray <double>)A.Clone());
            }
            int newLength;

            /*!HC:outArr1*/ double [] retDblArr;
            // build ILDimension
            newLength        = inDim.NumberOfElements / newDims[leadDim];
            newDims[leadDim] = 1;
            retDblArr        = ILMemoryPool.Pool.New </*!HC:outArr1*/ double>(newLength);
            ILDimension newDimension = new ILDimension(newDims);
            int         incOut       = newDimension.SequentialIndexDistance(leadDim);
            int         leadDimLen   = inDim[leadDim];
            int         nrHigherDims = inDim.NumberOfElements / leadDimLen;

            // physical -> pointer arithmetic
            if (leadDim == 0)
            {
                #region physical along 1st leading dimension
                unsafe
                {
                    fixed(/*!HC:outArr1*/ double *pOutArr = retDblArr)
                    fixed(/*!HC:inArr1*/ double *pInArr = A.m_data)
                    {
                        /*!HC:inArr1*/ double * lastElement;
                        /*!HC:outArr1*/ double *tmpOut = pOutArr;
                        /*!HC:inArr1*/ double * tmpIn  = pInArr;

                        for (int h = nrHigherDims; h-- > 0;)
                        {
                            lastElement = tmpIn + leadDimLen;
                            /*!HC:HCzero*/
                            *tmpOut = 0.0;
                            while (tmpIn < lastElement)
                            {
                                /*!HC:tmpOutStorage*/ *tmpOut += /*!HC:preEvalOp*/ (double)(*tmpIn++) /*!HC:postEvalOp*/;
                            }
                            /*!HC:operationResult*/
                            /**/
                            tmpOut++;
                        }
                    }
                }
                #endregion
            }
            else
            {
                #region physical along abitrary dimension
                // sum along abitrary dimension
                unsafe
                {
                    fixed(/*!HC:outArr1*/ double *pOutArr = retDblArr)
                    fixed(/*!HC:inArr1*/ double *pInArr = A.m_data)
                    {
                        /*!HC:outArr1*/ double *lastElementOut = newLength + pOutArr - 1;
                        int inLength = inDim.NumberOfElements - 1;
                        /*!HC:inArr1*/ double *lastElementIn = pInArr + inLength;
                        int inc = inDim.SequentialIndexDistance(leadDim);
                        /*!HC:outArr1*/ double *tmpOut = pOutArr;
                        int outLength = newLength - 1;
                        /*!HC:inArr1*/ double *leadEnd;
                        /*!HC:inArr1*/ double *tmpIn = pInArr;

                        for (int h = nrHigherDims; h-- > 0;)
                        {
                            leadEnd = tmpIn + leadDimLen * inc;
                            /*!HC:HCzero*/
                            *tmpOut = 0.0;
                            while (tmpIn < leadEnd)
                            {
                                /*!HC:tmpOutStorage*/ *tmpOut += /*!HC:preEvalOp*/ (double)(*tmpIn) /*!HC:postEvalOp*/;
                                tmpIn += inc;
                            }
                            /*!HC:operationResult*/
                            /**/
                            tmpOut += inc;
                            if (tmpOut > lastElementOut)
                            {
                                tmpOut = pOutArr + ((tmpOut - pOutArr) - outLength);
                            }
                            if (tmpIn > lastElementIn)
                            {
                                tmpIn = pInArr + ((tmpIn - pInArr) - inLength);
                            }
                        }
                    }
                }
                #endregion
            }

            return(new /*!HC:outCls1*/ ILArray <double> (retDblArr, newDims));;
        }