Changeset 477 for library/bdm/math

Show
Ignore:
Timestamp:
08/05/09 14:40:03 (15 years ago)
Author:
mido
Message:

panove, vite, jak jsem peclivej na upravu kodu.. snad se vam bude libit:) konfigurace je v souboru /system/astylerc

Location:
library/bdm/math
Files:
6 modified

Legend:

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

    r455 r477  
    99        mat Z; 
    1010        mat R; 
    11         mat V(1,v.length()); 
    12         V.set_row(0,v*sqrt(w)); 
    13         Z = concat_vertical ( Ch,V ); 
    14         qr ( Z,R ); 
    15         Ch = R ( 0, Ch.rows()-1, 0, Ch.cols()-1 ); 
     11        mat V ( 1, v.length() ); 
     12        V.set_row ( 0, v*sqrt ( w ) ); 
     13        Z = concat_vertical ( Ch, V ); 
     14        qr ( Z, R ); 
     15        Ch = R ( 0, Ch.rows() - 1, 0, Ch.cols() - 1 ); 
    1616}; 
    17 mat chmat::to_mat() const {mat F=Ch.T() *Ch;return F;}; 
     17mat chmat::to_mat() const { 
     18        mat F = Ch.T() * Ch; 
     19        return F; 
     20}; 
    1821void chmat::mult_sym ( const mat &C ) { 
    19         it_assert_debug(C.rows()==dim, "Wrong dimension of U"); 
    20         if(!qr(Ch*C.T(), Ch)) {it_warning("QR unstable in chmat mult_sym");} 
     22        it_assert_debug ( C.rows() == dim, "Wrong dimension of U" ); 
     23        if ( !qr ( Ch*C.T(), Ch ) ) { 
     24                it_warning ( "QR unstable in chmat mult_sym" ); 
     25        } 
    2126}; 
    2227void chmat::mult_sym ( const mat &C , chmat &U ) const { 
    23         it_assert_debug(C.rows()==U.dim, "Wrong dimension of U"); 
    24         if(!qr(Ch*C.T(), U.Ch)) {it_warning("QR unstable in chmat mult_sym");} 
     28        it_assert_debug ( C.rows() == U.dim, "Wrong dimension of U" ); 
     29        if ( !qr ( Ch*C.T(), U.Ch ) ) { 
     30                it_warning ( "QR unstable in chmat mult_sym" ); 
     31        } 
    2532}; 
    2633void chmat::mult_sym_t ( const mat &C ) { 
    27         it_assert_debug(C.cols()==dim, "Wrong dimension of U"); 
    28         if(!qr(Ch*C, Ch)) {it_warning("QR unstable in chmat mult_sym");} 
     34        it_assert_debug ( C.cols() == dim, "Wrong dimension of U" ); 
     35        if ( !qr ( Ch*C, Ch ) ) { 
     36                it_warning ( "QR unstable in chmat mult_sym" ); 
     37        } 
    2938}; 
    3039void chmat::mult_sym_t ( const mat &C, chmat &U ) const { 
    31         it_assert_debug(C.cols()==U.dim, "Wrong dimension of U"); 
    32         if(!qr(Ch*C, U.Ch)) {it_warning("QR unstable in chmat mult_sym");} 
     40        it_assert_debug ( C.cols() == U.dim, "Wrong dimension of U" ); 
     41        if ( !qr ( Ch*C, U.Ch ) ) { 
     42                it_warning ( "QR unstable in chmat mult_sym" ); 
     43        } 
    3344}; 
    3445double chmat::logdet() const { 
    35         double ldet=0.0; int i; 
     46        double ldet = 0.0; 
     47        int i; 
    3648        //sum of logs of (possibly negative!) diagonal entries 
    37         for ( i=0;i<Ch.rows();i++ ) {ldet+=log ( std::fabs ( Ch ( i,i ) ) );} 
     49        for ( i = 0; i < Ch.rows(); i++ ) { 
     50                ldet += log ( std::fabs ( Ch ( i, i ) ) ); 
     51        } 
    3852        return 2*ldet; //compensate for Ch being sqrt() 
    3953}; 
    4054//TODO can be done more efficiently using BLAS, see triangular matrices 
    41 vec chmat::sqrt_mult ( const vec &v ) const {vec pom; pom = Ch*v; return pom;}; 
    42 double chmat::qform ( const vec &v ) const {vec pom; pom = Ch*v; return pom*pom;}; 
    43 double chmat::invqform ( const vec &v ) const { 
    44         vec pom(v.length()); 
    45         forward_substitution(Ch.T(),v,pom); 
     55vec chmat::sqrt_mult ( const vec &v ) const { 
     56        vec pom; 
     57        pom = Ch * v; 
     58        return pom; 
     59}; 
     60double chmat::qform ( const vec &v ) const { 
     61        vec pom; 
     62        pom = Ch * v; 
    4663        return pom*pom; 
    4764}; 
    48 void chmat::clear() {Ch.clear();}; 
     65double chmat::invqform ( const vec &v ) const { 
     66        vec pom ( v.length() ); 
     67        forward_substitution ( Ch.T(), v, pom ); 
     68        return pom*pom; 
     69}; 
     70void chmat::clear() { 
     71        Ch.clear(); 
     72}; 
  • library/bdm/math/chmat.h

    r437 r477  
    4040        void clear(); 
    4141        //! add another chmat \c A2 with weight \c w. 
    42         void add ( const chmat &A2, double w=1.0 ) { 
    43                 it_assert_debug(dim==A2.dim,"Matrices of unequal dimension"); 
    44                 mat pre=concat_vertical(Ch,sqrt(w)*A2.Ch);  
    45                 mat post=zeros(pre.rows(),pre.cols());  
    46                 if(!qr(pre,post)) {it_warning("Unstable QR in chmat add");} 
    47                 Ch=post(0,dim-1,0,dim-1); 
     42        void add ( const chmat &A2, double w = 1.0 ) { 
     43                it_assert_debug ( dim == A2.dim, "Matrices of unequal dimension" ); 
     44                mat pre = concat_vertical ( Ch, sqrt ( w ) * A2.Ch ); 
     45                mat post = zeros ( pre.rows(), pre.cols() ); 
     46                if ( !qr ( pre, post ) ) { 
     47                        it_warning ( "Unstable QR in chmat add" ); 
     48                } 
     49                Ch = post ( 0, dim - 1, 0, dim - 1 ); 
    4850        }; 
    4951        //!Inversion in the same form, i.e. cholesky 
    50         void inv ( chmat &Inv ) const   { ( Inv.Ch ) = itpp::inv ( Ch ).T();}; //Fixme: can be more efficient 
     52        void inv ( chmat &Inv ) const   { 
     53                ( Inv.Ch ) = itpp::inv ( Ch ).T(); 
     54        }; //Fixme: can be more efficient 
    5155        ; 
    5256//      void inv ( mat &Inv ); 
     
    5559        virtual ~chmat() {}; 
    5660        //! 
    57         chmat ( ) : sqmat (),Ch ( ) {}; 
     61        chmat ( ) : sqmat (), Ch ( ) {}; 
    5862        //! Default constructor 
    59         chmat ( const int dim0 ) : sqmat ( dim0 ),Ch ( dim0,dim0 ) {}; 
     63        chmat ( const int dim0 ) : sqmat ( dim0 ), Ch ( dim0, dim0 ) {}; 
    6064        //! Default constructor 
    61         chmat ( const vec &v) : sqmat ( v.length() ),Ch ( diag(sqrt(v)) ) {}; 
     65        chmat ( const vec &v ) : sqmat ( v.length() ), Ch ( diag ( sqrt ( v ) ) ) {}; 
    6266        //! Copy constructor 
    63         chmat ( const chmat &Ch0) : sqmat ( Ch0.dim),Ch ( Ch0.dim,Ch0.dim ) {Ch=Ch0.Ch;}; 
     67        chmat ( const chmat &Ch0 ) : sqmat ( Ch0.dim ), Ch ( Ch0.dim, Ch0.dim ) { 
     68                Ch = Ch0.Ch; 
     69        }; 
    6470        //! Default constructor (m3k:cholform) 
    65         chmat ( const mat &M ) : sqmat ( M.rows() ),Ch ( M.rows(),M.cols() ) { 
     71        chmat ( const mat &M ) : sqmat ( M.rows() ), Ch ( M.rows(), M.cols() ) { 
    6672                mat Q; 
    67                 it_assert_debug ( M.rows() ==M.cols(),"chmat:: input matrix must be square!" ); 
    68                 Ch=chol ( M ); 
     73                it_assert_debug ( M.rows() == M.cols(), "chmat:: input matrix must be square!" ); 
     74                Ch = chol ( M ); 
    6975        }; 
    7076        //! Constructor 
    71         chmat ( const chmat &M, const ivec &perm ):sqmat(M.rows()){it_error("not implemneted");}; 
     77        chmat ( const chmat &M, const ivec &perm ) : sqmat ( M.rows() ) { 
     78                it_error ( "not implemneted" ); 
     79        }; 
    7280        //! Access function 
    73         mat & _Ch() {return Ch;} 
     81        mat & _Ch() { 
     82                return Ch; 
     83        } 
    7484        //! Access function 
    75         const mat & _Ch() const {return Ch;} 
     85        const mat & _Ch() const { 
     86                return Ch; 
     87        } 
    7688        //! Access functions 
    77         void setD ( const vec &nD ) {Ch=diag ( sqrt(nD) );} 
     89        void setD ( const vec &nD ) { 
     90                Ch = diag ( sqrt ( nD ) ); 
     91        } 
    7892        //! Access functions 
    7993        void setCh ( const vec &chQ ) { 
    80                 it_assert_debug(chQ.length()==dim*dim,"");  
    81                 copy_vector(dim*dim, chQ._data(), Ch._data());  
     94                it_assert_debug ( chQ.length() == dim*dim, "" ); 
     95                copy_vector ( dim*dim, chQ._data(), Ch._data() ); 
    8296        } 
    8397        //! Access functions 
    84         void setD ( const vec &nD, int i ) {for ( int j=i;j<nD.length();j++ ) {Ch( j,j ) =sqrt(nD ( j-i ));}} //Fixme can be more general 
     98        void setD ( const vec &nD, int i ) { 
     99                for ( int j = i; j < nD.length(); j++ ) { 
     100                        Ch ( j, j ) = sqrt ( nD ( j - i ) );    //Fixme can be more general 
     101                } 
     102        } 
    85103 
    86104        //! Operators 
    87105        chmat& operator += ( const chmat &A2 ); 
    88106        chmat& operator -= ( const chmat &A2 ); 
    89         chmat& operator * ( const double &d ){Ch*sqrt(d); return *this;}; 
    90         chmat& operator = ( const chmat &A2 ){Ch=A2.Ch;dim=A2.dim;return *this;} 
    91         chmat& operator *= ( double x ){Ch*=sqrt(x); return *this;}; 
     107        chmat& operator * ( const double &d ) { 
     108                Ch*sqrt ( d ); 
     109                return *this; 
     110        }; 
     111        chmat& operator = ( const chmat &A2 ) { 
     112                Ch = A2.Ch; 
     113                dim = A2.dim; 
     114                return *this; 
     115        } 
     116        chmat& operator *= ( double x ) { 
     117                Ch *= sqrt ( x ); 
     118                return *this; 
     119        }; 
    92120}; 
    93121 
     
    95123//////// Operations: 
    96124//!mapping of add operation to operators 
    97 inline chmat& chmat::operator += ( const chmat &A2 )  {this->add ( A2 );return *this;} 
     125inline chmat& chmat::operator += ( const chmat & A2 )  { 
     126        this->add ( A2 ); 
     127        return *this; 
     128} 
    98129//!mapping of negative add operation to operators 
    99 inline chmat& chmat::operator -= ( const chmat &A2 )  {this->add ( A2,-1.0 );return *this;} 
     130inline chmat& chmat::operator -= ( const chmat & A2 )  { 
     131        this->add ( A2, -1.0 ); 
     132        return *this; 
     133} 
    100134 
    101135#endif // CHMAT_H 
  • library/bdm/math/functions.h

    r384 r477  
    1515#include "../base/bdmbase.h" 
    1616 
    17 namespace bdm{ 
     17namespace bdm { 
    1818 
    1919//! class representing function \f$f(x) = a\f$, here \c rv is empty 
    20 class constfn : public fnc 
    21 { 
    22                 //! value of the function 
    23                 vec val; 
     20class constfn : public fnc { 
     21        //! value of the function 
     22        vec val; 
    2423 
    25         public: 
    26                 //vec eval() {return val;}; 
    27                 //! inherited 
    28                 vec eval ( const vec &cond ) {return val;}; 
    29                 //!Default constructor 
    30                 constfn ( const vec &val0 ) :fnc(), val ( val0 ) {dimy=val.length();}; 
     24public: 
     25        //vec eval() {return val;}; 
     26        //! inherited 
     27        vec eval ( const vec &cond ) { 
     28                return val; 
     29        }; 
     30        //!Default constructor 
     31        constfn ( const vec &val0 ) : fnc(), val ( val0 ) { 
     32                dimy = val.length(); 
     33        }; 
    3134}; 
    3235 
    3336//! Class representing function \f$f(x) = Ax+B\f$ 
    34 class linfn: public fnc 
    35 { 
    36                 //! Identification of \f$x\f$ 
    37                 RV rv; 
    38                 //! Matrix A 
    39                 mat A; 
    40                 //! vector B 
    41                 vec B; 
    42         public : 
    43                 vec eval (const vec &cond ) {it_assert_debug ( cond.length() ==A.cols(), "linfn::eval Wrong cond." );return A*cond+B;}; 
     37class linfn: public fnc { 
     38        //! Identification of \f$x\f$ 
     39        RV rv; 
     40        //! Matrix A 
     41        mat A; 
     42        //! vector B 
     43        vec B; 
     44public : 
     45        vec eval ( const vec &cond ) { 
     46                it_assert_debug ( cond.length() == A.cols(), "linfn::eval Wrong cond." ); 
     47                return A*cond + B; 
     48        }; 
    4449 
    4550//              linfn evalsome ( ivec &rvind ); 
    46                 //!default constructor 
    47                 linfn ( ) : fnc(), A ( ),B () { }; 
    48                 //! Set values of \c A and \c B 
    49                 void set_parameters ( const mat &A0 , const vec &B0 ) {A=A0; B=B0; dimy=A.rows();}; 
     51        //!default constructor 
     52        linfn ( ) : fnc(), A ( ), B () { }; 
     53        //! Set values of \c A and \c B 
     54        void set_parameters ( const mat &A0 , const vec &B0 ) { 
     55                A = A0; 
     56                B = B0; 
     57                dimy = A.rows(); 
     58        }; 
    5059}; 
    5160 
     
    60692) It could be generalized into multivariate form, (which was original meaning of \c fnc ). 
    6170*/ 
    62 class diffbifn: public fnc 
    63 { 
    64         protected: 
    65                 //! Indentifier of the first rv. 
    66                 RV rvx; 
    67                 //! Indentifier of the second rv. 
    68                 RV rvu; 
    69                 //! cache for rvx.count() 
    70                 int dimx; 
    71                 //! cache for rvu.count() 
    72                 int dimu; 
    73         public: 
    74                 //! Evaluates \f$f(x0,u0)\f$ (VS: Do we really need common eval? ) 
    75                 vec eval ( const vec &cond ) 
    76                 { 
    77                         it_assert_debug ( cond.length() == ( dimx+dimu ), "linfn::eval Wrong cond." ); 
    78                         return eval ( cond ( 0,dimx-1 ),cond ( dimx,dimx+dimu-1 ) );//-1 = end (in matlab) 
    79                 }; 
     71class diffbifn: public fnc { 
     72protected: 
     73        //! Indentifier of the first rv. 
     74        RV rvx; 
     75        //! Indentifier of the second rv. 
     76        RV rvu; 
     77        //! cache for rvx.count() 
     78        int dimx; 
     79        //! cache for rvu.count() 
     80        int dimu; 
     81public: 
     82        //! Evaluates \f$f(x0,u0)\f$ (VS: Do we really need common eval? ) 
     83        vec eval ( const vec &cond ) { 
     84                it_assert_debug ( cond.length() == ( dimx + dimu ), "linfn::eval Wrong cond." ); 
     85                return eval ( cond ( 0, dimx - 1 ), cond ( dimx, dimx + dimu - 1 ) );//-1 = end (in matlab) 
     86        }; 
    8087 
    81                 //! Evaluates \f$f(x0,u0)\f$ 
    82                 virtual vec eval ( const vec &x0, const vec &u0 ) {return zeros ( dimy );}; 
    83                 //! 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. 
    84                 virtual void dfdx_cond ( const vec &x0, const vec &u0, mat &A , bool full=true ) {}; 
    85                 //! 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. 
    86                 virtual void dfdu_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {}; 
    87                 //!Default constructor (dimy is not set!) 
    88                 diffbifn () : fnc() {}; 
    89                 //! access function 
    90                 int _dimx() const{return dimx;} 
    91                 //! access function 
    92                 int _dimu() const{return dimu;} 
     88        //! Evaluates \f$f(x0,u0)\f$ 
     89        virtual vec eval ( const vec &x0, const vec &u0 ) { 
     90                return zeros ( dimy ); 
     91        }; 
     92        //! 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. 
     93        virtual void dfdx_cond ( const vec &x0, const vec &u0, mat &A , bool full = true ) {}; 
     94        //! 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. 
     95        virtual void dfdu_cond ( const vec &x0, const vec &u0, mat &A, bool full = true ) {}; 
     96        //!Default constructor (dimy is not set!) 
     97        diffbifn () : fnc() {}; 
     98        //! access function 
     99        int _dimx() const { 
     100                return dimx; 
     101        } 
     102        //! access function 
     103        int _dimu() const { 
     104                return dimu; 
     105        } 
    93106}; 
    94107 
    95108//! Class representing function \f$f(x,u) = Ax+Bu\f$ 
    96109//TODO can be generalized into multilinear form! 
    97 class bilinfn: public diffbifn 
    98 { 
    99                 mat A; 
    100                 mat B; 
    101         public : 
    102                 //!\name Constructors 
    103                 //!@{ 
    104                  
    105                 bilinfn () : diffbifn () ,A() ,B()      {}; 
    106                 bilinfn (const mat A0, const mat B0) {set_parameters(A0,B0);}; 
    107                 //! Alternative constructor 
    108                 void set_parameters(const mat A0, const mat B0){ 
    109                         it_assert_debug(A0.rows()==B0.rows(),""); 
    110                         A=A0;B=B0; 
    111                         dimy=A.rows(); 
    112                         dimx=A.cols(); 
    113                         dimu=B.cols(); 
    114                 } 
    115                 //!@} 
    116                  
    117                 //!\name Mathematical operations 
    118                 //!@{ 
    119                 inline vec eval ( const  vec &x0, const vec &u0 ) 
    120                 { 
    121                         it_assert_debug ( x0.length() ==dimx, "linfn::eval Wrong xcond." ); 
    122                         it_assert_debug ( u0.length() ==dimu, "linfn::eval Wrong ucond." ); 
    123                         return A*x0+B*u0; 
    124                 } 
     110class bilinfn: public diffbifn { 
     111        mat A; 
     112        mat B; 
     113public : 
     114        //!\name Constructors 
     115        //!@{ 
    125116 
    126                 void dfdx_cond ( const vec &x0, const vec &u0, mat &F, bool full ) 
    127                 { 
    128                         it_assert_debug ( ( F.cols() ==A.cols() ) & ( F.rows() ==A.rows() ),"Allocated F is not compatible." ); 
    129                         if ( full ) F=A;        //else : nothing has changed no need to regenerate 
    130                 } 
    131                 //! 
    132                 void dfdu_cond ( const vec &x0, const vec &u0, mat &F,  bool full=true ) 
    133                 { 
    134                         it_assert_debug ( ( F.cols() ==B.cols() ) & ( F.rows() ==B.rows() ),"Allocated F is not compatible." ); 
    135                         if ( full ) F=B;        //else : nothing has changed no need to regenerate 
    136                 } 
    137                 //!@} 
     117        bilinfn () : diffbifn () , A() , B()    {}; 
     118        bilinfn ( const mat A0, const mat B0 ) { 
     119                set_parameters ( A0, B0 ); 
     120        }; 
     121        //! Alternative constructor 
     122        void set_parameters ( const mat A0, const mat B0 ) { 
     123                it_assert_debug ( A0.rows() == B0.rows(), "" ); 
     124                A = A0; 
     125                B = B0; 
     126                dimy = A.rows(); 
     127                dimx = A.cols(); 
     128                dimu = B.cols(); 
     129        } 
     130        //!@} 
     131 
     132        //!\name Mathematical operations 
     133        //!@{ 
     134        inline vec eval ( const  vec &x0, const vec &u0 ) { 
     135                it_assert_debug ( x0.length() == dimx, "linfn::eval Wrong xcond." ); 
     136                it_assert_debug ( u0.length() == dimu, "linfn::eval Wrong ucond." ); 
     137                return A*x0 + B*u0; 
     138        } 
     139 
     140        void dfdx_cond ( const vec &x0, const vec &u0, mat &F, bool full ) { 
     141                it_assert_debug ( ( F.cols() == A.cols() ) & ( F.rows() == A.rows() ), "Allocated F is not compatible." ); 
     142                if ( full ) F = A;      //else : nothing has changed no need to regenerate 
     143        } 
     144        //! 
     145        void dfdu_cond ( const vec &x0, const vec &u0, mat &F,  bool full = true ) { 
     146                it_assert_debug ( ( F.cols() == B.cols() ) & ( F.rows() == B.rows() ), "Allocated F is not compatible." ); 
     147                if ( full ) F = B;      //else : nothing has changed no need to regenerate 
     148        } 
     149        //!@} 
    138150}; 
    139151 
  • library/bdm/math/psi.cpp

    r329 r477  
    1212#define el 0.5772156649015329 
    1313 
    14 double psi(double x) 
    15 { 
    16     double s,ps,xa,x2; 
    17     int n,k; 
    18     static double a[] = { 
    19         -0.8333333333333e-01, 
    20          0.83333333333333333e-02, 
    21         -0.39682539682539683e-02, 
    22          0.41666666666666667e-02, 
    23         -0.75757575757575758e-02, 
    24          0.21092796092796093e-01, 
    25         -0.83333333333333333e-01, 
    26          0.4432598039215686}; 
     14double 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        }; 
    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     } 
    41     else if ((xa+0.5) == ((int)(xa+0.5))) { 
    42         n = xa-0.5; 
    43         for (k=1;k<=n;k++) { 
    44             s += 1.0/(2.0*k-1.0); 
    45         } 
    46         ps = 2.0*s-el-1.386294361119891; 
    47     } 
    48     else { 
    49         if (xa < 10.0) { 
    50             n = 10-(int)xa; 
    51             for (k=0;k<n;k++) { 
    52                 s += 1.0/(xa+k); 
    53             } 
    54             xa += n; 
    55         } 
    56         x2 = 1.0/(xa*xa); 
    57         ps = log(xa)-0.5/xa+x2*(((((((a[7]*x2+a[6])*x2+a[5])*x2+ 
    58             a[4])*x2+a[3])*x2+a[2])*x2+a[1])*x2+a[0]); 
    59         ps -= s; 
    60     } 
    61     if (x < 0.0) 
    62         ps = ps - M_PI*cos(M_PI*x)/sin(M_PI*x)-1.0/x; 
    63         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; 
    6462} 
  • library/bdm/math/square_mat.cpp

    r433 r477  
    66using std::endl; 
    77 
    8 void fsqmat::opupdt ( const vec &v, double w ) {M+=outer_product ( v,v*w );}; 
    9 mat fsqmat::to_mat() const {return M;}; 
    10 void fsqmat::mult_sym ( const mat &C) {M=C *M*C.T();}; 
    11 void fsqmat::mult_sym_t ( const mat &C) {M=C.T() *M*C;}; 
    12 void fsqmat::mult_sym ( const mat &C, fsqmat &U) const { U.M = ( C *(M*C.T()) );}; 
    13 void fsqmat::mult_sym_t ( const mat &C, fsqmat &U) const { U.M = ( C.T() *(M*C) );}; 
    14 void fsqmat::inv ( fsqmat &Inv ) const {mat IM = itpp::inv ( M ); Inv=IM;}; 
    15 void fsqmat::clear() {M.clear();}; 
    16 fsqmat::fsqmat ( const mat &M0 ) : sqmat(M0.cols()) 
    17 { 
    18         it_assert_debug ( ( M0.cols() ==M0.rows() ),"M0 must be square" ); 
    19         M=M0; 
     8void fsqmat::opupdt ( const vec &v, double w ) { 
     9        M += outer_product ( v, v * w ); 
     10}; 
     11mat fsqmat::to_mat() const { 
     12        return M; 
     13}; 
     14void fsqmat::mult_sym ( const mat &C ) { 
     15        M = C * M * C.T(); 
     16}; 
     17void fsqmat::mult_sym_t ( const mat &C ) { 
     18        M = C.T() * M * C; 
     19}; 
     20void fsqmat::mult_sym ( const mat &C, fsqmat &U ) const { 
     21        U.M = ( C * ( M * C.T() ) ); 
     22}; 
     23void fsqmat::mult_sym_t ( const mat &C, fsqmat &U ) const { 
     24        U.M = ( C.T() * ( M * C ) ); 
     25}; 
     26void fsqmat::inv ( fsqmat &Inv ) const { 
     27        mat IM = itpp::inv ( M ); 
     28        Inv = IM; 
     29}; 
     30void fsqmat::clear() { 
     31        M.clear(); 
     32}; 
     33fsqmat::fsqmat ( const mat &M0 ) : sqmat ( M0.cols() ) { 
     34        it_assert_debug ( ( M0.cols() == M0.rows() ), "M0 must be square" ); 
     35        M = M0; 
    2036}; 
    2137 
    2238//fsqmat::fsqmat() {}; 
    2339 
    24 fsqmat::fsqmat(const int dim0): sqmat(dim0), M(dim0,dim0) {}; 
     40fsqmat::fsqmat ( const int dim0 ) : sqmat ( dim0 ), M ( dim0, dim0 ) {}; 
    2541 
    2642std::ostream &operator<< ( std::ostream &os, const fsqmat &ld ) { 
     
    3046 
    3147 
    32 ldmat::ldmat( const mat &exL, const vec &exD ) : sqmat(exD.length()) { 
     48ldmat::ldmat ( const mat &exL, const vec &exD ) : sqmat ( exD.length() ) { 
    3349        D = exD; 
    3450        L = exL; 
    3551} 
    3652 
    37 ldmat::ldmat() :sqmat(0) {} 
    38  
    39 ldmat::ldmat(const int dim0): sqmat(dim0), D(dim0),L(dim0,dim0) {} 
    40  
    41 ldmat::ldmat(const vec D0):sqmat(D0.length()) { 
     53ldmat::ldmat() : sqmat ( 0 ) {} 
     54 
     55ldmat::ldmat ( const int dim0 ) : sqmat ( dim0 ), D ( dim0 ), L ( dim0, dim0 ) {} 
     56 
     57ldmat::ldmat ( const vec D0 ) : sqmat ( D0.length() ) { 
    4258        D = D0; 
    43         L = eye(dim); 
    44 } 
    45  
    46 ldmat::ldmat( const mat &V ):sqmat(V.cols()) { 
     59        L = eye ( dim ); 
     60} 
     61 
     62ldmat::ldmat ( const mat &V ) : sqmat ( V.cols() ) { 
    4763//TODO check if correct!! Based on heuristic observation of lu() 
    4864 
    49         it_assert_debug( dim == V.rows(),"ldmat::ldmat matrix V is not square!" ); 
    50                  
     65        it_assert_debug ( dim == V.rows(), "ldmat::ldmat matrix V is not square!" ); 
     66 
    5167        // L and D will be allocated by ldform() 
    52          
     68 
    5369        //Chol is unstable 
    54         this->ldform(chol(V),ones(dim)); 
     70        this->ldform ( chol ( V ), ones ( dim ) ); 
    5571//      this->ldform(ul(V),ones(dim)); 
    5672} 
    5773 
    58 void ldmat::opupdt( const vec &v,  double w ) { 
     74void ldmat::opupdt ( const vec &v,  double w ) { 
    5975        int dim = D.length(); 
    6076        double kr; 
     
    6581        double *rraw = r._data(); 
    6682 
    67         it_assert_debug( v.length() == dim, "LD::ldupdt vector v is not compatible with this ld." ); 
     83        it_assert_debug ( v.length() == dim, "LD::ldupdt vector v is not compatible with this ld." ); 
    6884 
    6985        for ( int i = dim - 1; i >= 0; i-- ) { 
    70                 dydr( rraw, Lraw + i, &w, Draw + i, rraw + i, 0, i, &kr, 1, dim ); 
     86                dydr ( rraw, Lraw + i, &w, Draw + i, rraw + i, 0, i, &kr, 1, dim ); 
    7187        } 
    7288} 
     
    8096mat ldmat::to_mat() const { 
    8197        int dim = D.length(); 
    82         mat V( dim, dim ); 
     98        mat V ( dim, dim ); 
    8399        double sum; 
    84100        int r, c, cc; 
    85101 
    86         for ( r = 0;r < dim;r++ ) { //row cycle 
    87                 for ( c = r;c < dim;c++ ) { 
     102        for ( r = 0; r < dim; r++ ) { //row cycle 
     103                for ( c = r; c < dim; c++ ) { 
    88104                        //column cycle, using symmetricity => c=r! 
    89105                        sum = 0.0; 
    90                         for ( cc = c;cc < dim;cc++ ) { //cycle over the remaining part of the vector 
    91                                 sum += L( cc, r ) * D( cc ) * L( cc, c ); 
     106                        for ( cc = c; cc < dim; cc++ ) { //cycle over the remaining part of the vector 
     107                                sum += L ( cc, r ) * D ( cc ) * L ( cc, c ); 
    92108                                //here L(cc,r) = L(r,cc)'; 
    93109                        } 
    94                         V( r, c ) = sum; 
     110                        V ( r, c ) = sum; 
    95111                        // symmetricity 
    96                         if ( r != c ) {V( c, r ) = sum;}; 
    97                 } 
    98         } 
    99         mat V2 = L.transpose()*diag( D )*L; 
     112                        if ( r != c ) { 
     113                                V ( c, r ) = sum; 
     114                        }; 
     115                } 
     116        } 
     117        mat V2 = L.transpose() * diag ( D ) * L; 
    100118        return V2; 
    101119} 
    102120 
    103121 
    104 void ldmat::add( const ldmat &ld2, double w ) { 
     122void ldmat::add ( const ldmat &ld2, double w ) { 
    105123        int dim = D.length(); 
    106124 
    107         it_assert_debug( ld2.D.length() == dim, "LD.add() incompatible sizes of LDs;" ); 
     125        it_assert_debug ( ld2.D.length() == dim, "LD.add() incompatible sizes of LDs;" ); 
    108126 
    109127        //Fixme can be done more efficiently either via dydr or ldform 
    110128        for ( int r = 0; r < dim; r++ ) { 
    111129                // Add columns of ld2.L' (i.e. rows of ld2.L) as dyads weighted by ld2.D 
    112                 this->opupdt( ld2.L.get_row( r ), w*ld2.D( r ) ); 
    113         } 
    114 } 
    115  
    116 void ldmat::clear(){L.clear(); for ( int i=0;i<L.cols();i++ ){L( i,i )=1;}; D.clear();} 
    117  
    118 void ldmat::inv( ldmat &Inv ) const { 
     130                this->opupdt ( ld2.L.get_row ( r ), w*ld2.D ( r ) ); 
     131        } 
     132} 
     133 
     134void ldmat::clear() { 
     135        L.clear(); 
     136        for ( int i = 0; i < L.cols(); i++ ) { 
     137                L ( i, i ) = 1; 
     138        }; 
     139        D.clear(); 
     140} 
     141 
     142void ldmat::inv ( ldmat &Inv ) const { 
    119143        Inv.clear();   //Inv = zero in LD 
    120         mat U = ltuinv( L ); 
    121  
    122         Inv.ldform( U.transpose(), 1.0 / D ); 
    123 } 
    124  
    125 void ldmat::mult_sym( const mat &C) { 
    126         mat A = L*C.T(); 
    127         this->ldform(A,D); 
    128 } 
    129  
    130 void ldmat::mult_sym_t( const mat &C) { 
    131         mat A = L*C; 
    132         this->ldform(A,D); 
    133 } 
    134  
    135 void ldmat::mult_sym( const mat &C, ldmat &U) const { 
    136         mat A=L*C.T(); //could be done more efficiently using BLAS 
    137         U.ldform(A,D); 
    138 } 
    139  
    140 void ldmat::mult_sym_t( const mat &C, ldmat &U) const { 
    141         mat A=L*C; 
    142 /*      vec nD=zeros(U.rows()); 
    143         nD.replace_mid(0, D); //I case that D < nD*/ 
    144         U.ldform(A,D); 
     144        mat U = ltuinv ( L ); 
     145 
     146        Inv.ldform ( U.transpose(), 1.0 / D ); 
     147} 
     148 
     149void ldmat::mult_sym ( const mat &C ) { 
     150        mat A = L * C.T(); 
     151        this->ldform ( A, D ); 
     152} 
     153 
     154void ldmat::mult_sym_t ( const mat &C ) { 
     155        mat A = L * C; 
     156        this->ldform ( A, D ); 
     157} 
     158 
     159void ldmat::mult_sym ( const mat &C, ldmat &U ) const { 
     160        mat A = L * C.T(); //could be done more efficiently using BLAS 
     161        U.ldform ( A, D ); 
     162} 
     163 
     164void ldmat::mult_sym_t ( const mat &C, ldmat &U ) const { 
     165        mat A = L * C; 
     166        /*      vec nD=zeros(U.rows()); 
     167                nD.replace_mid(0, D); //I case that D < nD*/ 
     168        U.ldform ( A, D ); 
    145169} 
    146170 
     
    150174        int i; 
    151175// sum logarithms of diagobal elements 
    152         for ( i=0; i<D.length(); i++ ){ldet+=log( D( i ) );}; 
     176        for ( i = 0; i < D.length(); i++ ) { 
     177                ldet += log ( D ( i ) ); 
     178        }; 
    153179        return ldet; 
    154180} 
    155181 
    156 double ldmat::qform( const vec &v ) const { 
     182double ldmat::qform ( const vec &v ) const { 
    157183        double x = 0.0, sum; 
    158         int i,j; 
    159  
    160         for ( i=0; i<D.length(); i++ ) { //rows of L 
     184        int i, j; 
     185 
     186        for ( i = 0; i < D.length(); i++ ) { //rows of L 
    161187                sum = 0.0; 
    162                 for ( j=0; j<=i; j++ ){sum+=L( i,j )*v( j );} 
    163                 x +=D( i )*sum*sum; 
     188                for ( j = 0; j <= i; j++ ) { 
     189                        sum += L ( i, j ) * v ( j ); 
     190                } 
     191                x += D ( i ) * sum * sum; 
    164192        }; 
    165193        return x; 
    166194} 
    167195 
    168 double ldmat::invqform( const vec &v ) const { 
     196double ldmat::invqform ( const vec &v ) const { 
    169197        double x = 0.0; 
    170198        int i; 
    171         vec pom(v.length()); 
    172          
    173         backward_substitution(L.T(),v,pom); 
    174          
    175         for ( i=0; i<D.length(); i++ ) { //rows of L 
    176                 x +=pom(i)*pom(i)/D(i); 
     199        vec pom ( v.length() ); 
     200 
     201        backward_substitution ( L.T(), v, pom ); 
     202 
     203        for ( i = 0; i < D.length(); i++ ) { //rows of L 
     204                x += pom ( i ) * pom ( i ) / D ( i ); 
    177205        }; 
    178206        return x; 
     
    180208 
    181209ldmat& ldmat::operator *= ( double x ) { 
    182         D*=x; 
     210        D *= x; 
    183211        return *this; 
    184212} 
    185213 
    186 vec ldmat::sqrt_mult( const vec &x ) const { 
    187         int i,j; 
    188         vec res( dim ); 
     214vec ldmat::sqrt_mult ( const vec &x ) const { 
     215        int i, j; 
     216        vec res ( dim ); 
    189217        //double sum; 
    190         for ( i=0;i<dim;i++ ) {//for each element of result 
    191                 res( i ) = 0.0; 
    192                 for ( j=i;j<dim;j++ ) {//sum D(j)*L(:,i).*x 
    193                         res( i ) += sqrt( D( j ) )*L( j,i )*x( j ); 
     218        for ( i = 0; i < dim; i++ ) {//for each element of result 
     219                res ( i ) = 0.0; 
     220                for ( j = i; j < dim; j++ ) {//sum D(j)*L(:,i).*x 
     221                        res ( i ) += sqrt ( D ( j ) ) * L ( j, i ) * x ( j ); 
    194222                } 
    195223        } 
     
    198226} 
    199227 
    200 void ldmat::ldform(const mat &A,const vec &D0 ) 
    201 { 
     228void ldmat::ldform ( const mat &A, const vec &D0 ) { 
    202229        int m = A.rows(); 
    203230        int n = A.cols(); 
    204         int mn = (m<n) ? m :n ; 
     231        int mn = ( m < n ) ? m : n ; 
    205232 
    206233//      it_assert_debug( A.cols()==dim,"ldmat::ldform A is not compatible" ); 
    207         it_assert_debug( D0.length()==A.rows(),"ldmat::ldform Vector D must have the length as row count of A" ); 
    208  
    209         L=concat_vertical( zeros( n,n ), diag( sqrt( D0 ) )*A ); 
    210         D=zeros( n+m ); 
    211  
    212         //unnecessary big L and D will be made smaller at the end of file        
    213         vec w=zeros( n+m ); 
    214     
     234        it_assert_debug ( D0.length() == A.rows(), "ldmat::ldform Vector D must have the length as row count of A" ); 
     235 
     236        L = concat_vertical ( zeros ( n, n ), diag ( sqrt ( D0 ) ) * A ); 
     237        D = zeros ( n + m ); 
     238 
     239        //unnecessary big L and D will be made smaller at the end of file 
     240        vec w = zeros ( n + m ); 
     241 
    215242        double sum, beta, pom; 
    216243 
    217         int cc=0; 
    218         int i=n; // indexovani o 1 niz, nez v matlabu 
    219         int ii,j,jj; 
    220         while ( (i>n-mn-cc) && (i>0) )  
    221         { 
     244        int cc = 0; 
     245        int i = n; // indexovani o 1 niz, nez v matlabu 
     246        int ii, j, jj; 
     247        while ( ( i > n - mn - cc ) && ( i > 0 ) ) { 
    222248                i--; 
    223249                sum = 0.0; 
    224250 
    225                 int last_v = m+i-n+cc+1; 
    226          
    227                 vec v = zeros( last_v + 1 ); //prepare v 
    228                 for ( ii=n-cc-1;ii<m+i+1;ii++ )  
    229                 { 
    230                         sum+= L( ii,i )*L( ii,i ); 
    231                         v( ii-n+cc+1 )=L( ii,i ); //assign v 
    232                 } 
    233  
    234                 if ( L( m+i,i )==0 )  
    235                         beta = sqrt( sum );              
     251                int last_v = m + i - n + cc + 1; 
     252 
     253                vec v = zeros ( last_v + 1 ); //prepare v 
     254                for ( ii = n - cc - 1; ii < m + i + 1; ii++ ) { 
     255                        sum += L ( ii, i ) * L ( ii, i ); 
     256                        v ( ii - n + cc + 1 ) = L ( ii, i ); //assign v 
     257                } 
     258 
     259                if ( L ( m + i, i ) == 0 ) 
     260                        beta = sqrt ( sum ); 
    236261                else 
    237                         beta = L( m+i,i )+sign( L( m+i,i ) )*sqrt( sum );                
    238       
    239                 if ( std::fabs( beta )<eps ) 
    240                 { 
     262                        beta = L ( m + i, i ) + sign ( L ( m + i, i ) ) * sqrt ( sum ); 
     263 
     264                if ( std::fabs ( beta ) < eps ) { 
    241265                        cc++; 
    242                         L.set_row( n-cc, L.get_row( m+i ) ); 
    243                         L.set_row( m+i,zeros(L.cols()) ); 
    244                         D( m+i )=0; L( m+i,i )=1; 
    245                         L.set_submatrix( n-cc,m+i-1,i,i,0 ); 
     266                        L.set_row ( n - cc, L.get_row ( m + i ) ); 
     267                        L.set_row ( m + i, zeros ( L.cols() ) ); 
     268                        D ( m + i ) = 0; 
     269                        L ( m + i, i ) = 1; 
     270                        L.set_submatrix ( n - cc, m + i - 1, i, i, 0 ); 
    246271                        continue; 
    247272                } 
    248273 
    249                 sum-=v(last_v)*v(last_v); 
    250                 sum/=beta*beta; 
     274                sum -= v ( last_v ) * v ( last_v ); 
     275                sum /= beta * beta; 
    251276                sum++; 
    252277 
    253                 v/=beta; 
    254                 v(last_v)=1; 
    255  
    256                 pom=-2.0/sum; 
    257                 // echo to venca    
    258  
    259                 for ( j=i;j>=0;j-- )  
    260                 { 
    261                         double w_elem = 0;                       
    262                         for ( ii=n-     cc;ii<=m+i+1;ii++ )  
    263                                 w_elem+= v( ii-n+cc )*L( ii-1,j );                       
    264                         w(j)=w_elem*pom; 
    265                 } 
    266  
    267                 for ( ii=n-cc-1;ii<=m+i;ii++ )  
    268                         for ( jj=0;jj<i;jj++ )  
    269                                 L( ii,jj )+= v( ii-n+cc+1)*w( jj ); 
    270  
    271                 for ( ii=n-cc-1;ii<m+i;ii++ ) 
    272                         L( ii,i )= 0; 
    273  
    274                 L( m+i,i )+=w( i ); 
    275                 D( m+i )=L( m+i,i )*L( m+i,i ); 
    276  
    277                 for ( ii=0;ii<=i;ii++ )  
    278                         L( m+i,ii )/=L( m+i,i );                 
    279         } 
    280  
    281         if ( i>=0 ) 
    282                 for ( ii=0;ii<i;ii++ )  
    283                 { 
    284                         jj = D.length()-1-n+ii; 
    285                         D(jj) = 0; 
    286                         L.set_row(jj,zeros(L.cols())); //TODO: set_row accepts Num_T 
    287                         L(jj,jj)=1; 
    288                 } 
    289  
    290         L.del_rows(0,m-1); 
    291         D.del(0,m-1); 
    292          
     278                v /= beta; 
     279                v ( last_v ) = 1; 
     280 
     281                pom = -2.0 / sum; 
     282                // echo to venca 
     283 
     284                for ( j = i; j >= 0; j-- ) { 
     285                        double w_elem = 0; 
     286                        for ( ii = n -  cc; ii <= m + i + 1; ii++ ) 
     287                                w_elem += v ( ii - n + cc ) * L ( ii - 1, j ); 
     288                        w ( j ) = w_elem * pom; 
     289                } 
     290 
     291                for ( ii = n - cc - 1; ii <= m + i; ii++ ) 
     292                        for ( jj = 0; jj < i; jj++ ) 
     293                                L ( ii, jj ) += v ( ii - n + cc + 1 ) * w ( jj ); 
     294 
     295                for ( ii = n - cc - 1; ii < m + i; ii++ ) 
     296                        L ( ii, i ) = 0; 
     297 
     298                L ( m + i, i ) += w ( i ); 
     299                D ( m + i ) = L ( m + i, i ) * L ( m + i, i ); 
     300 
     301                for ( ii = 0; ii <= i; ii++ ) 
     302                        L ( m + i, ii ) /= L ( m + i, i ); 
     303        } 
     304 
     305        if ( i >= 0 ) 
     306                for ( ii = 0; ii < i; ii++ ) { 
     307                        jj = D.length() - 1 - n + ii; 
     308                        D ( jj ) = 0; 
     309                        L.set_row ( jj, zeros ( L.cols() ) ); //TODO: set_row accepts Num_T 
     310                        L ( jj, jj ) = 1; 
     311                } 
     312 
     313        L.del_rows ( 0, m - 1 ); 
     314        D.del ( 0, m - 1 ); 
     315 
    293316        dim = L.rows(); 
    294317} 
     
    296319//////// Auxiliary Functions 
    297320 
    298 mat ltuinv( const mat &L ) { 
     321mat ltuinv ( const mat &L ) { 
    299322        int dim = L.cols(); 
    300         mat Il = eye( dim ); 
     323        mat Il = eye ( dim ); 
    301324        int i, j, k, m; 
    302325        double s; 
    303326 
    304327//Fixme blind transcription of ltuinv.m 
    305         for ( k = 1; k < ( dim );k++ ) { 
    306                 for ( i = 0; i < ( dim - k );i++ ) { 
     328        for ( k = 1; k < ( dim ); k++ ) { 
     329                for ( i = 0; i < ( dim - k ); i++ ) { 
    307330                        j = i + k; //change in .m 1+1=2, here 0+0+1=1 
    308                         s = L( j, i ); 
     331                        s = L ( j, i ); 
    309332                        for ( m = i + 1; m < ( j ); m++ ) { 
    310                                 s += L( m, i ) * Il( j, m ); 
     333                                s += L ( m, i ) * Il ( j, m ); 
    311334                        } 
    312                         Il( j, i ) = -s; 
     335                        Il ( j, i ) = -s; 
    313336                } 
    314337        } 
     
    317340} 
    318341 
    319 void dydr( double * r, double *f, double *Dr, double *Df, double *R, int jl, int jh, double *kr, int m, int mx ) 
     342void dydr ( double * r, double *f, double *Dr, double *Df, double *R, int jl, int jh, double *kr, int m, int mx ) 
    320343/******************************************************************** 
    321344 
     
    353376        double threshold = 1e-4; 
    354377 
    355         if ( fabs( *Dr ) < mzero ) *Dr = 0; 
     378        if ( fabs ( *Dr ) < mzero ) *Dr = 0; 
    356379        r0 = *R; 
    357380        *R = 0.0; 
     
    366389                *kr = 0.0; 
    367390                if ( *Df < -threshold ) { 
    368                         it_warning( "Problem in dydr: subraction of dyad results in negative definitness. Likely mistake in calling function." ); 
     391                        it_warning ( "Problem in dydr: subraction of dyad results in negative definitness. Likely mistake in calling function." ); 
    369392                } 
    370393                *Df = 0.0; 
  • library/bdm/math/square_mat.h

    r471 r477  
    2020 
    2121//! Auxiliary function dydr; dyadic reduction 
    22 void dydr( double * r, double *f, double *Dr, double *Df, double *R, int jl, int jh, double *kr, int m, int mx ); 
     22void dydr ( double * r, double *f, double *Dr, double *Df, double *R, int jl, int jh, double *kr, int m, int mx ); 
    2323 
    2424//! Auxiliary function ltuinv; inversion of a triangular matrix; 
    2525//TODO can be done via: dtrtri.f from lapack 
    26 mat ltuinv( const mat &L ); 
     26mat ltuinv ( const mat &L ); 
    2727 
    2828/*! \brief Abstract class for representation of double symmetric matrices in square-root form. 
     
    3030All operations defined on this class should be optimized for the chosen decomposition. 
    3131*/ 
    32 class sqmat 
    33 { 
    34         public: 
    35                 /*! 
    36                  * Perfroms a rank-1 update by outer product of vectors: \f$V = V + w v v'\f$. 
    37                  * @param  v Vector forming the outer product to be added 
    38                  * @param  w weight of updating; can be negative 
    39  
    40                  BLAS-2b operation. 
    41                  */ 
    42                 virtual void opupdt ( const vec &v, double w ) =0; 
    43  
    44                 /*! \brief Conversion to full matrix. 
    45                 */ 
    46  
    47                 virtual mat to_mat() const =0; 
    48  
    49                 /*! \brief Inplace symmetric multiplication by a SQUARE matrix \f$C\f$, i.e. \f$V = C*V*C'\f$ 
    50                 @param C multiplying matrix, 
    51                 */ 
    52                 virtual void mult_sym ( const mat &C ) =0; 
    53                  
    54                 /*! \brief Inplace symmetric multiplication by a SQUARE transpose of matrix \f$C\f$, i.e. \f$V = C'*V*C\f$ 
    55                 @param C multiplying matrix, 
    56                 */ 
    57                 virtual void mult_sym_t ( const mat &C ) =0; 
    58  
    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; 
     32class sqmat { 
     33public: 
     34        /*! 
     35         * Perfroms a rank-1 update by outer product of vectors: \f$V = V + w v v'\f$. 
     36         * @param  v Vector forming the outer product to be added 
     37         * @param  w weight of updating; can be negative 
     38 
     39         BLAS-2b operation. 
     40         */ 
     41        virtual void opupdt ( const vec &v, double w ) = 0; 
     42 
     43        /*! \brief Conversion to full matrix. 
     44        */ 
     45 
     46        virtual mat to_mat() const = 0; 
     47 
     48        /*! \brief Inplace symmetric multiplication by a SQUARE matrix \f$C\f$, i.e. \f$V = C*V*C'\f$ 
     49        @param C multiplying matrix, 
     50        */ 
     51        virtual void mult_sym ( const mat &C ) = 0; 
     52 
     53        /*! \brief Inplace symmetric multiplication by a SQUARE transpose of matrix \f$C\f$, i.e. \f$V = C'*V*C\f$ 
     54        @param C multiplying matrix, 
     55        */ 
     56        virtual void mult_sym_t ( const mat &C ) = 0; 
     57 
     58 
     59        /*! 
     60        \brief Logarithm of a determinant. 
     61 
     62        */ 
     63        virtual double logdet() const = 0; 
     64 
     65        /*! 
     66        \brief Multiplies square root of \f$V\f$ by vector \f$x\f$. 
     67 
     68        Used e.g. in generating normal samples. 
     69        */ 
     70        virtual vec sqrt_mult ( const vec &v ) const = 0; 
     71 
     72        /*! 
     73        \brief Evaluates quadratic form \f$x= v'*V*v\f$; 
     74 
     75        */ 
     76        virtual double qform ( const vec &v ) const = 0; 
     77 
     78        /*! 
     79        \brief Evaluates quadratic form \f$x= v'*inv(V)*v\f$; 
     80 
     81        */ 
     82        virtual double invqform ( const vec &v ) const = 0; 
    8483 
    8584//      //! easy version of the 
    8685//      sqmat inv(); 
    8786 
    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 {return dim;}; 
    93  
    94                 //! Reimplementing common functions of mat: rows(). 
    95                 int rows() const {return dim;}; 
    96  
    97                 //! Destructor for future use; 
    98                 virtual ~sqmat(){}; 
    99                 //! Default constructor 
    100                 sqmat(const int dim0): dim(dim0){}; 
    101                 //! Default constructor 
    102                 sqmat(): dim(0){}; 
    103         protected: 
    104                 //! dimension of the square matrix 
    105                 int dim; 
     87        //! Clearing matrix so that it corresponds to zeros. 
     88        virtual void clear() = 0; 
     89 
     90        //! Reimplementing common functions of mat: cols(). 
     91        int cols() const { 
     92                return dim; 
     93        }; 
     94 
     95        //! Reimplementing common functions of mat: rows(). 
     96        int rows() const { 
     97                return dim; 
     98        }; 
     99 
     100        //! Destructor for future use; 
     101        virtual ~sqmat() {}; 
     102        //! Default constructor 
     103        sqmat ( const int dim0 ) : dim ( dim0 ) {}; 
     104        //! Default constructor 
     105        sqmat() : dim ( 0 ) {}; 
     106protected: 
     107        //! dimension of the square matrix 
     108        int dim; 
    106109}; 
    107110 
     
    111114This class can be used to compare performance of algorithms using decomposed matrices with perormance of the same algorithms using full matrices; 
    112115*/ 
    113 class fsqmat: public sqmat 
    114 { 
    115         protected: 
    116                 //! Full matrix on which the operations are performed 
    117                 mat M; 
    118         public: 
    119                 void opupdt ( const vec &v, double w ); 
    120                 mat to_mat() const; 
    121                 void mult_sym ( const mat &C); 
    122                 void mult_sym_t ( const mat &C); 
    123                 //! store result of \c mult_sym in external matrix \f$U\f$ 
    124                 void mult_sym ( const mat &C, fsqmat &U) const; 
    125                 //! store result of \c mult_sym_t in external matrix \f$U\f$ 
    126                 void mult_sym_t ( const mat &C, fsqmat &U) const; 
    127                 void clear(); 
    128  
    129                 //! Default initialization 
    130                 fsqmat(){}; // mat will be initialized OK 
    131                 //! Default initialization with proper size 
    132                 fsqmat(const int dim0); // mat will be initialized OK 
    133                 //! Constructor 
    134                 fsqmat ( const mat &M ); 
    135                 //! Constructor 
    136                 fsqmat ( const fsqmat &M, const ivec &perm ):sqmat(M.rows()){it_error("not implemneted");}; 
    137                 //! Constructor 
    138                 fsqmat ( const vec &d ):sqmat(d.length()){M=diag(d);}; 
    139  
    140                 //! Destructor for future use; 
    141                 virtual ~fsqmat(){}; 
    142  
    143  
    144                 /*! \brief Matrix inversion preserving the chosen form. 
    145  
    146                 @param Inv a space where the inverse is stored. 
    147  
    148                 */ 
    149                 void inv ( fsqmat &Inv ) const; 
    150  
    151                 double logdet() const {return log ( det ( M ) );}; 
    152                 double qform (const  vec &v ) const {return ( v* ( M*v ) );}; 
    153                 double invqform (const  vec &v ) const {return ( v* ( itpp::inv(M)*v ) );}; 
    154                 vec sqrt_mult (const vec &v ) const {mat Ch=chol(M); return Ch*v;}; 
    155  
    156                 //! Add another matrix in fsq form with weight w 
    157                 void add ( const fsqmat &fsq2, double w=1.0 ){M+=fsq2.M;}; 
    158  
    159                 //! Access functions 
    160                 void setD (const vec &nD){M=diag(nD);} 
    161                 //! Access functions 
    162                 vec getD (){return diag(M);} 
    163                 //! Access functions 
    164                 void setD (const vec &nD, int i){for(int j=i;j<nD.length();j++){M(j,j)=nD(j-i);}} //Fixme can be more general 
    165  
    166  
    167                 //! add another fsqmat matrix 
    168                 fsqmat& operator += ( const fsqmat &A ) {M+=A.M;return *this;}; 
    169                 //! subtrack another fsqmat matrix 
    170                 fsqmat& operator -= ( const fsqmat &A ) {M-=A.M;return *this;}; 
    171                 //! multiply by a scalar 
    172                 fsqmat& operator *= ( double x ) {M*=x;return *this;}; 
     116class fsqmat: public sqmat { 
     117protected: 
     118        //! Full matrix on which the operations are performed 
     119        mat M; 
     120public: 
     121        void opupdt ( const vec &v, double w ); 
     122        mat to_mat() const; 
     123        void mult_sym ( const mat &C ); 
     124        void mult_sym_t ( const mat &C ); 
     125        //! store result of \c mult_sym in external matrix \f$U\f$ 
     126        void mult_sym ( const mat &C, fsqmat &U ) const; 
     127        //! store result of \c mult_sym_t in external matrix \f$U\f$ 
     128        void mult_sym_t ( const mat &C, fsqmat &U ) const; 
     129        void clear(); 
     130 
     131        //! Default initialization 
     132        fsqmat() {}; // mat will be initialized OK 
     133        //! Default initialization with proper size 
     134        fsqmat ( const int dim0 ); // mat will be initialized OK 
     135        //! Constructor 
     136        fsqmat ( const mat &M ); 
     137        //! Constructor 
     138        fsqmat ( const fsqmat &M, const ivec &perm ) : sqmat ( M.rows() ) { 
     139                it_error ( "not implemneted" ); 
     140        }; 
     141        //! Constructor 
     142        fsqmat ( const vec &d ) : sqmat ( d.length() ) { 
     143                M = diag ( d ); 
     144        }; 
     145 
     146        //! Destructor for future use; 
     147        virtual ~fsqmat() {}; 
     148 
     149 
     150        /*! \brief Matrix inversion preserving the chosen form. 
     151 
     152        @param Inv a space where the inverse is stored. 
     153 
     154        */ 
     155        void inv ( fsqmat &Inv ) const; 
     156 
     157        double logdet() const { 
     158                return log ( det ( M ) ); 
     159        }; 
     160        double qform ( const  vec &v ) const { 
     161                return ( v* ( M*v ) ); 
     162        }; 
     163        double invqform ( const  vec &v ) const { 
     164                return ( v* ( itpp::inv ( M ) *v ) ); 
     165        }; 
     166        vec sqrt_mult ( const vec &v ) const { 
     167                mat Ch = chol ( M ); 
     168                return Ch*v; 
     169        }; 
     170 
     171        //! Add another matrix in fsq form with weight w 
     172        void add ( const fsqmat &fsq2, double w = 1.0 ) { 
     173                M += fsq2.M; 
     174        }; 
     175 
     176        //! Access functions 
     177        void setD ( const vec &nD ) { 
     178                M = diag ( nD ); 
     179        } 
     180        //! Access functions 
     181        vec getD () { 
     182                return diag ( M ); 
     183        } 
     184        //! Access functions 
     185        void setD ( const vec &nD, int i ) { 
     186                for ( int j = i; j < nD.length(); j++ ) { 
     187                        M ( j, j ) = nD ( j - i );    //Fixme can be more general 
     188                } 
     189        } 
     190 
     191 
     192        //! add another fsqmat matrix 
     193        fsqmat& operator += ( const fsqmat &A ) { 
     194                M += A.M; 
     195                return *this; 
     196        }; 
     197        //! subtrack another fsqmat matrix 
     198        fsqmat& operator -= ( const fsqmat &A ) { 
     199                M -= A.M; 
     200                return *this; 
     201        }; 
     202        //! multiply by a scalar 
     203        fsqmat& operator *= ( double x ) { 
     204                M *= x; 
     205                return *this; 
     206        }; 
    173207//              fsqmat& operator = ( const fsqmat &A) {M=A.M; return *this;}; 
    174                 //! print full matrix 
    175                 friend std::ostream &operator<< ( std::ostream &os, const fsqmat &sq ); 
     208        //! print full matrix 
     209        friend std::ostream &operator<< ( std::ostream &os, const fsqmat &sq ); 
    176210 
    177211}; 
    178212 
    179 /*! \brief Matrix stored in LD form, (commonly known as UD)  
     213/*! \brief Matrix stored in LD form, (commonly known as UD) 
    180214 
    181215Matrix is decomposed as follows: \f[M = L'DL\f] where only \f$L\f$ and \f$D\f$ matrices are stored. 
    182216All inplace operations modifies only these and the need to compose and decompose the matrix is avoided. 
    183217*/ 
    184 class ldmat: public sqmat 
    185 { 
    186         public: 
    187                 //! Construct by copy of L and D. 
    188                 ldmat ( const mat &L, const vec &D ); 
    189                 //! Construct by decomposition of full matrix V. 
    190                 ldmat (const mat &V ); 
    191                 //! Construct by restructuring of V0 accordint to permutation vector perm. 
    192                 ldmat (const ldmat &V0, const ivec &perm):sqmat(V0.rows()){     ldform(V0.L.get_cols(perm), V0.D);}; 
    193                 //! Construct diagonal matrix with diagonal D0 
    194                 ldmat ( vec D0 ); 
    195                 //!Default constructor 
    196                 ldmat (); 
    197                 //! Default initialization with proper size 
    198                 ldmat(const int dim0); 
    199                  
    200                 //! Destructor for future use; 
    201                 virtual ~ldmat(){}; 
    202  
    203                 // Reimplementation of compulsory operatios 
    204  
    205                 void opupdt ( const vec &v, double w ); 
    206                 mat to_mat() const; 
    207                 void mult_sym ( const mat &C); 
    208                 void mult_sym_t ( const mat &C); 
    209                 //! Add another matrix in LD form with weight w 
    210                 void add ( const ldmat &ld2, double w=1.0 ); 
    211                 double logdet() const; 
    212                 double qform (const vec &v ) const; 
    213                 double invqform (const vec &v ) const; 
    214                 void clear(); 
    215                 vec sqrt_mult ( const vec &v ) const; 
    216  
    217                  
    218                 /*! \brief Matrix inversion preserving the chosen form. 
    219                 @param Inv a space where the inverse is stored. 
    220                 */ 
    221                 void inv ( ldmat &Inv ) const; 
    222  
    223                 /*! \brief Symmetric multiplication of \f$U\f$ by a general matrix \f$C\f$, result of which is stored in the current class. 
    224                 @param C matrix to multiply with 
    225                 @param U a space where the inverse is stored. 
    226                 */ 
    227                 void mult_sym ( const mat &C, ldmat &U) const; 
    228  
    229                 /*! \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. 
    230                 @param C matrix to multiply with 
    231                 @param U a space where the inverse is stored. 
    232                 */ 
    233                 void mult_sym_t ( const mat &C, ldmat &U) const; 
    234  
    235  
    236                 /*! \brief Transforms general \f$A'D0 A\f$ into pure \f$L'DL\f$ 
    237  
    238                 The new decomposition fullfills: \f$A'*diag(D)*A = self.L'*diag(self.D)*self.L\f$ 
    239                 @param A general matrix 
    240                 @param D0 general vector 
    241                 */ 
    242                 void ldform (const mat &A,const vec &D0 ); 
    243  
    244                 //! Access functions 
    245                 void setD (const vec &nD){D=nD;} 
    246                 //! Access functions 
    247                 void setD (const vec &nD, int i){D.replace_mid(i,nD);} //Fixme can be more general 
    248                 //! Access functions 
    249                 void setL (const vec &nL){L=nL;} 
    250  
    251                 //! Access functions 
    252                 const vec& _D() const {return D;} 
    253                 //! Access functions 
    254                 const mat& _L() const {return L;} 
    255  
    256                 //! add another ldmat matrix 
    257                 ldmat& operator += ( const ldmat &ldA ); 
    258                 //! subtract another ldmat matrix 
    259                 ldmat& operator -= ( const ldmat &ldA ); 
    260                 //! multiply by a scalar 
    261                 ldmat& operator *= ( double x ); 
    262  
    263                 //! print both \c L and \c D 
    264                 friend std::ostream &operator<< ( std::ostream &os, const ldmat &sq ); 
    265  
    266         protected: 
    267                 //! Positive vector \f$D\f$ 
    268                 vec D; 
    269                 //! Lower-triangular matrix \f$L\f$ 
    270                 mat L; 
     218class ldmat: public sqmat { 
     219public: 
     220        //! Construct by copy of L and D. 
     221        ldmat ( const mat &L, const vec &D ); 
     222        //! Construct by decomposition of full matrix V. 
     223        ldmat ( const mat &V ); 
     224        //! Construct by restructuring of V0 accordint to permutation vector perm. 
     225        ldmat ( const ldmat &V0, const ivec &perm ) : sqmat ( V0.rows() ) { 
     226                ldform ( V0.L.get_cols ( perm ), V0.D ); 
     227        }; 
     228        //! Construct diagonal matrix with diagonal D0 
     229        ldmat ( vec D0 ); 
     230        //!Default constructor 
     231        ldmat (); 
     232        //! Default initialization with proper size 
     233        ldmat ( const int dim0 ); 
     234 
     235        //! Destructor for future use; 
     236        virtual ~ldmat() {}; 
     237 
     238        // Reimplementation of compulsory operatios 
     239 
     240        void opupdt ( const vec &v, double w ); 
     241        mat to_mat() const; 
     242        void mult_sym ( const mat &C ); 
     243        void mult_sym_t ( const mat &C ); 
     244        //! Add another matrix in LD form with weight w 
     245        void add ( const ldmat &ld2, double w = 1.0 ); 
     246        double logdet() const; 
     247        double qform ( const vec &v ) const; 
     248        double invqform ( const vec &v ) const; 
     249        void clear(); 
     250        vec sqrt_mult ( const vec &v ) const; 
     251 
     252 
     253        /*! \brief Matrix inversion preserving the chosen form. 
     254        @param Inv a space where the inverse is stored. 
     255        */ 
     256        void inv ( ldmat &Inv ) const; 
     257 
     258        /*! \brief Symmetric multiplication of \f$U\f$ by a general matrix \f$C\f$, result of which is stored in the current class. 
     259        @param C matrix to multiply with 
     260        @param U a space where the inverse is stored. 
     261        */ 
     262        void mult_sym ( const mat &C, ldmat &U ) const; 
     263 
     264        /*! \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. 
     265        @param C matrix to multiply with 
     266        @param U a space where the inverse is stored. 
     267        */ 
     268        void mult_sym_t ( const mat &C, ldmat &U ) const; 
     269 
     270 
     271        /*! \brief Transforms general \f$A'D0 A\f$ into pure \f$L'DL\f$ 
     272 
     273        The new decomposition fullfills: \f$A'*diag(D)*A = self.L'*diag(self.D)*self.L\f$ 
     274        @param A general matrix 
     275        @param D0 general vector 
     276        */ 
     277        void ldform ( const mat &A, const vec &D0 ); 
     278 
     279        //! Access functions 
     280        void setD ( const vec &nD ) { 
     281                D = nD; 
     282        } 
     283        //! Access functions 
     284        void setD ( const vec &nD, int i ) { 
     285                D.replace_mid ( i, nD );    //Fixme can be more general 
     286        } 
     287        //! Access functions 
     288        void setL ( const vec &nL ) { 
     289                L = nL; 
     290        } 
     291 
     292        //! Access functions 
     293        const vec& _D() const { 
     294                return D; 
     295        } 
     296        //! Access functions 
     297        const mat& _L() const { 
     298                return L; 
     299        } 
     300 
     301        //! add another ldmat matrix 
     302        ldmat& operator += ( const ldmat &ldA ); 
     303        //! subtract another ldmat matrix 
     304        ldmat& operator -= ( const ldmat &ldA ); 
     305        //! multiply by a scalar 
     306        ldmat& operator *= ( double x ); 
     307 
     308        //! print both \c L and \c D 
     309        friend std::ostream &operator<< ( std::ostream &os, const ldmat &sq ); 
     310 
     311protected: 
     312        //! Positive vector \f$D\f$ 
     313        vec D; 
     314        //! Lower-triangular matrix \f$L\f$ 
     315        mat L; 
    271316 
    272317}; 
     
    274319//////// Operations: 
    275320//!mapping of add operation to operators 
    276 inline ldmat& ldmat::operator += ( const ldmat &ldA )  {this->add ( ldA );return *this;} 
     321inline ldmat& ldmat::operator += ( const ldmat & ldA )  { 
     322        this->add ( ldA ); 
     323        return *this; 
     324} 
    277325//!mapping of negative add operation to operators 
    278 inline ldmat& ldmat::operator -= ( const ldmat &ldA )  {this->add ( ldA,-1.0 );return *this;} 
     326inline ldmat& ldmat::operator -= ( const ldmat & ldA )  { 
     327        this->add ( ldA, -1.0 ); 
     328        return *this; 
     329} 
    279330 
    280331#endif // DC_H