예제 #1
0
파일: qr.cpp 프로젝트: iut-ibk/PowerVIBe
void qrdecompositionunpacked(ap::real_2d_array a,
     int m,
     int n,
     ap::real_2d_array& q,
     ap::real_2d_array& r)
{
    int i;
    int k;
    ap::real_1d_array tau;
    ap::real_1d_array work;
    ap::real_1d_array v;

    k = ap::minint(m, n);
    if( n<=0 )
    {
        return;
    }
    work.setbounds(1, m);
    v.setbounds(1, m);
    q.setbounds(1, m, 1, m);
    r.setbounds(1, m, 1, n);
    
    //
    // QRDecomposition
    //
    qrdecomposition(a, m, n, tau);
    
    //
    // R
    //
    for(i = 1; i <= n; i++)
    {
        r(1,i) = 0;
    }
    for(i = 2; i <= m; i++)
    {
        ap::vmove(&r(i, 1), &r(1, 1), ap::vlen(1,n));
    }
    for(i = 1; i <= k; i++)
    {
        ap::vmove(&r(i, i), &a(i, i), ap::vlen(i,n));
    }
    
    //
    // Q
    //
    unpackqfromqr(a, m, n, tau, m, q);
}
예제 #2
0
파일: svd.cpp 프로젝트: 0004c/VTK
/*************************************************************************
Obsolete 1-based subroutine.
See RMatrixSVD for 0-based replacement.
*************************************************************************/
bool svddecomposition(ap::real_2d_array a,
     int m,
     int n,
     int uneeded,
     int vtneeded,
     int additionalmemory,
     ap::real_1d_array& w,
     ap::real_2d_array& u,
     ap::real_2d_array& vt)
{
    bool result;
    ap::real_1d_array tauq;
    ap::real_1d_array taup;
    ap::real_1d_array tau;
    ap::real_1d_array e;
    ap::real_1d_array work;
    ap::real_2d_array t2;
    bool isupper;
    int minmn;
    int ncu;
    int nrvt;
    int nru;
    int ncvt;
    int i;
    int j;

    result = true;
    if( m==0||n==0 )
    {
        return result;
    }
    ap::ap_error::make_assertion(uneeded>=0&&uneeded<=2, "SVDDecomposition: wrong parameters!");
    ap::ap_error::make_assertion(vtneeded>=0&&vtneeded<=2, "SVDDecomposition: wrong parameters!");
    ap::ap_error::make_assertion(additionalmemory>=0&&additionalmemory<=2, "SVDDecomposition: wrong parameters!");
    
    //
    // initialize
    //
    minmn = ap::minint(m, n);
    w.setbounds(1, minmn);
    ncu = 0;
    nru = 0;
    if( uneeded==1 )
    {
        nru = m;
        ncu = minmn;
        u.setbounds(1, nru, 1, ncu);
    }
    if( uneeded==2 )
    {
        nru = m;
        ncu = m;
        u.setbounds(1, nru, 1, ncu);
    }
    nrvt = 0;
    ncvt = 0;
    if( vtneeded==1 )
    {
        nrvt = minmn;
        ncvt = n;
        vt.setbounds(1, nrvt, 1, ncvt);
    }
    if( vtneeded==2 )
    {
        nrvt = n;
        ncvt = n;
        vt.setbounds(1, nrvt, 1, ncvt);
    }
    
    //
    // M much larger than N
    // Use bidiagonal reduction with QR-decomposition
    //
    if( m>1.6*n )
    {
        if( uneeded==0 )
        {
            
            //
            // No left singular vectors to be computed
            //
            qrdecomposition(a, m, n, tau);
            for(i = 2; i <= n; i++)
            {
                for(j = 1; j <= i-1; j++)
                {
                    a(i,j) = 0;
                }
            }
            tobidiagonal(a, n, n, tauq, taup);
            unpackptfrombidiagonal(a, n, n, taup, nrvt, vt);
            unpackdiagonalsfrombidiagonal(a, n, n, isupper, w, e);
            result = bidiagonalsvddecomposition(w, e, n, isupper, false, u, 0, a, 0, vt, ncvt);
            return result;
        }
        else
        {
            
            //
            // Left singular vectors (may be full matrix U) to be computed
            //
            qrdecomposition(a, m, n, tau);
            unpackqfromqr(a, m, n, tau, ncu, u);
            for(i = 2; i <= n; i++)
            {
                for(j = 1; j <= i-1; j++)
                {
                    a(i,j) = 0;
                }
            }
            tobidiagonal(a, n, n, tauq, taup);
            unpackptfrombidiagonal(a, n, n, taup, nrvt, vt);
            unpackdiagonalsfrombidiagonal(a, n, n, isupper, w, e);
            if( additionalmemory<1 )
            {
                
                //
                // No additional memory can be used
                //
                multiplybyqfrombidiagonal(a, n, n, tauq, u, m, n, true, false);
                result = bidiagonalsvddecomposition(w, e, n, isupper, false, u, m, a, 0, vt, ncvt);
            }
            else
            {
                
                //
                // Large U. Transforming intermediate matrix T2
                //
                work.setbounds(1, ap::maxint(m, n));
                unpackqfrombidiagonal(a, n, n, tauq, n, t2);
                copymatrix(u, 1, m, 1, n, a, 1, m, 1, n);
                inplacetranspose(t2, 1, n, 1, n, work);
                result = bidiagonalsvddecomposition(w, e, n, isupper, false, u, 0, t2, n, vt, ncvt);
                matrixmatrixmultiply(a, 1, m, 1, n, false, t2, 1, n, 1, n, true, 1.0, u, 1, m, 1, n, 0.0, work);
            }
            return result;
        }
    }
    
    //
    // N much larger than M
    // Use bidiagonal reduction with LQ-decomposition
    //
    if( n>1.6*m )
    {
        if( vtneeded==0 )
        {
            
            //
            // No right singular vectors to be computed
            //
            lqdecomposition(a, m, n, tau);
            for(i = 1; i <= m-1; i++)
            {
                for(j = i+1; j <= m; j++)
                {
                    a(i,j) = 0;
                }
            }
            tobidiagonal(a, m, m, tauq, taup);
            unpackqfrombidiagonal(a, m, m, tauq, ncu, u);
            unpackdiagonalsfrombidiagonal(a, m, m, isupper, w, e);
            work.setbounds(1, m);
            inplacetranspose(u, 1, nru, 1, ncu, work);
            result = bidiagonalsvddecomposition(w, e, m, isupper, false, a, 0, u, nru, vt, 0);
            inplacetranspose(u, 1, nru, 1, ncu, work);
            return result;
        }
        else
        {
            
            //
            // Right singular vectors (may be full matrix VT) to be computed
            //
            lqdecomposition(a, m, n, tau);
            unpackqfromlq(a, m, n, tau, nrvt, vt);
            for(i = 1; i <= m-1; i++)
            {
                for(j = i+1; j <= m; j++)
                {
                    a(i,j) = 0;
                }
            }
            tobidiagonal(a, m, m, tauq, taup);
            unpackqfrombidiagonal(a, m, m, tauq, ncu, u);
            unpackdiagonalsfrombidiagonal(a, m, m, isupper, w, e);
            work.setbounds(1, ap::maxint(m, n));
            inplacetranspose(u, 1, nru, 1, ncu, work);
            if( additionalmemory<1 )
            {
                
                //
                // No additional memory available
                //
                multiplybypfrombidiagonal(a, m, m, taup, vt, m, n, false, true);
                result = bidiagonalsvddecomposition(w, e, m, isupper, false, a, 0, u, nru, vt, n);
            }
            else
            {
                
                //
                // Large VT. Transforming intermediate matrix T2
                //
                unpackptfrombidiagonal(a, m, m, taup, m, t2);
                result = bidiagonalsvddecomposition(w, e, m, isupper, false, a, 0, u, nru, t2, m);
                copymatrix(vt, 1, m, 1, n, a, 1, m, 1, n);
                matrixmatrixmultiply(t2, 1, m, 1, m, false, a, 1, m, 1, n, false, 1.0, vt, 1, m, 1, n, 0.0, work);
            }
            inplacetranspose(u, 1, nru, 1, ncu, work);
            return result;
        }
    }
    
    //
    // M<=N
    // We can use inplace transposition of U to get rid of columnwise operations
    //
    if( m<=n )
    {
        tobidiagonal(a, m, n, tauq, taup);
        unpackqfrombidiagonal(a, m, n, tauq, ncu, u);
        unpackptfrombidiagonal(a, m, n, taup, nrvt, vt);
        unpackdiagonalsfrombidiagonal(a, m, n, isupper, w, e);
        work.setbounds(1, m);
        inplacetranspose(u, 1, nru, 1, ncu, work);
        result = bidiagonalsvddecomposition(w, e, minmn, isupper, false, a, 0, u, nru, vt, ncvt);
        inplacetranspose(u, 1, nru, 1, ncu, work);
        return result;
    }
    
    //
    // Simple bidiagonal reduction
    //
    tobidiagonal(a, m, n, tauq, taup);
    unpackqfrombidiagonal(a, m, n, tauq, ncu, u);
    unpackptfrombidiagonal(a, m, n, taup, nrvt, vt);
    unpackdiagonalsfrombidiagonal(a, m, n, isupper, w, e);
    if( additionalmemory<2||uneeded==0 )
    {
        
        //
        // We cant use additional memory or there is no need in such operations
        //
        result = bidiagonalsvddecomposition(w, e, minmn, isupper, false, u, nru, a, 0, vt, ncvt);
    }
    else
    {
        
        //
        // We can use additional memory
        //
        t2.setbounds(1, minmn, 1, m);
        copyandtranspose(u, 1, m, 1, minmn, t2, 1, minmn, 1, m);
        result = bidiagonalsvddecomposition(w, e, minmn, isupper, false, u, 0, t2, m, vt, ncvt);
        copyandtranspose(t2, 1, minmn, 1, m, u, 1, m, 1, minmn);
    }
    return result;
}