Ejemplo n.º 1
0
        /// <summary>
        /// multiply and fold array elements along first non singleton dimension
        /// </summary>
        /// <param name="inArray">N-dimensional double array</param>
        /// <returns>array having the first non singleton dimension 
		/// reduced to the length 1 with the result of the products of 
		/// corresponding elements of inArray in that dimension.
		/// The result will have the same number of dimensions as 
		/// inArray, but the first non singleton dimension having the 
		/// size 1.</returns>
		public static ILArray<double> prod(ILArray<double> inArray) {
            int[] newDims = inArray.Dimensions.ToIntArray();
            int nsDim = 0;
            while (nsDim < newDims.Length && newDims[nsDim] < 2)
                nsDim++;
            if (nsDim == newDims.Length)
                // scalar -> return copy
                return (ILArray<double>)inArray.Clone();
            return prod(inArray, nsDim);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// multiply and fold array elements along first non singleton dimension
        /// </summary>
        /// <param name="inArray">N-dimensional double array</param>
        /// <returns>array having the first non singleton dimension
        /// reduced to the length 1 with the result of the products of
        /// corresponding elements of inArray in that dimension.
        /// The result will have the same number of dimensions as
        /// inArray, but the first non singleton dimension having the
        /// size 1.</returns>
        public static ILArray <double> prod(ILArray <double> inArray)
        {
            int[] newDims = inArray.Dimensions.ToIntArray();
            int   nsDim   = 0;

            while (nsDim < newDims.Length && newDims[nsDim] < 2)
            {
                nsDim++;
            }
            if (nsDim == newDims.Length)
            {
                // scalar -> return copy
                return((ILArray <double>)inArray.Clone());
            }
            return(prod(inArray, nsDim));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Decompose matrix A into uper and lower triangular part. Returns permutation matrix also.
        /// </summary>
        /// <param name="A">general input matrix. Size [m x n]</param>
        /// <param name="U">[output] reference to upper triangular matrix. Size [min(m,n) x n]. Must not be null.</param>
        /// <param name="P">[output] reference to permutation matrix. Size [min(m,n) x min(m,n)]. Must not be null.</param>
        /// <returns>lower triangular matrix L of size [m x min(m,n)]</returns>
        /// <remarks>A is decomposed into L and U, so that the equation
        /// <code>ILMath.multiply(L,U) == ILMath.multiply(P,A)</code>
        /// will hold except for round off error.
        /// <para>L and U will be true lower triangular matrices.</para>
        /// <example> <code>
        /// //Let's construct a matrix X:
        /// ILArray&lt;double&gt; X = new ILArray&lt;double&gt;(new double[]{1, 2, 3, 4, 4, 4, 5, 6, 7},3,3).T;
        /// // now X.ToString() will give something like:
        /// // {&lt;Double&gt; 63238509 [3x3] Ref(2)
        /// //(:,:)
        /// // 1,00000  2,00000  3,00000
        /// // 4,00000  4,00000  4,00000
        /// // 5,00000  6,00000  7,00000
        /// //}
        /// // construct references on U and P and call the decomposition
        /// ILArray&lt;double&gt; U = new ILArray&lt;double&gt;.empty();
        /// ILArray&lt;double&gt; P = new ILArray&lt;double&gt;.empty();
        /// ILArray&lt;double&gt; L = ILMath.lu(X, ref U, ref P);
        ///
        /// // L.ToString() is now:
        /// // {&lt;Double&gt; 19634871 [3x3] Phys.
        /// //(:,:)
        /// // 1,00000   0,00000   0,00000
        /// // 0,80000   1,00000   0,00000
        /// // 0,20000  -1,00000   1,00000
        /// //}
        /// // U is now:
        /// //{&lt;Double&gt; 22584602 [3x3] Phys.
        /// //(:,:)
        /// // 5,00000  6,00000  7,00000
        /// // 0,00000  -0,80000  -1,60000
        /// // 0,00000  0,00000  0,00000
        /// //}
        /// // and P is:
        /// //{&lt;Double&gt; 2192437 [3x3] Phys.
        /// //(:,:)
        /// // 0,00000  0,00000  1,00000
        /// // 0,00000  1,00000  0,00000
        /// // 1,00000  0,00000  0,00000
        /// //}
        /// </code>
        /// In order to reflect the pivoting done during the decomposition inside ?getrf, the matrix P may be used on A:
        /// <code>
        /// (ILMath.multiply(P,A) - ILMath.multiply(L,U)).ToString();
        /// // will give:
        /// //{&lt;Double&gt; 59192235 [3x3] Phys.
        /// //(:,:)
        /// // 0,00000  0,00000  0,00000
        /// // 0,00000  0,00000  0,00000
        /// // 0,00000  0,00000  0,00000
        /// //}
        /// </code>
        /// </example>
        /// <para>lu uses the Lapack function ?getrf.</para>
        /// <para>All of the matrices U,L,P returned will be solid ILArrays.</para>
        /// </remarks>
        /// <seealso cref="ILNumerics.BuiltInFunctions.ILMath.lu(ILArray&lt;double&gt;)"/>
        /// <seealso cref="ILNumerics.BuiltInFunctions.ILMath.lu(ILArray&lt;double&gt;, ref ILArray&lt;double&gt;)"/>
        /// <exception cref="ILNumerics.Exceptions.ILArgumentException"> if input A is not a matrix.</exception>
        public static ILArray <complex> lu(ILArray <complex> A, ref ILArray <complex> U, ref ILArray <complex> P)
        {
            if (!A.IsMatrix)
            {
                throw new ILArgumentSizeException("lu is defined for matrices only!");
            }
            int m = A.Dimensions[0], n = A.Dimensions[1], info = 0, minMN = (m < n)? m : n;
            ILArray <complex> L = (ILArray <complex>)A.Clone();

            int [] pivInd       = ILMemoryPool.Pool.New <int>(minMN);
            Lapack.zgetrf(m, n, L.m_data, m, pivInd, ref info);
            if (info < 0)
            {
                ILMemoryPool.Pool.RegisterObject(pivInd);
                throw new ILArgumentException("lu: illegal parameter error.");
                //} else if (info > 0) {
                //    // singular diagonal entry found
            }
            else
            {
                // completed successfuly
                if (!Object.Equals(U, null))
                {
                    if (!Object.Equals(P, null))
                    {
                        pivInd = perm2indicesForward(pivInd);
                        U      = copyUpperTriangle(L, minMN, n);
                        L      = copyLowerTriangle(L, m, minMN, new complex(1.0, 0.0));
                        P      = ILArray <complex> .zeros(minMN, minMN);

                        // construct permutation matrix P
                        for (int r = 0; r < m; r++)
                        {
                            P[r, pivInd[r]] = new complex(1.0, 0.0);
                        }
                    }
                    else
                    {
                        pivInd = perm2indicesBackward(pivInd);
                        U      = copyUpperTriangle(L, minMN, n);
                        L      = copyLowerTrianglePerm(L, m, minMN, new complex(1.0, 0.0), pivInd);
                    }
                }
            }
            ILMemoryPool.Pool.RegisterObject(pivInd);
            return(L);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// QR decomposition - raw Lapack output
        /// </summary>
        /// <param name="A">general input matrix A</param>
        /// <returns>orthonormal / unitary matrix Q and upper triangular
        /// matrix R packed into single matrix. This is the output of the
        /// lapack function ?geqrf.</returns>
        /// <remarks><para>Input matrix A will not be altered. </para>
        /// <para>The matrix returned is the direct output of the lapack
        /// function [d,s,c,z]geqrf respectively. This mean that it contains
        /// the decomposition factors Q and R, but they are cmbined into a
        /// single matrix for performance reasons. If you need one of the factors,
        /// you would use the overloaded function
        /// <see cref="ILNumerics.BuiltInFunctions.ILMath.qr(ILArray&lt;double&gt;,ref ILArray&lt;double&gt;)"/>
        /// instead, which returns those factors seperately.</para></remarks>
        public static /*!HC:inCls1*/ ILArray <double> qr(/*!HC:inCls1*/ ILArray <double> A)
        {
            if (!A.IsMatrix)
            {
                throw new ILArgumentException("qr decomposition: A must be a matrix");
            }
            int m = A.Dimensions[0], n = A.Dimensions[1];
            /*!HC:inCls1*/ ILArray <double> ret = (/*!HC:inCls1*/ ILArray <double>)A.Clone();

            /*!HC:inArr1*/ double [] tau        = new /*!HC:inArr1*/ double [(m < n)?m:n];
            int info = 0;

            /*!HC:lapack_*geqrf*/ Lapack.dgeqrf(m, n, ret.m_data, m, tau, ref info);
            if (info < 0)
            {
                throw new ILArgumentException("qr: an error occoured during decomposition");
            }
            return(ret);
        }
Ejemplo n.º 5
0
// DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !!
        /// <summary>
        /// QR decomposition - raw Lapack output
        /// </summary>
        /// <param name="A">general input matrix A</param>
        /// <returns>orthonormal / unitary matrix Q and upper triangular
        /// matrix R packed into single matrix. This is the output of the
        /// lapack function ?geqrf.</returns>
        /// <remarks><para>Input matrix A will not be altered. </para>
        /// <para>The matrix returned is the direct output of the lapack
        /// function [d,s,c,z]geqrf respectively. This mean that it contains
        /// the decomposition factors Q and R, but they are cmbined into a
        /// single matrix for performance reasons. If you need one of the factors,
        /// you would use the overloaded function
        /// <see cref="ILNumerics.BuiltInFunctions.ILMath.qr(ILArray&lt;double&gt;,ref ILArray&lt;double&gt;)"/>
        /// instead, which returns those factors seperately.</para></remarks>
        public static ILArray <complex> qr(ILArray <complex> A)
        {
            if (!A.IsMatrix)
            {
                throw new ILArgumentException("qr decomposition: A must be a matrix");
            }
            int m = A.Dimensions[0], n = A.Dimensions[1];
            ILArray <complex> ret = (ILArray <complex>)A.Clone();

            complex [] tau        = new  complex [(m < n)?m:n];
            int        info       = 0;

            Lapack.zgeqrf(m, n, ret.m_data, m, tau, ref info);
            if (info < 0)
            {
                throw new ILArgumentException("qr: an error occoured during decomposition");
            }
            return(ret);
        }
Ejemplo n.º 6
0
        protected void CreateMeshILArray(ILArray <double> x, ILArray <double> y, ILArray <double> z)
        {
            bounds  = new Cuboid(x.MinValue, y.MinValue, z.MinValue, x.MaxValue, y.MaxValue, z.MaxValue);
            lengthU = x.Dimensions[0];
            lengthV = x.Dimensions[1];
            ILArray <double> xs, ys, zs;

            if (x.IsReference)
            {
                xs = x.Clone() as ILArray <double>;
            }
            else
            {
                xs = x;
            }
            if (y.IsReference)
            {
                ys = y.Clone() as ILArray <double>;
            }
            else
            {
                ys = y;
            }
            if (z.IsReference)
            {
                zs = z.Clone() as ILArray <double>;
            }
            else
            {
                zs = z;
            }
            //if (x.IsReference || y.IsReference || z.IsReference) throw new Exception("x, y and z must be solid arrays");
            double[] xa          = xs.InternalArray4Experts;
            double[] ya          = ys.InternalArray4Experts;
            double[] za          = zs.InternalArray4Experts;
            Cuboid   modelBounds = new Cuboid(new System.Windows.Media.Media3D.Point3D(-10, -10, -10), new System.Windows.Media.Media3D.Point3D(10, 10, 10));

            UpdateModelVertices(xa, ya, za, lengthU, lengthV);
            CreateVertsAndInds();
            colourMap        = new ColourMap(ColourMapType.Jet, 256);
            colourMapIndices = FalseColourImage.IEnumerableToIndexArray(za, lengthU, lengthV, 256);
            SetColorFromIndices();
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Solve system of linear equations A*x = b, with A beeing a lower triangular matrix
 /// </summary>
 /// <param name="A">input matrix of Size [n x n], must be lower triangular. No check is made for that!</param>
 /// <param name="B">solution vector. Size [n x 1]</param>
 /// <param name="singularityDetect">output: this value gives the row of A, where a singularity has been detected (if any). If A is not singular, this will be a negative value.</param>
 /// <returns>Solution x solving A * x = b.</returns>
 /// <remarks><para>The solution will be determined via forward substitution</para>
 /// <para>Make sure, A and b are of correct size, since no checks are made for that!</para>
 /// <para>This function is used by ILMath.linsolve. There should be rare need for you to call this function directly.</para>
 /// <para>Elements of A above the main diagonal will not be accessed.</para>
 /// <para>If A has been found to be singular, the array returned will contain NaN values for corresponding elements!</para></remarks>
 internal static  ILArray<fcomplex> solveLowerTriangularSystem ( ILArray<fcomplex> A,  ILArray<fcomplex> B, ref int singularityDetect) {
     System.Diagnostics.Debug.Assert(B.Dimensions[1] >= 0); 
     System.Diagnostics.Debug.Assert(B.Dimensions[0] == A.Dimensions[1]); 
     System.Diagnostics.Debug.Assert(A.Dimensions[0] == A.Dimensions[1]); 
     singularityDetect = -1; 
     int n = A.Dimensions[0]; 
     int m = B.Dimensions[1]; 
     int spacingA0, spacingA1, info = 0; 
     char transA; 
     ILArray<fcomplex> ret = ( ILArray<fcomplex> )B.Clone(); 
     fcomplex [] retArr = ret.m_data;  
     if (isSuitableForLapack(A,out spacingA0,out spacingA1,out transA)) {
         // solve using Lapack
         unsafe {
             fixed ( fcomplex * ptrA = A.m_data) 
             fixed ( fcomplex * ptrB = ret.m_data) {
                 fcomplex * pA = ptrA + A.getBaseIndex(0); 
                 Lapack.ctrtrs ((transA == 'T')? 'U':'L',transA,'N',A.Dimensions[0],ret.Dimensions[1],(IntPtr)pA,spacingA1,(IntPtr)ptrB,n,ref info);
                 if (info < 0) 
                     throw new ILArgumentException ("linsolve: error inside Lapack function ?trtrs for argument: " + (-info));
                 if (info > 0) {
                     singularityDetect = info-1;
                     retArr = ret.m_data; 
                     for (spacingA0 = 0; spacingA0 < ret.Dimensions[1]; spacingA0++) {
                         info = spacingA0 * n + singularityDetect; 
                         for (spacingA1 = singularityDetect; spacingA1 < n; spacingA1++) {
                             retArr[info++] =  new fcomplex(float.NaN,float.NaN) ;     
                         }
                     }
                 } else {
                     singularityDetect = -1; 
                 }
             }
         }
         return ret; 
     }
     // must do it manually.... 
     System.Diagnostics.Debug.Assert(A.IsReference); 
     int[] Adim0 = A.m_indexOffset[0]; 
     int[] Adim1 = A.m_indexOffset[1];    
     fcomplex diagVal =  new fcomplex(0.0f,0.0f) ;
     fcomplex tmpVal;
     for (int b = 0; b < m; b++) {
         for (int r = 0; r < n; r++) {
             tmpVal =  new fcomplex(0.0f,0.0f) ; 
             diagVal = A.GetValue(r,r); 
             if (diagVal ==  new fcomplex(0.0f,0.0f) ) {
                 singularityDetect = r; 
                 for (; r < n; r++)
                     retArr[r + b * n] =  new fcomplex(float.PositiveInfinity,float.PositiveInfinity) ; 
             } else {
                 for (int c = 0; c < r; c++) {
                     tmpVal +=  A.m_data[Adim0[r] + Adim1[c]] * retArr[c + b * n]; 
                 }
                 retArr[r + b * n] = (retArr[r + b * n] - tmpVal) / diagVal; 
             }
         }
     }
     ret = new  ILArray<fcomplex> (retArr,n,m); 
     return ret; 
 }
Ejemplo n.º 8
0
        /// <summary>
        /// maximum
        /// </summary>
        /// <param name="A">input array, N-dimensional</param>
        /// <param name="I">return value. If this is an instance of an ILArray 
        /// (f.e. 'empty'), on return I will hold the indices into leadDim of  
        /// the maximum values. If, on entering the function, I is null, those indices 
        /// will not be computed and I will be ignored.</param>
        /// <param name="leadDim">index of dimension to operate along</param>
        /// <returns>ILArray of type double. If I was empty  having the dimension 'leadDim' 
        /// reduced to 1 and holding maximum values </returns>
        public static /*!HC:ToutCls*/ ILArray<double> max(/*!HC:TinCls*/ ILArray<double> A, ref /*!HC:TindCls*/ ILArray<double> I, int leadDim) {
			if (A.IsEmpty) {
                if (!object.Equals (I,null))
                    I = /*!HC:TindCls*/ ILArray<double> .empty(0,0); 
                return  /*!HC:ToutCls*/ ILArray<double> .empty(A.Dimensions); 
            }
            ILDimension inDim = A.Dimensions; 
			int[] newDims = inDim.ToIntArray();
            if (leadDim == newDims.Length || inDim[leadDim] == 1)
				// scalar or sum over singleton -> return copy
                return (/*!HC:ToutCls*/ ILArray<double> )A.Clone();

			int newLength;
			newLength = inDim.NumberOfElements / newDims[leadDim];
			newDims[leadDim] = 1;
            /*!HC:ToutArr*/ double [] retSystemArr;
            retSystemArr = new /*!HC:ToutArr*/ double [newLength];
            int leadDimLen = inDim[leadDim];
			int nrHigherDims = inDim.NumberOfElements / leadDimLen;
            #region HYCALPER GLOBAL_INIT

            /*!HC:TinArr*/ double result;
            /*!HC:TinArr*/ double curval;
            /*!HC:TindArr*/ double [] indices = null;
            bool createIndices = false; 
            if (!Object.Equals(I,null)) {
                indices = new /*!HC:TindArr*/ double [retSystemArr.Length];
                createIndices = true; 
            } 
            #endregion HYCALPER GLOBAL_INIT
            #region HYCALPER INIT_COMPLEX

            #endregion HYCALPER INIT_COMPLEX

			// physical -> pointer arithmetic
            if (leadDim == 0) {
#region physical along 1st leading dimension
                unsafe {
                    fixed (/*!HC:ToutArr*/ double * pOutArr = retSystemArr)
                    fixed (/*!HC:TinArr*/ double * pInArr = A.m_data)
                    fixed (/*!HC:TindArr*/ double * pIndices = indices) {
                        /*!HC:TinArr*/ double * lastElement; 
                        /*!HC:ToutArr*/ double * tmpOut = pOutArr;
                        /*!HC:TinArr*/ double * tmpIn = pInArr;
                        if (createIndices) {
                            /*!HC:TindArr*/ double * tmpInd = pIndices;
                            for (int h = nrHigherDims; h-- > 0; ) {
                                lastElement = tmpIn + leadDimLen;
                                #region HYCALPER PRELOOP
                                result = /*!HC:LIMITS*/ double.MinValue;
                                #endregion HYCALPER PRELOOP
                                while (tmpIn < lastElement) {
                                    curval = *tmpIn;
                                    #region HYCALPER INNERLOOP
                                    if (curval > result) {
                                        result = curval;
                                    #endregion HYCALPER INNERLOOP
                                        *tmpInd = (/*!HC:TindArr*/ double )(tmpIn - (lastElement - leadDimLen));
                                    }
                                    tmpIn++;
                                }
                                *(tmpOut++) = (/*!HC:ToutArr*/ double )result;
                                tmpInd++; 
                            }
                        } else {
                            /*!HC:TindArr*/ double * tmpInd = pIndices;
                            for (int h = nrHigherDims; h-- > 0; ) {
                                lastElement = tmpIn + leadDimLen;
                                #region HYCALPER PRELOOP
                                result = /*!HC:LIMITS*/ double.MinValue;
                                #endregion HYCALPER PRELOOP
                                while (tmpIn < lastElement) {
                                    curval = *tmpIn++;
                                    #region HYCALPER INNERLOOP
                                    if (curval > result) {
                                        result = curval;
                                    #endregion HYCALPER INNERLOOP
                                    }
                                }
                                #region HYCALPER POSTLOOP
                                *(tmpOut++) = (/*!HC:ToutArr*/ double )result;
                                #endregion HYCALPER POSTLOOP
                            }
                        }
                    }
                }
#endregion physical along 1st leading dimension
            } else {
#region physical along abitrary dimension
				// sum along abitrary dimension 
                unsafe {
                    fixed (/*!HC:ToutArr*/ double * pOutArr = retSystemArr)
                    fixed (/*!HC:TinArr*/ double * pInArr = A.m_data)
                    fixed (/*!HC:TindArr*/ double * pIndices = indices) {
                        /*!HC:ToutArr*/ double * lastElementOut = newLength + pOutArr - 1;
                        int inLength = inDim.NumberOfElements -1;
                        /*!HC:TinArr*/ double * lastElementIn = pInArr + inLength; 
                        int inc = inDim.SequentialIndexDistance(leadDim);
                        /*!HC:ToutArr*/ double * tmpOut = pOutArr;
                        int outLength = newLength - 1;
                        /*!HC:TinArr*/ double * leadEnd;
                        /*!HC:TinArr*/ double * tmpIn = pInArr;
                        if (createIndices) {
                            /*!HC:TindArr*/ double * tmpInd = pIndices;
                            for (int h = nrHigherDims; h-- > 0; ) {
                                leadEnd = tmpIn + leadDimLen * inc;
                                #region HYCALPER PRELOOP
                                result = /*!HC:LIMITS*/ double.MinValue;
                                #endregion HYCALPER PRELOOP
                                while (tmpIn < leadEnd) {
                                    curval = *tmpIn;
                                    #region HYCALPER INNERLOOP
                                    if (curval > result) {
                                        result = curval;
                                    #endregion HYCALPER INNERLOOP
                                        *tmpInd = (/*!HC:TindArr*/ double )(leadDimLen - (leadEnd - tmpIn) / inc);
                                    }
                                    tmpIn += inc;
                                }
                                #region HYCALPER POSTLOOP
                                *(tmpOut) = (/*!HC:ToutArr*/ double ) result;
                                #endregion HYCALPER POSTLOOP
                                tmpOut += inc;
                                tmpInd += inc;
                                if (tmpOut > lastElementOut) {
                                    tmpOut -= outLength;
                                    tmpInd -= outLength;
                                }
                                if (tmpIn > lastElementIn)
                                    tmpIn = pInArr + ((tmpIn - pInArr) - inLength);
                            }
                        } else {
                            for (int h = nrHigherDims; h-- > 0; ) {
                                leadEnd = tmpIn + leadDimLen * inc;
                                #region HYCALPER PRELOOP
                                result = /*!HC:LIMITS*/ double.MinValue;
                                #endregion HYCALPER PRELOOP
                                while (tmpIn < leadEnd) {
                                    curval = *tmpIn;
                                    #region HYCALPER INNERLOOP
                                    if (curval > result) {
                                        result = curval;
                                    #endregion HYCALPER INNERLOOP
                                    }
                                    tmpIn += inc;
                                }
                                #region HYCALPER POSTLOOP
                                *(tmpOut) = (/*!HC:ToutArr*/ double )result;
                                #endregion HYCALPER POSTLOOP
                                tmpOut += inc;
                                if (tmpOut > lastElementOut) {
                                    tmpOut -= outLength;
                                }
                                if (tmpIn > lastElementIn)
                                    tmpIn = pInArr + ((tmpIn - pInArr) - inLength);
                            }
                        }
                    }
				}
#endregion
			}

            if (createIndices) {
                I = new /*!HC:TindCls*/ ILArray<double> (indices, newDims);
            }
            return new /*!HC:ToutCls*/ ILArray<double> (retSystemArr, newDims);  
		}
Ejemplo n.º 9
0
 /// <summary>
 /// find eigenvalues  and eigenvectors 
 /// </summary>
 /// <param name="A">input: square matrix, size [n x n]</param>
 /// <param name="V">output (optional): eigenvectors</param>   
 /// <param name="propsA">matrix properties, on input - if specified, 
 /// will be used to choose the proper method of solution. On exit will be 
 /// filled according to the properties of A.</param>
 /// <param name="balance">true: permute A in order to increase the 
 /// numerical stability, false: do not permute A.</param>
 /// <returns>eigenvalues as vector (if V is null) or as diagonoal 
 /// matrix (if V was requested, i.e. not equaled null).</returns>
 /// <remarks><para>The eigenvalues of A are found by use of the 
 /// Lapack functions dgeevx, sgeevx, cgeevx and zgeevx. </para>
 /// <para>The arrays returned will be of complex inner type, 
 /// since no further constraints are set on the structure of 
 /// A (it may be nonsymmetric). Use 
 /// <see cref="ILNumerics.BuiltInFunctions.ILMath.eigSymm(ILArray&lt;double&gt;)"/> 
 /// or <see cref="ILNumerics.BuiltInFunctions.ILMath.eigSymm(ILArray&lt;double&gt;,ref ILArray&lt;double&gt;)"/> 
 /// functions for computing the real eigenvalues of symmetric 
 /// matrices explicitly.</para>
 /// <para>Depending on the parameter <paramref name="balance"/>, 
 /// A will be balanced first. This includes permutations and 
 /// scaling of A in order to improve the conditioning of the 
 /// eigenvalues.</para></remarks>
 /// <seealso cref="ILNumerics.BuiltInFunctions.ILMath.eig(ILArray&lt;double&gt;)"/>
 /// <seealso cref="ILNumerics.BuiltInFunctions.ILMath.eig(ILArray&lt;double&gt;,ref ILArray&lt;complex&gt;,ref MatrixProperties,bool)"/>
 /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if a 
 /// is not square</exception>
 public static /*!HC:HCClsCmplx*/ ILArray<complex> eig(/*!HC:HCCls1*/ ILArray<double> A, ref /*!HC:HCClsCmplx*/ ILArray<complex> V, ref MatrixProperties propsA, bool balance) {
     if (A.IsEmpty) {
         V = /*!HC:HCClsCmplx*/ ILArray<complex> .empty(A.Dimensions); 
         return /*!HC:HCClsCmplx*/ ILArray<complex> .empty(A.Dimensions); 
     }
     /*!HC:HCClsCmplx*/ ILArray<complex> ret = null;  
     int n = A.Dimensions[0]; 
     bool createVR = (object.Equals(V,null))? false:true; 
     if (n != A.Dimensions[1]) 
         throw new ILArgumentException("eig: matrix A must be square!");
     propsA |= MatrixProperties.Square; 
     if (((propsA & MatrixProperties.Hermitian) != 0 || ILMath.ishermitian(A))) {
         propsA |= MatrixProperties.Hermitian; 
         /*!HC:HCCls1*/ ILArray<double> Vd = null; 
         if (createVR) 
             Vd = /*!HC:HCCls1*/ ILArray<double> .empty(0,0);
         /*!HC:HCCls1*/ ILArray<double> tmpRet = eigSymm(A,ref Vd);
         if (createVR)
             V = /*!HC:HCCls2Cmplx*/ ILMath.tocomplex (Vd); 
         ret = /*!HC:HCCls2Cmplx*/ ILMath.tocomplex (tmpRet);
     } else {
         // nonsymmetric case
         char bal = (balance)? 'B':'N', jobvr;  
         /*!HC:HCCls1*/ ILArray<double> tmpA = (/*!HC:HCCls1*/ ILArray<double> )A.Clone(); 
         /*!HC:HCArr1*/ double [] vr = null;
         /*!HC:HCArr1*/ double [] wr = ILMemoryPool.Pool.New</*!HC:HCArr1*/ double >(n); 
         /*!HC:HCArrWI*/ 
         double[] wi = ILMemoryPool.Pool.New<double>(n); 
         /*!HC:HCArrReal*/ double [] scale  = ILMemoryPool.Pool.New</*!HC:HCArrReal*/ double >(n);
         /*!HC:HCArrReal*/ double [] rconde = ILMemoryPool.Pool.New</*!HC:HCArrReal*/ double >(n); 
         /*!HC:HCArrReal*/ double [] rcondv = ILMemoryPool.Pool.New</*!HC:HCArrReal*/ double >(n); 
         /*!HC:HCArrReal*/ double abnrm = 0; 
         int ldvr, ilo = 0, ihi = 0, info = 0;
         if (createVR) {
             ldvr = n;
             vr = ILMemoryPool.Pool.New</*!HC:HCArr1*/ double >(n * n);
             jobvr = 'V'; 
         } else {
             ldvr = 1; 
             vr = new /*!HC:HCArr1*/ double [1]; 
             jobvr = 'N'; 
         }
         /*!HC:HC?geevx*/
         Lapack.dgeevx(bal,'N',jobvr,'N',n,tmpA.m_data,n,wr,wi,new /*!HC:HCArr1*/ double [1],1,vr,ldvr,ref ilo,ref ihi,scale,ref abnrm,rconde,rcondv,ref info);   
         if (info != 0) 
             throw new ILArgumentException("eig: error in Lapack '?geevx': (" + info + ")");
         // create eigenvalues 
         /*!HC:HCArrCmplx*/ complex [] retArr = ILMemoryPool.Pool.New</*!HC:HCArrCmplx*/ complex >(n); 
         for (int i = 0; i < n; i++) {
             /*!HC:HCSortEVal*/
             retArr[i].real = wr[i]; retArr[i].imag = wi[i]; 
         }
         ret = new /*!HC:HCClsCmplx*/ ILArray<complex> (retArr,n,1);
         if (createVR) {
             #region HCSortEVec
             complex [] VArr = ILMemoryPool.Pool.New< complex >(n * n);
             for (int c = 0; c < n; c++) {
                 if (wi[c] != 0 && wi[c+1] != 0 && c < n-1) {
                     ilo = n * c; ihi = ilo + n;
                     for (int r = 0; r < n; r++) {
                         VArr[ilo].real = vr[ilo];
                         VArr[ilo].imag = vr[ihi];  
                         VArr[ihi].real = vr[ilo];  
                         VArr[ihi].imag = -vr[ihi]; 
                         ilo++; ihi++; 
                     }
                     c++; 
                 } else {
                     ilo = n * c;
                     for (int r = 0; r < n; r++) {
                         VArr[ilo].real = vr[ilo];
                         ilo++; 
                     }
                 }
             }
             V = new ILArray<complex> (VArr,n,n); 
             #endregion HYCALPER
             if (createVR) 
                 ret = ILMath.diag(ret); 
         }
     }
     return ret; 
 }
Ejemplo n.º 10
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  ILArray<complex>  sum ( ILArray<complex> A, int leadDim) {
            if (A.IsEmpty) 
                return  ILArray<complex> .empty(A.Dimensions); 
            if (A.IsScalar)
               
                return new  ILArray<complex> (new  complex []{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();
           
            if (inDim[leadDim] == 1) return ( ILArray<complex> )A.Clone();
			int newLength;
			 complex [] retDblArr;
			// build ILDimension
			newLength = inDim.NumberOfElements / newDims[leadDim];
			newDims[leadDim] = 1;
			retDblArr = ILMemoryPool.Pool.New< complex >(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 ( 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;
                            *tmpOut = 0.0;
                            while (tmpIn < lastElement) {
                                *tmpOut +=  (complex) (*tmpIn++)  ;
                            }
						    
                            /**/
                            tmpOut++;
                        }
                    }
				}
#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;
                            *tmpOut = 0.0;
                            while (tmpIn < leadEnd) {
                                *tmpOut +=  (complex) (*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<complex> (retDblArr, newDims);;
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Solve linear equation system
        /// </summary>
        /// <param name="A">Matrix A. Size [n x q]</param>
        /// <param name="B">'rigth hand side' B. Size [n x m]</param>
        /// <param name="props">Matrix properties. If defined, no checks are made for the structure of A. If the matrix A was found to be (close to or) singular, the 'MatrixProperties.Singular' flag in props will be set. This flag should be tested on return, in order to verify the reliability of the solution.</param>
        /// <returns>the solution x solving multiply(A,x) = B. Size [n x m]</returns>
        /// <remarks><para>depending on the <paramref name="props"/> parameter the equation system will be solved differently for special structures of A:
        /// <list type="bullet">
        /// <item>If A is square (q == n) and an <b>upper or lower triangular</b> matrix, the system will directly be solved via backward- or forward substitution. Therefore the Lapack function ?trtrs will be used, whenever the memory layout of A is suitable. This may be the case even for reference ILArray's!
        /// <example><![CDATA[ILArray<double> A = ILMath.randn(4); // construct 4 x 4 matrix
        /// A = A.T; // A is a reference array now! The transpose is fast and does not consume much memory
        /// // now construct a right side and solve the equations:
        /// ILArray<double> B = new ILArray<double> (1.0,2.0,3.0).T;
        /// ILMath.linsolve(A,B); // ... will be carried out via Lapack, even for all arrays involved beeing reference arrays! ]]></example></item>
        /// <item><para>if A is square and symmetric or hermitian, A will be decomposed into a triangular equation system using cholesky factorization and Lapack. The system is than solved using performant Lapack routines.</para>
        /// <para>if during the cholesky factorization A was found to be <b>not positive definite</b> - the corresponding flag in props will be cleaned and <c>null</c> will be returned.</para></item>
        /// <item>otherwise if A is square only, it will be decomposed into upper and lower triangular matrices using LU decomposition and Lapack. The triangular system is than solved using performant Lapack routines.</item>
        /// <item>otherwise, if A is of size [q x n] and q != n, the system is solved using QR decomposition. A may be rank deficient. The solution is computed by use of the Lapack routine '?gelsy' and may be a reference array.</item>
        /// </list></para>
        /// <para>Compatibility with Matlab<sup>(R)</sup>: If A is square, the algorithm used follows the same logic as Matlab up to Rel 14, with the exception of Hessenberg matrices wich are solved via LU factorization here. The un-squared case is handled differently. A direct Lapack driver function (?gelsy) is used here. Therefore the solutions might differ! However, the solution will of course fullfill the equation A * x = B without round off errrors. </para>
        /// <para>For specifiying the rank of A in the unsquare case (q != n), the eps member from <see cref="ILNumerics.Settings.ILSettings"/> class is used.</para></remarks>
        public static ILArray <complex> linsolve(ILArray <complex> A, ILArray <complex> B, ref MatrixProperties props)
        {
            if (object.Equals(A, null))
            {
                throw new ILArgumentException("linsolve: input argument A must not be null!");
            }
            if (object.Equals(B, null))
            {
                throw new ILArgumentException("linsolve: input argument B must not be null!");
            }
            if (A.IsEmpty || B.IsEmpty)
            {
                return(ILArray <complex> .empty(A.Dimensions));
            }
            if (A.Dimensions[0] != B.Dimensions[0])
            {
                throw new ILArgumentException("linsolve: number of rows for matrix A must match number of rows for RHS!");
            }
            int info = 0, m = A.Dimensions[0];
            ILArray <complex> ret;

            if (m == A.Dimensions[1])
            {
                props |= MatrixProperties.Square;
                if ((props & MatrixProperties.LowerTriangular) != 0)
                {
                    ret = solveLowerTriangularSystem(A, B, ref info);
                    if (info > 0)
                    {
                        props |= MatrixProperties.Singular;
                    }
                    return(ret);
                }
                if ((props & MatrixProperties.UpperTriangular) != 0)
                {
                    ret = solveUpperTriangularSystem(A, B, ref info);
                    if (info > 0)
                    {
                        props |= MatrixProperties.Singular;
                    }
                    return(ret);
                }
                if ((props & MatrixProperties.Hermitian) != 0)
                {
                    ILArray <complex> cholFact = A.copyUpperTriangle(m);
                    Lapack.zpotrf('U', m, cholFact.m_data, m, ref info);
                    if (info > 0)
                    {
                        props ^= MatrixProperties.Hermitian;
                        return(null);
                    }
                    else
                    {
                        // solve
                        ret = (ILArray <complex>)B.Clone();
                        Lapack.zpotrs('U', m, B.Dimensions[1], cholFact.m_data, m, ret.m_data, m, ref info);
                        return(ret);
                    }
                }
                else
                {
                    // attempt complete (expensive) LU factorization
                    ILArray <complex> L      = (ILArray <complex>)A.Clone();
                    int []            pivInd = new int[m];
                    Lapack.zgetrf(m, m, L.m_data, m, pivInd, ref info);
                    if (info > 0)
                    {
                        props |= MatrixProperties.Singular;
                    }
                    ret = (ILArray <complex>)B.Clone();
                    Lapack.zgetrs('N', m, B.Dimensions[1], L.m_data, m, pivInd, ret.m_data, m, ref info);
                    if (info < 0)
                    {
                        throw new ILArgumentException("linsolve: failed to solve via lapack dgetrs");
                    }
                    return(ret);
                }
            }
            else
            {
                // under- / overdetermined system
                int n = A.Dimensions[1], rank = 0, minMN = (m < n)? m:n, maxMN = (m > n)? m:n;
                int nrhs = B.Dimensions[1];
                if (B.Dimensions[0] != m)
                {
                    throw new ILArgumentException("linsolve: right hand side matrix B must match input A!");
                }
                ILArray <complex> tmpA = (ILArray <complex>)A.Clone();
                if (m < n)
                {
                    ret = new  ILArray <complex> (new  complex [n * nrhs], n, nrhs);
                    ret["0:" + (m - 1) + ";:"] = B;
                }
                else
                {
                    ret = (ILArray <complex>)B.Clone();
                }
                int [] JPVT = new int [n];
                Lapack.zgelsy(m, n, B.Dimensions[1], tmpA.m_data, m, ret.m_data,
                              maxMN, JPVT, ILMath.MachineParameterDouble.eps,
                              ref rank, ref info);
                if (n < m)
                {
                    ret = ret[ILMath.vector(0, n - 1), null];
                }
                if (rank < minMN)
                {
                    props |= MatrixProperties.RankDeficient;
                }
                return(ret);
            }
        }
Ejemplo n.º 12
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));;
        }
Ejemplo n.º 13
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);;
        }
Ejemplo n.º 14
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);;  
		}
Ejemplo n.º 15
0
 public void Test_SetRange_RangedPhysical() {
     int errorCode = 0; 
     try {
         ILArray<double> AOrig = ILMath.vector(1,24).Reshape(new ILDimension(4,3,2));  
         ILArray<double> ResOrig = new ILArray<double>(new double[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24},4,3,2);
         ILArray<double> A, Res, indb; 
         // test setrange for single element (sequential access) 
         for (int i = 0; i < 20; i++) {
             A = (ILArray<double>)AOrig.Clone();  
             Res = ((ILArray<double>)ResOrig.Clone()).Detach(); 
             A[i.ToString()] = 99;
             Res.m_data[i] = 99;
             if (!A.Equals(Res)) throw new Exception("A[\"" + i.ToString() + "\"] = 99 failed.");
             // test setrange via basearray
             A = (ILArray<double>)AOrig.Clone();  
             A[new int[]{i}] = 99;
             if (!A.Equals(Res)) throw new Exception("A[" + i.ToString() + "] = 99 failed.");
         }
         // test setrange for 2 single elements (sequential access) 
         errorCode = 1; 
         for (int i = 0; i < 20; i++) {
             A = (ILArray<double>)AOrig.Clone();  
             Res = ((ILArray<double>)ResOrig.Clone()).Detach(); 
             indb = new double[]{i,i+3}; 
             string inds = i.ToString() + "," + (i+3).ToString(); 
             Res.m_data[i] = 99;
             Res.m_data[i+3] = 99; 
             A[inds] = 99;
             if (!A.Equals(Res)) throw new Exception("A[\"" + i.ToString() + "," + (i+3).ToString() + "\"] = 99 failed.");
             // test setrange via basearray
             A = (ILArray<double>)AOrig.Clone();  
             A[indb] = 99;
             if (!A.Equals(Res)) throw new Exception("A[" + i.ToString() + "," + (i+3).ToString() + "] = 99 failed.");
         }
         errorCode = 2; 
         A = (ILArray<double>)AOrig.Clone();
         // reshaping range in second dimension 
         A["1;1:end"] = new double []{100,101,102,103,104};
         Res = ((ILArray<double>)ResOrig.Clone()).Detach(); 
         Res.m_data[5] = 100; 
         Res.m_data[9] = 101; 
         Res.m_data[13] = 102; 
         Res.m_data[17] = 103; 
         Res.m_data[21] = 104;
         if (!A.Equals(Res)) throw new Exception("A[1,1:end] = [100...104] failed.");
         // reshaping range in 2nd dimension - basearray indices
         indb = new double[]{1,2,3,4,5}; 
         A[1.0,indb] = new double[]{100,101,102,103,104};
         Res = ((ILArray<double>)ResOrig.Clone()).Detach(); 
         Res.m_data[5] = 100; 
         Res.m_data[9] = 101; 
         Res.m_data[13] = 102; 
         Res.m_data[17] = 103; 
         Res.m_data[21] = 104;
         if (!A.Equals(Res)) throw new Exception("A[1,[1,2,3,4,5]] = [100...104] failed.");
         // reshaping range in 2nd dimension - for reference storages 
         errorCode = 2; 
         A = ((ILArray<double>)AOrig.Clone()); 
         ILArray<double>.DetachReferences = ILDetachingBehavior.DetachSave;
         ILArray<double> ARef = (ILArray<double>)A.CreateReference();
         A.Dispose(); 
         // reshaping range in second dimension 
         ARef["1;1:end"] = new double[]{100,101,102,103,104};
         Res = ((ILArray<double>)ResOrig.Clone()).Detach(); 
         Res.m_data[5] = 100; 
         Res.m_data[9] = 101; 
         Res.m_data[13] = 102; 
         Res.m_data[17] = 103; 
         Res.m_data[21] = 104;
         if (!ARef.Equals(Res) || !ARef.IsReference) throw new Exception("A[1,1:end] = [100...104] failed.");
         // reshaping range in 2nd dimension - basearray indices
         indb = new double[]{1,2,3,4,5}; 
         ARef[1.0,indb] = new double[]{100,101,102,103,104};
         Res = ((ILArray<double>)ResOrig.Clone()).Detach(); 
         Res.m_data[5] = 100; 
         Res.m_data[9] = 101; 
         Res.m_data[13] = 102; 
         Res.m_data[17] = 103; 
         Res.m_data[21] = 104;
         if (!ARef.Equals(Res)) throw new Exception("A[1,[1,2,3,4,5]] = [100...104] failed.");
         // 
         errorCode = 3; 
         // test single element (sequential) via range for reference array
         for (int i = 0; i < 20; i++) {
             A = (ILArray<double>)AOrig.Clone(); 
             ARef = (ILArray<double>)A.CreateReference(); 
             A.Dispose(); 
             Res = ((ILArray<double>)ResOrig.Clone()).Detach(); 
             ARef[i.ToString()] = 99;
             Res.m_data[i] = 99;
             if (!ARef.Equals(Res) || !ARef.IsReference) throw new Exception("A[\"" + i.ToString() + "\"] = 99 failed.");
             // test setrange via basearray
             A = (ILArray<double>)AOrig.Clone(); 
             ARef = (ILArray<double>)A.CreateReference(); 
             A.Dispose(); 
             ARef[i] = 99;
             if (!ARef.Equals(Res) || !ARef.IsReference) throw new Exception("A[" + i.ToString() + "] = 99 failed.");
         }
         errorCode = 4; 
         
         // test scalar source - full dimension
         A = (ILArray<double>)AOrig.Clone();
         A.Detach(); 
         A[":"] = 111; 
         Res = ILMath.ones(4,3,2) * 111; 
         if (!A.Equals(Res)) throw new Exception("A[:] = {scalar} for physical array failed!");
         // ... explicit indices 
         Res = ILMath.ones(4,3,2) * 112; 
         A["0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23"] = 112; 
         if (!A.Equals(Res)) throw new Exception("A[0..23] = {scalar} for physical array failed!");
         // .. for reference storages 
         errorCode = 5; 
         A = (ILArray<double>)AOrig.Clone();
         ARef = (ILArray<double>) A.CreateReference(); 
         A.Dispose(); 
         ARef[":"] = 111; 
         Res = ILMath.ones(4,3,2) * 111; 
         if (!ARef.Equals(Res)) throw new Exception();
         Res = ILMath.ones(4,3,2) * 112; 
         ARef["0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23"] = 112; 
         if (!ARef.Equals(Res)) throw new Exception("A[0..23] = {scalar} for physical array failed!");
         
         // test scalar on all dimensions 
         errorCode = 6; 
         A = (ILArray<double>)AOrig.Clone();
         A.Detach(); 
         A[": ; : ; :"] = 113; 
         Res = ILMath.ones(4,3,2) * 113; 
         if (!A.Equals(Res)) throw new Exception("A[:;:;:] = {scalar} for physical array failed!");
         // ... reference 
         ARef = (ILArray<double>)A.CreateReference(); 
         A.Dispose(); 
         ARef[":;:;:"] = 114; 
         Res = ILMath.ones(4,3,2) * 114; 
         if (!ARef.Equals(Res)) throw new Exception("A[:;:;:] = {scalar} for reference array failed!");
         errorCode = 7; 
         
         // test scalar on all dimensions for explicit indices 
         A = (ILArray<double>)AOrig.Clone();
         A.Detach(); 
         A["0:end;0:end;1"] = 114; 
         Res = new ILArray<double>(new double[]{1,2,3,4,5,6,7,8,9,10,11,12,114,114,114,114,114,114,114,114,114,114,114,114},4,3,2);  
         if (!A.Equals(Res)) throw new Exception("A[0:end;0:end;1] = {scalar} for physical array failed!");
         // ... reference 
         ARef = (ILArray<double>)A.CreateReference(); 
         A.Dispose(); 
         ARef["0:end;0:end;1"] = 115; 
         Res = new ILArray<double>(new double[]{1,2,3,4,5,6,7,8,9,10,11,12,115,115,115,115,115,115,115,115,115,115,115,115},4,3,2);  
         if (!ARef.Equals(Res)) throw new Exception("A[0:end;0:end;1] = {scalar} for reference array failed!");
         // test extending range
         errorCode = 8; 
         A = ILArray<double>.empty(); 
         A[0] = 1;
         if (A.IsReference || !A.IsScalar || A.GetValue(0) != 1.0) throw new Exception("A[0] = 1 on empty array should extend array!");
         // same test for string definitions
         A = ILArray<double>.empty(); 
         ARef = (ILArray<double>) A.CreateReference(); 
         A["0"] = 1;
         ARef["0"] = 1; 
         if (A.IsReference || !A.IsScalar || A.GetValue(0) != 1.0) throw new Exception("A[0] = 1 on empty array should extend array!");
         if (A.IsReference || !ARef.IsScalar || ARef.GetValue(0) != 1.0) throw new Exception("ARef[0] = 1 on empty array should extend array!");
         Success();
     } catch (Exception e) {
         Error(errorCode, e.Message ); 
     }
 }
Ejemplo n.º 16
0
        public void Test_IndexAccessPhysicalSequential() {
            int errorCode = 1;
            try {
                // B = A[idx,0]
				ILArray<double> A = ILMath.reshape(ILMath.vector(0.0,23.0),2,3,4);
                A.MinimumRefDimensions = 2;
				ILArray<double> ind = new ILArray<double> (2,4,6,8); 
                ILArray<double> B = A[ind];  
				if (!B.Equals(ind))
					throw new Exception("Invalid value of result!"); 
				errorCode = 2;
                // B = A[idx,0]
				A = ILMath.reshape(ILMath.vector(0.0,23.0),2,3,4);
				ind = new ILArray<double> (2,4,6,8); 
				A.MinimumRefDimensions = 4; 
                B = A[ind];  
				if (!B.Equals(ind))
					throw new Exception("Invalid value of result!"); 
				errorCode = 3;
                ind = new ILArray<double> (new double[4]{2,4,6,8},2,2); 
                ILArray<double> Res = (ILArray<double>)ind.Clone(); 
                B = A[ind]; 
				if (!B.Equals(Res))
					throw new Exception("Invalid value of result!"); 
				errorCode = 4;
                ind = new ILArray<double> (new double[4]{2,4,6,8},2,2); 
                Res = (ILArray<double>)ind.T; 
                B = A[1,ind]; 
				if (!B.Equals(Res))
					throw new Exception("Invalid value of result!"); 
				Success();
                
            } catch (Exception e) {
				Error(errorCode,e.Message);
            }
        }
Ejemplo n.º 17
0
 /// <summary>
 /// QR decomposition - raw Lapack output
 /// </summary>
 /// <param name="A">general input matrix A</param>
 /// <returns>orthonormal / unitary matrix Q and upper triangular 
 /// matrix R packed into single matrix. This is the output of the 
 /// lapack function ?geqrf.</returns>
 /// <remarks><para>Input matrix A will not be altered. </para>
 /// <para>The matrix returned is the direct output of the lapack 
 /// function [d,s,c,z]geqrf respectively. This mean that it contains 
 /// the decomposition factors Q and R, but they are cmbined into a 
 /// single matrix for performance reasons. If you need one of the factors, 
 /// you would use the overloaded function 
 /// <see cref="ILNumerics.BuiltInFunctions.ILMath.qr(ILArray&lt;double&gt;,ref ILArray&lt;double&gt;)"/> 
 /// instead, which returns those factors seperately.</para></remarks>
 public static /*!HC:inCls1*/ ILArray<double> qr(/*!HC:inCls1*/ ILArray<double> A) {
     if (!A.IsMatrix) 
         throw new ILArgumentException("qr decomposition: A must be a matrix"); 
     int m = A.Dimensions[0], n = A.Dimensions[1]; 
     /*!HC:inCls1*/ ILArray<double> ret = (/*!HC:inCls1*/ ILArray<double> )A.Clone();  
     /*!HC:inArr1*/ double [] tau = new /*!HC:inArr1*/ double [(m<n)?m:n];  
     int info = 0; 
     /*!HC:lapack_*geqrf*/ Lapack.dgeqrf (m,n,ret.m_data,m,tau,ref info); 
     if (info < 0)
         throw new ILArgumentException("qr: an error occoured during decomposition"); 
     return ret; 
 }
Ejemplo n.º 18
0
// DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !! 
        /// <summary>
        /// maximum
        /// </summary>
        /// <param name="A">input array, N-dimensional</param>
        /// <param name="I">return value. If this is an instance of an ILArray 
        /// (f.e. 'empty'), on return I will hold the indices into leadDim of  
        /// the maximum values. If, on entering the function, I is null, those indices 
        /// will not be computed and I will be ignored.</param>
        /// <param name="leadDim">index of dimension to operate along</param>
        /// <returns>ILArray of type double. If I was empty  having the dimension 'leadDim' 
        /// reduced to 1 and holding maximum values </returns>
        public static  ILLogicalArray min( ILArray<byte> A, ref  ILArray<double> I, int leadDim) {
			ILDimension inDim = A.Dimensions; 
			int[] newDims = inDim.ToIntArray();
            if (leadDim == newDims.Length || inDim[leadDim] == 1)
				// scalar or sum over singleton -> return copy
                return ( ILLogicalArray )A.Clone();

			int newLength;
			newLength = inDim.NumberOfElements / newDims[leadDim];
			newDims[leadDim] = 1;
            byte [] retSystemArr;
            retSystemArr = new  byte [newLength];
            int leadDimLen = inDim[leadDim];
			int nrHigherDims = inDim.NumberOfElements / leadDimLen;
            #region HYCALPER GLOBAL_INIT

            byte result;
            byte curval;
            double [] indices = null;
            bool createIndices = false; 
            if (!Object.Equals(I,null)) {
                indices = new  double [retSystemArr.Length];
                createIndices = true; 
            } 
            #endregion HYCALPER GLOBAL_INIT
            

			// physical -> pointer arithmetic
            if (leadDim == 0) {
#region physical along 1st leading dimension
                unsafe {
                    fixed ( byte * pOutArr = retSystemArr)
                    fixed ( byte * pInArr = A.m_data)
                    fixed ( double * pIndices = indices) {
                        byte * lastElement; 
                        byte * tmpOut = pOutArr;
                        byte * tmpIn = pInArr;
                        if (createIndices) {
                            double * tmpInd = pIndices;
                            for (int h = nrHigherDims; h-- > 0; ) {
                                lastElement = tmpIn + leadDimLen;
                                result = byte.MaxValue;
                                while (tmpIn < lastElement) {
                                    curval = *tmpIn;
                                    if (curval < result) {
                                                result = curval;
                                            
                                        *tmpInd = ( double )(tmpIn - (lastElement - leadDimLen));
                                    }
                                    tmpIn++; 
                                }
                                *(tmpOut++) = ( byte )result;
                                tmpInd++; 
                            }
                        } else {
                            double * tmpInd = pIndices;
                            for (int h = nrHigherDims; h-- > 0; ) {
                                lastElement = tmpIn + leadDimLen;
                                result = byte.MaxValue;
                                while (tmpIn < lastElement) {
                                    curval = *tmpIn++;
                                    if (curval < result) {
                                                result = curval;
                                            
                                    }
                                }
                                #region HYCALPER POSTLOOP
                                *(tmpOut++) = ( byte )result;
                                #endregion HYCALPER POSTLOOP
                            }
                        }
                    }
                }
#endregion physical along 1st leading dimension
            } else {
#region physical along abitrary dimension
				// sum along abitrary dimension 
                unsafe {
                    fixed ( byte * pOutArr = retSystemArr)
                    fixed ( byte * pInArr = A.m_data)
                    fixed ( double * pIndices = indices) {
                        byte * lastElementOut = newLength + pOutArr - 1;
                        int inLength = inDim.NumberOfElements -1;
                        byte * lastElementIn = pInArr + inLength; 
                        int inc = inDim.SequentialIndexDistance(leadDim);
                        byte * tmpOut = pOutArr;
                        int outLength = newLength - 1;
                        byte * leadEnd;
                        byte * tmpIn = pInArr;
                        if (createIndices) {
                            double * tmpInd = pIndices;
                            for (int h = nrHigherDims; h-- > 0; ) {
                                leadEnd = tmpIn + leadDimLen * inc;
                                result = byte.MaxValue;
                                while (tmpIn < leadEnd) {
                                    curval = *tmpIn;
                                    if (curval < result) {
                                                result = curval;
                                            
                                        *tmpInd = ( double )(leadDimLen - (leadEnd - tmpIn) / inc);
                                    }
                                    tmpIn += inc;
                                }
                                #region HYCALPER POSTLOOP
                                *(tmpOut) = ( byte ) result;
                                #endregion HYCALPER POSTLOOP
                                tmpOut += inc;
                                tmpInd += inc;
                                if (tmpOut > lastElementOut) {
                                    tmpOut -= outLength;
                                    tmpInd -= outLength;
                                }
                                if (tmpIn > lastElementIn)
                                    tmpIn = pInArr + ((tmpIn - pInArr) - inLength);
                            }
                        } else {
                            for (int h = nrHigherDims; h-- > 0; ) {
                                leadEnd = tmpIn + leadDimLen * inc;
                                result = byte.MaxValue;
                                while (tmpIn < leadEnd) {
                                    curval = *tmpIn;
                                    if (curval < result) {
                                                result = curval;
                                            
                                    }
                                    tmpIn += inc;
                                }
                                #region HYCALPER POSTLOOP
                                *(tmpOut) = ( byte )result;
                                #endregion HYCALPER POSTLOOP
                                tmpOut += inc;
                                if (tmpOut > lastElementOut) {
                                    tmpOut -= outLength;
                                }
                                if (tmpIn > lastElementIn)
                                    tmpIn = pInArr + ((tmpIn - pInArr) - inLength);
                            }
                        }
                    }
				}
#endregion
			}

            if (createIndices) {
                I = new  ILArray<double> (indices, newDims);
            }
            return new  ILLogicalArray (retSystemArr, newDims);  
		}
Ejemplo n.º 19
0
 /// <summary>
 /// QR decomposition - raw Lapack output
 /// </summary>
 /// <param name="A">general input matrix A</param>
 /// <returns>orthonormal / unitary matrix Q and upper triangular 
 /// matrix R packed into single matrix. This is the output of the 
 /// lapack function ?geqrf.</returns>
 /// <remarks><para>Input matrix A will not be altered. </para>
 /// <para>The matrix returned is the direct output of the lapack 
 /// function [d,s,c,z]geqrf respectively. This mean that it contains 
 /// the decomposition factors Q and R, but they are cmbined into a 
 /// single matrix for performance reasons. If you need one of the factors, 
 /// you would use the overloaded function 
 /// <see cref="ILNumerics.BuiltInFunctions.ILMath.qr(ILArray&lt;double&gt;,ref ILArray&lt;double&gt;)"/> 
 /// instead, which returns those factors seperately.</para></remarks>
 public static  ILArray<complex> qr( ILArray<complex> A) {
     if (!A.IsMatrix) 
         throw new ILArgumentException("qr decomposition: A must be a matrix"); 
     int m = A.Dimensions[0], n = A.Dimensions[1]; 
     ILArray<complex> ret = ( ILArray<complex> )A.Clone();  
     complex [] tau = new  complex [(m<n)?m:n];  
     int info = 0; 
     Lapack.zgeqrf (m,n,ret.m_data,m,tau,ref info); 
     if (info < 0)
         throw new ILArgumentException("qr: an error occoured during decomposition"); 
     return ret; 
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Solve linear equation system
 /// </summary>
 /// <param name="A">Matrix A. Size [n x q]</param>
 /// <param name="B">'rigth hand side' B. Size [n x m]</param>
 /// <param name="props">Matrix properties. If defined, no checks are made for the structure of A. If the matrix A was found to be (close to or) singular, the 'MatrixProperties.Singular' flag in props will be set. This flag should be tested on return, in order to verify the reliability of the solution.</param>
 /// <returns>the solution x solving multiply(A,x) = B. Size [n x m]</returns>
 /// <remarks><para>depending on the <paramref name="props"/> parameter the equation system will be solved differently for special structures of A:
 /// <list type="bullet">
 /// <item>If A is square (q == n) and an <b>upper or lower triangular</b> matrix, the system will directly be solved via backward- or forward substitution. Therefore the Lapack function ?trtrs will be used, whenever the memory layout of A is suitable. This may be the case even for reference ILArray's! 
 /// <example><![CDATA[ILArray<double> A = ILMath.randn(4); // construct 4 x 4 matrix 
 /// A = A.T; // A is a reference array now! The transpose is fast and does not consume much memory
 /// // now construct a right side and solve the equations: 
 /// ILArray<double> B = new ILArray<double> (1.0,2.0,3.0).T; 
 /// ILMath.linsolve(A,B); // ... will be carried out via Lapack, even for all arrays involved beeing reference arrays! ]]></example></item>
 /// <item><para>if A is square and symmetric or hermitian, A will be decomposed into a triangular equation system using cholesky factorization and Lapack. The system is than solved using performant Lapack routines.</para>
 /// <para>if during the cholesky factorization A was found to be <b>not positive definite</b> - the corresponding flag in props will be cleaned and <c>null</c> will be returned.</para></item>
 /// <item>otherwise if A is square only, it will be decomposed into upper and lower triangular matrices using LU decomposition and Lapack. The triangular system is than solved using performant Lapack routines.</item>
 /// <item>otherwise, if A is of size [q x n] and q != n, the system is solved using QR decomposition. A may be rank deficient. The solution is computed by use of the Lapack routine '?gelsy' and may be a reference array.</item>
 /// </list></para>
 /// <para>Compatibility with Matlab<sup>(R)</sup>: If A is square, the algorithm used follows the same logic as Matlab up to Rel 14, with the exception of Hessenberg matrices wich are solved via LU factorization here. The un-squared case is handled differently. A direct Lapack driver function (?gelsy) is used here. Therefore the solutions might differ! However, the solution will of course fullfill the equation A * x = B without round off errrors. </para>
 /// <para>For specifiying the rank of A in the unsquare case (q != n), the eps member from <see cref="ILNumerics.Settings.ILSettings"/> class is used.</para></remarks>
 public static  ILArray<complex> linsolve( ILArray<complex> A,  ILArray<complex> B, ref MatrixProperties props) {
     if (object.Equals(A,null)) 
         throw new ILArgumentException("linsolve: input argument A must not be null!"); 
     if (object.Equals(B,null))
         throw new ILArgumentException("linsolve: input argument B must not be null!"); 
     if (A.IsEmpty || B.IsEmpty)
         return  ILArray<complex> .empty(A.Dimensions); 
     if (A.Dimensions[0] != B.Dimensions[0])
         throw new ILArgumentException("linsolve: number of rows for matrix A must match number of rows for RHS!");
     int info = 0, m = A.Dimensions[0]; 
     ILArray<complex> ret; 
     if (m == A.Dimensions[1]) {
         props |= MatrixProperties.Square; 
         if ((props & MatrixProperties.LowerTriangular) != 0) {
             ret = solveLowerTriangularSystem(A,B,ref info); 
             if (info > 0)
                 props |= MatrixProperties.Singular; 
             return ret;
         } 
         if ((props & MatrixProperties.UpperTriangular) != 0) {
             ret = solveUpperTriangularSystem(A,B, ref info); 
             if (info > 0)
                 props |= MatrixProperties.Singular; 
            return ret; 
         } 
         if ((props & MatrixProperties.Hermitian) != 0) {
             ILArray<complex> cholFact = A.copyUpperTriangle(m);
             Lapack.zpotrf ('U', m, cholFact.m_data, m, ref info); 
             if (info > 0) {
                 props ^= MatrixProperties.Hermitian; 
                 return null; 
             }  else {
                 // solve 
                 ret = ( ILArray<complex> )B.Clone(); 
                 Lapack.zpotrs ('U',m,B.Dimensions[1],cholFact.m_data,m,ret.m_data,m,ref info);   
                 return ret; 
             } 
         } else {
             // attempt complete (expensive) LU factorization 
             ILArray<complex> L = ( ILArray<complex> )A.Clone();  
             int [] pivInd = new int[m]; 
             Lapack.zgetrf (m, m, L.m_data, m, pivInd ,ref info); 
             if (info > 0)
                 props |= MatrixProperties.Singular; 
             ret = ( ILArray<complex> )B.Clone(); 
             Lapack.zgetrs ('N',m,B.Dimensions[1],L.m_data,m,pivInd,ret.m_data,m,ref info); 
             if (info < 0) 
                 throw new ILArgumentException("linsolve: failed to solve via lapack dgetrs");
             return ret; 
         }
     } else {
         // under- / overdetermined system
         int n = A.Dimensions[1], rank = 0, minMN = (m < n)? m:n, maxMN = (m > n)? m:n;
         int nrhs = B.Dimensions[1];
         if (B.Dimensions[0] != m) 
             throw new ILArgumentException("linsolve: right hand side matrix B must match input A!"); 
         ILArray<complex> tmpA = ( ILArray<complex> )A.Clone();
         if (m < n) {
             ret = new  ILArray<complex> (new  complex [n * nrhs],n,nrhs);
             ret["0:"+(m-1)+";:"] = B;
         } else {
             ret = ( ILArray<complex> )B.Clone();
         }
         int [] JPVT = new int [n]; 
         Lapack.zgelsy (m, n, B.Dimensions[1], tmpA.m_data, m, ret.m_data, 
                             maxMN, JPVT,  ILMath.MachineParameterDouble.eps ,
                             ref rank, ref info); 
         if (n < m) {
             ret = ret[ILMath.vector(0,n-1),null];
         }
         if (rank < minMN)
             props |= MatrixProperties.RankDeficient; 
         return ret; 
     }
 }
Ejemplo n.º 21
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);;  
		}
Ejemplo n.º 22
0
 protected void CreateMeshILArray(ILArray<double> x, ILArray<double> y, ILArray<double> z)
 {
     bounds = new Cuboid(x.MinValue, y.MinValue, z.MinValue, x.MaxValue, y.MaxValue, z.MaxValue);
     lengthU = x.Dimensions[0];
     lengthV = x.Dimensions[1];
     ILArray<double> xs, ys, zs;
     if (x.IsReference)
         xs = x.Clone() as ILArray<double>;
     else xs = x;
     if (y.IsReference)
         ys = y.Clone() as ILArray<double>;
     else ys = y;
     if (z.IsReference)
         zs = z.Clone() as ILArray<double>;
     else zs = z;
     //if (x.IsReference || y.IsReference || z.IsReference) throw new Exception("x, y and z must be solid arrays");
     double[] xa = xs.InternalArray4Experts;
     double[] ya = ys.InternalArray4Experts;
     double[] za = zs.InternalArray4Experts;
     Cuboid modelBounds = new Cuboid(new System.Windows.Media.Media3D.Point3D(-10, -10, -10), new System.Windows.Media.Media3D.Point3D(10, 10, 10));
     UpdateModelVertices(xa, ya, za, lengthU, lengthV);
     CreateVertsAndInds();
     colourMap = new ColourMap(ColourMapType.Jet, 256);
     colourMapIndices = FalseColourImage.IEnumerableToIndexArray(za, lengthU, lengthV, 256);
     SetColorFromIndices();
 } 
Ejemplo n.º 23
0
        /// <summary>
        /// maximum
        /// </summary>
        /// <param name="A">input array, N-dimensional</param>
        /// <param name="I">return value. If this is an instance of an ILArray 
        /// (f.e. 'empty'), on return I will hold the indices into leadDim of  
        /// the maximum values. If, on entering the function, I is null, those indices 
        /// will not be computed and I will be ignored.</param>
        /// <param name="leadDim">index of dimension to operate along</param>
        /// <returns>ILArray of type double. If I was empty  having the dimension 'leadDim' 
        /// reduced to 1 and holding maximum values </returns>
        public static  ILArray<complex> max( ILArray<complex> A, ref  ILArray<double> I, int leadDim) {
			if (A.IsEmpty) {
                if (!object.Equals (I,null))
                    I =  ILArray<double> .empty(0,0); 
                return  ILArray<complex> .empty(A.Dimensions); 
            }
            ILDimension inDim = A.Dimensions; 
			int[] newDims = inDim.ToIntArray();
            if (leadDim == newDims.Length || inDim[leadDim] == 1)
				// scalar or sum over singleton -> return copy
                return ( ILArray<complex> )A.Clone();

			int newLength;
			newLength = inDim.NumberOfElements / newDims[leadDim];
			newDims[leadDim] = 1;
            complex [] retSystemArr;
            retSystemArr = new  complex [newLength];
            int leadDimLen = inDim[leadDim];
			int nrHigherDims = inDim.NumberOfElements / leadDimLen;
            #region HYCALPER GLOBAL_INIT

            complex result;
            complex curval;
            double [] indices = null;
            bool createIndices = false; 
            if (!Object.Equals(I,null)) {
                indices = new  double [retSystemArr.Length];
                createIndices = true; 
            } 
            #endregion HYCALPER GLOBAL_INIT
            double curabsval; double curabsmaxval; 

			// physical -> pointer arithmetic
            if (leadDim == 0) {
#region physical along 1st leading dimension
                unsafe {
                    fixed ( complex * pOutArr = retSystemArr)
                    fixed ( complex * pInArr = A.m_data)
                    fixed ( double * pIndices = indices) {
                        complex * lastElement; 
                        complex * tmpOut = pOutArr;
                        complex * tmpIn = pInArr;
                        if (createIndices) {
                            double * tmpInd = pIndices;
                            for (int h = nrHigherDims; h-- > 0; ) {
                                lastElement = tmpIn + leadDimLen;
                                curabsmaxval = double.MinValue; result = new complex(); 
                                while (tmpIn < lastElement) {
                                    curval = *tmpIn;
                                    curabsval = complex.Abs(curval);
                                            if (curabsval > curabsmaxval) {
                                                curabsmaxval = curabsval;
                                                result = curval;
                                            
                                        *tmpInd = ( double )(tmpIn - (lastElement - leadDimLen));
                                    }
                                    tmpIn++;
                                }
                                *(tmpOut++) = ( complex )result;
                                tmpInd++; 
                            }
                        } else {
                            double * tmpInd = pIndices;
                            for (int h = nrHigherDims; h-- > 0; ) {
                                lastElement = tmpIn + leadDimLen;
                                curabsmaxval = double.MinValue; result = new complex(); 
                                while (tmpIn < lastElement) {
                                    curval = *tmpIn++;
                                    curabsval = complex.Abs(curval);
                                            if (curabsval > curabsmaxval) {
                                                curabsmaxval = curabsval;
                                                result = curval;
                                            
                                    }
                                }
                                #region HYCALPER POSTLOOP
                                *(tmpOut++) = ( complex )result;
                                #endregion HYCALPER POSTLOOP
                            }
                        }
                    }
                }
#endregion physical along 1st leading dimension
            } else {
#region physical along abitrary dimension
				// sum along abitrary dimension 
                unsafe {
                    fixed ( complex * pOutArr = retSystemArr)
                    fixed ( complex * pInArr = A.m_data)
                    fixed ( double * pIndices = indices) {
                        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;
                        if (createIndices) {
                            double * tmpInd = pIndices;
                            for (int h = nrHigherDims; h-- > 0; ) {
                                leadEnd = tmpIn + leadDimLen * inc;
                                curabsmaxval = double.MinValue; result = new complex(); 
                                while (tmpIn < leadEnd) {
                                    curval = *tmpIn;
                                    curabsval = complex.Abs(curval);
                                            if (curabsval > curabsmaxval) {
                                                curabsmaxval = curabsval;
                                                result = curval;
                                            
                                        *tmpInd = ( double )(leadDimLen - (leadEnd - tmpIn) / inc);
                                    }
                                    tmpIn += inc;
                                }
                                #region HYCALPER POSTLOOP
                                *(tmpOut) = ( complex ) result;
                                #endregion HYCALPER POSTLOOP
                                tmpOut += inc;
                                tmpInd += inc;
                                if (tmpOut > lastElementOut) {
                                    tmpOut -= outLength;
                                    tmpInd -= outLength;
                                }
                                if (tmpIn > lastElementIn)
                                    tmpIn = pInArr + ((tmpIn - pInArr) - inLength);
                            }
                        } else {
                            for (int h = nrHigherDims; h-- > 0; ) {
                                leadEnd = tmpIn + leadDimLen * inc;
                                curabsmaxval = double.MinValue; result = new complex(); 
                                while (tmpIn < leadEnd) {
                                    curval = *tmpIn;
                                    curabsval = complex.Abs(curval);
                                            if (curabsval > curabsmaxval) {
                                                curabsmaxval = curabsval;
                                                result = curval;
                                            
                                    }
                                    tmpIn += inc;
                                }
                                #region HYCALPER POSTLOOP
                                *(tmpOut) = ( complex )result;
                                #endregion HYCALPER POSTLOOP
                                tmpOut += inc;
                                if (tmpOut > lastElementOut) {
                                    tmpOut -= outLength;
                                }
                                if (tmpIn > lastElementIn)
                                    tmpIn = pInArr + ((tmpIn - pInArr) - inLength);
                            }
                        }
                    }
				}
#endregion
			}

            if (createIndices) {
                I = new  ILArray<double> (indices, newDims);
            }
            return new  ILArray<complex> (retSystemArr, newDims);  
		}
Ejemplo n.º 24
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 ILArray <complex> sum(ILArray <complex> A, int leadDim)
        {
            if (A.IsEmpty)
            {
                return(ILArray <complex> .empty(A.Dimensions));
            }
            if (A.IsScalar)
            {
                return(new  ILArray <complex> (new  complex [] { 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();

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

            complex [] retDblArr;
            // build ILDimension
            newLength        = inDim.NumberOfElements / newDims[leadDim];
            newDims[leadDim] = 1;
            retDblArr        = ILMemoryPool.Pool.New <complex>(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(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;
                            *tmpOut = 0.0;
                            while (tmpIn < lastElement)
                            {
                                *tmpOut += (complex)(*tmpIn++);
                            }

                            /**/
                            tmpOut++;
                        }
                    }
                }
                #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;
                            *tmpOut = 0.0;
                            while (tmpIn < leadEnd)
                            {
                                *tmpOut += (complex)(*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 <complex> (retDblArr, newDims));;
        }
Ejemplo n.º 25
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  ILArray<UInt16>  sum ( ILArray<UInt16> A, int leadDim) {
            if (leadDim >= A.Dimensions.NumberOfDimensions)
                throw new ILArgumentException("dimension parameter out of range!");
            if (A.IsEmpty)       
                return  ILArray<UInt16> .empty(A.Dimensions); 
            if (A.IsScalar) {
               
                return new  ILArray<UInt16> (new  UInt16 []{A.GetValue(0)},1,1);
            }
            ILDimension inDim = A.Dimensions; 
			int[] newDims = inDim.ToIntArray();
           
            if (inDim[leadDim] == 1) return ( ILArray<UInt16> )A.Clone();
			int newLength;
			 UInt16 [] retDblArr;
			// build ILDimension
			newLength = inDim.NumberOfElements / newDims[leadDim];
			newDims[leadDim] = 1;
			retDblArr = ILMemoryPool.Pool.New< UInt16 >(newLength);
            ILDimension newDimension = new ILDimension(newDims); 
            int incOut = newDimension.SequentialIndexDistance(leadDim); 
            int leadDimLen = inDim[leadDim];
            int posCounter; 
			int nrHigherDims = inDim.NumberOfElements / leadDimLen;
            if (A.IsReference) {
#region Reference storage
				// ========================  REFERENCE double Storage ===========
				if (A.IsMatrix) {
#region Matrix
					////////////////////////////   MATRIX   ///////////////////////
					unsafe {
						ILIndexOffset idxOffset = A.m_indexOffset;
						int secDim = (leadDim + 1) % 2;
						fixed (int* leadDimStart = idxOffset[leadDim],
								secDimStart = idxOffset[secDim]) {
							fixed ( UInt16 * pOutArr = retDblArr)
						    fixed ( UInt16 * pInArr = A.m_data) {
								 UInt16 * tmpOut = pOutArr;
								 UInt16 * lastElementOut = tmpOut + retDblArr.Length;
								 UInt16 * 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 = 0;
									while (leadDimIdx <= leadDimEnd) {
                                        UInt16 inVal = *(tmpIn + *leadDimIdx++); 
                                        /**/
										 *tmpOut +=  (UInt16) (inVal)  ;
									}
                                    
                                    /**/
                                    tmpOut++;
								}
							}
						}
					} 
#endregion
				} else {
					/////////////////////////////   ARBITRARY DIMENSIONS //////////
#region arbitrary size
					unsafe {
						ILIndexOffset idxOffset = A.m_indexOffset;
						int[] curPosition = new int[A.Dimensions.NumberOfDimensions];
						fixed (int* leadDimStart = idxOffset[leadDim]) {
							fixed ( UInt16 * pOutArr = retDblArr)
							fixed ( UInt16 * pInArr = A.m_data) {
								 UInt16 * tmpOut = pOutArr;
								 UInt16 * lastElementOut = tmpOut + retDblArr.Length - 1;
								 UInt16 * tmpIn = pInArr + A.m_indexOffset.Map(0);
								int* leadDimIdx = leadDimStart;
								int* leadDimEnd = leadDimStart + leadDimLen;
								int dimLen = curPosition.Length;
								int d, curD;
								// start at first element
                                posCounter = retDblArr.Length; 
								while (posCounter-->0) {
									leadDimIdx = leadDimStart;
                                    *tmpOut = 0;
									while (leadDimIdx < leadDimEnd){
                                        UInt16 inVal = *(tmpIn + *leadDimIdx++); 
                                        /**/
										 *tmpOut +=  (UInt16) (inVal)  ;
									 
                                    /**/
                                    }
                                    tmpOut += incOut;
                                    if (tmpOut > lastElementOut)
                                        tmpOut -= (retDblArr.Length - 1);
									// increment higher dimensions 
									d = 1;
									while (d < dimLen) {
										curD = (d + leadDim) % dimLen;
										curPosition[curD]++;
										if (curPosition[curD] < idxOffset[curD].Length) {
											break;
										}
										curPosition[curD] = 0;
										d++;
									}
                                    tmpIn = pInArr + A.m_indexOffset.IndexFromArray(curPosition); 
								}
							}
						}
					}
#endregion
				}
				// ==============================================================
#endregion
			} else {
				// physical -> pointer arithmetic
                if (leadDim == 0) {
#region physical along 1st leading dimension
                    unsafe {
                        fixed ( UInt16 * pOutArr = retDblArr)
                        fixed ( UInt16 * pInArr = A.m_data) {
                            UInt16 * lastElement;
                            UInt16 * tmpOut = pOutArr;
                            UInt16 * tmpIn = pInArr;
                            for (int h = nrHigherDims; h-- > 0; ) {
								lastElement = tmpIn + leadDimLen;
                                *tmpOut = 0;
                                while (tmpIn < lastElement) {
                                    UInt16 inVal = *(tmpIn++); 
                                    /**/
                                    *tmpOut +=  (UInt16) (inVal)  ;
                                }
							    
                                /**/
                                tmpOut++;
                            }
                        }
					}
#endregion
				} else {
#region physical along abitrary dimension
					// sum along abitrary dimension 
                    unsafe {
                        fixed ( UInt16 * pOutArr = retDblArr)
                        fixed ( UInt16 * pInArr = A.m_data) {
                            UInt16 * lastElementOut = newLength + pOutArr -1;
                            int inLength = inDim.NumberOfElements -1; 
                            UInt16 * lastElementIn = pInArr + inLength; 
                            int inc = inDim.SequentialIndexDistance(leadDim); 
                            UInt16 * tmpOut = pOutArr;
                            int outLength = newLength - 1;
                            UInt16 * leadEnd; 
                            UInt16 * tmpIn = pInArr;
                            for (int h = nrHigherDims; h--> 0; ) {
								leadEnd = tmpIn + leadDimLen * inc;
                                *tmpOut = 0;
                                while (tmpIn < leadEnd) {
                                    UInt16 inVal = *(tmpIn); 
                                    tmpIn += inc; 
                                    /**/
                                    *tmpOut +=  (UInt16) (inVal)  ;
                                }
								 
                                /**/
                                tmpOut  += inc;
                                if (tmpOut > lastElementOut)
                                    tmpOut = pOutArr + ((tmpOut - pOutArr) - outLength);
                                if (tmpIn > lastElementIn)
                                    tmpIn = pInArr + ((tmpIn - pInArr) - inLength); 
                            }
                        }
					}
#endregion
				}
			}
			return new  ILArray<UInt16> (retDblArr, newDims);;
        }
Ejemplo n.º 26
0
 /// <summary>
 /// Solve system of linear equations A*x = b, with A beeing a lower triangular matrix
 /// </summary>
 /// <param name="A">input matrix of Size [n x n], must be lower triangular. No check is made for that!</param>
 /// <param name="B">solution vector. Size [n x 1]</param>
 /// <param name="singularityDetect">output: this value gives the row of A, where a singularity has been detected (if any). If A is not singular, this will be a negative value.</param>
 /// <returns>Solution x solving A * x = b.</returns>
 /// <remarks><para>The solution will be determined via forward substitution</para>
 /// <para>Make sure, A and b are of correct size, since no checks are made for that!</para>
 /// <para>This function is used by ILMath.linsolve. There should be rare need for you to call this function directly.</para>
 /// <para>Elements of A above the main diagonal will not be accessed.</para>
 /// <para>If A has been found to be singular, the array returned will contain NaN values for corresponding elements!</para></remarks>
 internal static /*!HC:inCls1*/ ILArray<double> solveLowerTriangularSystem (/*!HC:inCls1*/ ILArray<double> A, /*!HC:inCls1*/ ILArray<double> B, ref int singularityDetect) {
     System.Diagnostics.Debug.Assert(B.Dimensions[1] >= 0); 
     System.Diagnostics.Debug.Assert(B.Dimensions[0] == A.Dimensions[1]); 
     System.Diagnostics.Debug.Assert(A.Dimensions[0] == A.Dimensions[1]); 
     singularityDetect = -1; 
     int n = A.Dimensions[0]; 
     int m = B.Dimensions[1]; 
     int spacingA0, spacingA1, info = 0; 
     char transA; 
     /*!HC:inCls1*/ ILArray<double> ret = (/*!HC:inCls1*/ ILArray<double> )B.Clone(); 
     /*!HC:inArr1*/ double [] retArr = ret.m_data;  
     if (isSuitableForLapack(A,out spacingA0,out spacingA1,out transA)) {
         // solve using Lapack
         unsafe {
             fixed (/*!HC:inArr1*/ double * ptrA = A.m_data) 
             fixed (/*!HC:inArr1*/ double * ptrB = ret.m_data) {
                 /*!HC:inArr1*/ double * pA = ptrA + A.getBaseIndex(0); 
                 /*!HC:lapack.?trtrs*/ Lapack.dtrtrs ((transA == 'T')? 'U':'L',transA,'N',A.Dimensions[0],ret.Dimensions[1],(IntPtr)pA,spacingA1,(IntPtr)ptrB,n,ref info);
                 if (info < 0) 
                     throw new ILArgumentException ("linsolve: error inside Lapack function ?trtrs for argument: " + (-info));
                 if (info > 0) {
                     singularityDetect = info-1;
                     retArr = ret.m_data; 
                     for (spacingA0 = 0; spacingA0 < ret.Dimensions[1]; spacingA0++) {
                         info = spacingA0 * n + singularityDetect; 
                         for (spacingA1 = singularityDetect; spacingA1 < n; spacingA1++) {
                             retArr[info++] = /*!HC:notANumber*/ double.NaN ;     
                         }
                     }
                 } else {
                     singularityDetect = -1; 
                 }
             }
         }
         return ret; 
     }
     // must do it manually.... 
     System.Diagnostics.Debug.Assert(A.IsReference); 
     int[] Adim0 = A.m_indexOffset[0]; 
     int[] Adim1 = A.m_indexOffset[1];    
     /*!HC:inArr1*/ double diagVal = /*!HC:zeroVal*/ 0.0 ;
     /*!HC:inArr1*/ double tmpVal;
     for (int b = 0; b < m; b++) {
         for (int r = 0; r < n; r++) {
             tmpVal = /*!HC:zeroVal*/ 0.0 ; 
             diagVal = A.GetValue(r,r); 
             if (diagVal == /*!HC:zeroVal*/ 0.0 ) {
                 singularityDetect = r; 
                 for (; r < n; r++)
                     retArr[r + b * n] = /*!HC:posInfty*/ double.PositiveInfinity ; 
             } else {
                 for (int c = 0; c < r; c++) {
                     tmpVal +=  A.m_data[Adim0[r] + Adim1[c]] * retArr[c + b * n]; 
                 }
                 retArr[r + b * n] = (retArr[r + b * n] - tmpVal) / diagVal; 
             }
         }
     }
     ret = new /*!HC:inCls1*/ ILArray<double> (retArr,n,m); 
     return ret; 
 }
Ejemplo n.º 27
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));;
        }
Ejemplo n.º 28
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));;
        }