Fast solution of dense linear system of fixed dimension (N=9), symmetric, positive-semidefinite

后端 未结 6 460
旧巷少年郎
旧巷少年郎 2021-01-18 04:10

Which algorithm you would recommend for fast solution of dense linear system of fixed dimension (N=9) (matrix is symmetric, positive-semidefinite)?

  • Gaussian el
6条回答
  •  独厮守ぢ
    2021-01-18 05:10

    Like others above, I recommend cholesky. I've found that the increased number of additions, subtractions and memory accesses means that LDLt is slower than cholesky.

    There are in fact a number a number of variations on cholesky, and which one will be fastest depends on the representation you choose for your matrices. I generally use a fortran style representation, that is a matrix M is a double* M with M(i,j) being m[i+dim*j]; for this I reckon that an upper triangular cholesky is (a little) the fastest, that is one seeks upper triangular U with U'*U = M.

    For fixed, small, dimension it is definitely worth considering writing a version that uses no loops. A relatively straightforward way to do this is to write a program to do it. As I recall, using a routine that deals with the general case as a template, it only took a morning to write a program that would write a specific fixed dimension version. The savings can be considerable. For example my general version takes 0.47 seconds to do a million 9x9 factorisations, while the loopless version takes 0.17 seconds -- these timings running single threaded on a 2.6GHz pc.

    To show that this is not a major task, I've included the source of such a program below. It includes the general version of the factorisation as a comment. I've used this code in circumstances where the matrices are not close to singular, and I reckon it works ok there; however it may well be too crude for more delicate work.

    /*  ----------------------------------------------------------------
    **  to write fixed dimension ut cholesky routines
    **  ----------------------------------------------------------------
    */
    #include    
    #include    
    #include    
    #include    
    #include    
    /*  ----------------------------------------------------------------
    */
    #if 0
    static  inline  double  vec_dot_1_1( int dim, const double* x, const double* y)
    {   
    double  d = 0.0;
        while( --dim >= 0)
        {   d += *x++ * *y++;
        }
        return d;
    }
    
       /*   ----------------------------------------------------------------
        **  ut cholesky: solve U'*U = P for ut U in P (only ut of P accessed)
        **  ----------------------------------------------------------------
        */   
    
    int mat_ut_cholesky( int dim, double* P)
    {
    int i, j;
    double  d;
    double* Ucoli;
    
        for( Ucoli=P, i=0; i

提交回复
热议问题