| 1 | #include <itpp/itbase.h> |
|---|
| 2 | #include <itpp/base/bessel.h> |
|---|
| 3 | #include "libEF.h" |
|---|
| 4 | #include <math.h> |
|---|
| 5 | |
|---|
| 6 | namespace bdm{ |
|---|
| 7 | |
|---|
| 8 | Uniform_RNG UniRNG; |
|---|
| 9 | Normal_RNG NorRNG; |
|---|
| 10 | Gamma_RNG GamRNG; |
|---|
| 11 | |
|---|
| 12 | using std::cout; |
|---|
| 13 | |
|---|
| 14 | void BMEF::bayes ( const vec &dt ) {this->bayes ( dt,1.0 );}; |
|---|
| 15 | |
|---|
| 16 | vec egiw::sample() const { |
|---|
| 17 | it_warning ( "Function not implemented" ); |
|---|
| 18 | return vec_1 ( 0.0 ); |
|---|
| 19 | } |
|---|
| 20 | |
|---|
| 21 | double egiw::evallog_nn ( const vec &val ) const { |
|---|
| 22 | int vend = val.length()-1; |
|---|
| 23 | |
|---|
| 24 | if ( xdim==1 ) { //same as the following, just quicker. |
|---|
| 25 | double r = val ( vend ); //last entry! |
|---|
| 26 | vec Psi ( nPsi+xdim ); |
|---|
| 27 | Psi ( 0 ) = -1.0; |
|---|
| 28 | Psi.set_subvector ( 1,val ( 0,vend-1 ) ); // fill the rest |
|---|
| 29 | |
|---|
| 30 | double Vq=V.qform ( Psi ); |
|---|
| 31 | return -0.5* ( nu*log ( r ) + Vq /r ); |
|---|
| 32 | } |
|---|
| 33 | else { |
|---|
| 34 | mat Th= reshape ( val ( 0,nPsi*xdim-1 ),nPsi,xdim ); |
|---|
| 35 | fsqmat R ( reshape ( val ( nPsi*xdim,vend ),xdim,xdim ) ); |
|---|
| 36 | mat Tmp=concat_vertical ( -eye ( xdim ),Th ); |
|---|
| 37 | fsqmat iR ( xdim ); |
|---|
| 38 | R.inv ( iR ); |
|---|
| 39 | |
|---|
| 40 | return -0.5* ( nu*R.logdet() + trace ( iR.to_mat() *Tmp.T() *V.to_mat() *Tmp ) ); |
|---|
| 41 | } |
|---|
| 42 | } |
|---|
| 43 | |
|---|
| 44 | double egiw::lognc() const { |
|---|
| 45 | const vec& D = V._D(); |
|---|
| 46 | |
|---|
| 47 | double m = nu - nPsi -xdim-1; |
|---|
| 48 | #define log2 0.693147180559945286226763983 |
|---|
| 49 | #define logpi 1.144729885849400163877476189 |
|---|
| 50 | #define log2pi 1.83787706640935 |
|---|
| 51 | #define Inf std::numeric_limits<double>::infinity() |
|---|
| 52 | |
|---|
| 53 | double nkG = 0.5* xdim* ( -nPsi *log2pi + sum ( log ( D ( xdim,D.length()-1 ) ) ) ); |
|---|
| 54 | // temporary for lgamma in Wishart |
|---|
| 55 | double lg=0; |
|---|
| 56 | for ( int i =0; i<xdim;i++ ) {lg+=lgamma ( 0.5* ( m-i ) );} |
|---|
| 57 | |
|---|
| 58 | double nkW = 0.5* ( m*sum ( log ( D ( 0,xdim-1 ) ) ) ) \ |
|---|
| 59 | - 0.5*xdim* ( m*log2 + 0.5* ( xdim-1 ) *log2pi ) - lg; |
|---|
| 60 | |
|---|
| 61 | it_assert_debug ( ( ( -nkG-nkW ) >-Inf ) && ( ( -nkG-nkW ) <Inf ), "ARX improper" ); |
|---|
| 62 | return -nkG-nkW; |
|---|
| 63 | } |
|---|
| 64 | |
|---|
| 65 | vec egiw::mean() const { |
|---|
| 66 | |
|---|
| 67 | if ( xdim==1 ) { |
|---|
| 68 | const mat &L= V._L(); |
|---|
| 69 | const vec &D= V._D(); |
|---|
| 70 | int end = L.rows()-1; |
|---|
| 71 | |
|---|
| 72 | vec m ( rv.count() ); |
|---|
| 73 | mat iLsub = ltuinv ( L ( xdim,end,xdim,end ) ); |
|---|
| 74 | |
|---|
| 75 | vec L0 = L.get_col ( 0 ); |
|---|
| 76 | |
|---|
| 77 | m.set_subvector ( 0,iLsub*L0 ( 1,end ) ); |
|---|
| 78 | m ( end ) = D ( 0 ) / ( nu -nPsi -2*xdim -2 ); |
|---|
| 79 | return m; |
|---|
| 80 | } |
|---|
| 81 | else { |
|---|
| 82 | mat M; |
|---|
| 83 | mat R; |
|---|
| 84 | mean_mat ( M,R ); |
|---|
| 85 | return cvectorize ( concat_vertical ( M,R ) ); |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | } |
|---|
| 89 | void egiw::mean_mat ( mat &M, mat&R ) const { |
|---|
| 90 | const mat &L= V._L(); |
|---|
| 91 | const vec &D= V._D(); |
|---|
| 92 | int end = L.rows()-1; |
|---|
| 93 | |
|---|
| 94 | ldmat ldR ( L ( 0,xdim-1,0,xdim-1 ), D ( 0,xdim-1 ) / ( nu -nPsi -2*xdim -2 ) ); //exp val of R |
|---|
| 95 | mat iLsub=ltuinv ( L ( xdim,end,xdim,end ) ); |
|---|
| 96 | |
|---|
| 97 | // set mean value |
|---|
| 98 | mat Lpsi = L ( xdim,end,0,xdim-1 ); |
|---|
| 99 | M= iLsub*Lpsi; |
|---|
| 100 | R= ldR.to_mat() ; |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | vec egamma::sample() const { |
|---|
| 104 | vec smp ( rv.count() ); |
|---|
| 105 | int i; |
|---|
| 106 | |
|---|
| 107 | for ( i=0; i<rv.count(); i++ ) { |
|---|
| 108 | if ( beta ( i ) >std::numeric_limits<double>::epsilon() ) { |
|---|
| 109 | GamRNG.setup ( alpha ( i ),beta ( i ) ); |
|---|
| 110 | } |
|---|
| 111 | else { |
|---|
| 112 | GamRNG.setup ( alpha ( i ),std::numeric_limits<double>::epsilon() ); |
|---|
| 113 | } |
|---|
| 114 | #pragma omp critical |
|---|
| 115 | smp ( i ) = GamRNG(); |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | return smp; |
|---|
| 119 | } |
|---|
| 120 | |
|---|
| 121 | // mat egamma::sample ( int N ) const { |
|---|
| 122 | // mat Smp ( rv.count(),N ); |
|---|
| 123 | // int i,j; |
|---|
| 124 | // |
|---|
| 125 | // for ( i=0; i<rv.count(); i++ ) { |
|---|
| 126 | // GamRNG.setup ( alpha ( i ),beta ( i ) ); |
|---|
| 127 | // |
|---|
| 128 | // for ( j=0; j<N; j++ ) { |
|---|
| 129 | // Smp ( i,j ) = GamRNG(); |
|---|
| 130 | // } |
|---|
| 131 | // } |
|---|
| 132 | // |
|---|
| 133 | // return Smp; |
|---|
| 134 | // } |
|---|
| 135 | |
|---|
| 136 | double egamma::evallog ( const vec &val ) const { |
|---|
| 137 | double res = 0.0; //the rest will be added |
|---|
| 138 | int i; |
|---|
| 139 | |
|---|
| 140 | for ( i=0; i<rv.count(); i++ ) { |
|---|
| 141 | res += ( alpha ( i ) - 1 ) *std::log ( val ( i ) ) - beta ( i ) *val ( i ); |
|---|
| 142 | } |
|---|
| 143 | double tmp=res-lognc();; |
|---|
| 144 | it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); |
|---|
| 145 | return tmp; |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | double egamma::lognc() const { |
|---|
| 149 | double res = 0.0; //will be added |
|---|
| 150 | int i; |
|---|
| 151 | |
|---|
| 152 | for ( i=0; i<rv.count(); i++ ) { |
|---|
| 153 | res += lgamma ( alpha ( i ) ) - alpha ( i ) *std::log ( beta ( i ) ) ; |
|---|
| 154 | } |
|---|
| 155 | |
|---|
| 156 | return res; |
|---|
| 157 | } |
|---|
| 158 | |
|---|
| 159 | //MGamma |
|---|
| 160 | void mgamma::set_parameters ( double k0 ) { |
|---|
| 161 | k=k0; |
|---|
| 162 | ep = &epdf; |
|---|
| 163 | epdf.set_parameters ( k*ones ( rv.count() ),*_beta ); |
|---|
| 164 | }; |
|---|
| 165 | |
|---|
| 166 | ivec eEmp::resample ( RESAMPLING_METHOD method ) { |
|---|
| 167 | ivec ind=zeros_i ( n ); |
|---|
| 168 | ivec N_babies = zeros_i ( n ); |
|---|
| 169 | vec cumDist = cumsum ( w ); |
|---|
| 170 | vec u ( n ); |
|---|
| 171 | int i,j,parent; |
|---|
| 172 | double u0; |
|---|
| 173 | |
|---|
| 174 | switch ( method ) { |
|---|
| 175 | case MULTINOMIAL: |
|---|
| 176 | u ( n - 1 ) = pow ( UniRNG.sample(), 1.0 / n ); |
|---|
| 177 | |
|---|
| 178 | for ( i = n - 2;i >= 0;i-- ) { |
|---|
| 179 | u ( i ) = u ( i + 1 ) * pow ( UniRNG.sample(), 1.0 / ( i + 1 ) ); |
|---|
| 180 | } |
|---|
| 181 | |
|---|
| 182 | break; |
|---|
| 183 | |
|---|
| 184 | case STRATIFIED: |
|---|
| 185 | |
|---|
| 186 | for ( i = 0;i < n;i++ ) { |
|---|
| 187 | u ( i ) = ( i + UniRNG.sample() ) / n; |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | break; |
|---|
| 191 | |
|---|
| 192 | case SYSTEMATIC: |
|---|
| 193 | u0 = UniRNG.sample(); |
|---|
| 194 | |
|---|
| 195 | for ( i = 0;i < n;i++ ) { |
|---|
| 196 | u ( i ) = ( i + u0 ) / n; |
|---|
| 197 | } |
|---|
| 198 | |
|---|
| 199 | break; |
|---|
| 200 | |
|---|
| 201 | default: |
|---|
| 202 | it_error ( "PF::resample(): Unknown resampling method" ); |
|---|
| 203 | } |
|---|
| 204 | |
|---|
| 205 | // U is now full |
|---|
| 206 | j = 0; |
|---|
| 207 | |
|---|
| 208 | for ( i = 0;i < n;i++ ) { |
|---|
| 209 | while ( u ( i ) > cumDist ( j ) ) j++; |
|---|
| 210 | |
|---|
| 211 | N_babies ( j ) ++; |
|---|
| 212 | } |
|---|
| 213 | // We have assigned new babies for each Particle |
|---|
| 214 | // Now, we fill the resulting index such that: |
|---|
| 215 | // * particles with at least one baby should not move * |
|---|
| 216 | // This assures that reassignment can be done inplace; |
|---|
| 217 | |
|---|
| 218 | // find the first parent; |
|---|
| 219 | parent=0; while ( N_babies ( parent ) ==0 ) parent++; |
|---|
| 220 | |
|---|
| 221 | // Build index |
|---|
| 222 | for ( i = 0;i < n;i++ ) { |
|---|
| 223 | if ( N_babies ( i ) > 0 ) { |
|---|
| 224 | ind ( i ) = i; |
|---|
| 225 | N_babies ( i ) --; //this index was now replicated; |
|---|
| 226 | } |
|---|
| 227 | else { |
|---|
| 228 | // test if the parent has been fully replicated |
|---|
| 229 | // if yes, find the next one |
|---|
| 230 | while ( ( N_babies ( parent ) ==0 ) || ( N_babies ( parent ) ==1 && parent>i ) ) parent++; |
|---|
| 231 | |
|---|
| 232 | // Replicate parent |
|---|
| 233 | ind ( i ) = parent; |
|---|
| 234 | |
|---|
| 235 | N_babies ( parent ) --; //this index was now replicated; |
|---|
| 236 | } |
|---|
| 237 | |
|---|
| 238 | } |
|---|
| 239 | |
|---|
| 240 | // copy the internals according to ind |
|---|
| 241 | for ( i=0;i<n;i++ ) { |
|---|
| 242 | if ( ind ( i ) !=i ) { |
|---|
| 243 | samples ( i ) =samples ( ind ( i ) ); |
|---|
| 244 | } |
|---|
| 245 | w ( i ) = 1.0/n; |
|---|
| 246 | } |
|---|
| 247 | |
|---|
| 248 | return ind; |
|---|
| 249 | } |
|---|
| 250 | |
|---|
| 251 | void eEmp::set_parameters ( const vec &w0, const epdf* epdf0 ) { |
|---|
| 252 | //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0"); |
|---|
| 253 | w=w0; |
|---|
| 254 | w/=sum ( w0 );//renormalize |
|---|
| 255 | n=w.length(); |
|---|
| 256 | samples.set_size ( n ); |
|---|
| 257 | |
|---|
| 258 | for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();} |
|---|
| 259 | } |
|---|
| 260 | |
|---|
| 261 | void eEmp::set_samples ( const epdf* epdf0 ) { |
|---|
| 262 | //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0"); |
|---|
| 263 | w=1; |
|---|
| 264 | w/=sum ( w );//renormalize |
|---|
| 265 | |
|---|
| 266 | for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();} |
|---|
| 267 | } |
|---|
| 268 | |
|---|
| 269 | }; |
|---|