예제 #1
0
        /*************************************************************************
        *  LQ decomposition of a rectangular matrix of size MxN
        *
        *  Input parameters:
        *   A   -   matrix A whose indexes range within [1..M, 1..N].
        *   M   -   number of rows in matrix A.
        *   N   -   number of columns in matrix A.
        *
        *  Output parameters:
        *   A   -   matrices L and Q in compact form (see below)
        *   Tau -   array of scalar factors which are used to form
        *           matrix Q. Array whose index ranges within [1..Min(M,N)].
        *
        *  Matrix A is represented as A = LQ, where Q is an orthogonal matrix of size
        *  MxM, L - lower triangular (or lower trapezoid) matrix of size M x N.
        *
        *  The elements of matrix L are located on and below the main diagonal of
        *  matrix A. The elements which are located in Tau array and above the main
        *  diagonal of matrix A are used to form matrix Q as follows:
        *
        *  Matrix Q is represented as a product of elementary reflections
        *
        *  Q = H(k)*H(k-1)*...*H(2)*H(1),
        *
        *  where k = min(m,n), and each H(i) is of the form
        *
        *  H(i) = 1 - tau * v * (v^T)
        *
        *  where tau is a scalar stored in Tau[I]; v - real vector,
        *  so that v(1:i-1) = 0, v(i) = 1, v(i+1:n) stored in A(i,i+1:n).
        *
        *  -- ALGLIB --
        *    Copyright 2005 by Bochkanov Sergey
        *************************************************************************/
        public static void Decomposition(ref double[,] a,
                                         int m,
                                         int n,
                                         ref double[] tau)
        {
            double[] work  = new double[0];
            double[] t     = new double[0];
            int      i     = 0;
            int      k     = 0;
            int      nmip1 = 0;
            int      minmn = 0;
            int      maxmn = 0;
            double   tmp   = 0;
            int      i_    = 0;
            int      i1_   = 0;

            minmn = Math.Min(m, n);
            maxmn = Math.Max(m, n);
            work  = new double[m + 1];
            t     = new double[n + 1];
            tau   = new double[minmn + 1];

            //
            // Test the input arguments
            //
            k = Math.Min(m, n);
            for (i = 1; i <= k; i++)
            {
                //
                // Generate elementary reflector H(i) to annihilate A(i,i+1:n)
                //
                nmip1 = n - i + 1;
                i1_   = (i) - (1);
                for (i_ = 1; i_ <= nmip1; i_++)
                {
                    t[i_] = a[i, i_ + i1_];
                }
                Reflections.GenerateReflection(ref t, nmip1, ref tmp);
                tau[i] = tmp;
                i1_    = (1) - (i);
                for (i_ = i; i_ <= n; i_++)
                {
                    a[i, i_] = t[i_ + i1_];
                }
                t[1] = 1;
                if (i < n)
                {
                    //
                    // Apply H(i) to A(i+1:m,i:n) from the right
                    //
                    Reflections.ApplyReflectionFromTheRight(ref a, tau[i], ref t, i + 1, m, i, n, ref work);
                }
            }
        }
예제 #2
0
        /*************************************************************************
        *  Reduction of a rectangular matrix to  bidiagonal form
        *
        *  The algorithm reduces the rectangular matrix A to  bidiagonal form by
        *  orthogonal transformations P and Q: A = Q*B*P.
        *
        *  Input parameters:
        *   A       -   source matrix. Array whose indexes range within [1..N, 1..N].
        *   M       -   number of rows in matrix A.
        *   N       -   number of columns in matrix A.
        *
        *  Output parameters:
        *   A       -   matrices Q, B, P in compact form (see below).
        *   TauQ    -   scalar factors which are used to form matrix Q.
        *   TauP    -   scalar factors which are used to form matrix P.
        *
        *  The main diagonal and one of the secondary diagonals of matrix A are
        *  replaced with bidiagonal matrix B. Other elements contain elementary
        *  reflections which form MxM matrix Q and NxN matrix P, respectively.
        *
        *  If M>=N, B is the upper bidiagonal MxN matrix and is stored in the
        *  corresponding  elements  of matrix A. Matrix Q is represented as a product
        *  of elementary reflections Q = H(1)*H(2)*...*H(n), where H(i) = 1 - tau*v*v'.
        *  Here tau is a scalar which is stored in TauQ[i], and vector v has the
        *  following structure: v(1:i-1)=0, v(i)=1, v(i+1:m) is stored in elements
        *  A(i+1:m,i). Matrix P is as follows: P = G(1)*G(2)*...*G(n-1), where
        *  G(i) = 1 - tau*u*u'. Tau is stored in TauP[i], u(1:i)=0, u(i+1)=1,  u(i+2:n)
        *  is stored in elements A(i,i+2:n).
        *
        *  If M<N, B is the lower bidiagonal MxN matrix and is stored in the
        *  corresponding elements of matrix A. Q = H(1)*H(2)*...*H(m-1), where
        *  H(i) = 1 - tau*v*v',  tau  is stored in TauQ, v(1:i)=0, v(i+1)=1, v(i+2:m)
        *  is stored in elements A(i+1:m,i).  P = G(1)*G(2)*...*G(m),  G(i) = 1 - tau*u*u',
        *  tau is stored in TauP,  u(1:i-1)=0, u(i)=1, u(i+1:n) is stored A(i,i+1:n).
        *
        *  EXAMPLE:
        *
        *  m=6, n=5 (m > n):               m=5, n=6 (m < n):
        *
        *  (  d   e   u1  u1  u1 )         (  d   u1  u1  u1  u1  u1 )
        *  (  v1  d   e   u2  u2 )         (  e   d   u2  u2  u2  u2 )
        *  (  v1  v2  d   e   u3 )         (  v1  e   d   u3  u3  u3 )
        *  (  v1  v2  v3  d   e  )         (  v1  v2  e   d   u4  u4 )
        *  (  v1  v2  v3  v4  d  )         (  v1  v2  v3  e   d   u5 )
        *  (  v1  v2  v3  v4  v5 )
        *
        *  Here vi and ui are vectors which form H(i) and G(i), and d and e -
        *  are the diagonal and off-diagonal elements of matrix B.
        *************************************************************************/
        public static void ToBidiagonal(ref double[,] a,
                                        int m,
                                        int n,
                                        ref double[] tauq,
                                        ref double[] taup)
        {
            double[] work  = new double[0];
            double[] t     = new double[0];
            int      minmn = 0;
            int      maxmn = 0;
            int      i     = 0;
            double   ltau  = 0;
            int      mmip1 = 0;
            int      nmi   = 0;
            int      ip1   = 0;
            int      nmip1 = 0;
            int      mmi   = 0;
            int      i_    = 0;
            int      i1_   = 0;

            minmn = Math.Min(m, n);
            maxmn = Math.Max(m, n);
            work  = new double[maxmn + 1];
            t     = new double[maxmn + 1];
            taup  = new double[minmn + 1];
            tauq  = new double[minmn + 1];
            if (m >= n)
            {
                //
                // Reduce to upper bidiagonal form
                //
                for (i = 1; i <= n; i++)
                {
                    //
                    // Generate elementary reflector H(i) to annihilate A(i+1:m,i)
                    //
                    mmip1 = m - i + 1;
                    i1_   = (i) - (1);
                    for (i_ = 1; i_ <= mmip1; i_++)
                    {
                        t[i_] = a[i_ + i1_, i];
                    }
                    Reflections.GenerateReflection(ref t, mmip1, ref ltau);
                    tauq[i] = ltau;
                    i1_     = (1) - (i);
                    for (i_ = i; i_ <= m; i_++)
                    {
                        a[i_, i] = t[i_ + i1_];
                    }
                    t[1] = 1;

                    //
                    // Apply H(i) to A(i:m,i+1:n) from the left
                    //
                    Reflections.ApplyReflectionFromTheLeft(ref a, ltau, ref t, i, m, i + 1, n, ref work);
                    if (i < n)
                    {
                        //
                        // Generate elementary reflector G(i) to annihilate
                        // A(i,i+2:n)
                        //
                        nmi = n - i;
                        ip1 = i + 1;
                        i1_ = (ip1) - (1);
                        for (i_ = 1; i_ <= nmi; i_++)
                        {
                            t[i_] = a[i, i_ + i1_];
                        }
                        Reflections.GenerateReflection(ref t, nmi, ref ltau);
                        taup[i] = ltau;
                        i1_     = (1) - (ip1);
                        for (i_ = ip1; i_ <= n; i_++)
                        {
                            a[i, i_] = t[i_ + i1_];
                        }
                        t[1] = 1;

                        //
                        // Apply G(i) to A(i+1:m,i+1:n) from the right
                        //
                        Reflections.ApplyReflectionFromTheRight(ref a, ltau, ref t, i + 1, m, i + 1, n, ref work);
                    }
                    else
                    {
                        taup[i] = 0;
                    }
                }
            }
            else
            {
                //
                // Reduce to lower bidiagonal form
                //
                for (i = 1; i <= m; i++)
                {
                    //
                    // Generate elementary reflector G(i) to annihilate A(i,i+1:n)
                    //
                    nmip1 = n - i + 1;
                    i1_   = (i) - (1);
                    for (i_ = 1; i_ <= nmip1; i_++)
                    {
                        t[i_] = a[i, i_ + i1_];
                    }
                    Reflections.GenerateReflection(ref t, nmip1, ref ltau);
                    taup[i] = ltau;
                    i1_     = (1) - (i);
                    for (i_ = i; i_ <= n; i_++)
                    {
                        a[i, i_] = t[i_ + i1_];
                    }
                    t[1] = 1;

                    //
                    // Apply G(i) to A(i+1:m,i:n) from the right
                    //
                    Reflections.ApplyReflectionFromTheRight(ref a, ltau, ref t, i + 1, m, i, n, ref work);
                    if (i < m)
                    {
                        //
                        // Generate elementary reflector H(i) to annihilate
                        // A(i+2:m,i)
                        //
                        mmi = m - i;
                        ip1 = i + 1;
                        i1_ = (ip1) - (1);
                        for (i_ = 1; i_ <= mmi; i_++)
                        {
                            t[i_] = a[i_ + i1_, i];
                        }
                        Reflections.GenerateReflection(ref t, mmi, ref ltau);
                        tauq[i] = ltau;
                        i1_     = (1) - (ip1);
                        for (i_ = ip1; i_ <= m; i_++)
                        {
                            a[i_, i] = t[i_ + i1_];
                        }
                        t[1] = 1;

                        //
                        // Apply H(i) to A(i+1:m,i+1:n) from the left
                        //
                        Reflections.ApplyReflectionFromTheLeft(ref a, ltau, ref t, i + 1, m, i + 1, n, ref work);
                    }
                    else
                    {
                        tauq[i] = 0;
                    }
                }
            }
        }