Пример #1
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);
        }
Пример #2
0
        /// <summary>
        /// QR decomposition, returning Q and R, optionally economical sized
        /// </summary>
        /// <param name="A">general input matrix A of size [m x n]</param>
        /// <param name="R">output parameter. Upper triangular matrix R as
        /// result of decomposition. Size [m x n] or [min(m,n) x n] (see remarks). </param>
        /// <param name="economySize">if true, the size of Q and R will
        /// be [m x m] and [m x n] respectively. However, if m &lt; n,
        /// the economySize parameter has no effect. </param>
        /// <returns>Orthonormal real / unitary complex matrix Q as result
        /// of decomposition. Size [m x m] or [m x min(m,n)], depending
        /// on <paramref name="economySize"/> (see remarks below)</returns>
        /// <remarks>The function returns Q and R such that the equation
        /// <para>A = Q * R</para> holds with roundoff errors. ('*'
        /// denotes matrix multiplication.)
        /// <para>Q and R will be solid ILArray's.</para></remarks>
        public static ILArray <complex> qr(
            ILArray <complex> A,
            ref ILArray <complex> R, bool economySize)
        {
            if (Object.Equals(R, null))
            {
                return(qr(A));
            }
            int m = A.Dimensions[0];
            int n = A.Dimensions[1];

            if (m < n && economySize)
            {
                return(qr(A, ref R, false));
            }
            ILArray <complex> ret;

            if (m == 0 || n == 0)
            {
                R = new  ILArray <complex> (new  complex [0], m, n);
                return(ILArray <complex> .empty(A.Dimensions));
            }
            int minMN = (m < n)?m:n;
            int info  = 0;

            complex [] tau = new  complex [minMN];
            complex [] QArr;
            if (m >= n)
            {
                ret = new  ILArray <complex> (
                    new  complex [(economySize)? minMN * m : m * m],
                    m, (economySize)? minMN: m);
            }
            else
            {
                // economySize is always false ... !
                // a temporary array is needed for extraction of the compact lapack Q (?geqrf)
                ret = new  ILArray <complex> (
                    new  complex [m * n], m, n);
            }
            QArr = ret.m_data;
            for (int i = m * n; i-- > 0;)
            {
                QArr[i] = A.GetValue(i);
            }
            Lapack.zgeqrf(m, n, QArr, m, tau, ref info);
            if (info != 0)
            {
                throw new ILArgumentException("qr: error inside lapack library (?geqrf). info=" + info.ToString());
            }
            // extract R, Q
            if (economySize)
            {
                R = copyUpperTriangle(QArr, m, n, minMN);
                Lapack.zungqr(m, minMN, tau.Length, QArr, m, tau, ref info);
            }
            else
            {
                R = copyUpperTriangle(QArr, m, n, m);
                Lapack.zungqr(m, m, tau.Length, QArr, m, tau, ref info);
                if (m < n)
                {
                    ret = ret[":;0:" + (m - 1)];
                }
            }
            if (info != 0)
            {
                throw new ILArgumentException("qr: error in lapack library (???gqr). info=" + info.ToString());
            }
            return(ret);
        }