| 255 | //forward declaration |
| 256 | class mstudent; |
| 257 | |
| 258 | /*! distribution of multivariate Student t density |
| 259 | |
| 260 | Based on article by Genest and Zidek, |
| 261 | */ |
| 262 | template<class sq_T> |
| 263 | class estudent : public eEF{ |
| 264 | protected: |
| 265 | //! mena value |
| 266 | vec mu; |
| 267 | //! matrix H |
| 268 | sq_T H; |
| 269 | //! degrees of freedom |
| 270 | double delta; |
| 271 | public: |
| 272 | double evallog_nn(const vec &val) const{ |
| 273 | double tmp = -0.5*H.logdet() - 0.5*(delta + dim) * log(1+ H.invqform(val - mu)/delta); |
| 274 | return tmp; |
| 275 | } |
| 276 | double lognc() const { |
| 277 | //log(pi) = 1.14472988584940 |
| 278 | double tmp = -lgamma(0.5*(delta+dim))+lgamma(0.5*delta) + 0.5*dim*(log(delta) + 1.14472988584940); |
| 279 | return tmp; |
| 280 | } |
| 281 | void marginal (const RV &rvm, estudent<sq_T> &marg) const { |
| 282 | ivec ind = rvm.findself_ids(rv); // indeces of rvm in rv |
| 283 | marg._mu() = mu(ind); |
| 284 | marg._H() = sq_T(H,ind); |
| 285 | marg._delta() = delta; |
| 286 | marg.validate(); |
| 287 | } |
| 288 | shared_ptr<epdf> marginal(const RV &rvm) const { |
| 289 | shared_ptr<estudent<sq_T> > tmp = new estudent<sq_T>; |
| 290 | marginal(rvm, *tmp); |
| 291 | return tmp; |
| 292 | } |
| 293 | vec sample() const NOT_IMPLEMENTED(vec(0)) |
| 294 | |
| 295 | vec mean() const {return mu;} |
| 296 | mat covariance() const {return delta/(delta-2)*H.to_mat();} |
| 297 | vec variance() const {return diag(covariance());} |
| 298 | //! \name access |
| 299 | //! @{ |
| 300 | //! access function |
| 301 | vec& _mu() {return mu;} |
| 302 | //! access function |
| 303 | sq_T& _H() {return H;} |
| 304 | //! access function |
| 305 | double& _delta() {return delta;} |
| 306 | //!@} |
| 307 | //! todo |
| 308 | void from_setting(const Setting &set){ |
| 309 | epdf::from_setting(set); |
| 310 | mat H0; |
| 311 | UI::get(H0,set, "H"); |
| 312 | H= H0; // conversion!! |
| 313 | UI::get(delta,set,"delta"); |
| 314 | UI::get(mu,set,"mu"); |
| 315 | } |
| 316 | void to_setting(Setting &set) const{ |
| 317 | epdf::to_setting(set); |
| 318 | UI::save(H.to_mat(), set, "H"); |
| 319 | UI::save(delta, set, "delta"); |
| 320 | UI::save(mu, set, "mu"); |
| 321 | } |
| 322 | void validate() { |
| 323 | dim = H.rows(); |
| 324 | } |
| 325 | }; |
| 326 | UIREGISTER2(estudent,fsqmat); |
| 327 | UIREGISTER2(estudent,ldmat); |
| 328 | UIREGISTER2(estudent,chmat); |
| 380 | //! marginal density (only student for now) |
| 381 | shared_ptr<epdf> marginal(const RV &rvm) const { |
| 382 | bdm_assert(dimx==1, "Not supported"); |
| 383 | //TODO - this is too trivial!!! |
| 384 | ivec ind = rvm.findself_ids(rv); |
| 385 | if (min(ind)==0) { //assume it si |
| 386 | shared_ptr<estudent<ldmat> > tmp = new estudent<ldmat>; |
| 387 | mat M; |
| 388 | ldmat Vz; |
| 389 | ldmat Lam; |
| 390 | factorize(M,Vz,Lam); |
| 391 | |
| 392 | tmp->_mu() = M.get_col(0); |
| 393 | ldmat H; |
| 394 | Vz.inv(H); |
| 395 | H *=Lam._D()(0)/nu; |
| 396 | tmp->_H() = H; |
| 397 | tmp->_delta() = nu; |
| 398 | tmp->validate(); |
| 399 | return tmp; |
| 400 | } |
| 401 | return NULL; |
| 402 | } |