Show
Ignore:
Timestamp:
07/06/07 18:58:19 (2 years ago)
Author:
pernet
Message:

New row echelon form and reduced row echelon form

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • include/fflas-ffpack/ffpack.h

    r25 r26  
    464464         * Compute the product UL of the upper, resp lower triangular matrices U and L 
    465465         * stored one above the other in the square matrix A. 
    466          * The matrix U is supposed to be unit diagonal 
     466         * Diag == Unit if the matrix U is unit diagonal 
    467467         *  
    468468         */ 
    469469        template<class Field> 
    470470        static void 
    471         ftrtrm (const Field& F, const size_t N, typename Field::Element * A, const size_t lda){ 
     471        ftrtrm (const Field& F, const FFLAS_DIAG diag, const size_t N, 
     472                typename Field::Element * A, const size_t lda){ 
    472473                 
    473474                typename Field::Element one; 
    474475                F.init(one,1.0); 
    475  
    476                  if (N == 1) 
     476                 
     477                if (N == 1) 
    477478                        return; 
    478479                size_t N1 = N/2; 
    479480                size_t N2 = N-N1; 
    480481                 
    481                 ftrtrm (F, N1, A, lda); 
     482                ftrtrm (F, diag, N1, A, lda); 
    482483                 
    483484                fgemm (F, FflasNoTrans, FflasNoTrans, N1, N1, N2, one, 
    484485                       A+N1, lda, A+N1*lda, lda, one, A, lda); 
    485486                 
    486                 ftrmm (F, FflasRight, FflasLower, FflasNoTrans, FflasNonUnit, N1, N2, one, A + N1*(lda+1), lda, A + N1, lda); 
    487                  
    488                 ftrmm (F, FflasLeft, FflasUpper, FflasNoTrans, FflasUnit, N2, N1, one, A + N1*(lda+1), lda, A + N1*lda, lda); 
    489                  
    490                 ftrtrm (F, N2, A + N1*(lda+1), lda); 
     487                ftrmm (F, FflasRight, FflasLower, FflasNoTrans, (diag == FflasUnit) ? FflasNonUnit : FflasUnit, N1, N2, one, A + N1*(lda+1), lda, A + N1, lda); 
     488                 
     489                ftrmm (F, FflasLeft, FflasUpper, FflasNoTrans, diag, N2, N1, one, A + N1*(lda+1), lda, A + N1*lda, lda); 
     490                 
     491                ftrtrm (F, diag, N2, A + N1*(lda+1), lda); 
    491492                 
    492493        } 
     
    496497         *  
    497498         * After the computation A = [ M \ V ] such that AU = C is a column echelon 
    498          * decomposition of A, with U = P^T [  V (+Ir) ] and C = M //+ Q [ Ir   ] 
    499          *                                  [ 0 In-r   ]           //    [    0 ] 
     499         * decomposition of A, with U = P^T [ V + Ir ] and C = M //+ Q [ Ir   ] 
     500         *                                  [ 0 In-r ]           //    [    0 ] 
    500501         * Qt = Q^T 
    501502         */ 
     
    514515                t1.clear(); 
    515516                t1.start(); 
    516                 r = LUdivine (F, FflasUnit, M, N, A, lda, P, Qt); 
     517                r = LUdivine (F, FflasUnit, FflasNoTrans, M, N, A, lda, P, Qt); 
    517518                t1.stop(); 
    518519                //cerr<<"LU --> "<<t1.usertime()<<endl; 
     
    526527                ftrmm (F, FflasLeft, FflasUpper, FflasNoTrans, FflasUnit, r, N-r, 
    527528                       mone, A, lda, A+r, lda); 
     529 
     530                t2.stop(); 
     531                //cerr<<"U^-1 --> "<<t2.usertime()<<endl; 
     532 
     533                return r; 
     534        } 
     535 
     536        /** 
     537         * Compute the Row Echelon form of the input matrix in-place. 
     538         *  
     539         * After the computation A = [ L \ M ] such that L A = R is a column echelon 
     540         * decomposition of A, with L =  [ L+Ir  0   ] P  and R = M 
     541         *                               [      In-r ]                
     542         * Qt = Q^T 
     543         */ 
     544        template <class Field> 
     545        static size_t 
     546        RowEchelonForm (const Field& F, const size_t M, const size_t N, 
     547                        typename Field::Element * A, const size_t lda, 
     548                        size_t* P, size_t* Qt){ 
     549 
     550                typename Field::Element one, mone; 
     551                F.init (one, 1.0); 
     552                F.neg (mone, one); 
     553                size_t r; 
     554 
     555                Timer t1; 
     556                t1.clear(); 
     557                t1.start(); 
     558                r = LUdivine (F, FflasUnit, FflasTrans,  M, N, A, lda, P, Qt); 
     559                t1.stop(); 
     560                //cerr<<"LU --> "<<t1.usertime()<<endl; 
     561                 
     562                Timer t2; 
     563                t2.clear(); 
     564                t2.start(); 
     565                ftrtri (F, FflasLower, FflasUnit, r, A, lda); 
     566 
     567 
     568                ftrmm (F, FflasRight, FflasLower, FflasNoTrans, FflasUnit, M-r, r, 
     569                       mone, A, lda, A+r*lda, lda); 
    528570 
    529571                t2.stop(); 
     
    573615                       one, A, lda, A+r*lda, lda); 
    574616 
    575                 ftrtrm (F, r, A, lda); 
     617                ftrtrm (F, FflasUnit, r, A, lda); 
     618                t1.stop(); 
     619                //cerr<<"U^-1L^-1 --> "<<t1.usertime()<<endl;       
     620                 
     621                return r; 
     622 
     623        } 
     624 
     625        /** 
     626         * Compute the Reduced Row Echelon form of the input matrix in-place. 
     627         *  
     628         * After the computation A = [  V  ] such that L A = R is a reduced row echelon 
     629         *                           [ M 0 ] 
     630         * decomposition of A, where L =  [ V      ] P^T and R =  [ Ir M  ] Q 
     631         *                                [ 0 In-r ]              [ 0     ] 
     632         * Qt = Q^T 
     633         */ 
     634        template <class Field> 
     635        static size_t 
     636        ReducedRowEchelonForm (const Field& F, const size_t M, const size_t N, 
     637                               typename Field::Element * A, const size_t lda, 
     638                               size_t* P, size_t* Qt){ 
     639                 
     640                typename Field::Element one, mone; 
     641                F.init (one, 1.0); 
     642                F.neg (mone, one); 
     643                size_t r; 
     644 
     645                r = RowEchelonForm (F, M, N, A, lda, P, Qt); 
     646                         
     647                Timer t1; 
     648                t1.clear(); 
     649                t1.start(); 
     650                // M = M Q^T  
     651                for (int i=0; i<r; ++i){ 
     652                        if ( Qt[i]> (size_t) i ){ 
     653                                fswap( F, i+1,  
     654                                       A + Qt[i], lda,  
     655                                       A + i, lda ); 
     656                        } 
     657                } 
     658                 
     659                ftrtri (F, FflasUpper, FflasNonUnit, r, A, lda); 
     660                 
     661                ftrmm (F, FflasLeft, FflasUpper, FflasNoTrans, FflasNonUnit, r, N-r, 
     662                       one, A, lda, A+r, lda); 
     663                 
     664                ftrtrm (F, FflasNonUnit, r, A, lda); 
     665                 
    576666                t1.stop(); 
    577667                //cerr<<"U^-1L^-1 --> "<<t1.usertime()<<endl;