Changeset 477 for library/bdm/math
- Timestamp:
- 08/05/09 14:40:03 (15 years ago)
- Location:
- library/bdm/math
- Files:
-
- 6 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/math/chmat.cpp
r455 r477 9 9 mat Z; 10 10 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 ); 16 16 }; 17 mat chmat::to_mat() const {mat F=Ch.T() *Ch;return F;}; 17 mat chmat::to_mat() const { 18 mat F = Ch.T() * Ch; 19 return F; 20 }; 18 21 void 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 } 21 26 }; 22 27 void 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 } 25 32 }; 26 33 void 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 } 29 38 }; 30 39 void 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 } 33 44 }; 34 45 double chmat::logdet() const { 35 double ldet=0.0; int i; 46 double ldet = 0.0; 47 int i; 36 48 //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 } 38 52 return 2*ldet; //compensate for Ch being sqrt() 39 53 }; 40 54 //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); 55 vec chmat::sqrt_mult ( const vec &v ) const { 56 vec pom; 57 pom = Ch * v; 58 return pom; 59 }; 60 double chmat::qform ( const vec &v ) const { 61 vec pom; 62 pom = Ch * v; 46 63 return pom*pom; 47 64 }; 48 void chmat::clear() {Ch.clear();}; 65 double chmat::invqform ( const vec &v ) const { 66 vec pom ( v.length() ); 67 forward_substitution ( Ch.T(), v, pom ); 68 return pom*pom; 69 }; 70 void chmat::clear() { 71 Ch.clear(); 72 }; -
library/bdm/math/chmat.h
r437 r477 40 40 void clear(); 41 41 //! 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 ); 48 50 }; 49 51 //!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 51 55 ; 52 56 // void inv ( mat &Inv ); … … 55 59 virtual ~chmat() {}; 56 60 //! 57 chmat ( ) : sqmat (), Ch ( ) {};61 chmat ( ) : sqmat (), Ch ( ) {}; 58 62 //! Default constructor 59 chmat ( const int dim0 ) : sqmat ( dim0 ), Ch ( dim0,dim0 ) {};63 chmat ( const int dim0 ) : sqmat ( dim0 ), Ch ( dim0, dim0 ) {}; 60 64 //! 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 ) ) ) {}; 62 66 //! 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 }; 64 70 //! 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() ) { 66 72 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 ); 69 75 }; 70 76 //! 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 }; 72 80 //! Access function 73 mat & _Ch() {return Ch;} 81 mat & _Ch() { 82 return Ch; 83 } 74 84 //! Access function 75 const mat & _Ch() const {return Ch;} 85 const mat & _Ch() const { 86 return Ch; 87 } 76 88 //! Access functions 77 void setD ( const vec &nD ) {Ch=diag ( sqrt(nD) );} 89 void setD ( const vec &nD ) { 90 Ch = diag ( sqrt ( nD ) ); 91 } 78 92 //! Access functions 79 93 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() ); 82 96 } 83 97 //! 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 } 85 103 86 104 //! Operators 87 105 chmat& operator += ( const chmat &A2 ); 88 106 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 }; 92 120 }; 93 121 … … 95 123 //////// Operations: 96 124 //!mapping of add operation to operators 97 inline chmat& chmat::operator += ( const chmat &A2 ) {this->add ( A2 );return *this;} 125 inline chmat& chmat::operator += ( const chmat & A2 ) { 126 this->add ( A2 ); 127 return *this; 128 } 98 129 //!mapping of negative add operation to operators 99 inline chmat& chmat::operator -= ( const chmat &A2 ) {this->add ( A2,-1.0 );return *this;} 130 inline chmat& chmat::operator -= ( const chmat & A2 ) { 131 this->add ( A2, -1.0 ); 132 return *this; 133 } 100 134 101 135 #endif // CHMAT_H -
library/bdm/math/functions.h
r384 r477 15 15 #include "../base/bdmbase.h" 16 16 17 namespace bdm {17 namespace bdm { 18 18 19 19 //! 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; 20 class constfn : public fnc { 21 //! value of the function 22 vec val; 24 23 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();}; 24 public: 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 }; 31 34 }; 32 35 33 36 //! 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;}; 37 class linfn: public fnc { 38 //! Identification of \f$x\f$ 39 RV rv; 40 //! Matrix A 41 mat A; 42 //! vector B 43 vec B; 44 public : 45 vec eval ( const vec &cond ) { 46 it_assert_debug ( cond.length() == A.cols(), "linfn::eval Wrong cond." ); 47 return A*cond + B; 48 }; 44 49 45 50 // 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 }; 50 59 }; 51 60 … … 60 69 2) It could be generalized into multivariate form, (which was original meaning of \c fnc ). 61 70 */ 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 }; 71 class diffbifn: public fnc { 72 protected: 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; 81 public: 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 }; 80 87 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 } 93 106 }; 94 107 95 108 //! Class representing function \f$f(x,u) = Ax+Bu\f$ 96 109 //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 } 110 class bilinfn: public diffbifn { 111 mat A; 112 mat B; 113 public : 114 //!\name Constructors 115 //!@{ 125 116 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 //!@} 138 150 }; 139 151 -
library/bdm/math/psi.cpp
r329 r477 12 12 #define el 0.5772156649015329 13 13 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};14 double 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 }; 27 27 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; 64 62 } -
library/bdm/math/square_mat.cpp
r433 r477 6 6 using std::endl; 7 7 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; 8 void fsqmat::opupdt ( const vec &v, double w ) { 9 M += outer_product ( v, v * w ); 10 }; 11 mat fsqmat::to_mat() const { 12 return M; 13 }; 14 void fsqmat::mult_sym ( const mat &C ) { 15 M = C * M * C.T(); 16 }; 17 void fsqmat::mult_sym_t ( const mat &C ) { 18 M = C.T() * M * C; 19 }; 20 void fsqmat::mult_sym ( const mat &C, fsqmat &U ) const { 21 U.M = ( C * ( M * C.T() ) ); 22 }; 23 void fsqmat::mult_sym_t ( const mat &C, fsqmat &U ) const { 24 U.M = ( C.T() * ( M * C ) ); 25 }; 26 void fsqmat::inv ( fsqmat &Inv ) const { 27 mat IM = itpp::inv ( M ); 28 Inv = IM; 29 }; 30 void fsqmat::clear() { 31 M.clear(); 32 }; 33 fsqmat::fsqmat ( const mat &M0 ) : sqmat ( M0.cols() ) { 34 it_assert_debug ( ( M0.cols() == M0.rows() ), "M0 must be square" ); 35 M = M0; 20 36 }; 21 37 22 38 //fsqmat::fsqmat() {}; 23 39 24 fsqmat::fsqmat (const int dim0): sqmat(dim0), M(dim0,dim0) {};40 fsqmat::fsqmat ( const int dim0 ) : sqmat ( dim0 ), M ( dim0, dim0 ) {}; 25 41 26 42 std::ostream &operator<< ( std::ostream &os, const fsqmat &ld ) { … … 30 46 31 47 32 ldmat::ldmat ( const mat &exL, const vec &exD ) : sqmat(exD.length()) {48 ldmat::ldmat ( const mat &exL, const vec &exD ) : sqmat ( exD.length() ) { 33 49 D = exD; 34 50 L = exL; 35 51 } 36 52 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()) {53 ldmat::ldmat() : sqmat ( 0 ) {} 54 55 ldmat::ldmat ( const int dim0 ) : sqmat ( dim0 ), D ( dim0 ), L ( dim0, dim0 ) {} 56 57 ldmat::ldmat ( const vec D0 ) : sqmat ( D0.length() ) { 42 58 D = D0; 43 L = eye (dim);44 } 45 46 ldmat::ldmat ( const mat &V ):sqmat(V.cols()) {59 L = eye ( dim ); 60 } 61 62 ldmat::ldmat ( const mat &V ) : sqmat ( V.cols() ) { 47 63 //TODO check if correct!! Based on heuristic observation of lu() 48 64 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 51 67 // L and D will be allocated by ldform() 52 68 53 69 //Chol is unstable 54 this->ldform (chol(V),ones(dim));70 this->ldform ( chol ( V ), ones ( dim ) ); 55 71 // this->ldform(ul(V),ones(dim)); 56 72 } 57 73 58 void ldmat::opupdt ( const vec &v, double w ) {74 void ldmat::opupdt ( const vec &v, double w ) { 59 75 int dim = D.length(); 60 76 double kr; … … 65 81 double *rraw = r._data(); 66 82 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." ); 68 84 69 85 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 ); 71 87 } 72 88 } … … 80 96 mat ldmat::to_mat() const { 81 97 int dim = D.length(); 82 mat V ( dim, dim );98 mat V ( dim, dim ); 83 99 double sum; 84 100 int r, c, cc; 85 101 86 for ( r = 0; r < dim;r++ ) { //row cycle87 for ( c = r; c < dim;c++ ) {102 for ( r = 0; r < dim; r++ ) { //row cycle 103 for ( c = r; c < dim; c++ ) { 88 104 //column cycle, using symmetricity => c=r! 89 105 sum = 0.0; 90 for ( cc = c; cc < dim;cc++ ) { //cycle over the remaining part of the vector91 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 ); 92 108 //here L(cc,r) = L(r,cc)'; 93 109 } 94 V ( r, c ) = sum;110 V ( r, c ) = sum; 95 111 // 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; 100 118 return V2; 101 119 } 102 120 103 121 104 void ldmat::add ( const ldmat &ld2, double w ) {122 void ldmat::add ( const ldmat &ld2, double w ) { 105 123 int dim = D.length(); 106 124 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;" ); 108 126 109 127 //Fixme can be done more efficiently either via dydr or ldform 110 128 for ( int r = 0; r < dim; r++ ) { 111 129 // 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 134 void 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 142 void ldmat::inv ( ldmat &Inv ) const { 119 143 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 BLAS137 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 149 void ldmat::mult_sym ( const mat &C ) { 150 mat A = L * C.T(); 151 this->ldform ( A, D ); 152 } 153 154 void ldmat::mult_sym_t ( const mat &C ) { 155 mat A = L * C; 156 this->ldform ( A, D ); 157 } 158 159 void 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 164 void 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 ); 145 169 } 146 170 … … 150 174 int i; 151 175 // 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 }; 153 179 return ldet; 154 180 } 155 181 156 double ldmat::qform ( const vec &v ) const {182 double ldmat::qform ( const vec &v ) const { 157 183 double x = 0.0, sum; 158 int i, j;159 160 for ( i =0; i<D.length(); i++ ) { //rows of L184 int i, j; 185 186 for ( i = 0; i < D.length(); i++ ) { //rows of L 161 187 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; 164 192 }; 165 193 return x; 166 194 } 167 195 168 double ldmat::invqform ( const vec &v ) const {196 double ldmat::invqform ( const vec &v ) const { 169 197 double x = 0.0; 170 198 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 L176 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 ); 177 205 }; 178 206 return x; … … 180 208 181 209 ldmat& ldmat::operator *= ( double x ) { 182 D *=x;210 D *= x; 183 211 return *this; 184 212 } 185 213 186 vec ldmat::sqrt_mult ( const vec &x ) const {187 int i, j;188 vec res ( dim );214 vec ldmat::sqrt_mult ( const vec &x ) const { 215 int i, j; 216 vec res ( dim ); 189 217 //double sum; 190 for ( i =0;i<dim;i++ ) {//for each element of result191 res ( i ) = 0.0;192 for ( j =i;j<dim;j++ ) {//sum D(j)*L(:,i).*x193 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 ); 194 222 } 195 223 } … … 198 226 } 199 227 200 void ldmat::ldform(const mat &A,const vec &D0 ) 201 { 228 void ldmat::ldform ( const mat &A, const vec &D0 ) { 202 229 int m = A.rows(); 203 230 int n = A.cols(); 204 int mn = ( m<n) ? m :n ;231 int mn = ( m < n ) ? m : n ; 205 232 206 233 // 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 215 242 double sum, beta, pom; 216 243 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 ) ) { 222 248 i--; 223 249 sum = 0.0; 224 250 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 ); 236 261 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 ) { 241 265 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 ); 246 271 continue; 247 272 } 248 273 249 sum -=v(last_v)*v(last_v);250 sum /=beta*beta;274 sum -= v ( last_v ) * v ( last_v ); 275 sum /= beta * beta; 251 276 sum++; 252 277 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 293 316 dim = L.rows(); 294 317 } … … 296 319 //////// Auxiliary Functions 297 320 298 mat ltuinv ( const mat &L ) {321 mat ltuinv ( const mat &L ) { 299 322 int dim = L.cols(); 300 mat Il = eye ( dim );323 mat Il = eye ( dim ); 301 324 int i, j, k, m; 302 325 double s; 303 326 304 327 //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++ ) { 307 330 j = i + k; //change in .m 1+1=2, here 0+0+1=1 308 s = L ( j, i );331 s = L ( j, i ); 309 332 for ( m = i + 1; m < ( j ); m++ ) { 310 s += L ( m, i ) * Il( j, m );333 s += L ( m, i ) * Il ( j, m ); 311 334 } 312 Il ( j, i ) = -s;335 Il ( j, i ) = -s; 313 336 } 314 337 } … … 317 340 } 318 341 319 void dydr ( double * r, double *f, double *Dr, double *Df, double *R, int jl, int jh, double *kr, int m, int mx )342 void dydr ( double * r, double *f, double *Dr, double *Df, double *R, int jl, int jh, double *kr, int m, int mx ) 320 343 /******************************************************************** 321 344 … … 353 376 double threshold = 1e-4; 354 377 355 if ( fabs ( *Dr ) < mzero ) *Dr = 0;378 if ( fabs ( *Dr ) < mzero ) *Dr = 0; 356 379 r0 = *R; 357 380 *R = 0.0; … … 366 389 *kr = 0.0; 367 390 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." ); 369 392 } 370 393 *Df = 0.0; -
library/bdm/math/square_mat.h
r471 r477 20 20 21 21 //! 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 );22 void dydr ( double * r, double *f, double *Dr, double *Df, double *R, int jl, int jh, double *kr, int m, int mx ); 23 23 24 24 //! Auxiliary function ltuinv; inversion of a triangular matrix; 25 25 //TODO can be done via: dtrtri.f from lapack 26 mat ltuinv ( const mat &L );26 mat ltuinv ( const mat &L ); 27 27 28 28 /*! \brief Abstract class for representation of double symmetric matrices in square-root form. … … 30 30 All operations defined on this class should be optimized for the chosen decomposition. 31 31 */ 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; 32 class sqmat { 33 public: 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; 84 83 85 84 // //! easy version of the 86 85 // sqmat inv(); 87 86 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 ) {}; 106 protected: 107 //! dimension of the square matrix 108 int dim; 106 109 }; 107 110 … … 111 114 This class can be used to compare performance of algorithms using decomposed matrices with perormance of the same algorithms using full matrices; 112 115 */ 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;}; 116 class fsqmat: public sqmat { 117 protected: 118 //! Full matrix on which the operations are performed 119 mat M; 120 public: 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 }; 173 207 // fsqmat& operator = ( const fsqmat &A) {M=A.M; return *this;}; 174 175 208 //! print full matrix 209 friend std::ostream &operator<< ( std::ostream &os, const fsqmat &sq ); 176 210 177 211 }; 178 212 179 /*! \brief Matrix stored in LD form, (commonly known as UD) 213 /*! \brief Matrix stored in LD form, (commonly known as UD) 180 214 181 215 Matrix is decomposed as follows: \f[M = L'DL\f] where only \f$L\f$ and \f$D\f$ matrices are stored. 182 216 All inplace operations modifies only these and the need to compose and decompose the matrix is avoided. 183 217 */ 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; 218 class ldmat: public sqmat { 219 public: 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 311 protected: 312 //! Positive vector \f$D\f$ 313 vec D; 314 //! Lower-triangular matrix \f$L\f$ 315 mat L; 271 316 272 317 }; … … 274 319 //////// Operations: 275 320 //!mapping of add operation to operators 276 inline ldmat& ldmat::operator += ( const ldmat &ldA ) {this->add ( ldA );return *this;} 321 inline ldmat& ldmat::operator += ( const ldmat & ldA ) { 322 this->add ( ldA ); 323 return *this; 324 } 277 325 //!mapping of negative add operation to operators 278 inline ldmat& ldmat::operator -= ( const ldmat &ldA ) {this->add ( ldA,-1.0 );return *this;} 326 inline ldmat& ldmat::operator -= ( const ldmat & ldA ) { 327 this->add ( ldA, -1.0 ); 328 return *this; 329 } 279 330 280 331 #endif // DC_H