Show
Ignore:
Timestamp:
09/14/07 10:59:29 (1 year ago)
Author:
pernet
Message:

* minor change to the arith progression charpoly
* introduce fgetrs and fgesv for more general system solving (including rank defficient matrices)

Files:
1 modified

Legend:

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

    r44 r48  
    3030// TransPosed version has to be implemented too. 
    3131#define __FFPACK_LUDIVINE_CUTOFF 0 
     32         
     33#define __FFPACK_CHARPOLY_THRESHOLD 30 
    3234 
    3335        /** 
     
    5658                                   FfpackDanilevski=5, 
    5759                                   FfpackArithProg=6, 
    58                                    FfpackKGFastG=7 
    59         }; 
     60                                   FfpackKGFastG=7}; 
    6061         
    6162        class CharpolyFailed{}; 
    6263         
    6364        enum FFPACK_MINPOLY_TAG { FfpackDense=1, 
    64                                     FfpackKGF=2 }; 
     65                                  FfpackKGF=2}; 
    6566 
    6667        /**  
     
    8081                size_t *P = new size_t[N]; 
    8182                size_t *Q = new size_t[M]; 
    82                 size_t R = LUdivine( F, FflasNonUnit, FflasNoTrans, M, N, A, lda, P, Q, FfpackLQUP); 
     83                size_t R = LUdivine (F, FflasNonUnit, FflasNoTrans, M, N, 
     84                                     A, lda, P, Q, FfpackLQUP); 
    8385                delete[] Q; 
    8486                delete[] P; 
     
    103105                size_t *P = new size_t[N]; 
    104106                size_t *Q = new size_t[M]; 
    105                 bool singular  = !LUdivine( F, FflasNonUnit, FflasNoTrans, M, N, A, lda,  
    106                                             P, Q, FfpackSingular); 
     107                bool singular  = !LUdivine (F, FflasNonUnit, FflasNoTrans, M, N, 
     108                                            A, lda, P, Q, FfpackSingular); 
    107109                 
    108110                delete[] P; 
     
    130132                size_t *P = new size_t[N]; 
    131133                size_t *Q = new size_t[M]; 
    132                 singular  = !LUdivine( F, FflasNonUnit, FflasNoTrans,  M, N, A, lda, P, Q, FfpackSingular); 
     134                singular  = !LUdivine (F, FflasNonUnit, FflasNoTrans,  M, N, 
     135                                       A, lda, P, Q, FfpackSingular); 
    133136                if (singular){ 
    134137                        F.init(det,0.0); 
     
    155158 
    156159        /** 
     160         * Solve the system A X = B or X A = B, using the LQUP decomposition of A 
     161         * already computed inplace with LUdivine(FflasNoTrans, FflasNonUnit). 
     162         * Version for A square. 
     163         * If A is rank deficient, a solution is returned if the system is consistent, 
     164         * Otherwise an info is 1 
     165         *  
     166         * @param Side Determine wheter the resolution is left or right looking. 
     167         * @param M row dimension of B 
     168         * @param N col dimension of B 
     169         * @param R rank of A 
     170         * @param A input matrix 
     171         * @param lda leading dimension of A 
     172         * @param P column permutation of the LQUP decomposition of A 
     173         * @param Q column permutation of the LQUP decomposition of A 
     174         * @param B Right/Left hand side matrix. Initially stores B, finally stores the solution X. 
     175         * @param ldb leading dimension of B 
     176         * @info Succes of the computation: 0 if successfull, >0 if system is inconsistent 
     177         */ 
     178        template <class Field> 
     179        static typename Field::Element * 
     180        fgetrs (const Field& F, 
     181                const FFLAS_SIDE Side, 
     182                const size_t M, const size_t N, const size_t R, 
     183                const Field::Element *A, const size_t lda, 
     184                const size_t *P, const size_t *Q, 
     185                Field::Element *B, const size_t ldb, 
     186                int * info){ 
     187 
     188                static zero; 
     189                F.init (zero, 0.0); 
     190                if (Side == FflasLeft) { // Left looking solve A X = B 
     191 
     192                        SolveLB (F, FflasLeft, M, N, R, A, lda, Q, B, ldb); 
     193 
     194                        applyP (F, FflasLeft, FflasNoTrans, N, 0, R, B, ldb, Q); 
     195 
     196                        bool consistent = true; 
     197                        for (size_t i = R; i < M; ++i) 
     198                                for (size_t j = 0; j < N; ++j) 
     199                                        if (!F.isZero (*(B + i*ldb + j))) 
     200                                                consistent = false; 
     201                        if (!consistent) { 
     202                                std::cerr<<"System is inconsistent"<<std::endl; 
     203                                *info = 1; 
     204                        } 
     205                        // The last rows of B are now supposed to be 0 
     206                        //                      for (size_t i = R; i < M; ++i) 
     207                        //                              for (size_t j = 0; j < N; ++j) 
     208                        //                                      *(B + i*ldb + j) = zero; 
     209 
     210                        ftrsm (F, FflasLeft, FflasUpper, FflasNoTrans, FflasNonUnit,  
     211                               R, N, one, A, lda , B, ldb); 
     212                         
     213                        applyP (F, FflasLeft, FflasTrans, N, 0, R, B, ldb, P); 
     214 
     215                        return B; 
     216                         
     217                } else { // Right Looking X A = B 
     218 
     219                        applyP (F, FflasRight, FflasTrans, M, 0, R, B, ldb, P); 
     220                         
     221                        ftrsm (F, FflasRight, FflasUpper, FflasNoTrans, FflasNonUnit,  
     222                               N, R, one, A, lda , B, ldb); 
     223 
     224                        fgemm (F, FflasNoTrans, FflasNoTrans, M, N-R, R, one, 
     225                               B, ldb, A+R, lda, mone, B+R, ldb); 
     226 
     227                        bool consistent = true; 
     228                        for (size_t i = 0; i < M; ++i) 
     229                                for (size_t j = R; j < N; ++j) 
     230                                        if (!F.isZero (*(B + i*ldb + j))) 
     231                                                consistent = false; 
     232                        if (!consistent) { 
     233                                std::cerr<<"System is inconsistent"<<std::endl; 
     234                                *info = 1; 
     235                        } 
     236                        // The last cols of B are now supposed to be 0 
     237 
     238                        applyP (F, FflasRight, FflasNoTrans, M, 0, R, B, ldb, Q); 
     239 
     240                        SolveLB (F, FflasRight, M, N, R, A, lda, Q, B, ldb); 
     241                } 
     242        } 
     243         
     244        /** 
     245         * Solve the system A X = B or X A = B, using the LQUP decomposition of A 
     246         * already computed inplace with LUdivine(FflasNoTrans, FflasNonUnit). 
     247         * Version for A rectangular. 
     248         * If A is rank deficient, a solution is returned if the system is consistent, 
     249         * Otherwise an info is 1 
     250         *  
     251         * @param Side Determine wheter the resolution is left or right looking. 
     252         * @param M row dimension of A 
     253         * @param N col dimension of A 
     254         * @param NRHS number of columns (if Side = FflasLeft) or row (if Side = FflasRight) of the matrices X and B 
     255         * @param R rank of A 
     256         * @param A input matrix 
     257         * @param lda leading dimension of A 
     258         * @param P column permutation of the LQUP decomposition of A 
     259         * @param Q column permutation of the LQUP decomposition of A 
     260         * @param X solution matrix 
     261         * @param ldx leading dimension of X 
     262         * @param B Right/Left hand side matrix.  
     263         * @param ldb leading dimension of B 
     264         * @info Succes of the computation: 0 if successfull, >0 if system is inconsistent 
     265         */ 
     266        template <class Field> 
     267        static typename Field::Element * 
     268        fgetrs (const Field& F, 
     269                const FFLAS_SIDE Side, 
     270                const size_t M, const size_t N, const size_t NRHS, const size_t R, 
     271                const Field::Element *A, const size_t lda, 
     272                const size_t *P, const size_t *Q, 
     273                Field::Element *X, const size_t ldb, 
     274                const Field::Element *B, const size_t ldb, 
     275                int * info) { 
     276 
     277                static zero; 
     278                F.init (zero, 0.0); 
     279                if (Side == FflasLeft) { // Left looking solve A X = B 
     280 
     281                        for (size_t i=0; i < N; ++i) 
     282                                fcopy (F, NRHS, X + i*ldx, 1, B + i*ldb, 1); 
     283                                
     284                        SolveLB (F, FflasLeft, M, N, R, A, lda, Q, B, ldb); 
     285 
     286                        applyP (F, FflasLeft, FflasNoTrans, N, 0, R, B, ldb, Q); 
     287 
     288                        bool consistent = true; 
     289                        for (size_t i = R; i < M; ++i) 
     290                                for (size_t j = 0; j < N; ++j) 
     291                                        if (!F.isZero (*(B + i*ldb + j))) 
     292                                                consistent = false; 
     293                        if (!consistent) { 
     294                                std::cerr<<"System is inconsistent"<<std::endl; 
     295                                *info = 1; 
     296                        } 
     297                        // The last rows of B are now supposed to be 0 
     298                        //                      for (size_t i = R; i < M; ++i) 
     299                        //                              for (size_t j = 0; j < N; ++j) 
     300                        //                                      *(B + i*ldb + j) = zero; 
     301 
     302                        ftrsm (F, FflasLeft, FflasUpper, FflasNoTrans, FflasNonUnit,  
     303                               R, N, one, A, lda , B, ldb); 
     304                         
     305                        applyP (F, FflasLeft, FflasTrans, N, 0, R, B, ldb, P); 
     306 
     307                        return B; 
     308                         
     309                } else { // Right Looking X A = B 
     310 
     311                        for (size_t i=0; i < NRHS; ++i) 
     312                                fcopy (F, M, X + i*ldx, 1, B + i*ldb, 1); 
     313 
     314                        applyP (F, FflasRight, FflasTrans, M, 0, R, B, ldb, P); 
     315                         
     316                        ftrsm (F, FflasRight, FflasUpper, FflasNoTrans, FflasNonUnit,  
     317                               N, R, one, A, lda , B, ldb); 
     318 
     319                        fgemm (F, FflasNoTrans, FflasNoTrans, M, N-R, R, one, 
     320                               B, ldb, A+R, lda, mone, B+R, ldb); 
     321 
     322                        bool consistent = true; 
     323                        for (size_t i = 0; i < M; ++i) 
     324                                for (size_t j = R; j < N; ++j) 
     325                                        if (!F.isZero (*(B + i*ldb + j))) 
     326                                                consistent = false; 
     327                        if (!consistent) { 
     328                                std::cerr<<"System is inconsistent"<<std::endl; 
     329                                *info = 1; 
     330                        } 
     331                        // The last cols of B are now supposed to be 0 
     332 
     333                        applyP (F, FflasRight, FflasNoTrans, M, 0, R, B, ldb, Q); 
     334 
     335                        SolveLB (F, FflasRight, M, N, R, A, lda, Q, B, ldb); 
     336                } 
     337        } 
     338 
     339        /** 
     340         * @brief Square system solver 
     341         * @param Field The computation domain 
     342         * @param Side Determine wheter the resolution is left or right looking 
     343         * @param M row dimension of B 
     344         * @param N col dimension of B 
     345         * @param A input matrix 
     346         * @param lda leading dimension of A 
     347         * @param P column permutation of the LQUP decomposition of A 
     348         * @param Q column permutation of the LQUP decomposition of A 
     349         * @param B Right/Left hand side matrix. Initially contains B, finally contains the solution X. 
     350         * @param ldb leading dimension of B 
     351         * @info Succes of the computation: 0 if successfull, >0 if system is inconsistent 
     352         * @return a pointer to B 
     353         *  
     354         * Solve the system A X = B or X A = B. 
     355         * Version for A square. 
     356         * If A is rank deficient, a solution is returned if the system is consistent, 
     357         * Otherwise an info is 1 
     358         */ 
     359        template <class Field> 
     360        static typename Field::Element * 
     361        fgesv (const FFLAS_SIDE Side, 
     362               const size_t M, const size_t N, 
     363               const Field::Element *A, const size_t lda, 
     364               Field::Element *B, const size_t ldb, 
     365               int * info){ 
     366 
     367                size_t Na; 
     368                if (Side == FflasLeft) 
     369                        Na = M; 
     370                else 
     371                        Na = N; 
     372                 
     373                size_t P = new size_t[Na]; 
     374                size_t Q = new size_t[Na]; 
     375 
     376                size_t R = LUdivine (F, FflasNonUnit, FflasNoTrans, Na, Na, A, lda, P, Q, FfpackLQUP); 
     377 
     378                fgetrs (F, Side, M, N , R, A, lda, P, Q, B, ldb, info); 
     379                 
     380                delete[] P; 
     381                delete[] Q; 
     382 
     383                return B; 
     384        } 
     385         
     386        /** 
    157387         * Solve the system Ax=b, using LQUP factorization and 
    158388         * two triangular system resolutions. 
     
    172402               typename Field::Element * A, const size_t lda, 
    173403               typename Field::Element * x, const int incx, 
    174                const typename Field::Element * b, const int incb ) 
    175         { 
     404               const typename Field::Element * b, const int incb ){ 
    176405                typename Field::Element one, zero; 
    177406                F.init(one,1.0); 
     
    762991                 typename Field::Element * B, const size_t ldb ){ 
    763992                 
    764                  typename Field::Element one, zero; 
     993                typename Field::Element one, zero; 
    765994                F.init(one, 1.0); 
    766995                F.init(zero, 0.0);