示例#1
0
 /// <summary>
 /// sum all elements of array A
 /// </summary>
 /// <param name="A">n-dim array</param>
 /// <returns><para>scalar sum of all elements of A.</para>
 /// <para>If A is empty, an empty array will be returned.</para></returns>
 /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if A was null.</exception>
 /// <seealso cref="ILNumerics.BuiltInFunctions.ILMath.sum(ILArray&lt;double&gt;)"/>
 public static  ILArray<fcomplex> sumall ( ILArray<fcomplex> A) {
     if (object.Equals(A,null))
         throw new ILArgumentException("sumall: argument must not be null!");
     if (A.IsEmpty) {
         return  ILArray<fcomplex> .empty(0,0); 
     } 
     fcomplex retArr =  new fcomplex(0.0f,0.0f) ; 
     if (A.m_indexOffset == null) {
         unsafe {
             fixed ( fcomplex * inArrStart = A.m_data) {
                 fcomplex * inArrWalk = inArrStart; 
                 fcomplex * inArrEnd = inArrStart + A.Dimensions.NumberOfElements; 
                 while (inArrWalk < inArrEnd) {
                     retArr += *inArrWalk++; 
                 }
             }
         }
     } else {
         unsafe {
             fixed ( fcomplex * inArrStart = A.m_data)  {
                 for (int i = A.Dimensions.NumberOfElements; i -->0;) {
                     retArr += *(inArrStart + A.getBaseIndex(i)); 
                 }
             }
         }
     }
     return new  ILArray<fcomplex> (new  fcomplex [1]{retArr},1,1);
 }
示例#2
0
        /// <summary>
        /// invert elements of A, return result as out argument
        /// </summary>
        /// <param name="A"></param>
        /// <param name="outArray"></param>
        public static void  invert(ILArray <fcomplex> A, ILArray <fcomplex> outArray)
        {
            #region array + array
            ILDimension inDim = A.Dimensions;
            if (!inDim.IsSameSize(outArray.Dimensions))
            {
                throw new ILDimensionMismatchException();
            }
            int leadDim = 0, leadDimLen = inDim [0];
            // 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(fcomplex *inA1 = A.m_data)
                fixed(fcomplex * inA2 = outArray.m_data)
                {
                    fcomplex *pInA1  = inA1;
                    fcomplex *pInA2  = inA2;
                    int       c      = 0;
                    fcomplex *outEnd = inA2 + outArray.m_data.Length;

                    if (A.IsReference)
                    {
                        while (pInA2 < outEnd)    //HC07

                        {
                            *pInA2++ = (*(pInA1 + A.getBaseIndex(c++)) * (-1.0f));
                        }
                    }
                    else
                    {
                        while (pInA2 < outEnd)    //HC11

                        {
                            *pInA2++ = (*pInA1++ /*HC:*/ *(-1.0f));
                        }
                    }
                }
                #endregion array + array
            }
            return;
        }
示例#3
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 <fcomplex> 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(fcomplex * pInArr = A.m_data)
                            {
                                byte *    tmpOut     = pOutArr;
                                fcomplex *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 = fcomplex.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(fcomplex * pInArr = A.m_data)
                            {
                                byte *    tmpOut    = pOutArr;
                                byte *    tmpOutEnd = tmpOut + retDblArr.Length - 1;
                                fcomplex *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 = fcomplex.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(fcomplex * pInArr = A.m_data)
                    {
                        byte *    lastElement = pOutArr + retDblArr.Length;
                        byte *    tmpOut      = pOutArr;
                        fcomplex *tmpIn       = pInArr;

                        while (tmpOut < lastElement)   // HC02

                        {
                            *tmpOut++ = fcomplex.IsInfinity(*tmpIn++)  ?(byte)1:(byte)0;
                        }
                    }
                }
                #endregion
            }
            return(new  ILLogicalArray(retDblArr, inDim));
        }
示例#4
0
        /// <summary>
        /// Create array initialized with all elements set to one.
        /// </summary>
        /// <param name="type">Numeric type specification. One value out of the types listed in the <see cred="ILNumerics.NumericType"/>
        /// enum.</param>
        /// <param name="dimensions">Dimension specification. At least one dimension must be specified.</param>
        /// <returns>ILArray&lt;BaseT&gt; of inner type corresponding to <paramref name="type"/> argument.</returns>
        /// <remarks>The array returned may be cast to the appropriate actual type afterwards.
        /// <para>
        /// <list type="number">
        /// <listheader>The following types are supported: </listheader>
        /// <item>Double</item>
        /// <item>Single</item>
        /// <item>Complex</item>
        /// <item>FComplex</item>
        /// <item>Byte</item>
        /// <item>Char</item>
        /// <item>Int16</item>
        /// <item>Int32</item>
        /// <item>Int64</item>
        /// <item>UInt16</item>
        /// <item>UInt32</item>
        /// <item>UInt64</item>
        /// </list>
        /// </para>
        /// </remarks>
        public static ILBaseArray ones(NumericType type, params int[] dimensions)
        {
            if (dimensions.Length < 1)
            {
                throw new ILArgumentException("ones: invalid dimension specified!");
            }
            switch (type)
            {
            case NumericType.Double:
                return(ones(dimensions));

            case NumericType.Single:
                ILDimension dim = new ILDimension(dimensions);
                unsafe {
                    float[] data = null;
                    data = new float[dim.NumberOfElements];
                    fixed(float *pD = data)
                    {
                        float *pStart = pD;
                        float *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = 1.0f;
                        }
                    }

                    return(new ILArray <float>(data, dimensions));
                }

            case NumericType.Complex:
                dim = new ILDimension(dimensions);
                unsafe {
                    complex[] data = null;
                    data = new complex[dim.NumberOfElements];
                    fixed(complex *pD = data)
                    {
                        complex *pStart = pD;
                        complex *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = new complex(1.0, 1.0);
                        }
                    }

                    return(new ILArray <complex>(data, dimensions));
                }

            case NumericType.FComplex:
                dim = new ILDimension(dimensions);
                unsafe {
                    fcomplex[] data = null;
                    data = new fcomplex[dim.NumberOfElements];
                    fixed(fcomplex *pD = data)
                    {
                        fcomplex *pStart = pD;
                        fcomplex *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = new fcomplex(1.0f, 1.0f);
                        }
                    }

                    return(new ILArray <fcomplex>(data, dimensions));
                }

            case NumericType.Byte:
                dim = new ILDimension(dimensions);
                unsafe {
                    byte[] data = null;
                    data = new byte[dim.NumberOfElements];
                    fixed(byte *pD = data)
                    {
                        byte *pStart = pD;
                        byte *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = 1;
                        }
                    }

                    return(new ILArray <byte>(data, dimensions));
                }

            case NumericType.Char:
                dim = new ILDimension(dimensions);
                unsafe {
                    char[] data = null;
                    data = new char[dim.NumberOfElements];
                    fixed(char *pD = data)
                    {
                        char *pStart = pD;
                        char *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = Char.MinValue;
                        }
                    }

                    return(new ILArray <char>(data, dimensions));
                }

            case NumericType.Int16:
                dim = new ILDimension(dimensions);
                unsafe {
                    Int16[] data = null;
                    data = new Int16[dim.NumberOfElements];
                    fixed(Int16 *pD = data)
                    {
                        Int16 *pStart = pD;
                        Int16 *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = 1;
                        }
                    }

                    return(new ILArray <Int16>(data, dimensions));
                }

            case NumericType.Int32:
                dim = new ILDimension(dimensions);
                unsafe {
                    Int32[] data = null;
                    data = new Int32[dim.NumberOfElements];
                    fixed(Int32 *pD = data)
                    {
                        Int32 *pStart = pD;
                        Int32 *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = 1;
                        }
                    }

                    return(new ILArray <Int32>(data, dimensions));
                }

            case NumericType.Int64:
                dim = new ILDimension(dimensions);
                unsafe {
                    Int64[] data = null;
                    data = new Int64[dim.NumberOfElements];
                    fixed(Int64 *pD = data)
                    {
                        Int64 *pStart = pD;
                        Int64 *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = 1;
                        }
                    }

                    return(new ILArray <Int64>(data, dimensions));
                }

            case NumericType.UInt16:
                dim = new ILDimension(dimensions);
                unsafe {
                    UInt16[] data = null;
                    data = new UInt16[dim.NumberOfElements];
                    fixed(UInt16 *pD = data)
                    {
                        UInt16 *pStart = pD;
                        UInt16 *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = 1;
                        }
                    }

                    return(new ILArray <UInt16>(data, dimensions));
                }

            case NumericType.UInt32:
                dim = new ILDimension(dimensions);
                unsafe {
                    UInt32[] data = null;
                    data = new UInt32[dim.NumberOfElements];
                    fixed(UInt32 *pD = data)
                    {
                        UInt32 *pStart = pD;
                        UInt32 *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = 1;
                        }
                    }

                    return(new ILArray <UInt32>(data, dimensions));
                }

            case NumericType.UInt64:
                dim = new ILDimension(dimensions);
                unsafe {
                    UInt64[] data = null;
                    data = new UInt64[dim.NumberOfElements];
                    fixed(UInt64 *pD = data)
                    {
                        UInt64 *pStart = pD;
                        UInt64 *pEnd   = pD + data.Length;

                        while (pEnd > pStart)
                        {
                            *(--pEnd) = 1;
                        }
                    }

                    return(new ILArray <UInt64>(data, dimensions));
                }
            }
            return(null);
        }
        /// <summary>
        /// GEneral Matrix Multiply this array
        /// </summary>
        /// <overloads>General Matrix Multiply for double, float, complex and fcomplex arrays</overloads>
        /// <param name="A"><![CDATA[ILArray<>]]> matrix A</param>
        /// <param name="B"><![CDATA[ILArray<>]]> matrix B</param>
        /// <returns><![CDATA[ILArray<double>]]> new array - result of matrix multiplication</returns>
        /// <remarks>Both arrays must be matrices. The matrix will be multiplied only
        /// if dimensions match accordingly. Therefore B's number of rows must
        /// equal A's number of columns. An Exception will be thrown otherwise.
        /// The multiplication will carried out on BLAS libraries, if availiable and the
        /// storage memory structure meets BLAS's requirements. If not it will be done inside .NET's
        /// framework 'by hand'. This is especially true for referencing storages with
        /// irregular dimensions. However, even GEMM on those reference storages linking into
        /// a physical storage can (an will) be carried out via BLAS dll's, if the spacing
        /// into dimensions matches the requirements of BLAS. Those are:
        /// <list>
        /// <item>the elements of one dimension will be adjecently layed out, and</item>
        /// <item>the elements of the second dimension must be regular (evenly) spaced</item>
        /// </list>
        /// <para>For reference arrays where the spacing between adjecent elements do not meet the
        /// requirements above, the matrix multiplication will be made without optimization and
        /// therefore suffer from low performance in relation to solid arrays. See <a href="http://ilnumerics.net?site=5142">online documentation: referencing for ILNumerics.Net</a></para>
        /// </remarks>
        /// <exception cref="ILNumerics.Exceptions.ILArgumentSizeException">if at least one arrays is not a matrix</exception>
        /// <exception cref="ILNumerics.Exceptions.ILDimensionMismatchException">if the size of both matrices do not match</exception>
        public static ILArray <fcomplex> multiply(ILArray <fcomplex> A, ILArray <fcomplex> B)
        {
            ILArray <fcomplex> ret = null;

            if (A.Dimensions.NumberOfDimensions != 2 ||
                B.Dimensions.NumberOfDimensions != 2)
            {
                throw new ILArgumentSizeException("Matrix multiply: arguments must be 2-d.");
            }
            if (A.Dimensions[1] != B.Dimensions[0])
            {
                throw new ILDimensionMismatchException("Matrix multiply: inner matrix dimensions must match.");
            }
            // decide wich method to use
            // test auf Regelmigkeit der Dimensionen
            int  spacingA0;
            int  spacingA1;
            int  spacingB0;
            int  spacingB1;
            char transA, transB;

            fcomplex [] retArr = null;
            isSuitableForLapack(A, B, out spacingA0, out spacingA1, out spacingB0, out spacingB1, out transA, out transB);
            if (A.m_dimensions.NumberOfElements > ILAtlasMinimumElementSize ||
                B.m_dimensions.NumberOfElements > ILAtlasMinimumElementSize)
            {
                // do BLAS GEMM
                retArr = new  fcomplex [A.m_dimensions[0] * B.m_dimensions[1]];
                if (((spacingA0 == 1 && spacingA1 > int.MinValue) || (spacingA1 == 1 && spacingA0 > int.MinValue)) &&
                    ((spacingB0 == 1 && spacingB1 > int.MinValue) || (spacingB1 == 1 && spacingB0 > int.MinValue)))
                {
                    ret = new  ILArray <fcomplex> (retArr, new ILDimension(A.m_dimensions[0], B.m_dimensions[1]));
                    if (transA == 't')
                    {
                        spacingA1 = spacingA0;
                    }
                    if (transB == 't')
                    {
                        spacingB1 = spacingB0;
                    }
                    unsafe
                    {
                        fixed(fcomplex *ptrC = retArr)
                        fixed(fcomplex * pA = A.m_data)
                        fixed(fcomplex * pB = B.m_data)
                        {
                            fcomplex *ptrA = pA + A.getBaseIndex(0);
                            fcomplex *ptrB = pB + B.getBaseIndex(0);

                            if (transA == 't')
                            {
                                spacingA1 = spacingA0;
                            }
                            if (transB == 't')
                            {
                                spacingB1 = spacingB0;
                            }
                            Lapack.cgemm(transA, transB, A.m_dimensions[0], B.m_dimensions[1],
                                         A.m_dimensions[1], ( fcomplex )1.0, (IntPtr)ptrA, spacingA1,
                                         (IntPtr)ptrB, spacingB1, ( fcomplex )1.0, retArr, A.m_dimensions[0]);
                        }
                    }
                    return(ret);
                }
            }
            // do GEMM by hand
            retArr = new  fcomplex [A.m_dimensions[0] * B.m_dimensions[1]];
            ret    = new  ILArray <fcomplex> (retArr, A.m_dimensions[0], B.m_dimensions[1]);
            unsafe {
                int in2Len1 = B.m_dimensions[1];
                int in1Len0 = A.m_dimensions[0];
                int in1Len1 = A.m_dimensions[1];
                fixed(fcomplex *ptrC = retArr)
                {
                    fcomplex *pC = ptrC;

                    for (int c = 0; c < in2Len1; c++)
                    {
                        for (int r = 0; r < in1Len0; r++)
                        {
                            for (int n = 0; n < in1Len1; n++)
                            {
                                *pC += A.GetValue(r, n) * B.GetValue(n, c);
                            }
                            pC++;
                        }
                    }
                }
            }
            return(ret);
        }