Show
Ignore:
Timestamp:
06/08/07 15:50:40 (2 years ago)
Author:
pernet
Message:

Add new code for Echelon form computations:

- ColumnEchelonForm?
- ReducedColumnEchelonForm?
- ftrtri
- ftrtrm

To be debugged

Files:
1 modified

Legend:

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

    r21 r23  
    2727#define __FFPACK_LUDIVINE_CUTOFF 100 
    2828        /** 
    29          * \brief Set of elimination based routines for dense linear algebra with matrices over finite prime field of characteristic less than 2^26. 
     29         * \brief Set of elimination based routines for dense linear algebra 
     30         * with matrices over finite prime field of characteristic less than 2^26. 
    3031         * 
    31          *  This class only provides a set of static member functions. No instantiation is allowed. 
     32         *  This class only provides a set of static member functions. 
     33         *  No instantiation is allowed. 
    3234         * 
    3335         * It enlarges the set of BLAS routines of the class FFLAS, with higher  
     
    404406                        size_t* P, size_t* Q, const FFPACK_LUDIVINE_TAG LuTag=FfpackLQUP); 
    405407         
     408 
     409 
     410        /** 
     411         * Compute the inverse of a triangular matrix. 
     412         * @param Uplo whether the matrix is upper of lower triangular 
     413         * @param Diag whether the matrix if unit diagonal 
     414         *  
     415         */ 
     416         template<class Field> 
     417         static void 
     418         ftrtri (const Field& F, const FFLAS_UPLO Uplo, const FFLAS_DIAG Diag, 
     419                 const size_t N, typename Field::Element * A, const size_t lda){ 
     420 
     421                 typename Field::Element mone, one; 
     422                 F.init(one,1.0); 
     423                 F.init(mone,-1.0); 
     424                 if ((N == 1) && (Diag == FflasNonUnit)) 
     425                         F.divin (*A); 
     426                 else{ 
     427                         size_t N1 = N/2; 
     428                         size_t N2 = N - N1; 
     429                         ftrtri (F, Uplo, Diag, N1, A, lda); 
     430                         ftrtri (F, Uplo, Diag, N2, A + N1*(lda+1), lda); 
     431                         if (Uplo == FflasUpper){ 
     432                                 ftrmm (F, FflasLeft, Uplo, FflasNoTrans, Diag, N1, N2, 
     433                                        one, A, lda, A + N1, lda); 
     434                                 ftrmm (F, FflasRight, Uplo, FflasNoTrans, Diag, N1, N2, 
     435                                        mone, A + N1*(lda+1), lda, A + N1, lda); 
     436                         } else { 
     437                                 ftrmm (F, FflasLeft, Uplo, FflasNoTrans, Diag, N2, N1, 
     438                                        one, A + N1*(lda+1), lda, A + N1*lda, lda); 
     439                                 ftrmm (F, FflasRight, Uplo, FflasNoTrans, Diag, N2, N1, 
     440                                        mone, A, lda, A + N1*lda, lda); 
     441                         } 
     442                 } 
     443         } 
     444 
     445 
     446        /** 
     447         * Compute the product UL of the upper, resp lower triangular matrices U and L 
     448         * stored one above the other in the square matrix A. 
     449         * The matrix U is supposed to be unit diagonal 
     450         *  
     451         */ 
     452        template<class Field> 
     453        static void 
     454        ftrtrm (const Field& F, const size_t N, typename Field::Element * A, const size_t lda){ 
     455                 
     456                typename Field::Element one; 
     457                F.init(one,1.0); 
     458 
     459                 if (N == 1) 
     460                        return; 
     461                size_t N1 = N/2; 
     462                size_t N2 = N-N1; 
     463                 
     464                ftrtrm (F, N1, A, lda); 
     465                 
     466                fgemm (F, FflasNoTrans, FflasNoTrans, N1, N1, N2, one, 
     467                       A+N1, lda, A+N1*lda, lda, one, A, lda); 
     468                 
     469                ftrmm (F, FflasRight, FflasLower, N1, N2, one, A + N1*(lda+1), lda, A + N1, lda); 
     470                 
     471                ftrmm (F, FflasLeft, FflasUpper, N2, N1, one, A + N1*(lda+1), lda, A + N1*lda, lda); 
     472                 
     473                ftrtrm (F, N2, A + N1*(lda+1), lda); 
     474                 
     475        } 
     476 
     477        /** 
     478         * Compute the Column Echelon form of the input matrix in-place. 
     479         *  
     480         * After the computation A = [ M \ V ] such that AU = C is a column echelon 
     481         * decomposition of A, with U = P^T [  V     ] and C = M + Q [ Ir   ] 
     482         *                                  [ 0 In-r ]               [    0 ] 
     483         */ 
     484        template <class Field> 
     485        static size_t 
     486        ColumnEchelonForm (const Field& F, const size_t M, const size_t N, 
     487                           typename Field::Element * A, const size_t lda, 
     488                           size_t* P, size_t* Q){ 
     489 
     490                typename Field::Element one, mone; 
     491                F.init (one, 1.0); 
     492                F.neg (mone, one); 
     493                size_t r; 
     494 
     495                r = LUdivine (F, FflasUnit, M, N, A, lda, P, Q); 
     496 
     497                ftrtri (F, FflasUpper, FflasUnit, r, A, lda); 
     498 
     499                ftrmm (F, FflasLeft, FflasUpper, FflasNoTrans, FflasUnit, r, N, 
     500                       mone, A, lda, A+r, lda); 
     501 
     502                return r; 
     503 
     504        } 
     505 
     506        /** 
     507         * Compute the Reduced Column Echelon form of the input matrix in-place. 
     508         *  
     509         * After the computation A = [  V  ] such that AU = R is a reduced column echelon 
     510         *                           [ M 0 ] 
     511         * decomposition of A, where U = P^T [  V     ] and R = Q [ Ir   ] 
     512         *                                   [ 0 In-r ]           [ M  0 ] 
     513         */ 
     514         
     515        template <class Field> 
     516        static size_t 
     517        ReducedColumnEchelonForm (const Field& F, const size_t M, const size_t N, 
     518                                  typename Field::Element * A, const size_t lda, 
     519                                  size_t* P, size_t* Q){ 
     520                 
     521                typename Field::Element one, mone; 
     522                F.init (one, 1.0); 
     523                F.neg (mone, one); 
     524                size_t r; 
     525 
     526                r = ColumnEchelonForm (F, M, N, A, lda, P, Q); 
     527 
     528                // M = Q^T M  
     529                for (int i=r-1; i>=0; --i){ 
     530                        if ( Q[i]> (size_t) i ){ 
     531                                fswap( F, i,  
     532                                       A + Q[i]*lda, 1,  
     533                                       A + i*lda, 1 ); 
     534                        } 
     535                } 
     536                 
     537                ftrtri (F, FflasLower, FflasNonUnit, r, A, lda); 
     538                 
     539                ftrmm (F, FflasRight, FflasLower, FflasNoTrans, FflasNonUnit, r, N, 
     540                       one, A, lda, A+r, lda); 
     541 
     542                ftrtrm (F, r, A, lda); 
     543 
     544                return r; 
     545 
     546        } 
     547         
    406548        // Apply a permutation submatrix of P (between ibeg and iend) to a matrix 
    407549        // to (iend-ibeg) vectors of size M stored in A (as column for NoTrans  
     
    582724        } 
    583725 
     726 
    584727        template<class Field> 
    585728        static void trinv_left( const Field& F, const size_t N, const typename Field::Element * L, const size_t ldl,