Changeset 3

Show
Ignore:
Timestamp:
03/11/07 15:11:02 (2 years ago)
Author:
pernet
Message:

New algorithm for charpoly: CharpolyArithProg?

- Complete the unfinished preconditionning phase (using complementary subspace comp. and rec. call)
- Exception management for the Las Vegas failure
- set as default for charpoly

Location:
include/fflas-ffpack
Files:
4 modified

Legend:

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

    r1 r3  
    4848                                   FfpackKGFast=4, 
    4949                                   FfpackDanilevski=5, 
    50                                    FfpackKGFastG=6 
     50                                   FfpackArithProg=6, 
     51                                   FfpackKGFastG=7 
    5152        }; 
     53         
     54        class CharpolyFailed{}; 
    5255         
    5356        enum FFPACK_MINPOLY_TAG { FfpackDense=1, 
     
    451454        CharPoly( const Field& F, std::list<Polynomial>& charp, const size_t N, 
    452455                  typename Field::Element * A, const size_t lda, 
    453                   const enum FFPACK_CHARPOLY_TAG CharpTag= FfpackLUK); 
     456                  const enum FFPACK_CHARPOLY_TAG CharpTag= FfpackArithProg); 
    454457         
    455458        //--------------------------------------------------------------------- 
     
    469472 
    470473        // Solve L X = B or X L = B in place 
    471         // L is M*M if Side == FflasLeft and N*N if Side == FflasRigt, B is M*N. 
     474        // L is M*M if Side == FflasLeft and N*N if Side == FflasRight, B is M*N. 
    472475        // Only the R non trivial column of L are stored in the M*R matrix L 
    473476        // Requirement :  so that L could  be expanded in-place 
     
    483486                F.init(one, 1.0); 
    484487                F.init(zero, 0.0); 
     488                size_t LM = (Side == FflasRight)?N:M; 
    485489                for (int i=R-1; i>=0; --i){ 
    486490                        if (  Q[i] > (size_t) i){ 
    487491                                //for (size_t j=0; j<=Q[i]; ++j) 
    488492                                //F.init( *(L+Q[i]+j*ldl), 0 ); 
    489                                 fcopy( F, M-Q[i]-1, L+Q[i]*(ldl+1)+ldl,ldl, L+(Q[i]+1)*ldl+i, ldl ); 
    490                                 for ( size_t j=Q[i]*ldl; j<M*ldl; j+=ldl) 
     493                                //cerr<<"1 deplacement "<<i<<"<-->"<<Q[i]<<endl; 
     494                                fcopy( F, LM-Q[i]-1, L+Q[i]*(ldl+1)+ldl,ldl, L+(Q[i]+1)*ldl+i, ldl ); 
     495                                for ( size_t j=Q[i]*ldl; j<LM*ldl; j+=ldl) 
    491496                                        F.assign( *(L+i+j), zero ); 
    492497                        } 
    493498                } 
    494499                ftrsm( F, Side, FflasLower, FflasNoTrans, FflasUnit, M, N, one, L, ldl , B, ldb); 
    495                  
     500                //write_field(F,cerr<<"dans solveLB "<<endl,L,N,N,ldl); 
    496501                // Undo the permutation of L 
    497502                for (size_t i=0; i<R; ++i){ 
     
    499504                                //for (size_t j=0; j<=Q[i]; ++j) 
    500505                                //F.init( *(L+Q[i]+j*ldl), 0 ); 
    501                                 fcopy( F, M-Q[i]-1, L+(Q[i]+1)*ldl+i, ldl, L+Q[i]*(ldl+1)+ldl,ldl ); 
    502                                 for ( size_t j=Q[i]*ldl; j<M*ldl; j+=ldl) 
     506                                fcopy( F, LM-Q[i]-1, L+(Q[i]+1)*ldl+i, ldl, L+Q[i]*(ldl+1)+ldl,ldl ); 
     507                                for ( size_t j=Q[i]*ldl; j<LM*ldl; j+=ldl) 
    503508                                        F.assign( *(L+Q[i]+j), zero ); 
    504509                        } 
     
    547552                        int j=R-1; 
    548553                        while ( j >=0 ) { 
     554                                //cerr<<"j="<<j<<endl; 
    549555                                k = ib = Q[j]; 
    550556                                while ( (j>=0) &&  (Q[j] == k)  ) {--k;--j;} 
    551557                                Ldim = ib-k; 
     558                                //cerr<<"Ldim, ib, k, N = "<<Ldim<<" "<<ib<<" "<<k<<" "<<N<<endl; 
    552559                                Lcurr = L + j+1 + (k+1)*ldl; 
    553560                                Bcurr = B + ib; 
    554561                                Rcurr = Lcurr + Ldim*ldl; 
    555                                 fgemm( F, FflasNoTrans, FflasNoTrans, M, N-ib-1, Ldim, Mone, Bcurr, ldb, Rcurr, ldl,  one, Bcurr-Ldim, ldb); 
     562                                fgemm (F, FflasNoTrans, FflasNoTrans, M,  Ldim, N-ib-1, Mone, Bcurr, ldb, Rcurr, ldl,  one, Bcurr-Ldim, ldb); 
    556563                                //cerr<<"j avant="<<j<<endl; 
    557564                                //cerr<<"k, ib, j, R "<<k<<" "<<ib<<" "<<j<<" "<<R<<endl; 
    558565                                //cerr<<"M,k="<<M<<" "<<k<<endl; 
    559566                                //cerr<<" ftrsm with M, N="<<Ldim<<" "<<N<<endl; 
    560                                 ftrsm( F, Side, FflasLower, FflasNoTrans, FflasUnit, M, Ldim, one, Lcurr, ldl , Bcurr-Ldim, ldb ); 
     567                                ftrsm (F, Side, FflasLower, FflasNoTrans, FflasUnit, M, Ldim, one, Lcurr, ldl , Bcurr-Ldim, ldb ); 
    561568                                //cerr<<"M,k="<<M<<" "<<k<<endl; 
    562569                                //cerr<<" fgemm with M, N, K="<<M-k<<" "<<N<<" "<<Ldim<<endl; 
     
    581588        template <class Field, class Polynomial> 
    582589        static std::list<Polynomial>& 
    583         Frobenius (const Field& F, std::list<Polynomial>& frobeniusForm,  
    584                    const size_t N, typename Field::Element * A, const size_t lda, const size_t c); 
     590        CharpolyArithProg (const Field& F, std::list<Polynomial>& frobeniusForm,  
     591                           const size_t N, typename Field::Element * A, const size_t lda, const size_t c); 
    585592        template <class Field> 
    586593        static void CompressRows (Field& F, const size_t M, 
  • include/fflas-ffpack/ffpack_charpoly.inl

    r1 r3  
    1111template <class Field, class Polynomial> 
    1212std::list<Polynomial>& 
    13 FFPACK::CharPoly( const Field& F, std::list<Polynomial>& charp, const size_t N, 
    14                             typename Field::Element * A, const size_t lda, 
    15                             const enum FFPACK_CHARPOLY_TAG CharpTag ){ 
    16         switch ( CharpTag ) { 
     13FFPACK::CharPoly (const Field& F, std::list<Polynomial>& charp, const size_t N, 
     14                  typename Field::Element * A, const size_t lda, 
     15                  const enum FFPACK_CHARPOLY_TAG CharpTag){ 
     16        switch (CharpTag) { 
    1717        case FfpackLUK:{ 
    1818                typename Field::Element * X = new typename Field::Element[N*(N+1)]; 
    19                 LUKrylov( F, charp, N, A, lda, X, N); 
     19                LUKrylov (F, charp, N, A, lda, X, N); 
    2020                delete[] X; 
    2121                return charp; 
    2222        } 
    2323        case FfpackKG:{ 
    24                 return KellerGehrig( F, charp, N, A, lda ); 
     24                return KellerGehrig (F, charp, N, A, lda); 
    2525                break; 
    2626        } 
     
    3131        case FfpackKGFast:{ 
    3232                size_t mc, mb, j; 
    33                 if (KGFast( F, charp, N, A, lda, &mc, &mb, &j )){ 
     33                if (KGFast (F, charp, N, A, lda, &mc, &mb, &j)){ 
    3434                        std::cerr<<"NON GENERIC MATRIX PROVIDED TO KELLER-GEHRIG-FAST"<<std::endl; 
    3535                } 
     
    4343        case FfpackHybrid:{ 
    4444                typename Field::Element * X = new typename Field::Element[N*(N+1)]; 
    45                 LUKrylov_KGFast( F, charp, N, A, lda, X, N); 
     45                LUKrylov_KGFast (F, charp, N, A, lda, X, N); 
    4646                delete[] X; 
     47                return charp; 
     48                break; 
     49        } 
     50 
     51        case FfpackArithProg:{ 
     52                size_t attempts=0; 
     53                bool cont = false; 
     54                do{ 
     55                        try { 
     56                                CharpolyArithProg (F, charp, N, A, lda, 30); 
     57                        } 
     58                        catch (CharpolyFailed){ 
     59                                if (attempts<2) 
     60                                        cont = true; 
     61                                else 
     62                                        CharPoly(F, charp, N, A, lda, FfpackLUK); 
     63 
     64                        } 
     65                } while (cont); 
    4766                return charp; 
    4867                break; 
     
    5069        default:{ 
    5170                typename Field::Element * X = new typename Field::Element[N*(N+1)]; 
    52                 LUKrylov( F, charp, N, A, lda, X, N); 
     71                LUKrylov (F, charp, N, A, lda, X, N); 
    5372                delete[] X; 
    5473                return charp; 
     
    6079template <class Field, class Polynomial> 
    6180std::list<Polynomial>& 
    62 FFPACK::LUKrylov( const Field& F, std::list<Polynomial>& charp, const size_t N, 
    63                   typename Field::Element * A, const size_t lda, 
    64                   typename Field::Element * X, const size_t ldx){ 
     81FFPACK::LUKrylov (const Field& F, std::list<Polynomial>& charp, const size_t N, 
     82                 typename Field::Element * A, const size_t lda, 
     83                 typename Field::Element * X, const size_t ldx){ 
    6584         
    6685        typedef typename Field::Element elt; 
     
    7392        charp.clear(); 
    7493        int nbfac = 0; 
    75         while( Ncurr > 0 ){ 
     94        while (Ncurr > 0){ 
    7695                size_t P[Ncurr]; 
    77                 Polynomial minP;//=new  Polynomial(); 
    78                 MinPoly( F, minP, Ncurr, A, lda, X2, ldx, P ); 
     96                Polynomial minP;//=new Polynomial(); 
     97                MinPoly (F, minP, Ncurr, A, lda, X2, ldx, P); 
    7998                int k = minP.size()-1; // degre of minpoly 
    80                 if ( (k==1) && F.isZero( (minP)[0] ) ){ // minpoly is X 
     99                if ((k==1) && F.isZero ((minP)[0])){ // minpoly is X 
    81100                        Ai = A; 
    82101                        int j = Ncurr*Ncurr; 
    83                         while ( j-- && F.isZero(*(Ai++)) ); 
    84                         if ( !j ){ // A is 0, CharPoly=X^n 
     102                        while (j-- && F.isZero(*(Ai++))); 
     103                        if (!j){ // A is 0, CharPoly=X^n 
    85104                                minP.resize(Ncurr+1); 
    86105                                (minP)[1] = zero; 
     
    90109                } 
    91110                nbfac++; 
    92                 charp.push_front( minP ); 
    93                 if ( k==Ncurr ){ 
     111                charp.push_front (minP); 
     112                if (k==Ncurr){ 
    94113                        return charp; 
    95114                } 
     
    97116                elt * X21 = X2 + k*ldx; 
    98117                elt * X22 = X21 + k; 
    99                 //  Compute the n-k last rows of A' = PA^tP^t in X2_ 
     118                // Compute the n-k last rows of A' = PA^tP^t in X2_ 
    100119                // A = A . P^t 
    101                 applyP( F, FflasRight, FflasTrans, Ncurr, 0, k, A, lda, P); 
     120                applyP (F, FflasRight, FflasTrans, Ncurr, 0, k, A, lda, P); 
    102121                // Copy X2_ = (A'_2)^t 
    103                 for ( Xi = X21, Ai = A+k; Xi != X21 + Nrest*ldx; Ai++, Xi+=ldx-Ncurr ) 
    104                         for ( size_t jj=0; jj<Ncurr*lda; jj+=lda ) 
     122                for (Xi = X21, Ai = A+k; Xi != X21 + Nrest*ldx; Ai++, Xi+=ldx-Ncurr) 
     123                        for (size_t jj=0; jj<Ncurr*lda; jj+=lda) 
    105124                                *(Xi++) = *(Ai+jj); 
    106125                // A = A . P : Undo the permutation on A 
    107                 applyP( F, FflasRight, FflasNoTrans, Ncurr, 0, k, A, lda, P); 
    108                 // X2_ = X2_ . P^t (=  ( P A^t P^t )2_ )  
    109                 applyP( F, FflasRight, FflasTrans, Nrest, 0, k, X21, ldx, P); 
     126                applyP (F, FflasRight, FflasNoTrans, Ncurr, 0, k, A, lda, P); 
     127                // X2_ = X2_ . P^t (=  (P A^t P^t)2_)  
     128                applyP (F, FflasRight, FflasTrans, Nrest, 0, k, X21, ldx, P); 
    110129                // X21 = X21 . S1^-1 
    111130                ftrsm(F, FflasRight, FflasUpper, FflasNoTrans, FflasUnit, Nrest, k, 
    112                       one, X2, ldx, X21, ldx);   
     131                      one, X2, ldx, X21, ldx);  
    113132                // Creation of the matrix A2 for recurise call  
    114                 for ( Xi = X22, Ai = A; 
    115                       Xi != X22 + Nrest*ldx; 
    116                       Xi += (ldx-Nrest), Ai += (lda-Nrest) ) 
    117                         for ( size_t jj=0; jj<Nrest; ++jj ) 
     133                for (Xi = X22, Ai = A; 
     134                     Xi != X22 + Nrest*ldx; 
     135                     Xi += (ldx-Nrest), Ai += (lda-Nrest)) 
     136                        for (size_t jj=0; jj<Nrest; ++jj) 
    118137                                *(Ai++) = *(Xi++); 
    119                 fgemm( F, FflasNoTrans, FflasNoTrans, Nrest, Nrest, k, Mone, 
    120                        X21, ldx, X2+k, ldx, one, A, lda ); 
     138                fgemm (F, FflasNoTrans, FflasNoTrans, Nrest, Nrest, k, Mone, 
     139                       X21, ldx, X2+k, ldx, one, A, lda); 
    121140                X2 = X22; 
    122141                Ncurr = Nrest; 
     
    127146template <class Field, class Polynomial> 
    128147std::list<Polynomial>& 
    129 FFPACK::LUKrylov_KGFast( const Field& F, std::list<Polynomial>& charp, const size_t N, 
    130                                   typename Field::Element * A, const size_t lda, 
    131                                   typename Field::Element * X, const size_t ldx){ 
     148FFPACK::LUKrylov_KGFast (const Field& F, std::list<Polynomial>& charp, const size_t N, 
     149                        typename Field::Element * A, const size_t lda, 
     150                        typename Field::Element * X, const size_t ldx){ 
    132151         
    133152        typedef typename Field::Element elt; 
     
    139158        size_t kg_mc, kg_mb, kg_j; 
    140159         
    141         if (!KGFast( F, charp, N, A, lda, &kg_mc, &kg_mb, &kg_j )) 
     160        if (!KGFast (F, charp, N, A, lda, &kg_mc, &kg_mb, &kg_j)) 
    142161                return charp; 
    143162        else{// Matrix A is not generic 
     
    147166                size_t *P = new size_t[N]; 
    148167 
    149                 MinPoly( F, *minP, N, A, lda, X, ldx, P, FfpackKGF, kg_mc, kg_mb, kg_j ); 
     168                MinPoly (F, *minP, N, A, lda, X, ldx, P, FfpackKGF, kg_mc, kg_mb, kg_j); 
    150169                size_t k = minP->size()-1; // degre of minpoly 
    151                 if ( (k==1) && F.isZero( (*minP)[0] ) ){ // minpoly is X 
     170                if ((k==1) && F.isZero ((*minP)[0])){ // minpoly is X 
    152171                        Ai = A; 
    153172                        int j = N*N; 
    154                         while ( j-- && F.isZero(*(Ai++)) ); 
    155                         if ( !j ){ // A is 0, CharPoly=X^n 
     173                        while (j-- && F.isZero(*(Ai++))); 
     174                        if (!j){ // A is 0, CharPoly=X^n 
    156175                                minP->resize(N+1); 
    157176                                (*minP)[1] = zero; 
     
    161180                } 
    162181                 
    163                 if ( k==N ){ 
     182                if (k==N){ 
    164183                        charp.clear(); 
    165184                        charp.push_front(*minP); // CharPoly = MinPoly 
     
    176195                size_t imax = kg_mc+kg_mb; 
    177196                // First Id 
    178                 for ( size_t j = 0; j < lambda; ++j){ 
     197                for (size_t j = 0; j < lambda; ++j){ 
    179198                        for (size_t i=0; i<imax; ++i) 
    180                                 F.assign( *(A+j+i*lda), zero); 
    181                         F.assign( *(A+j+imax*lda), one); 
     199                                F.assign (*(A+j+i*lda), zero); 
     200                        F.assign (*(A+j+imax*lda), one); 
    182201                        for (size_t i=imax+1; i<N; ++i) 
    183                                 F.assign( *(A+j+i*lda), zero); 
     202                                F.assign (*(A+j+i*lda), zero); 
    184203                        ++imax; 
    185204                } 
    186205                // Column block B 
    187206                for (typename Field::Element* Ai=A; Ai<A+N*lda; Ai+=lda) 
    188                         fcopy( F, kg_mb, Ai+lambda, 1, Ai+N-kg_mc-kg_mb, 1 ); 
     207                        fcopy (F, kg_mb, Ai+lambda, 1, Ai+N-kg_mc-kg_mb, 1); 
    189208 
    190209                // Second Id block 
     
    192211                for (size_t j = 0; j< kg_j*kg_mc; ++j){ 
    193212                        for (size_t i = 0; i<imax; ++i) 
    194                                 F.assign( *(A+lambda+kg_mb+j+i*lda), zero ); 
    195                         F.assign( *(A+lambda+kg_mb+j+imax*lda), one ); 
     213                                F.assign (*(A+lambda+kg_mb+j+i*lda), zero); 
     214                        F.assign (*(A+lambda+kg_mb+j+imax*lda), one); 
    196215                        for (size_t i = imax+1; i<N; ++i) 
    197                                 F.assign( *(A+lambda+kg_mb+j+i*lda), zero ); 
     216                                F.assign (*(A+lambda+kg_mb+j+i*lda), zero); 
    198217                        ++imax; 
    199218                } 
    200219                 
    201                 //  Compute the n-k last rows of A' = PA^tP^t in X2_ 
     220                // Compute the n-k last rows of A' = PA^tP^t in X2_ 
    202221                 
    203222                // A = P . A  
    204                 applyP( F, FflasLeft, FflasNoTrans, N, 0, k,  
     223                applyP (F, FflasLeft, FflasNoTrans, N, 0, k,  
    205224                        const_cast<typename Field::Element* &>(A), lda, P); 
    206225                 
    207226                // Copy X2_ = (A'2_) 
    208                 for ( Xi = X21, Ai = A+k*lda; Xi != X21 + Nrest*ldx; Ai+=lda-N, Xi+=ldx-N ){ 
    209                         for ( size_t jj=0; jj<N; ++jj ){ 
     227                for (Xi = X21, Ai = A+k*lda; Xi != X21 + Nrest*ldx; Ai+=lda-N, Xi+=ldx-N){ 
     228                        for (size_t jj=0; jj<N; ++jj){ 
    210229                                *(Xi++) = *(Ai++); 
    211230                        } 
     
    213232 
    214233                // A = P^t . A : Undo the permutation on A 
    215                 applyP( F, FflasLeft, FflasTrans, N, 0, k,  
     234                applyP (F, FflasLeft, FflasTrans, N, 0, k,  
    216235                        const_cast<typename Field::Element* &>(A), lda, P); 
    217236         
    218                 // X2_ = X2_ . P^t (=  ( P A P^t )2_ )  
    219                 applyP( F, FflasRight, FflasTrans, Nrest, 0, k, X21, ldx, P); 
     237                // X2_ = X2_ . P^t (=  (P A P^t)2_)  
     238                applyP (F, FflasRight, FflasTrans, Nrest, 0, k, X21, ldx, P); 
    220239 
    221240                // X21 = X21 . S1^-1 
     
    226245                elt * A2 = new elt[Nrest*Nrest]; 
    227246         
    228                 for ( Xi = X22, A2i = A2; 
    229                       Xi != X22 + Nrest*ldx; 
    230                       Xi += (ldx-Nrest) ){ 
    231                         for ( size_t jj=0; jj<Nrest; ++jj ){ 
     247                for (Xi = X22, A2i = A2; 
     248                     Xi != X22 + Nrest*ldx; 
     249                     Xi += (ldx-Nrest)){ 
     250                        for (size_t jj=0; jj<Nrest; ++jj){ 
    232251                                *(A2i++) = *(Xi++); 
    233252                        } 
    234253                } 
    235                 fgemm( F, FflasNoTrans, FflasNoTrans, Nrest, Nrest, k, Mone, 
    236                        X21, ldx, X+k, ldx, one, A2, Nrest ); 
     254                fgemm (F, FflasNoTrans, FflasNoTrans, Nrest, Nrest, k, Mone, 
     255                       X21, ldx, X+k, ldx, one, A2, Nrest); 
    237256         
    238257                // Recursive call on X22 
    239                 LUKrylov_KGFast( F, charp, Nrest, A2, Nrest, X22, ldx ); 
    240                 charp.push_front( *minP ); 
     258                LUKrylov_KGFast (F, charp, Nrest, A2, Nrest, X22, ldx); 
     259                charp.push_front (*minP); 
    241260                delete[] P; 
    242261                delete[] A2; 
  • include/fflas-ffpack/ffpack_frobenius.inl

    r1 r3  
    1414 
    1515//--------------------------------------------------------------------- 
    16 // Frobenius: Las Vegas algorithm to compute the Frobenius normal form over a large field 
     16// CharpolyArithProg: Las Vegas algorithm to compute the Charpoly normal form over a large field 
    1717//--------------------------------------------------------------------- 
    1818 
     
    146146template <class Field, class Polynomial> 
    147147std::list<Polynomial>& 
    148 FFPACK::Frobenius (const Field& F, std::list<Polynomial>& frobeniusForm,  
    149                    const size_t N, typename Field::Element * A, const size_t lda, const size_t c){ 
     148FFPACK::CharpolyArithProg (const Field& F, std::list<Polynomial>& frobeniusForm,  
     149                           const size_t N, typename Field::Element * A, const size_t lda, const size_t c){ 
    150150         
    151151        static typename Field::Element one, zero, mone; 
     
    156156        size_t * rp = new size_t[2*N]; 
    157157 
    158         size_t noc = static_cast<size_t>(ceil(N/double(c))); 
    159  
    160         // Building the workplace matrix Aw 
     158        size_t noc = static_cast<size_t>(ceil(double(N)/double(c))); 
     159 
     160        // Building the workplace matrix  
    161161        typename Field::Element *K = new typename Field::Element[N*(noc*c)]; 
    162162        typename Field::Element *K2 = new typename Field::Element[N*(noc*c)]; 
     
    170170         
    171171        size_t *dA = new size_t[N]; //PA 
    172         size_t *dK = new size_t[N]; 
     172        //      size_t *dK = new size_t[N]; 
    173173 
    174174 
     
    185185//             K+(c-2)*noc*ldk, ldk, A, lda, zero, K+(c-1)*noc*ldk, ldk); 
    186186 
    187 //      write_field(F,cerr<<"K = "<<endl,K, c*noc,N,ldk); 
    188 //      write_field(F,cerr<<"A = "<<endl,A, N,N,ldk); 
     187        //write_field(F,cerr<<"K = "<<endl,K, c*noc,N,ldk); 
     188        //write_field(F,cerr<<"A = "<<endl,A, N,N,ldk); 
    189189        size_t * Pk = new size_t[N]; 
    190190        size_t * Qk = new size_t[c*noc]; 
     
    193193        size_t w_idx = 0; 
    194194        for (size_t i=0; i<noc; ++i) 
    195                 for (size_t j=0; j<c; ++j) 
    196                         fcopy(F, N, (K2+(w_idx++)*ldk), 1, (K+(i+j*noc)*ldk), 1); 
     195                for (size_t j=0; j<c; ++j, w_idx++) 
     196                        fcopy(F, N, (K2+(w_idx)*ldk), 1, (K+(i+j*noc)*ldk), 1); 
    197197 
    198198        for (size_t i=0; i<noc*c; ++i) 
     
    200200         
    201201        size_t R = LUdivine(F, FflasNonUnit, noc*c, N, K, ldk, Pk, Qk, FfpackLQUP); 
    202         if (R<N){ 
    203                 std::cerr<<"Preconditionning failed; not yet implemented"<<std::endl; 
    204                 exit(-1); 
    205         } 
    206          
     202 
     203        //write_field(F,cerr<<"Apres LUDivine K = "<<endl,K, c*noc,N,ldk); 
     204        // cerr<<"Q = "; 
     205//      for (size_t i=0; i<noc*c; ++i) 
     206//              cerr<<Qk[i]<<" "; 
     207//      cerr<<endl; 
    207208        size_t row_idx = 0; 
    208         size_t * degini = new size_t[noc]; 
     209        size_t * dK = new size_t[noc]; 
    209210        for (size_t i=0; i<noc; ++i) 
    210                 degini[i]=0; 
    211         // size_t * degK = new size_t[c]; 
    212 //      for (size_t i=0; i<c; ++i) 
    213 //              degK[i]=0; 
     211                dK[i]=0; 
    214212         
    215213        size_t i=0; 
    216214        row_idx=0; 
     215        size_t dold = c; 
     216        size_t nb_full_blocks = 0; 
     217        size_t Mk = 0; 
    217218        for (size_t k = 0; k<noc; ++k){ 
    218219                size_t d = 0; 
    219220                while ( (d<c) && (row_idx<R) && (Qk[row_idx] == i)) {i++; row_idx++; d++;} 
    220                 degini[k] = d; 
     221                if (d > dold){ 
     222                        std::cerr << "FAIL in preconditionning phase:" 
     223                             << " degree sequence is not monotonically not increasing" 
     224                             << std::endl; 
     225                        //exit (-1); 
     226                        throw CharpolyFailed(); 
     227                } 
     228                         
     229                dK[k] = dold = d; 
     230                Mk++; 
     231                if (d == c) 
     232                        nb_full_blocks++; 
    221233                i = Qk[row_idx]; 
    222234        } 
    223          
    224 //      for (size_t i = 0; i<N; ++i) 
    225 //              if (Qk[row_idx] == i){ 
    226 //                      degini[i % noc] ++; 
    227 //      //              degK[i/noc] ++; 
    228 //                      row_idx ++; 
     235        //cerr<<"Mk = "<<Mk<<endl; 
     236        // Selection of the last iterate of each block 
     237        size_t bk_idx = 0; 
     238        //write_field (F,cerr<<"Avant fgemm K2 = "<<endl, K2, noc*c, N, ldk); 
     239 
     240        for (size_t i = 0; i < Mk; ++i){ 
     241#if DEBUG 
     242                std::cerr<<"dK ["<<i<<"] = "<<dK[i]<<std::endl; 
     243#endif 
     244                fcopy (F, N, (K2+i*ldk), 1, (K2 + (bk_idx + dK[i]-1)*ldk), 1); 
     245                //cerr<<"(bk_idx+dK[i]-1) = "<<(bk_idx+dK[i]-1)<<endl; 
     246                bk_idx+= c; 
     247        } 
     248 
     249        typename Field::Element* K2b = K2+Mk*ldk; 
     250        // K <- K A^T  
     251