Changeset 1064 for library/bdm/math

Show
Ignore:
Timestamp:
06/09/10 14:00:40 (14 years ago)
Author:
mido
Message:

astyle applied all over the library

Location:
library/bdm/math
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • library/bdm/math/chmat.cpp

    r811 r1064  
    77 
    88void chmat::add ( const chmat &A2, double w ) { 
    9         bdm_assert_debug ( dim == A2.dim, "Matrices of unequal dimension" ); 
    10         mat pre = concat_vertical ( Ch, sqrt ( w ) * A2.Ch ); 
    11         mat post = zeros ( pre.rows(), pre.cols() ); 
    12         if ( !qr ( pre, post ) ) { 
    13                 bdm_warning ( "Unstable QR in chmat add" ); 
    14         } 
    15         Ch = post ( 0, dim - 1, 0, dim - 1 ); 
     9    bdm_assert_debug ( dim == A2.dim, "Matrices of unequal dimension" ); 
     10    mat pre = concat_vertical ( Ch, sqrt ( w ) * A2.Ch ); 
     11    mat post = zeros ( pre.rows(), pre.cols() ); 
     12    if ( !qr ( pre, post ) ) { 
     13        bdm_warning ( "Unstable QR in chmat add" ); 
     14    } 
     15    Ch = post ( 0, dim - 1, 0, dim - 1 ); 
    1616}; 
    1717 
    1818void chmat::opupdt ( const vec &v, double w ) { 
    1919//TODO see cholupdt in lhotse 
    20         mat Z; 
    21         mat R; 
    22         mat V ( 1, v.length() ); 
    23         V.set_row ( 0, v*sqrt ( w ) ); 
    24         Z = concat_vertical ( Ch, V ); 
    25         qr ( Z, R ); 
    26         Ch = R ( 0, Ch.rows() - 1, 0, Ch.cols() - 1 ); 
     20    mat Z; 
     21    mat R; 
     22    mat V ( 1, v.length() ); 
     23    V.set_row ( 0, v*sqrt ( w ) ); 
     24    Z = concat_vertical ( Ch, V ); 
     25    qr ( Z, R ); 
     26    Ch = R ( 0, Ch.rows() - 1, 0, Ch.cols() - 1 ); 
    2727} 
    2828 
    2929mat chmat::to_mat() const { 
    30         mat F = Ch.T() * Ch; 
    31         return F; 
     30    mat F = Ch.T() * Ch; 
     31    return F; 
    3232} 
    3333 
    3434void chmat::mult_sym ( const mat &C ) { 
    35         bdm_assert_debug ( C.rows() == dim, "Wrong dimension of U" ); 
    36         if ( !qr ( Ch*C.T(), Ch ) ) { 
    37                 bdm_warning ( "QR unstable in chmat mult_sym" ); 
    38         } 
     35    bdm_assert_debug ( C.rows() == dim, "Wrong dimension of U" ); 
     36    if ( !qr ( Ch*C.T(), Ch ) ) { 
     37        bdm_warning ( "QR unstable in chmat mult_sym" ); 
     38    } 
    3939} 
    4040 
    4141void chmat::mult_sym ( const mat &C , chmat &U ) const { 
    42         bdm_assert_debug ( C.rows() == U.dim, "Wrong dimension of U" ); 
    43         if ( !qr ( Ch*C.T(), U.Ch ) ) { 
    44                 bdm_warning ( "QR unstable in chmat mult_sym" ); 
    45         } 
     42    bdm_assert_debug ( C.rows() == U.dim, "Wrong dimension of U" ); 
     43    if ( !qr ( Ch*C.T(), U.Ch ) ) { 
     44        bdm_warning ( "QR unstable in chmat mult_sym" ); 
     45    } 
    4646} 
    4747 
    4848void chmat::mult_sym_t ( const mat &C ) { 
    49         bdm_assert_debug ( C.cols() == dim, "Wrong dimension of U" ); 
    50         if ( !qr ( Ch*C, Ch ) ) { 
    51                 bdm_warning ( "QR unstable in chmat mult_sym" ); 
    52         } 
     49    bdm_assert_debug ( C.cols() == dim, "Wrong dimension of U" ); 
     50    if ( !qr ( Ch*C, Ch ) ) { 
     51        bdm_warning ( "QR unstable in chmat mult_sym" ); 
     52    } 
    5353} 
    5454 
    5555void chmat::mult_sym_t ( const mat &C, chmat &U ) const { 
    56         bdm_assert_debug ( C.cols() == U.dim, "Wrong dimension of U" ); 
    57         if ( !qr ( Ch*C, U.Ch ) ) { 
    58                 bdm_warning ( "QR unstable in chmat mult_sym" ); 
    59         } 
     56    bdm_assert_debug ( C.cols() == U.dim, "Wrong dimension of U" ); 
     57    if ( !qr ( Ch*C, U.Ch ) ) { 
     58        bdm_warning ( "QR unstable in chmat mult_sym" ); 
     59    } 
    6060} 
    6161 
    6262double chmat::logdet() const { 
    63         double ldet = 0.0; 
    64         int i; 
    65         //sum of logs of (possibly negative!) diagonal entries 
    66         for ( i = 0; i < Ch.rows(); i++ ) { 
    67                 ldet += log ( std::fabs ( Ch ( i, i ) ) ); 
    68         } 
    69         return 2*ldet; //compensate for Ch being sqrt() 
     63    double ldet = 0.0; 
     64    int i; 
     65    //sum of logs of (possibly negative!) diagonal entries 
     66    for ( i = 0; i < Ch.rows(); i++ ) { 
     67        ldet += log ( std::fabs ( Ch ( i, i ) ) ); 
     68    } 
     69    return 2*ldet; //compensate for Ch being sqrt() 
    7070} 
    7171 
    7272//TODO can be done more efficiently using BLAS, see triangular matrices 
    7373vec chmat::sqrt_mult ( const vec &v ) const { 
    74         vec pom; 
    75         pom = Ch.T() * v; 
    76         return pom; 
     74    vec pom; 
     75    pom = Ch.T() * v; 
     76    return pom; 
    7777} 
    7878 
    7979double chmat::qform ( const vec &v ) const { 
    80         vec pom; 
    81         pom = Ch * v; 
    82         return pom*pom; 
     80    vec pom; 
     81    pom = Ch * v; 
     82    return pom*pom; 
    8383} 
    8484 
    8585double chmat::invqform ( const vec &v ) const { 
    86         vec pom ( v.length() ); 
    87         forward_substitution ( Ch.T(), v, pom ); 
    88         return pom*pom; 
     86    vec pom ( v.length() ); 
     87    forward_substitution ( Ch.T(), v, pom ); 
     88    return pom*pom; 
    8989} 
    9090 
    9191void chmat::clear() { 
    92         Ch.clear(); 
     92    Ch.clear(); 
    9393} 
    9494 
  • library/bdm/math/chmat.h

    r772 r1064  
    2727protected: 
    2828//! Upper triangle of the cholesky matrix 
    29         mat Ch; 
     29    mat Ch; 
    3030public: 
    3131 
    32         void opupdt ( const vec &v, double w ); 
    33         mat to_mat() const; 
    34         void mult_sym ( const mat &C ); 
    35         //! mult_sym with return value in parameter \c U 
    36         void mult_sym ( const mat &C , chmat &U ) const; 
    37         void mult_sym_t ( const mat &C ); 
    38         //! mult_sym with return value in parameter \c U 
    39         void mult_sym_t ( const mat &C, chmat &U ) const; 
    40         double logdet() const; 
    41         vec sqrt_mult ( const vec &v ) const; 
    42         double qform ( const vec &v ) const; 
    43         double invqform ( const vec &v ) const; 
    44         void clear(); 
    45         //! add another chmat \c A2 with weight \c w. 
    46         void add ( const chmat &A2, double w = 1.0 ); 
    47         //!Inversion in the same form, i.e. cholesky 
    48         void inv ( chmat &Inv ) const   { 
    49                 ( Inv.Ch ) = itpp::inv ( Ch ).T(); 
    50                 Inv.dim = dim; 
    51         }; //Fixme: can be more efficient 
    52         ; 
     32    void opupdt ( const vec &v, double w ); 
     33    mat to_mat() const; 
     34    void mult_sym ( const mat &C ); 
     35    //! mult_sym with return value in parameter \c U 
     36    void mult_sym ( const mat &C , chmat &U ) const; 
     37    void mult_sym_t ( const mat &C ); 
     38    //! mult_sym with return value in parameter \c U 
     39    void mult_sym_t ( const mat &C, chmat &U ) const; 
     40    double logdet() const; 
     41    vec sqrt_mult ( const vec &v ) const; 
     42    double qform ( const vec &v ) const; 
     43    double invqform ( const vec &v ) const; 
     44    void clear(); 
     45    //! add another chmat \c A2 with weight \c w. 
     46    void add ( const chmat &A2, double w = 1.0 ); 
     47    //!Inversion in the same form, i.e. cholesky 
     48    void inv ( chmat &Inv ) const       { 
     49        ( Inv.Ch ) = itpp::inv ( Ch ).T(); 
     50        Inv.dim = dim; 
     51    }; //Fixme: can be more efficient 
     52    ; 
    5353//      void inv ( mat &Inv ); 
    5454 
    55         //! Destructor for future use; 
    56         virtual ~chmat() {}; 
    57         //! 
    58         chmat ( ) : sqmat (), Ch ( ) {}; 
    59         //! Default constructor 
    60         chmat ( const int dim0 ) : sqmat ( dim0 ), Ch ( dim0, dim0 ) {}; 
    61         //! Default constructor 
    62         chmat ( const vec &v ) : sqmat ( v.length() ), Ch ( diag ( sqrt ( v ) ) ) {}; 
    63         //! Copy constructor 
    64         chmat ( const chmat &Ch0 ) : sqmat ( Ch0.dim ), Ch ( Ch0.dim, Ch0.dim ) { 
    65                 Ch = Ch0.Ch; 
    66         } 
     55    //! Destructor for future use; 
     56    virtual ~chmat() {}; 
     57    //! 
     58    chmat ( ) : sqmat (), Ch ( ) {}; 
     59    //! Default constructor 
     60    chmat ( const int dim0 ) : sqmat ( dim0 ), Ch ( dim0, dim0 ) {}; 
     61    //! Default constructor 
     62    chmat ( const vec &v ) : sqmat ( v.length() ), Ch ( diag ( sqrt ( v ) ) ) {}; 
     63    //! Copy constructor 
     64    chmat ( const chmat &Ch0 ) : sqmat ( Ch0.dim ), Ch ( Ch0.dim, Ch0.dim ) { 
     65        Ch = Ch0.Ch; 
     66    } 
    6767 
    68         //! Default constructor (m3k:cholform) 
    69         chmat ( const mat &M ) : sqmat ( M.rows() ), Ch ( M.rows(), M.cols() ) { 
    70                 mat Q; 
    71                 bdm_assert_debug ( M.rows() == M.cols(), "chmat:: input matrix must be square!" ); 
    72                 Ch = chol ( M ); 
    73         } 
     68    //! Default constructor (m3k:cholform) 
     69    chmat ( const mat &M ) : sqmat ( M.rows() ), Ch ( M.rows(), M.cols() ) { 
     70        mat Q; 
     71        bdm_assert_debug ( M.rows() == M.cols(), "chmat:: input matrix must be square!" ); 
     72        Ch = chol ( M ); 
     73    } 
    7474 
    75         /*! 
    76           Some templates require this constructor to compile, but 
    77           it shouldn't actually be called. 
    78           \note may be numerically unstable 
    79         */ 
    80         chmat ( const chmat &M, const ivec &perm ): sqmat(perm.length()) { 
    81                 mat complete = M.to_mat (); 
    82                 mat subs = complete.get_cols(perm); 
    83                 Ch = chol(subs.get_rows(perm)); 
    84         } 
     75    /*! 
     76      Some templates require this constructor to compile, but 
     77      it shouldn't actually be called. 
     78      \note may be numerically unstable 
     79    */ 
     80    chmat ( const chmat &M, const ivec &perm ): sqmat(perm.length()) { 
     81        mat complete = M.to_mat (); 
     82        mat subs = complete.get_cols(perm); 
     83        Ch = chol(subs.get_rows(perm)); 
     84    } 
    8585 
    86         //! Access function 
    87         mat & _Ch() { 
    88                 return Ch; 
    89         } 
    90         //! Access function 
    91         const mat & _Ch() const { 
    92                 return Ch; 
    93         } 
    94         //! Access functions 
    95         void setD ( const vec &nD ) { 
    96                 Ch = diag ( sqrt ( nD ) ); 
    97         } 
    98         //! Access functions 
    99         void setCh ( const vec &chQ ) { 
    100                 bdm_assert_debug ( chQ.length() == dim * dim, "wrong length" ); 
    101                 copy_vector ( dim*dim, chQ._data(), Ch._data() ); 
    102         } 
    103         //! access function 
    104         void setCh ( const chmat &Ch0 ) { 
    105                 Ch = Ch0._Ch(); 
    106                 dim = Ch0.rows(); 
    107         } 
    108         //! access function 
    109         void setCh ( const mat &Ch0 ) { 
    110                 //TODO check if Ch0 is OK!!! 
    111                 Ch = Ch0; 
    112                 dim = Ch0.rows(); 
    113         } 
     86    //! Access function 
     87    mat & _Ch() { 
     88        return Ch; 
     89    } 
     90    //! Access function 
     91    const mat & _Ch() const { 
     92        return Ch; 
     93    } 
     94    //! Access functions 
     95    void setD ( const vec &nD ) { 
     96        Ch = diag ( sqrt ( nD ) ); 
     97    } 
     98    //! Access functions 
     99    void setCh ( const vec &chQ ) { 
     100        bdm_assert_debug ( chQ.length() == dim * dim, "wrong length" ); 
     101        copy_vector ( dim*dim, chQ._data(), Ch._data() ); 
     102    } 
     103    //! access function 
     104    void setCh ( const chmat &Ch0 ) { 
     105        Ch = Ch0._Ch(); 
     106        dim = Ch0.rows(); 
     107    } 
     108    //! access function 
     109    void setCh ( const mat &Ch0 ) { 
     110        //TODO check if Ch0 is OK!!! 
     111        Ch = Ch0; 
     112        dim = Ch0.rows(); 
     113    } 
    114114 
    115         //! Access functions 
    116         void setD ( const vec &nD, int i ) { 
    117                 for ( int j = i; j < nD.length(); j++ ) { 
    118                         Ch ( j, j ) = sqrt ( nD ( j - i ) );    //Fixme can be more general 
    119                 } 
    120         } 
     115    //! Access functions 
     116    void setD ( const vec &nD, int i ) { 
     117        for ( int j = i; j < nD.length(); j++ ) { 
     118            Ch ( j, j ) = sqrt ( nD ( j - i ) );    //Fixme can be more general 
     119        } 
     120    } 
    121121 
    122         //! Operator 
    123         chmat& operator += ( const chmat &A2 ); 
    124         //! Operator 
    125         chmat& operator -= ( const chmat &A2 ); 
    126         //! Operator 
    127         chmat& operator * ( const double &d ) { 
    128                 Ch*sqrt ( d ); 
    129                 return *this; 
    130         }; 
    131         //! Operator 
    132         chmat& operator = ( const chmat &A2 ) { 
    133                 Ch = A2.Ch; 
    134                 dim = A2.dim; 
    135                 return *this; 
    136         } 
    137         //! Operator 
    138         chmat& operator *= ( double x ) { 
    139                 Ch *= sqrt ( x ); 
    140                 return *this; 
    141         }; 
     122    //! Operator 
     123    chmat& operator += ( const chmat &A2 ); 
     124    //! Operator 
     125    chmat& operator -= ( const chmat &A2 ); 
     126    //! Operator 
     127    chmat& operator * ( const double &d ) { 
     128        Ch*sqrt ( d ); 
     129        return *this; 
     130    }; 
     131    //! Operator 
     132    chmat& operator = ( const chmat &A2 ) { 
     133        Ch = A2.Ch; 
     134        dim = A2.dim; 
     135        return *this; 
     136    } 
     137    //! Operator 
     138    chmat& operator *= ( double x ) { 
     139        Ch *= sqrt ( x ); 
     140        return *this; 
     141    }; 
    142142}; 
    143143 
     
    146146//!mapping of add operation to operators 
    147147inline chmat& chmat::operator += ( const chmat & A2 )  { 
    148         this->add ( A2 ); 
    149         return *this; 
     148    this->add ( A2 ); 
     149    return *this; 
    150150} 
    151151//!mapping of negative add operation to operators 
    152152inline chmat& chmat::operator -= ( const chmat & A2 )  { 
    153         this->add ( A2, -1.0 ); 
    154         return *this; 
     153    this->add ( A2, -1.0 ); 
     154    return *this; 
    155155} 
    156156 
  • library/bdm/math/functions.h

    r800 r1064  
    2020//! class representing function \f$f(x) = a\f$, here \c rv is empty 
    2121class constfn : public fnc { 
    22         //! value of the function 
    23         vec val; 
     22    //! value of the function 
     23    vec val; 
    2424 
    2525public: 
    26         //vec eval() {return val;}; 
    27         //! inherited 
    28         vec eval ( const vec &cond ) { 
    29                 return val; 
    30         }; 
    31         //!Default constructor 
    32         constfn ( const vec &val0 ) : fnc(), val ( val0 ) { 
    33                 dimy = val.length(); 
    34                 dimc = 0; 
    35         }; 
     26    //vec eval() {return val;}; 
     27    //! inherited 
     28    vec eval ( const vec &cond ) { 
     29        return val; 
     30    }; 
     31    //!Default constructor 
     32    constfn ( const vec &val0 ) : fnc(), val ( val0 ) { 
     33        dimy = val.length(); 
     34        dimc = 0; 
     35    }; 
    3636}; 
    3737 
    3838//! Class representing function \f$f(x) = Ax+B\f$ 
    3939class linfn: public fnc { 
    40         //! Identification of \f$x\f$ 
    41         RV rv; 
    42         //! Matrix A 
    43         mat A; 
    44         //! vector B 
    45         vec B; 
     40    //! Identification of \f$x\f$ 
     41    RV rv; 
     42    //! Matrix A 
     43    mat A; 
     44    //! vector B 
     45    vec B; 
    4646public : 
    47         vec eval ( const vec &cond ) { 
    48                 bdm_assert_debug ( cond.length() == A.cols(), "linfn::eval Wrong cond." ); 
    49                 return A * cond + B; 
    50         } 
     47    vec eval ( const vec &cond ) { 
     48        bdm_assert_debug ( cond.length() == A.cols(), "linfn::eval Wrong cond." ); 
     49        return A * cond + B; 
     50    } 
    5151 
    5252//              linfn evalsome ( ivec &rvind ); 
    53         //!default constructor 
    54         linfn ( ) : fnc(), A ( ), B () { }; 
    55         //! Set values of \c A and \c B 
    56         void set_parameters ( const mat &A0 , const vec &B0 ) { 
    57                 A = A0; 
    58                 B = B0; 
    59         }; 
    60         void from_setting(const Setting &set){ 
    61                 UI::get(A,set,"A",UI::compulsory); 
    62                 UI::get(B,set,"B",UI::compulsory); 
    63         } 
    64         void validate(){ 
    65                 dimy = A.rows(); 
    66                 dimc = A.cols(); 
    67         } 
    68          
     53    //!default constructor 
     54    linfn ( ) : fnc(), A ( ), B () { }; 
     55    //! Set values of \c A and \c B 
     56    void set_parameters ( const mat &A0 , const vec &B0 ) { 
     57        A = A0; 
     58        B = B0; 
     59    }; 
     60    void from_setting(const Setting &set) { 
     61        UI::get(A,set,"A",UI::compulsory); 
     62        UI::get(B,set,"B",UI::compulsory); 
     63    } 
     64    void validate() { 
     65        dimy = A.rows(); 
     66        dimc = A.cols(); 
     67    } 
     68 
    6969}; 
    7070UIREGISTER(linfn); 
     
    8282class diffbifn: public fnc { 
    8383protected: 
    84         //! Indentifier of the first rv. 
    85         RV rvx; 
    86         //! Indentifier of the second rv. 
    87         RV rvu; 
    88         //! cache for rvx.count() 
    89         int dimx; 
    90         //! cache for rvu.count() 
    91         int dimu; 
     84    //! Indentifier of the first rv. 
     85    RV rvx; 
     86    //! Indentifier of the second rv. 
     87    RV rvu; 
     88    //! cache for rvx.count() 
     89    int dimx; 
     90    //! cache for rvu.count() 
     91    int dimu; 
    9292public: 
    93         //! Evaluates \f$f(x0,u0)\f$ (VS: Do we really need common eval? ) 
    94         vec eval ( const vec &cond ) { 
    95                 bdm_assert_debug ( cond.length() == ( dimx + dimu ), "linfn::eval Wrong cond." ); 
    96                 if ( dimu > 0 ) { 
    97                         return eval ( cond ( 0, dimx - 1 ), cond ( dimx, dimx + dimu - 1 ) );//-1 = end (in matlab) 
    98                 } else { 
    99                         return eval ( cond ( 0, dimx - 1 ), vec ( 0 ) );//-1 = end (in matlab) 
    100                 } 
     93    //! Evaluates \f$f(x0,u0)\f$ (VS: Do we really need common eval? ) 
     94    vec eval ( const vec &cond ) { 
     95        bdm_assert_debug ( cond.length() == ( dimx + dimu ), "linfn::eval Wrong cond." ); 
     96        if ( dimu > 0 ) { 
     97            return eval ( cond ( 0, dimx - 1 ), cond ( dimx, dimx + dimu - 1 ) );//-1 = end (in matlab) 
     98        } else { 
     99            return eval ( cond ( 0, dimx - 1 ), vec ( 0 ) );//-1 = end (in matlab) 
     100        } 
    101101 
    102         } 
     102    } 
    103103 
    104         //! Evaluates \f$f(x0,u0)\f$ 
    105         virtual vec eval ( const vec &x0, const vec &u0 ) { 
    106                 return zeros ( dimy ); 
    107         }; 
    108         //! Evaluates \f$A=\frac{d}{dx}f(x,u)|_{x0,u0}\f$ and writes result into \c A . @param full denotes that even unchanged entries are to be rewritten. When, false only the changed elements are computed. @param x0 numeric value of \f$x\f$, @param u0 numeric value of \f$u\f$ @param A a place where the result will be stored. 
    109         virtual void dfdx_cond ( const vec &x0, const vec &u0, mat &A , bool full = true ) {}; 
    110         //! Evaluates \f$A=\frac{d}{du}f(x,u)|_{x0,u0}\f$ and writes result into \c A . @param full denotes that even unchanged entries are to be rewritten. When, false only the changed elements are computed.        @param x0 numeric value of \f$x\f$, @param u0 numeric value of \f$u\f$ @param A a place where the result will be stored. 
    111         virtual void dfdu_cond ( const vec &x0, const vec &u0, mat &A, bool full = true ) {}; 
    112         //!Default constructor (dimy is not set!) 
    113         diffbifn () : fnc() {}; 
    114         //! access function 
    115         int _dimx() const { 
    116                 return dimx; 
    117         } 
    118         //! access function 
    119         int _dimu() const { 
    120                 return dimu; 
    121         } 
     104    //! Evaluates \f$f(x0,u0)\f$ 
     105    virtual vec eval ( const vec &x0, const vec &u0 ) { 
     106        return zeros ( dimy ); 
     107    }; 
     108    //! Evaluates \f$A=\frac{d}{dx}f(x,u)|_{x0,u0}\f$ and writes result into \c A . @param full denotes that even unchanged entries are to be rewritten. When, false only the changed elements are computed. @param x0 numeric value of \f$x\f$, @param u0 numeric value of \f$u\f$ @param A a place where the result will be stored. 
     109    virtual void dfdx_cond ( const vec &x0, const vec &u0, mat &A , bool full = true ) {}; 
     110    //! Evaluates \f$A=\frac{d}{du}f(x,u)|_{x0,u0}\f$ and writes result into \c A . @param full denotes that even unchanged entries are to be rewritten. When, false only the changed elements are computed.    @param x0 numeric value of \f$x\f$, @param u0 numeric value of \f$u\f$ @param A a place where the result will be stored. 
     111    virtual void dfdu_cond ( const vec &x0, const vec &u0, mat &A, bool full = true ) {}; 
     112    //!Default constructor (dimy is not set!) 
     113    diffbifn () : fnc() {}; 
     114    //! access function 
     115    int _dimx() const { 
     116        return dimx; 
     117    } 
     118    //! access function 
     119    int _dimu() const { 
     120        return dimu; 
     121    } 
    122122}; 
    123123 
     
    125125//TODO can be generalized into multilinear form! 
    126126class bilinfn: public diffbifn { 
    127         mat A; 
    128         mat B; 
     127    mat A; 
     128    mat B; 
    129129public : 
    130         //!\name Constructors 
    131         //!@{ 
     130    //!\name Constructors 
     131    //!@{ 
    132132 
    133         bilinfn () : diffbifn (), A(), B() { } 
     133    bilinfn () : diffbifn (), A(), B() { } 
    134134 
    135         bilinfn ( const mat &A0, const mat &B0 ) { 
    136                 set_parameters ( A0, B0 ); 
    137         } 
     135    bilinfn ( const mat &A0, const mat &B0 ) { 
     136        set_parameters ( A0, B0 ); 
     137    } 
    138138 
    139         //! Alternative initialization 
    140         void set_parameters ( const mat &A0, const mat &B0 ) { 
    141                 bdm_assert ( A0.rows() == B0.rows(), "bilinfn matrices must have the same number of rows" ); 
    142                 A = A0; 
    143                 B = B0; 
    144                 dimy = A.rows(); 
    145                 dimx = A.cols(); 
    146                 dimu = B.cols(); 
    147         } 
    148         //!@} 
     139    //! Alternative initialization 
     140    void set_parameters ( const mat &A0, const mat &B0 ) { 
     141        bdm_assert ( A0.rows() == B0.rows(), "bilinfn matrices must have the same number of rows" ); 
     142        A = A0; 
     143        B = B0; 
     144        dimy = A.rows(); 
     145        dimx = A.cols(); 
     146        dimu = B.cols(); 
     147    } 
     148    //!@} 
    149149 
    150         //!\name Mathematical operations 
    151         //!@{ 
    152         inline vec eval ( const  vec &x0, const vec &u0 ) { 
    153                 bdm_assert_debug ( x0.length() == dimx, "bilinfn::eval Wrong xcond." ); 
    154                 bdm_assert_debug ( u0.length() == dimu, "bilinfn::eval Wrong ucond." ); 
    155                 return A*x0 + B*u0; 
    156         } 
     150    //!\name Mathematical operations 
     151    //!@{ 
     152    inline vec eval ( const  vec &x0, const vec &u0 ) { 
     153        bdm_assert_debug ( x0.length() == dimx, "bilinfn::eval Wrong xcond." ); 
     154        bdm_assert_debug ( u0.length() == dimu, "bilinfn::eval Wrong ucond." ); 
     155        return A*x0 + B*u0; 
     156    } 
    157157 
    158         void dfdx_cond ( const vec &x0, const vec &u0, mat &F, bool full ) { 
    159                 bdm_assert_debug ( ( F.cols() == A.cols() ) && ( F.rows() == A.rows() ), "Allocated F is not compatible." ); 
    160                 if ( full ) F = A;      //else : nothing has changed no need to regenerate 
    161         } 
     158    void dfdx_cond ( const vec &x0, const vec &u0, mat &F, bool full ) { 
     159        bdm_assert_debug ( ( F.cols() == A.cols() ) && ( F.rows() == A.rows() ), "Allocated F is not compatible." ); 
     160        if ( full ) F = A;      //else : nothing has changed no need to regenerate 
     161    } 
    162162 
    163         void dfdu_cond ( const vec &x0, const vec &u0, mat &F,  bool full = true ) { 
    164                 bdm_assert_debug ( ( F.cols() == B.cols() ) && ( F.rows() == B.rows() ), "Allocated F is not compatible." ); 
    165                 if ( full ) F = B;      //else : nothing has changed no need to regenerate 
    166         } 
    167         //!@} 
     163    void dfdu_cond ( const vec &x0, const vec &u0, mat &F,  bool full = true ) { 
     164        bdm_assert_debug ( ( F.cols() == B.cols() ) && ( F.rows() == B.rows() ), "Allocated F is not compatible." ); 
     165        if ( full ) F = B;      //else : nothing has changed no need to regenerate 
     166    } 
     167    //!@} 
    168168}; 
    169169 
  • library/bdm/math/psi.cpp

    r706 r1064  
    1313 
    1414double psi ( double x ) { 
    15         double s, ps, xa, x2; 
    16         int n, k; 
    17         static double a[] = { 
    18                 -0.8333333333333e-01, 
    19                 0.83333333333333333e-02, 
    20                 -0.39682539682539683e-02, 
    21                 0.41666666666666667e-02, 
    22                 -0.75757575757575758e-02, 
    23                 0.21092796092796093e-01, 
    24                 -0.83333333333333333e-01, 
    25                 0.4432598039215686 
    26         }; 
     15    double s, ps, xa, x2; 
     16    int n, k; 
     17    static double a[] = { 
     18        -0.8333333333333e-01, 
     19        0.83333333333333333e-02, 
     20        -0.39682539682539683e-02, 
     21        0.41666666666666667e-02, 
     22        -0.75757575757575758e-02, 
     23        0.21092796092796093e-01, 
     24        -0.83333333333333333e-01, 
     25        0.4432598039215686 
     26    }; 
    2727 
    28         xa = fabs ( x ); 
    29         s = 0.0; 
    30         if ( ( x == ( int ) x ) && ( x <= 0.0 ) ) { 
    31                 ps = 1e308; 
    32                 return ps; 
    33         } 
    34         if ( xa == ( int ) xa ) { 
    35                 n = xa; 
    36                 for ( k = 1; k < n; k++ ) { 
    37                         s += 1.0 / k; 
    38                 } 
    39                 ps =  s - el; 
    40         } else if ( ( xa + 0.5 ) == ( ( int ) ( xa + 0.5 ) ) ) { 
    41                 n = xa - 0.5; 
    42                 for ( k = 1; k <= n; k++ ) { 
    43                         s += 1.0 / ( 2.0 * k - 1.0 ); 
    44                 } 
    45                 ps = 2.0 * s - el - 1.386294361119891; 
    46         } else { 
    47                 if ( xa < 10.0 ) { 
    48                         n = 10 - ( int ) xa; 
    49                         for ( k = 0; k < n; k++ ) { 
    50                                 s += 1.0 / ( xa + k ); 
    51                         } 
    52                         xa += n; 
    53                 } 
    54                 x2 = 1.0 / ( xa * xa ); 
    55                 ps = log ( xa ) - 0.5 / xa + x2 * ( ( ( ( ( ( ( a[7] * x2 + a[6] ) * x2 + a[5] ) * x2 + 
    56                                                         a[4] ) * x2 + a[3] ) * x2 + a[2] ) * x2 + a[1] ) * x2 + a[0] ); 
    57                 ps -= s; 
    58         } 
    59         if ( x < 0.0 ) 
    60                 ps = ps - M_PI * cos ( M_PI * x ) / sin ( M_PI * x ) - 1.0 / x; 
    61         return ps; 
     28    xa = fabs ( x ); 
     29    s = 0.0; 
     30    if ( ( x == ( int ) x ) && ( x <= 0.0 ) ) { 
     31        ps = 1e308; 
     32        return ps; 
     33    } 
     34    if ( xa == ( int ) xa ) { 
     35        n = xa; 
     36        for ( k = 1; k < n; k++ ) { 
     37            s += 1.0 / k; 
     38        } 
     39        ps =  s - el; 
     40    } else if ( ( xa + 0.5 ) == ( ( int ) ( xa + 0.5 ) ) ) { 
     41        n = xa - 0.5; 
     42        for ( k = 1; k <= n; k++ ) { 
     43            s += 1.0 / ( 2.0 * k - 1.0 ); 
     44        } 
     45        ps = 2.0 * s - el - 1.386294361119891; 
     46    } else { 
     47        if ( xa < 10.0 ) { 
     48            n = 10 - ( int ) xa; 
     49            for ( k = 0; k < n; k++ ) { 
     50                s += 1.0 / ( xa + k ); 
     51            } 
     52            xa += n; 
     53        } 
     54        x2 = 1.0 / ( xa * xa ); 
     55        ps = log ( xa ) - 0.5 / xa + x2 * ( ( ( ( ( ( ( a[7] * x2 + a[6] ) * x2 + a[5] ) * x2 + 
     56                                                a[4] ) * x2 + a[3] ) * x2 + a[2] ) * x2 + a[1] ) * x2 + a[0] ); 
     57        ps -= s; 
     58    } 
     59    if ( x < 0.0 ) 
     60        ps = ps - M_PI * cos ( M_PI * x ) / sin ( M_PI * x ) - 1.0 / x; 
     61    return ps; 
    6262} 
  • library/bdm/math/square_mat.cpp

    r737 r1064  
    99 
    1010void fsqmat::opupdt ( const vec &v, double w ) { 
    11         M += outer_product ( v, v * w ); 
     11    M += outer_product ( v, v * w ); 
    1212}; 
    1313mat fsqmat::to_mat() const { 
    14         return M; 
     14    return M; 
    1515}; 
    1616void fsqmat::mult_sym ( const mat &C ) { 
    17         M = C * M * C.T(); 
     17    M = C * M * C.T(); 
    1818}; 
    1919void fsqmat::mult_sym_t ( const mat &C ) { 
    20         M = C.T() * M * C; 
     20    M = C.T() * M * C; 
    2121}; 
    2222void fsqmat::mult_sym ( const mat &C, fsqmat &U ) const { 
    23         U.M = ( C * ( M * C.T() ) ); 
     23    U.M = ( C * ( M * C.T() ) ); 
    2424}; 
    2525void fsqmat::mult_sym_t ( const mat &C, fsqmat &U ) const { 
    26         U.M = ( C.T() * ( M * C ) ); 
     26    U.M = ( C.T() * ( M * C ) ); 
    2727}; 
    2828void fsqmat::inv ( fsqmat &Inv ) const { 
    29         mat IM = itpp::inv ( M ); 
    30         Inv = IM; 
     29    mat IM = itpp::inv ( M ); 
     30    Inv = IM; 
    3131}; 
    3232void fsqmat::clear() { 
    33         M.clear(); 
     33    M.clear(); 
    3434}; 
    3535fsqmat::fsqmat ( const mat &M0 ) : sqmat ( M0.cols() ) { 
    36         bdm_assert_debug ( ( M0.cols() == M0.rows() ), "M0 must be square" ); 
    37         M = M0; 
     36    bdm_assert_debug ( ( M0.cols() == M0.rows() ), "M0 must be square" ); 
     37    M = M0; 
    3838}; 
    3939 
     
    4343 
    4444std::ostream &operator<< ( std::ostream &os, const fsqmat &ld ) { 
    45         os << ld.M << endl; 
    46         return os; 
     45    os << ld.M << endl; 
     46    return os; 
    4747} 
    4848 
    4949 
    5050ldmat::ldmat ( const mat &exL, const vec &exD ) : sqmat ( exD.length() ) { 
    51         D = exD; 
    52         L = exL; 
     51    D = exD; 
     52    L = exL; 
    5353} 
    5454 
     
    5858 
    5959ldmat::ldmat ( const vec D0 ) : sqmat ( D0.length() ) { 
    60         D = D0; 
    61         L = eye ( dim ); 
     60    D = D0; 
     61    L = eye ( dim ); 
    6262} 
    6363 
    6464ldmat::ldmat ( const mat &V ) : sqmat ( V.cols() ) { 
    6565 
    66         bdm_assert_debug ( dim == V.rows(), "ldmat::ldmat matrix V is not square!" ); 
    67  
    68         // L and D will be allocated by ldform() 
    69         //Chol is unstable 
    70         this->ldform ( chol ( V ), ones ( dim ) ); 
     66    bdm_assert_debug ( dim == V.rows(), "ldmat::ldmat matrix V is not square!" ); 
     67 
     68    // L and D will be allocated by ldform() 
     69    //Chol is unstable 
     70    this->ldform ( chol ( V ), ones ( dim ) ); 
    7171} 
    7272 
    7373void ldmat::opupdt ( const vec &v,  double w ) { 
    74         int dim = D.length(); 
    75         double kr; 
    76         vec r = v; 
    77         //beware! it is potentionally dangerous, if ITpp change _behaviour of _data()! 
    78         double *Lraw = L._data(); 
    79         double *Draw = D._data(); 
    80         double *rraw = r._data(); 
    81  
    82         bdm_assert_debug ( v.length() == dim, "LD::ldupdt vector v is not compatible with this ld." ); 
    83  
    84         for ( int i = dim - 1; i >= 0; i-- ) { 
    85                 dydr ( rraw, Lraw + i, &w, Draw + i, rraw + i, 0, i, &kr, 1, dim ); 
    86         } 
     74    int dim = D.length(); 
     75    double kr; 
     76    vec r = v; 
     77    //beware! it is potentionally dangerous, if ITpp change _behaviour of _data()! 
     78    double *Lraw = L._data(); 
     79    double *Draw = D._data(); 
     80    double *rraw = r._data(); 
     81 
     82    bdm_assert_debug ( v.length() == dim, "LD::ldupdt vector v is not compatible with this ld." ); 
     83 
     84    for ( int i = dim - 1; i >= 0; i-- ) { 
     85        dydr ( rraw, Lraw + i, &w, Draw + i, rraw + i, 0, i, &kr, 1, dim ); 
     86    } 
    8787} 
    8888 
    8989std::ostream &operator<< ( std::ostream &os, const ldmat &ld ) { 
    90         os << "L:" << ld.L << endl; 
    91         os << "D:" << ld.D << endl; 
    92         return os; 
     90    os << "L:" << ld.L << endl; 
     91    os << "D:" << ld.D << endl; 
     92    return os; 
    9393} 
    9494 
    9595mat ldmat::to_mat() const { 
    96         int dim = D.length(); 
    97         mat V ( dim, dim ); 
    98         double sum; 
    99         int r, c, cc; 
    100  
    101         for ( r = 0; r < dim; r++ ) { //row cycle 
    102                 for ( c = r; c < dim; c++ ) { 
    103                         //column cycle, using symmetricity => c=r! 
    104                         sum = 0.0; 
    105                         for ( cc = c; cc < dim; cc++ ) { //cycle over the remaining part of the vector 
    106                                 sum += L ( cc, r ) * D ( cc ) * L ( cc, c ); 
    107                                 //here L(cc,r) = L(r,cc)'; 
    108                         } 
    109                         V ( r, c ) = sum; 
    110                         // symmetricity 
    111                         if ( r != c ) { 
    112                                 V ( c, r ) = sum; 
    113                         }; 
    114                 } 
    115         } 
    116         //mat V2 = L.transpose() * diag ( D ) * L; 
    117         return V; 
     96    int dim = D.length(); 
     97    mat V ( dim, dim ); 
     98    double sum; 
     99    int r, c, cc; 
     100 
     101    for ( r = 0; r < dim; r++ ) { //row cycle 
     102        for ( c = r; c < dim; c++ ) { 
     103            //column cycle, using symmetricity => c=r! 
     104            sum = 0.0; 
     105            for ( cc = c; cc < dim; cc++ ) { //cycle over the remaining part of the vector 
     106                sum += L ( cc, r ) * D ( cc ) * L ( cc, c ); 
     107                //here L(cc,r) = L(r,cc)'; 
     108            } 
     109            V ( r, c ) = sum; 
     110            // symmetricity 
     111            if ( r != c ) { 
     112                V ( c, r ) = sum; 
     113            }; 
     114        } 
     115    } 
     116    //mat V2 = L.transpose() * diag ( D ) * L; 
     117    return V; 
    118118} 
    119119 
    120120 
    121121void ldmat::add ( const ldmat &ld2, double w ) { 
    122         int dim = D.length(); 
    123  
    124         bdm_assert_debug ( ld2.D.length() == dim, "LD.add() incompatible sizes of LDs" ); 
    125  
    126         //Fixme can be done more efficiently either via dydr or ldform 
    127         for ( int r = 0; r < dim; r++ ) { 
    128                 // Add columns of ld2.L' (i.e. rows of ld2.L) as dyads weighted by ld2.D 
    129                 this->opupdt ( ld2.L.get_row ( r ), w*ld2.D ( r ) ); 
    130         } 
     122    int dim = D.length(); 
     123 
     124    bdm_assert_debug ( ld2.D.length() == dim, "LD.add() incompatible sizes of LDs" ); 
     125 
     126    //Fixme can be done more efficiently either via dydr or ldform 
     127    for ( int r = 0; r < dim; r++ ) { 
     128        // Add columns of ld2.L' (i.e. rows of ld2.L) as dyads weighted by ld2.D 
     129        this->opupdt ( ld2.L.get_row ( r ), w*ld2.D ( r ) ); 
     130    } 
    131131} 
    132132 
    133133void ldmat::clear() { 
    134         L.clear(); 
    135         for ( int i = 0; i < L.cols(); i++ ) { 
    136                 L ( i, i ) = 1; 
    137         }; 
    138         D.clear(); 
     134    L.clear(); 
     135    for ( int i = 0; i < L.cols(); i++ ) { 
     136        L ( i, i ) = 1; 
     137    }; 
     138    D.clear(); 
    139139} 
    140140 
    141141void ldmat::inv ( ldmat &Inv ) const { 
    142         Inv.clear();   //Inv = zero in LD 
    143         mat U = ltuinv ( L ); 
    144  
    145         Inv.ldform ( U.transpose(), 1.0 / D ); 
     142    Inv.clear();   //Inv = zero in LD 
     143    mat U = ltuinv ( L ); 
     144 
     145    Inv.ldform ( U.transpose(), 1.0 / D ); 
    146146} 
    147147 
    148148void ldmat::mult_sym ( const mat &C ) { 
    149         mat A = L * C.T(); 
    150         this->ldform ( A, D ); 
     149    mat A = L * C.T(); 
     150    this->ldform ( A, D ); 
    151151} 
    152152 
    153153void ldmat::mult_sym_t ( const mat &C ) { 
    154         mat A = L * C; 
    155         this->ldform ( A, D ); 
     154    mat A = L * C; 
     155    this->ldform ( A, D ); 
    156156} 
    157157 
    158158void ldmat::mult_sym ( const mat &C, ldmat &U ) const { 
    159         mat A = L * C.T(); //could be done more efficiently using BLAS 
    160         U.ldform ( A, D ); 
     159    mat A = L * C.T(); //could be done more efficiently using BLAS 
     160    U.ldform ( A, D ); 
    161161} 
    162162 
    163163void ldmat::mult_sym_t ( const mat &C, ldmat &U ) const { 
    164         mat A = L * C; 
    165         /*      vec nD=zeros(U.rows()); 
    166                 nD.replace_mid(0, D); //I case that D < nD*/ 
    167         U.ldform ( A, D ); 
     164    mat A = L * C; 
     165    /*  vec nD=zeros(U.rows()); 
     166        nD.replace_mid(0, D); //I case that D < nD*/ 
     167    U.ldform ( A, D ); 
    168168} 
    169169 
    170170 
    171171double ldmat::logdet() const { 
    172         double ldet = 0.0; 
    173         int i; 
     172    double ldet = 0.0; 
     173    int i; 
    174174// sum logarithms of diagobal elements 
    175         for ( i = 0; i < D.length(); i++ ) { 
    176                 ldet += log ( D ( i ) ); 
    177         }; 
    178         return ldet; 
     175    for ( i = 0; i < D.length(); i++ ) { 
     176        ldet += log ( D ( i ) ); 
     177    }; 
     178    return ldet; 
    179179} 
    180180 
    181181double ldmat::qform ( const vec &v ) const { 
    182         double x = 0.0, sum; 
    183         int i, j; 
    184  
    185         for ( i = 0; i < D.length(); i++ ) { //rows of L 
    186                 sum = 0.0; 
    187                 for ( j = 0; j <= i; j++ ) { 
    188                         sum += L ( i, j ) * v ( j ); 
    189                 } 
    190                 x += D ( i ) * sum * sum; 
    191         }; 
    192         return x; 
     182    double x = 0.0, sum; 
     183    int i, j; 
     184 
     185    for ( i = 0; i < D.length(); i++ ) { //rows of L 
     186        sum = 0.0; 
     187        for ( j = 0; j <= i; j++ ) { 
     188            sum += L ( i, j ) * v ( j ); 
     189        } 
     190        x += D ( i ) * sum * sum; 
     191    }; 
     192    return x; 
    193193} 
    194194 
    195195double ldmat::invqform ( const vec &v ) const { 
    196         double x = 0.0; 
    197         int i; 
    198         vec pom ( v.length() ); 
    199  
    200         backward_substitution ( L.T(), v, pom ); 
    201  
    202         for ( i = 0; i < D.length(); i++ ) { //rows of L 
    203                 x += pom ( i ) * pom ( i ) / D ( i ); 
    204         }; 
    205         return x; 
     196    double x = 0.0; 
     197    int i; 
     198    vec pom ( v.length() ); 
     199 
     200    backward_substitution ( L.T(), v, pom ); 
     201 
     202    for ( i = 0; i < D.length(); i++ ) { //rows of L 
     203        x += pom ( i ) * pom ( i ) / D ( i ); 
     204    }; 
     205    return x; 
    206206} 
    207207 
    208208ldmat& ldmat::operator *= ( double x ) { 
    209         D *= x; 
    210         return *this; 
     209    D *= x; 
     210    return *this; 
    211211} 
    212212 
    213213vec ldmat::sqrt_mult ( const vec &x ) const { 
    214         int i, j; 
    215         vec res ( dim ); 
    216         //double sum; 
    217         for ( i = 0; i < dim; i++ ) {//for each element of result 
    218                 res ( i ) = 0.0; 
    219                 for ( j = i; j < dim; j++ ) {//sum D(j)*L(:,i).*x 
    220                         res ( i ) += sqrt ( D ( j ) ) * L ( j, i ) * x ( j ); 
    221                 } 
    222         } 
     214    int i, j; 
     215    vec res ( dim ); 
     216    //double sum; 
     217    for ( i = 0; i < dim; i++ ) {//for each element of result 
     218        res ( i ) = 0.0; 
     219        for ( j = i; j < dim; j++ ) {//sum D(j)*L(:,i).*x 
     220            res ( i ) += sqrt ( D ( j ) ) * L ( j, i ) * x ( j ); 
     221        } 
     222    } 
    223223//      vec res2 = L.transpose()*diag( sqrt( D ) )*x; 
    224         return res; 
     224    return res; 
    225225} 
    226226 
    227227void ldmat::ldform ( const mat &A, const vec &D0 ) { 
    228         int m = A.rows(); 
    229         int n = A.cols(); 
    230         int mn = ( m < n ) ? m : n ; 
    231  
    232         bdm_assert_debug ( D0.length() == A.rows(), "ldmat::ldform Vector D must have the length as row count of A" ); 
    233  
    234         L = concat_vertical ( zeros ( n, n ), diag ( sqrt ( D0 ) ) * A ); 
    235         D = zeros ( n + m ); 
    236  
    237         //unnecessary big L and D will be made smaller at the end of file 
    238         vec w = zeros ( n + m ); 
    239  
    240         double sum, beta, pom; 
    241  
    242         int cc = 0; 
    243         int i = n; // indexovani o 1 niz, nez v matlabu 
    244         int ii, j, jj; 
    245         while ( ( i > n - mn - cc ) && ( i > 0 ) ) { 
    246                 i--; 
    247                 sum = 0.0; 
    248  
    249                 int last_v = m + i - n + cc + 1; 
    250  
    251                 vec v = zeros ( last_v + 1 ); //prepare v 
    252                 for ( ii = n - cc - 1; ii < m + i + 1; ii++ ) { 
    253                         sum += L ( ii, i ) * L ( ii, i ); 
    254                         v ( ii - n + cc + 1 ) = L ( ii, i ); //assign v 
    255                 } 
    256  
    257                 if ( L ( m + i, i ) == 0 ) 
    258                         beta = sqrt ( sum ); 
    259                 else 
    260                         beta = L ( m + i, i ) + sign ( L ( m + i, i ) ) * sqrt ( sum ); 
    261  
    262                 if ( std::fabs ( beta ) < eps ) { 
    263                         cc++; 
    264                         L.set_row ( n - cc, L.get_row ( m + i ) ); 
    265                         L.set_row ( m + i, zeros ( L.cols() ) ); 
    266                         D ( m + i ) = 0; 
    267                         L ( m + i, i ) = 1; 
    268                         L.set_submatrix ( n - cc, m + i - 1, i, i, 0 ); 
    269                         continue; 
    270                 } 
    271  
    272                 sum -= v ( last_v ) * v ( last_v ); 
    273                 sum /= beta * beta; 
    274                 sum++; 
    275  
    276                 v /= beta; 
    277                 v ( last_v ) = 1; 
    278  
    279                 pom = -2.0 / sum; 
    280                 // echo to venca 
    281  
    282                 for ( j = i; j >= 0; j-- ) { 
    283                         double w_elem = 0; 
    284                         for ( ii = n -  cc; ii <= m + i + 1; ii++ ) 
    285                                 w_elem += v ( ii - n + cc ) * L ( ii - 1, j ); 
    286                         w ( j ) = w_elem * pom; 
    287                 } 
    288  
    289                 for ( ii = n - cc - 1; ii <= m + i; ii++ ) 
    290                         for ( jj = 0; jj < i; jj++ ) 
    291                                 L ( ii, jj ) += v ( ii - n + cc + 1 ) * w ( jj ); 
    292  
    293                 for ( ii = n - cc - 1; ii < m + i; ii++ ) 
    294                         L ( ii, i ) = 0; 
    295  
    296                 L ( m + i, i ) += w ( i ); 
    297                 D ( m + i ) = L ( m + i, i ) * L ( m + i, i ); 
    298  
    299                 for ( ii = 0; ii <= i; ii++ ) 
    300                         L ( m + i, ii ) /= L ( m + i, i ); 
    301         } 
    302  
    303         if ( i >= 0 ) 
    304                 for ( ii = 0; ii < i; ii++ ) { 
    305                         jj = D.length() - 1 - n + ii; 
    306                         D ( jj ) = 0; 
    307                         L.set_row ( jj, zeros ( L.cols() ) ); //TODO: set_row accepts Num_T 
    308                         L ( jj, jj ) = 1; 
    309                 } 
    310  
    311         L.del_rows ( 0, m - 1 ); 
    312         D.del ( 0, m - 1 ); 
    313  
    314         dim = L.rows(); 
     228    int m = A.rows(); 
     229    int n = A.cols(); 
     230    int mn = ( m < n ) ? m : n ; 
     231 
     232    bdm_assert_debug ( D0.length() == A.rows(), "ldmat::ldform Vector D must have the length as row count of A" ); 
     233 
     234    L = concat_vertical ( zeros ( n, n ), diag ( sqrt ( D0 ) ) * A ); 
     235    D = zeros ( n + m ); 
     236 
     237    //unnecessary big L and D will be made smaller at the end of file 
     238    vec w = zeros ( n + m ); 
     239 
     240    double sum, beta, pom; 
     241 
     242    int cc = 0; 
     243    int i = n; // indexovani o 1 niz, nez v matlabu 
     244    int ii, j, jj; 
     245    while ( ( i > n - mn - cc ) && ( i > 0 ) ) { 
     246        i--; 
     247        sum = 0.0; 
     248 
     249        int last_v = m + i - n + cc + 1; 
     250 
     251        vec v = zeros ( last_v + 1 ); //prepare v 
     252        for ( ii = n - cc - 1; ii < m + i + 1; ii++ ) { 
     253            sum += L ( ii, i ) * L ( ii, i ); 
     254            v ( ii - n + cc + 1 ) = L ( ii, i ); //assign v 
     255        } 
     256 
     257        if ( L ( m + i, i ) == 0 ) 
     258            beta = sqrt ( sum ); 
     259        else 
     260            beta = L ( m + i, i ) + sign ( L ( m + i, i ) ) * sqrt ( sum ); 
     261 
     262        if ( std::fabs ( beta ) < eps ) { 
     263            cc++; 
     264            L.set_row ( n - cc, L.get_row ( m + i ) ); 
     265            L.set_row ( m + i, zeros ( L.cols() ) ); 
     266            D ( m + i ) = 0; 
     267            L ( m + i, i ) = 1; 
     268            L.set_submatrix ( n - cc, m + i - 1, i, i, 0 ); 
     269            continue; 
     270        } 
     271 
     272        sum -= v ( last_v ) * v ( last_v ); 
     273        sum /= beta * beta; 
     274        sum++; 
     275 
     276        v /= beta; 
     277        v ( last_v ) = 1; 
     278 
     279        pom = -2.0 / sum; 
     280        // echo to venca 
     281 
     282        for ( j = i; j >= 0; j-- ) { 
     283            double w_elem = 0; 
     284            for ( ii = n -      cc; ii <= m + i + 1; ii++ ) 
     285                w_elem += v ( ii - n + cc ) * L ( ii - 1, j ); 
     286            w ( j ) = w_elem * pom; 
     287        } 
     288 
     289        for ( ii = n - cc - 1; ii <= m + i; ii++ ) 
     290            for ( jj = 0; jj < i; jj++ ) 
     291                L ( ii, jj ) += v ( ii - n + cc + 1 ) * w ( jj ); 
     292 
     293        for ( ii = n - cc - 1; ii < m + i; ii++ ) 
     294            L ( ii, i ) = 0; 
     295 
     296        L ( m + i, i ) += w ( i ); 
     297        D ( m + i ) = L ( m + i, i ) * L ( m + i, i ); 
     298 
     299        for ( ii = 0; ii <= i; ii++ ) 
     300            L ( m + i, ii ) /= L ( m + i, i ); 
     301    } 
     302 
     303    if ( i >= 0 ) 
     304        for ( ii = 0; ii < i; ii++ ) { 
     305            jj = D.length() - 1 - n + ii; 
     306            D ( jj ) = 0; 
     307            L.set_row ( jj, zeros ( L.cols() ) ); //TODO: set_row accepts Num_T 
     308            L ( jj, jj ) = 1; 
     309        } 
     310 
     311    L.del_rows ( 0, m - 1 ); 
     312    D.del ( 0, m - 1 ); 
     313 
     314    dim = L.rows(); 
    315315} 
    316316 
     
    318318 
    319319mat ltuinv ( const mat &L ) { 
    320         int dim = L.cols(); 
    321         mat Il = eye ( dim ); 
    322         int i, j, k, m; 
    323         double s; 
     320    int dim = L.cols(); 
     321    mat Il = eye ( dim ); 
     322    int i, j, k, m; 
     323    double s; 
    324324 
    325325//Fixme blind transcription of ltuinv.m 
    326         for ( k = 1; k < ( dim ); k++ ) { 
    327                 for ( i = 0; i < ( dim - k ); i++ ) { 
    328                         j = i + k; //change in .m 1+1=2, here 0+0+1=1 
    329                         s = L ( j, i ); 
    330                         for ( m = i + 1; m < ( j ); m++ ) { 
    331                                 s += L ( m, i ) * Il ( j, m ); 
    332                         } 
    333                         Il ( j, i ) = -s; 
    334                 } 
    335         } 
    336  
    337         return Il; 
     326    for ( k = 1; k < ( dim ); k++ ) { 
     327        for ( i = 0; i < ( dim - k ); i++ ) { 
     328            j = i + k; //change in .m 1+1=2, here 0+0+1=1 
     329            s = L ( j, i ); 
     330            for ( m = i + 1; m < ( j ); m++ ) { 
     331                s += L ( m, i ) * Il ( j, m ); 
     332            } 
     333            Il ( j, i ) = -s; 
     334        } 
     335    } 
     336 
     337    return Il; 
    338338} 
    339339 
     
    369369********************************************************************/ 
    370370{ 
    371         int j, jm; 
    372         double kD, r0; 
    373         double mzero = 2.2e-16; 
    374         double threshold = 1e-4; 
    375  
    376         if ( fabs ( *Dr ) < mzero ) *Dr = 0; 
    377         r0 = *R; 
    378         *R = 0.0; 
    379         kD = *Df; 
    380         *kr = r0 * *Dr; 
    381         *Df = kD + r0 * ( *kr ); 
    382         if ( *Df > mzero ) { 
    383                 kD /= *Df; 
    384                 *kr /= *Df; 
    385         } else { 
    386                 kD = 1.0; 
    387                 *kr = 0.0; 
    388                 if ( *Df < -threshold ) { 
    389                         bdm_warning ( "Problem in dydr: subraction of dyad results in negative definitness. Likely mistake in calling function." ); 
    390                 } 
    391                 *Df = 0.0; 
    392         } 
    393         *Dr *= kD; 
    394         jm = mx * jl; 
    395         for ( j = m * jl; j < m*jh; j += m ) { 
    396                 r[j] -=  r0 * f[jm]; 
    397                 f[jm] += *kr * r[j]; 
    398                 jm += mx; 
    399         } 
    400 } 
    401  
    402 } 
     371    int j, jm; 
     372    double kD, r0; 
     373    double mzero = 2.2e-16; 
     374    double threshold = 1e-4; 
     375 
     376    if ( fabs ( *Dr ) < mzero ) *Dr = 0; 
     377    r0 = *R; 
     378    *R = 0.0; 
     379    kD = *Df; 
     380    *kr = r0 * *Dr; 
     381    *Df = kD + r0 * ( *kr ); 
     382    if ( *Df > mzero ) { 
     383        kD /= *Df; 
     384        *kr /= *Df; 
     385    } else { 
     386        kD = 1.0; 
     387        *kr = 0.0; 
     388        if ( *Df < -threshold ) { 
     389            bdm_warning ( "Problem in dydr: subraction of dyad results in negative definitness. Likely mistake in calling function." ); 
     390        } 
     391        *Df = 0.0; 
     392    } 
     393    *Dr *= kD; 
     394    jm = mx * jl; 
     395    for ( j = m * jl; j < m*jh; j += m ) { 
     396        r[j] -=  r0 * f[jm]; 
     397        f[jm] += *kr * r[j]; 
     398        jm += mx; 
     399    } 
     400} 
     401 
     402} 
  • library/bdm/math/square_mat.h

    r1015 r1064  
    3535class sqmat { 
    3636public: 
    37         /*! 
    38         * Perfroms a rank-1 update by outer product of vectors: \f$V = V + w v v'\f$. 
    39         * @param  v Vector forming the outer product to be added 
    40         * @param  w weight of updating; can be negative 
    41  
    42         BLAS-2b operation. 
    43         */ 
    44         virtual void opupdt ( const vec &v, double w ) = 0; 
    45  
    46         /*! \brief Conversion to full matrix. 
    47         */ 
    48         virtual mat to_mat() const = 0; 
    49  
    50         /*! \brief Inplace symmetric multiplication by a SQUARE matrix \f$C\f$, i.e. \f$V = C*V*C'\f$ 
    51         @param C multiplying matrix, 
    52         */ 
    53         virtual void mult_sym ( const mat &C ) = 0; 
    54  
    55         /*! \brief Inplace symmetric multiplication by a SQUARE transpose of matrix \f$C\f$, i.e. \f$V = C'*V*C\f$ 
    56         @param C multiplying matrix, 
    57         */ 
    58         virtual void mult_sym_t ( const mat &C ) = 0; 
    59  
    60         /*! 
    61         \brief Logarithm of a determinant. 
    62  
    63         */ 
    64         virtual double logdet() const = 0; 
    65  
    66         /*! 
    67         \brief Multiplies square root of \f$V\f$ by vector \f$x\f$. 
    68  
    69         Used e.g. in generating normal samples. 
    70         */ 
    71         virtual vec sqrt_mult ( const vec &v )  const = 0; 
    72  
    73         /*! 
    74         \brief Evaluates quadratic form \f$x= v'*V*v\f$; 
    75  
    76         */ 
    77         virtual double qform ( const vec &v ) const = 0; 
    78  
    79         /*! 
    80         \brief Evaluates quadratic form \f$x= v'*inv(V)*v\f$; 
    81  
    82         */ 
    83         virtual double invqform ( const vec &v ) const = 0; 
     37    /*! 
     38    * Perfroms a rank-1 update by outer product of vectors: \f$V = V + w v v'\f$. 
     39    * @param  v Vector forming the outer product to be added 
     40    * @param  w weight of updating; can be negative 
     41 
     42    BLAS-2b operation. 
     43    */ 
     44    virtual void opupdt ( const vec &v, double w ) = 0; 
     45 
     46    /*! \brief Conversion to full matrix. 
     47    */ 
     48    virtual mat to_mat() const = 0; 
     49 
     50    /*! \brief Inplace symmetric multiplication by a SQUARE matrix \f$C\f$, i.e. \f$V = C*V*C'\f$ 
     51    @param C multiplying matrix, 
     52    */ 
     53    virtual void mult_sym ( const mat &C ) = 0; 
     54 
     55    /*! \brief Inplace symmetric multiplication by a SQUARE transpose of matrix \f$C\f$, i.e. \f$V = C'*V*C\f$ 
     56    @param C multiplying matrix, 
     57    */ 
     58    virtual void mult_sym_t ( const mat &C ) = 0; 
     59 
     60    /*! 
     61    \brief Logarithm of a determinant. 
     62 
     63    */ 
     64    virtual double logdet() const = 0; 
     65 
     66    /*! 
     67    \brief Multiplies square root of \f$V\f$ by vector \f$x\f$. 
     68 
     69    Used e.g. in generating normal samples. 
     70    */ 
     71    virtual vec sqrt_mult ( const vec &v )  const = 0; 
     72 
     73    /*! 
     74    \brief Evaluates quadratic form \f$x= v'*V*v\f$; 
     75 
     76    */ 
     77    virtual double qform ( const vec &v ) const = 0; 
     78 
     79    /*! 
     80    \brief Evaluates quadratic form \f$x= v'*inv(V)*v\f$; 
     81 
     82    */ 
     83    virtual double invqform ( const vec &v ) const = 0; 
    8484 
    8585//      //! easy version of the 
    8686//      sqmat inv(); 
    8787 
    88         //! Clearing matrix so that it corresponds to zeros. 
    89         virtual void clear() = 0; 
    90  
    91         //! Reimplementing common functions of mat: cols(). 
    92         int cols() const { 
    93                 return dim; 
    94         }; 
    95  
    96         //! Reimplementing common functions of mat: rows(). 
    97         int rows() const { 
    98                 return dim; 
    99         }; 
    100  
    101         //! Destructor for future use; 
    102         virtual ~sqmat() {}; 
    103         //! Default constructor 
    104         sqmat ( const int dim0 ) : dim ( dim0 ) {}; 
    105         //! Default constructor 
    106         sqmat() : dim ( 0 ) {}; 
     88    //! Clearing matrix so that it corresponds to zeros. 
     89    virtual void clear() = 0; 
     90 
     91    //! Reimplementing common functions of mat: cols(). 
     92    int cols() const { 
     93        return dim; 
     94    }; 
     95 
     96    //! Reimplementing common functions of mat: rows(). 
     97    int rows() const { 
     98        return dim; 
     99    }; 
     100 
     101    //! Destructor for future use; 
     102    virtual ~sqmat() {}; 
     103    //! Default constructor 
     104    sqmat ( const int dim0 ) : dim ( dim0 ) {}; 
     105    //! Default constructor 
     106    sqmat() : dim ( 0 ) {}; 
    107107protected: 
    108         //! dimension of the square matrix 
    109         int dim; 
     108    //! dimension of the square matrix 
     109    int dim; 
    110110}; 
    111111 
     
    117117class fsqmat: public sqmat { 
    118118protected: 
    119         //! Full matrix on which the operations are performed 
    120         mat M; 
     119    //! Full matrix on which the operations are performed 
     120    mat M; 
    121121public: 
    122         void opupdt ( const vec &v, double w ); 
    123         mat to_mat() const; 
    124         void mult_sym ( const mat &C ); 
    125         void mult_sym_t ( const mat &C ); 
    126         //! store result of \c mult_sym in external matrix \f$U\f$ 
    127         void mult_sym ( const mat &C, fsqmat &U ) const; 
    128         //! store result of \c mult_sym_t in external matrix \f$U\f$ 
    129         void mult_sym_t ( const mat &C, fsqmat &U ) const; 
    130         void clear(); 
    131  
    132         //! Default initialization 
    133         fsqmat() {}; // mat will be initialized OK 
    134         //! Default initialization with proper size 
    135         fsqmat ( const int dim0 ); // mat will be initialized OK 
    136         //! Constructor 
    137         fsqmat ( const mat &M ); 
    138  
    139         /*! 
    140           Some templates require this constructor to compile, but 
    141           it shouldn't actually be called. 
    142         */ 
    143         fsqmat ( const fsqmat &M, const ivec &perm ) { 
    144                 bdm_error ( "not implemented" ); 
    145         } 
    146  
    147         //! Constructor 
    148         fsqmat ( const vec &d ) : sqmat ( d.length() ) { 
    149                 M = diag ( d ); 
    150         }; 
    151  
    152         //! Destructor for future use; 
    153         virtual ~fsqmat() {}; 
    154  
    155  
    156         /*! \brief Matrix inversion preserving the chosen form. 
    157  
    158         @param Inv a space where the inverse is stored. 
    159  
    160         */ 
    161         void inv ( fsqmat &Inv ) const; 
    162  
    163         double logdet() const { 
    164                 return log ( det ( M ) ); 
    165         }; 
    166         double qform ( const  vec &v ) const { 
    167                 return ( v* ( M*v ) ); 
    168         }; 
    169         double invqform ( const  vec &v ) const { 
    170                 return ( v* ( itpp::inv ( M ) *v ) ); 
    171         }; 
    172         vec sqrt_mult ( const vec &v ) const { 
    173                 mat Ch = chol ( M ); 
    174                 return Ch*v; 
    175         }; 
    176  
    177         //! Add another matrix in fsq form with weight w 
    178         void add ( const fsqmat &fsq2, double w = 1.0 ) { 
    179                 M += fsq2.M; 
    180         }; 
    181  
    182         //! Access functions 
    183         void setD ( const vec &nD ) { 
    184                 M = diag ( nD ); 
    185         } 
    186         //! Access functions 
    187         vec getD () { 
    188                 return diag ( M ); 
    189         } 
    190         //! Access functions 
    191         void setD ( const vec &nD, int i ) { 
    192                 for ( int j = i; j < nD.length(); j++ ) { 
    193                         M ( j, j ) = nD ( j - i );    //Fixme can be more general 
    194                 } 
    195         } 
    196  
    197  
    198         //! add another fsqmat matrix 
    199         fsqmat& operator += ( const fsqmat &A ) { 
    200                 M += A.M; 
    201                 return *this; 
    202         }; 
    203         //! subtrack another fsqmat matrix 
    204         fsqmat& operator -= ( const fsqmat &A ) { 
    205                 M -= A.M; 
    206                 return *this; 
    207         }; 
    208         //! multiply by a scalar 
    209         fsqmat& operator *= ( double x ) { 
    210                 M *= x; 
    211                 return *this; 
    212         }; 
    213  
    214         //! cast to normal mat 
    215         operator mat&() { 
    216                 return M; 
    217         }; 
     122    void opupdt ( const vec &v, double w ); 
     123    mat to_mat() const; 
     124    void mult_sym ( const mat &C ); 
     125    void mult_sym_t ( const mat &C ); 
     126    //! store result of \c mult_sym in external matrix \f$U\f$ 
     127    void mult_sym ( const mat &C, fsqmat &U ) const; 
     128    //! store result of \c mult_sym_t in external matrix \f$U\f$ 
     129    void mult_sym_t ( const mat &C, fsqmat &U ) const; 
     130    void clear(); 
     131 
     132    //! Default initialization 
     133    fsqmat() {}; // mat will be initialized OK 
     134    //! Default initialization with proper size 
     135    fsqmat ( const int dim0 ); // mat will be initialized OK 
     136    //! Constructor 
     137    fsqmat ( const mat &M ); 
     138 
     139    /*! 
     140      Some templates require this constructor to compile, but 
     141      it shouldn't actually be called. 
     142    */ 
     143    fsqmat ( const fsqmat &M, const ivec &perm ) { 
     144        bdm_error ( "not implemented" ); 
     145    } 
     146 
     147    //! Constructor 
     148    fsqmat ( const vec &d ) : sqmat ( d.length() ) { 
     149        M = diag ( d ); 
     150    }; 
     151 
     152    //! Destructor for future use; 
     153    virtual ~fsqmat() {}; 
     154 
     155 
     156    /*! \brief Matrix inversion preserving the chosen form. 
     157 
     158    @param Inv a space where the inverse is stored. 
     159 
     160    */ 
     161    void inv ( fsqmat &Inv ) const; 
     162 
     163    double logdet() const { 
     164        return log ( det ( M ) ); 
     165    }; 
     166    double qform ( const  vec &v ) const { 
     167        return ( v* ( M*v ) ); 
     168    }; 
     169    double invqform ( const  vec &v ) const { 
     170        return ( v* ( itpp::inv ( M ) *v ) ); 
     171    }; 
     172    vec sqrt_mult ( const vec &v ) const { 
     173        mat Ch = chol ( M ); 
     174        return Ch*v; 
     175    }; 
     176 
     177    //! Add another matrix in fsq form with weight w 
     178    void add ( const fsqmat &fsq2, double w = 1.0 ) { 
     179        M += fsq2.M; 
     180    }; 
     181 
     182    //! Access functions 
     183    void setD ( const vec &nD ) { 
     184        M = diag ( nD ); 
     185    } 
     186    //! Access functions 
     187    vec getD () { 
     188        return diag ( M ); 
     189    } 
     190    //! Access functions 
     191    void setD ( const vec &nD, int i ) { 
     192        for ( int j = i; j < nD.length(); j++ ) { 
     193            M ( j, j ) = nD ( j - i );    //Fixme can be more general 
     194        } 
     195    } 
     196 
     197 
     198    //! add another fsqmat matrix 
     199    fsqmat& operator += ( const fsqmat &A ) { 
     200        M += A.M; 
     201        return *this; 
     202    }; 
     203    //! subtrack another fsqmat matrix 
     204    fsqmat& operator -= ( const fsqmat &A ) { 
     205        M -= A.M; 
     206        return *this; 
     207    }; 
     208    //! multiply by a scalar 
     209    fsqmat& operator *= ( double x ) { 
     210        M *= x; 
     211        return *this; 
     212    }; 
     213 
     214    //! cast to normal mat 
     215    operator mat&() { 
     216        return M; 
     217    }; 
    218218 
    219219//              fsqmat& operator = ( const fsqmat &A) {M=A.M; return *this;}; 
    220         //! print full matrix 
    221         friend std::ostream &operator<< ( std::ostream &os, const fsqmat &sq ); 
    222         //!access function 
    223         mat & _M ( ) { 
    224                 return M; 
    225         }; 
     220    //! print full matrix 
     221    friend std::ostream &operator<< ( std::ostream &os, const fsqmat &sq ); 
     222    //!access function 
     223    mat & _M ( ) { 
     224        return M; 
     225    }; 
    226226 
    227227}; 
     
    235235class ldmat: public sqmat { 
    236236public: 
    237         //! Construct by copy of L and D. 
    238         ldmat ( const mat &L, const vec &D ); 
    239         //! Construct by decomposition of full matrix V. 
    240         ldmat ( const mat &V ); 
    241         //! Construct by restructuring of V0 accordint to permutation vector perm. 
    242         ldmat ( const ldmat &V0, const ivec &perm ) : sqmat ( V0.rows() ) { 
    243                 ldform ( V0.L.get_cols ( perm ), V0.D ); 
    244         }; 
    245         //! Construct diagonal matrix with diagonal D0 
    246         ldmat ( vec D0 ); 
    247         //!Default constructor 
    248         ldmat (); 
    249         //! Default initialization with proper size 
    250         ldmat ( const int dim0 ); 
    251  
    252         //! Destructor for future use; 
    253         virtual ~ldmat() {}; 
    254  
    255         // Reimplementation of compulsory operatios 
    256  
    257         void opupdt ( const vec &v, double w ); 
    258         mat to_mat() const; 
    259         void mult_sym ( const mat &C ); 
    260         void mult_sym_t ( const mat &C ); 
    261         //! Add another matrix in LD form with weight w 
    262         void add ( const ldmat &ld2, double w = 1.0 ); 
    263         double logdet() const; 
    264         double qform ( const vec &v ) const; 
    265         double invqform ( const vec &v ) const; 
    266         void clear(); 
    267         vec sqrt_mult ( const vec &v ) const; 
    268  
    269  
    270         /*! \brief Matrix inversion preserving the chosen form. 
    271         @param Inv a space where the inverse is stored. 
    272         */ 
    273         void inv ( ldmat &Inv ) const; 
    274  
    275         /*! \brief Symmetric multiplication of \f$U\f$ by a general matrix \f$C\f$, result of which is stored in the current class. 
    276         @param C matrix to multiply with 
    277         @param U a space where the inverse is stored. 
    278         */ 
    279         void mult_sym ( const mat &C, ldmat &U ) const; 
    280  
    281         /*! \brief Symmetric multiplication of \f$U\f$ by a transpose of a general matrix \f$C\f$, result of which is stored in the current class. 
    282         @param C matrix to multiply with 
    283         @param U a space where the inverse is stored. 
    284         */ 
    285         void mult_sym_t ( const mat &C, ldmat &U ) const; 
    286  
    287  
    288         /*! \brief Transforms general \f$A'D0 A\f$ into pure \f$L'DL\f$ 
    289  
    290         The new decomposition fullfills: \f$A'*diag(D)*A = self.L'*diag(self.D)*self.L\f$ 
    291         @param A general matrix 
    292         @param D0 general vector 
    293         */ 
    294         void ldform ( const mat &A, const vec &D0 ); 
    295  
    296         //! Access functions 
    297         void setD ( const vec &nD ) { 
    298                 D = nD; 
    299         } 
    300         //! Access functions 
    301         void setD ( const vec &nD, int i ) { 
    302                 D.replace_mid ( i, nD );    //Fixme can be more general 
    303         } 
    304         //! Access functions 
    305         void setL ( const vec &nL ) { 
    306                 L = nL; 
    307         } 
     237    //! Construct by copy of L and D. 
     238    ldmat ( const mat &L, const vec &D ); 
     239    //! Construct by decomposition of full matrix V. 
     240    ldmat ( const mat &V ); 
     241    //! Construct by restructuring of V0 accordint to permutation vector perm. 
     242    ldmat ( const ldmat &V0, const ivec &perm ) : sqmat ( V0.rows() ) { 
     243        ldform ( V0.L.get_cols ( perm ), V0.D ); 
     244    }; 
     245    //! Construct diagonal matrix with diagonal D0 
     246    ldmat ( vec D0 ); 
     247    //!Default constructor 
     248    ldmat (); 
     249    //! Default initialization with proper size 
     250    ldmat ( const int dim0 ); 
     251 
     252    //! Destructor for future use; 
     253    virtual ~ldmat() {}; 
     254 
     255    // Reimplementation of compulsory operatios 
     256 
     257    void opupdt ( const vec &v, double w ); 
     258    mat to_mat() const; 
     259    void mult_sym ( const mat &C ); 
     260    void mult_sym_t ( const mat &C ); 
     261    //! Add another matrix in LD form with weight w 
     262    void add ( const ldmat &ld2, double w = 1.0 ); 
     263    double logdet() const; 
     264    double qform ( const vec &v ) const; 
     265    double invqform ( const vec &v ) const; 
     266    void clear(); 
     267    vec sqrt_mult ( const vec &v ) const; 
     268 
     269 
     270    /*! \brief Matrix inversion preserving the chosen form. 
     271    @param Inv a space where the inverse is stored. 
     272    */ 
     273    void inv ( ldmat &Inv ) const; 
     274 
     275    /*! \brief Symmetric multiplication of \f$U\f$ by a general matrix \f$C\f$, result of which is stored in the current class. 
     276    @param C matrix to multiply with 
     277    @param U a space where the inverse is stored. 
     278    */ 
     279    void mult_sym ( const mat &C, ldmat &U ) const; 
     280 
     281    /*! \brief Symmetric multiplication of \f$U\f$ by a transpose of a general matrix \f$C\f$, result of which is stored in the current class. 
     282    @param C matrix to multiply with 
     283    @param U a space where the inverse is stored. 
     284    */ 
     285    void mult_sym_t ( const mat &C, ldmat &U ) const; 
     286 
     287 
     288    /*! \brief Transforms general \f$A'D0 A\f$ into pure \f$L'DL\f$ 
     289 
     290    The new decomposition fullfills: \f$A'*diag(D)*A = self.L'*diag(self.D)*self.L\f$ 
     291    @param A general matrix 
     292    @param D0 general vector 
     293    */ 
     294    void ldform ( const mat &A, const vec &D0 ); 
     295 
     296    //! Access functions 
     297    void setD ( const vec &nD ) { 
     298        D = nD; 
     299    } 
     300    //! Access functions 
     301    void setD ( const vec &nD, int i ) { 
     302        D.replace_mid ( i, nD );    //Fixme can be more general 
     303    } 
     304    //! Access functions 
     305    void setL ( const vec &nL ) { 
     306        L = nL; 
     307    } 
    308308 
    309309//! Access functions 
    310 const vec& _D() const { 
    311         return D; 
    312 } 
     310    const vec& _D() const { 
     311        return D; 
     312    } 
    313313//! Access functions 
    314 const mat& _L() const { 
    315         return L; 
    316 } 
     314    const mat& _L() const { 
     315        return L; 
     316    } 
    317317//! Access functions 
    318 vec& __D() { 
    319         return D; 
    320 } 
     318    vec& __D() { 
     319        return D; 
     320    } 
    321321//! Access functions 
    322 mat& __L() { 
    323         return L; 
    324 } 
    325 void validate(){ 
    326         dim= L.rows(); 
    327 } 
    328  
    329         //! add another ldmat matrix 
    330         ldmat& operator += ( const ldmat &ldA ); 
    331         //! subtract another ldmat matrix 
    332         ldmat& operator -= ( const ldmat &ldA ); 
    333         //! multiply by a scalar 
    334         ldmat& operator *= ( double x ); 
    335  
    336         //! print both \c L and \c D 
    337         friend std::ostream &operator<< ( std::ostream &os, const ldmat &sq ); 
     322    mat& __L() { 
     323        return L; 
     324    } 
     325    void validate() { 
     326        dim= L.rows(); 
     327    } 
     328 
     329    //! add another ldmat matrix 
     330    ldmat& operator += ( const ldmat &ldA ); 
     331    //! subtract another ldmat matrix 
     332    ldmat& operator -= ( const ldmat &ldA ); 
     333    //! multiply by a scalar 
     334    ldmat& operator *= ( double x ); 
     335 
     336    //! print both \c L and \c D 
     337    friend std::ostream &operator<< ( std::ostream &os, const ldmat &sq ); 
    338338 
    339339protected: 
    340         //! Positive vector \f$D\f$ 
    341         vec D; 
    342         //! Lower-triangular matrix \f$L\f$ 
    343         mat L; 
     340    //! Positive vector \f$D\f$ 
     341    vec D; 
     342    //! Lower-triangular matrix \f$L\f$ 
     343    mat L; 
    344344 
    345345}; 
     
    348348//!mapping of add operation to operators 
    349349inline ldmat& ldmat::operator += ( const ldmat & ldA )  { 
    350         this->add ( ldA ); 
    351         return *this; 
     350    this->add ( ldA ); 
     351    return *this; 
    352352} 
    353353//!mapping of negative add operation to operators 
    354354inline ldmat& ldmat::operator -= ( const ldmat & ldA )  { 
    355         this->add ( ldA, -1.0 ); 
    356         return *this; 
     355    this->add ( ldA, -1.0 ); 
     356    return *this; 
    357357} 
    358358