00001 
00013 #ifndef EF_H
00014 #define EF_H
00015 
00016 
00017 #include "../shared_ptr.h"
00018 #include "../base/bdmbase.h"
00019 #include "../math/chmat.h"
00020 
00021 namespace bdm
00022 {
00023 
00024 
00026 extern Uniform_RNG UniRNG;
00028 extern Normal_RNG NorRNG;
00030 extern Gamma_RNG GamRNG;
00031 
00038 class eEF : public epdf
00039 {
00040         public:
00041 
00043                 eEF () : epdf () {};
00045                 virtual double lognc() const = 0;
00046 
00048                 virtual double evallog_nn (const vec &val) const {
00049                         bdm_error ("Not implemented");
00050                         return 0.0;
00051                 }
00052 
00054                 virtual double evallog (const vec &val) const {
00055                         double tmp;
00056                         tmp = evallog_nn (val) - lognc();
00057                         return tmp;
00058                 }
00060                 virtual vec evallog_m (const mat &Val) const {
00061                         vec x (Val.cols());
00062                         for (int i = 0;i < Val.cols();i++) {x (i) = evallog_nn (Val.get_col (i)) ;}
00063                         return x -lognc();
00064                 }
00066                 virtual vec evallog_m (const Array<vec> &Val) const {
00067                         vec x (Val.length());
00068                         for (int i = 0;i < Val.length();i++) {x (i) = evallog_nn (Val (i)) ;}
00069                         return x -lognc();
00070                 }
00071 
00073                 virtual void pow (double p) {
00074                         bdm_error ("Not implemented");
00075                 }
00076 };
00077 
00078 
00080 class BMEF : public BM
00081 {
00082         protected:
00084                 double frg;
00086                 double last_lognc;
00087         public:
00089                 BMEF (double frg0 = 1.0) : BM (), frg (frg0) {}
00091                 BMEF (const BMEF &B) : BM (B), frg (B.frg), last_lognc (B.last_lognc) {}
00093                 virtual void set_statistics (const BMEF* BM0) {
00094                         bdm_error ("Not implemented");
00095                 }
00096 
00098                 virtual void bayes (const vec &data, const double w) {};
00099                 
00100                 void bayes (const vec &dt);
00101 
00103                 virtual void flatten (const BMEF * B) {
00104                         bdm_error ("Not implemented");
00105                 }
00106 
00107                 BMEF* _copy_ () const {
00108                         bdm_error ("function _copy_ not implemented for this BM");
00109                         return NULL;
00110                 }
00111 };
00112 
00113 template<class sq_T, template <typename> class TEpdf>
00114 class mlnorm;
00115 
00121 template<class sq_T>
00122 class enorm : public eEF
00123 {
00124         protected:
00126                 vec mu;
00128                 sq_T R;
00129         public:
00132 
00133                 enorm () : eEF (), mu (), R () {};
00134                 enorm (const vec &mu, const sq_T &R) {set_parameters (mu, R);}
00135                 void set_parameters (const vec &mu, const sq_T &R);
00136                 void from_setting (const Setting &root);
00137                 void validate() {
00138                         bdm_assert_debug (mu.length() == R.rows(), "parameters mismatch");
00139                         dim = mu.length();
00140                 }
00142 
00145 
00147                 void dupdate (mat &v, double nu = 1.0);
00148 
00149                 vec sample() const;
00150 
00151                 double evallog_nn (const vec &val) const;
00152                 double lognc () const;
00153                 vec mean() const {return mu;}
00154                 vec variance() const {return diag (R.to_mat());}
00155 
00156                 shared_ptr<mpdf> condition ( const RV &rvn ) const;
00157 
00158                 
00159                 
00160                 
00161                 
00162                 void condition ( const RV &rvn, mpdf &target ) const;
00163 
00164                 shared_ptr<epdf> marginal (const RV &rvn ) const;
00165                 void marginal ( const RV &rvn, enorm<sq_T> &target ) const;
00167 
00170 
00171                 vec& _mu() {return mu;}
00172                 const vec& _mu() const {return mu;}
00173                 void set_mu (const vec mu0) { mu = mu0;}
00174                 sq_T& _R() {return R;}
00175                 const sq_T& _R() const {return R;}
00177 
00178 };
00179 UIREGISTER2 (enorm, chmat);
00180 SHAREDPTR2 ( enorm, chmat );
00181 UIREGISTER2 (enorm, ldmat);
00182 SHAREDPTR2 ( enorm, ldmat );
00183 UIREGISTER2 (enorm, fsqmat);
00184 SHAREDPTR2 ( enorm, fsqmat );
00185 
00186 
00193 class egiw : public eEF
00194 {
00195         protected:
00197                 ldmat V;
00199                 double nu;
00201                 int dimx;
00203                 int nPsi;
00204         public:
00207                 egiw() : eEF() {};
00208                 egiw (int dimx0, ldmat V0, double nu0 = -1.0) : eEF() {set_parameters (dimx0, V0, nu0);};
00209 
00210                 void set_parameters (int dimx0, ldmat V0, double nu0 = -1.0) {
00211                         dimx = dimx0;
00212                         nPsi = V0.rows() - dimx;
00213                         dim = dimx * (dimx + nPsi); 
00214 
00215                         V = V0;
00216                         if (nu0 < 0) {
00217                                 nu = 0.1 + nPsi + 2 * dimx + 2; 
00218                                 
00219                         } else {
00220                                 nu = nu0;
00221                         }
00222                 }
00224 
00225                 vec sample() const;
00226                 vec mean() const;
00227                 vec variance() const;
00228 
00230                 vec est_theta() const;
00231 
00233                 ldmat est_theta_cov() const;
00234 
00236                 void mean_mat (mat &M, mat&R) const;
00238                 double evallog_nn (const vec &val) const;
00239                 double lognc () const;
00240                 void pow (double p) {V *= p;nu *= p;};
00241 
00244 
00245                 ldmat& _V() {return V;}
00246                 const ldmat& _V() const {return V;}
00247                 double& _nu()  {return nu;}
00248                 const double& _nu() const {return nu;}
00249                 void from_setting (const Setting &set) {
00250                         UI::get (nu, set, "nu", UI::compulsory);
00251                         UI::get (dimx, set, "dimx", UI::compulsory);
00252                         mat V;
00253                         UI::get (V, set, "V", UI::compulsory);
00254                         set_parameters (dimx, V, nu);
00255                         shared_ptr<RV> rv = UI::build<RV> (set, "rv", UI::compulsory);
00256                         set_rv (*rv);
00257                 }
00259 };
00260 UIREGISTER ( egiw );
00261 SHAREDPTR ( egiw );
00262 
00271 class eDirich: public eEF
00272 {
00273         protected:
00275                 vec beta;
00276         public:
00279 
00280                 eDirich () : eEF () {};
00281                 eDirich (const eDirich &D0) : eEF () {set_parameters (D0.beta);};
00282                 eDirich (const vec &beta0) {set_parameters (beta0);};
00283                 void set_parameters (const vec &beta0) {
00284                         beta = beta0;
00285                         dim = beta.length();
00286                 }
00288 
00289                 vec sample() const {
00290                         bdm_error ("Not implemented");
00291                         return vec();
00292                 }
00293 
00294                 vec mean() const {return beta / sum (beta);};
00295                 vec variance() const {double gamma = sum (beta); return elem_mult (beta, (beta + 1)) / (gamma* (gamma + 1));}
00297                 double evallog_nn (const vec &val) const {
00298                         double tmp; tmp = (beta - 1) * log (val);
00299                         return tmp;
00300                 }
00301 
00302                 double lognc () const {
00303                         double tmp;
00304                         double gam = sum (beta);
00305                         double lgb = 0.0;
00306                         for (int i = 0;i < beta.length();i++) {lgb += lgamma (beta (i));}
00307                         tmp = lgb - lgamma (gam);
00308                         return tmp;
00309                 }
00310 
00312                 vec& _beta()  {return beta;}
00314 };
00315 
00317 class multiBM : public BMEF
00318 {
00319         protected:
00321                 eDirich est;
00323                 vec β
00324         public:
00326                 multiBM () : BMEF (), est (), beta (est._beta()) {
00327                         if (beta.length() > 0) {last_lognc = est.lognc();}
00328                         else{last_lognc = 0.0;}
00329                 }
00331                 multiBM (const multiBM &B) : BMEF (B), est (B.est), beta (est._beta()) {}
00333                 void set_statistics (const BM* mB0) {const multiBM* mB = dynamic_cast<const multiBM*> (mB0); beta = mB->beta;}
00334                 void bayes (const vec &dt) {
00335                         if (frg < 1.0) {beta *= frg;last_lognc = est.lognc();}
00336                         beta += dt;
00337                         if (evalll) {ll = est.lognc() - last_lognc;}
00338                 }
00339                 double logpred (const vec &dt) const {
00340                         eDirich pred (est);
00341                         vec &beta = pred._beta();
00342 
00343                         double lll;
00344                         if (frg < 1.0)
00345                                 {beta *= frg;lll = pred.lognc();}
00346                         else
00347                                 if (evalll) {lll = last_lognc;}
00348                                 else{lll = pred.lognc();}
00349 
00350                         beta += dt;
00351                         return pred.lognc() - lll;
00352                 }
00353                 void flatten (const BMEF* B) {
00354                         const multiBM* E = dynamic_cast<const multiBM*> (B);
00355                         
00356                         const vec &Eb = E->beta;
00357                         beta *= (sum (Eb) / sum (beta));
00358                         if (evalll) {last_lognc = est.lognc();}
00359                 }
00361                 const eDirich& posterior() const {return est;};
00363                 void set_parameters (const vec &beta0) {
00364                         est.set_parameters (beta0);
00365                         if (evalll) {last_lognc = est.lognc();}
00366                 }
00367 };
00368 
00378 class egamma : public eEF
00379 {
00380         protected:
00382                 vec alpha;
00384                 vec beta;
00385         public :
00388                 egamma () : eEF (), alpha (0), beta (0) {};
00389                 egamma (const vec &a, const vec &b) {set_parameters (a, b);};
00390                 void set_parameters (const vec &a, const vec &b) {alpha = a, beta = b;dim = alpha.length();};
00392 
00393                 vec sample() const;
00394                 double evallog (const vec &val) const;
00395                 double lognc () const;
00397                 vec& _alpha() {return alpha;}
00399                 vec& _beta() {return beta;}
00400                 vec mean() const {return elem_div (alpha, beta);}
00401                 vec variance() const {return elem_div (alpha, elem_mult (beta, beta)); }
00402 
00411                 void from_setting (const Setting &set) {
00412                         epdf::from_setting (set); 
00413                         UI::get (alpha, set, "alpha", UI::compulsory);
00414                         UI::get (beta, set, "beta", UI::compulsory);
00415                         validate();
00416                 }
00417                 void validate() {
00418                         bdm_assert_debug (alpha.length() == beta.length(), "parameters do not match");
00419                         dim = alpha.length();
00420                 }
00421 };
00422 UIREGISTER (egamma);
00423 SHAREDPTR ( egamma );
00424 
00441 class eigamma : public egamma
00442 {
00443         protected:
00444         public :
00449 
00450                 vec sample() const {return 1.0 / egamma::sample();};
00452                 vec mean() const {return elem_div (beta, alpha - 1);}
00453                 vec variance() const {vec mea = mean(); return elem_div (elem_mult (mea, mea), alpha - 2);}
00454 };
00455 
00457 
00458 
00459 
00460 
00461 
00462 
00464 
00465 
00466 
00467 
00468 
00469 
00471 
00472 class euni: public epdf
00473 {
00474         protected:
00476                 vec low;
00478                 vec high;
00480                 vec distance;
00482                 double nk;
00484                 double lnk;
00485         public:
00488                 euni () : epdf () {}
00489                 euni (const vec &low0, const vec &high0) {set_parameters (low0, high0);}
00490                 void set_parameters (const vec &low0, const vec &high0) {
00491                         distance = high0 - low0;
00492                         low = low0;
00493                         high = high0;
00494                         nk = prod (1.0 / distance);
00495                         lnk = log (nk);
00496                         dim = low.length();
00497                 }
00499 
00500                 double evallog (const vec &val) const  {
00501                         if (any (val < low) && any (val > high)) {return inf;}
00502                         else return lnk;
00503                 }
00504                 vec sample() const {
00505                         vec smp (dim);
00506 #pragma omp critical
00507                         UniRNG.sample_vector (dim , smp);
00508                         return low + elem_mult (distance, smp);
00509                 }
00511                 vec mean() const {return (high -low) / 2.0;}
00512                 vec variance() const {return (pow (high, 2) + pow (low, 2) + elem_mult (high, low)) / 3.0;}
00521                 void from_setting (const Setting &set) {
00522                         epdf::from_setting (set); 
00523 
00524                         UI::get (high, set, "high", UI::compulsory);
00525                         UI::get (low, set, "low", UI::compulsory);
00526                         set_parameters(low,high);
00527                         validate();
00528                 }
00529                 void validate() {
00530                         bdm_assert(high.length()==low.length(), "Incompatible high and low vectors");
00531                         dim = high.length();
00532                         bdm_assert_debug (min (distance) > 0.0, "bad support");
00533                 }
00534 };
00535 UIREGISTER(euni);
00536 
00542 template < class sq_T, template <typename> class TEpdf = enorm >
00543 class mlnorm : public mpdf_internal< TEpdf<sq_T> >
00544 {
00545         protected:
00547                 mat A;
00549                 vec mu_const;
00550 
00551         public:
00554                 mlnorm() : mpdf_internal< TEpdf<sq_T> >() {};
00555                 mlnorm (const mat &A, const vec &mu0, const sq_T &R) : mpdf_internal< TEpdf<sq_T> >() {
00556                         set_parameters (A, mu0, R);
00557                 }
00558 
00560                 void set_parameters (const  mat &A0, const vec &mu0, const sq_T &R0) {
00561                         bdm_assert_debug (A0.rows() == mu0.length(), "mlnorm: A vs. mu mismatch");
00562                         bdm_assert_debug (A0.rows() == R0.rows(), "mlnorm: A vs. R mismatch");
00563                         
00564                         this->iepdf.set_parameters (zeros (A0.rows()), R0);
00565                         A = A0;
00566                         mu_const = mu0;
00567                         this->dimc = A0.cols();
00568                 }
00571                 void condition (const vec &cond) {
00572                         this->iepdf._mu() = A * cond + mu_const;
00573 
00574                 }
00575 
00577                 const vec& _mu_const() const {return mu_const;}
00579                 const mat& _A() const {return A;}
00581                 mat _R() const { return this->iepdf._R().to_mat(); }
00582 
00584                 template<typename sq_M>
00585                 friend std::ostream &operator<< (std::ostream &os,  mlnorm<sq_M, enorm> &ml);
00586 
00587                 void from_setting (const Setting &set) {
00588                         mpdf::from_setting (set);
00589 
00590                         UI::get (A, set, "A", UI::compulsory);
00591                         UI::get (mu_const, set, "const", UI::compulsory);
00592                         mat R0;
00593                         UI::get (R0, set, "R", UI::compulsory);
00594                         set_parameters (A, mu_const, R0);
00595                 };
00596 };
00597 UIREGISTER2 (mlnorm,ldmat);
00598 SHAREDPTR2 ( mlnorm, ldmat );
00599 UIREGISTER2 (mlnorm,fsqmat);
00600 SHAREDPTR2 ( mlnorm, fsqmat );
00601 UIREGISTER2 (mlnorm, chmat);
00602 SHAREDPTR2 ( mlnorm, chmat );
00603 
00605 template<class sq_T>
00606 class mgnorm : public mpdf_internal< enorm< sq_T > >
00607 {
00608         private:
00609 
00610                 shared_ptr<fnc> g;
00611 
00612         public:
00614                 mgnorm() : mpdf_internal<enorm<sq_T> >() { }
00616                 inline void set_parameters (const shared_ptr<fnc> &g0, const sq_T &R0);
00617                 inline void condition (const vec &cond);
00618 
00619 
00647                 void from_setting (const Setting &set) {
00648                         shared_ptr<fnc> g = UI::build<fnc> (set, "g", UI::compulsory);
00649 
00650                         mat R;
00651                         vec dR;
00652                         if (UI::get (dR, set, "dR"))
00653                                 R = diag (dR);
00654                         else
00655                                 UI::get (R, set, "R", UI::compulsory);
00656 
00657                         set_parameters (g, R);
00658                 }
00659 };
00660 
00661 UIREGISTER2 (mgnorm, chmat);
00662 SHAREDPTR2 ( mgnorm, chmat );
00663 
00664 
00672 class mlstudent : public mlnorm<ldmat, enorm>
00673 {
00674         protected:
00676                 ldmat Lambda;
00678                 ldmat &_R;
00680                 ldmat Re;
00681         public:
00682                 mlstudent () : mlnorm<ldmat, enorm> (),
00683                                 Lambda (),      _R (iepdf._R()) {}
00685                 void set_parameters (const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0) {
00686                         iepdf.set_parameters (mu0, R0);
00687                         A = A0;
00688                         mu_const = mu0;
00689                         Re = R0;
00690                         Lambda = Lambda0;
00691                 }
00692                 void condition (const vec &cond) {
00693                         iepdf._mu() = A * cond + mu_const;
00694                         double zeta;
00695                         
00696                         if ( (cond.length() + 1) == Lambda.rows()) {
00697                                 zeta = Lambda.invqform (concat (cond, vec_1 (1.0)));
00698                         } else {
00699                                 zeta = Lambda.invqform (cond);
00700                         }
00701                         _R = Re;
00702                         _R *= (1 + zeta);
00703                 };
00704 
00705                 void validate() {
00706                         bdm_assert_debug (A.rows() == mu_const.length(), "mlstudent: A vs. mu mismatch");
00707                         bdm_assert_debug (_R.rows() == A.rows(), "mlstudent: A vs. R mismatch");
00708                         
00709                 }
00710 };
00720 class mgamma : public mpdf_internal<egamma>
00721 {
00722         protected:
00723 
00725                 double k;
00726 
00728                 vec &_beta;
00729 
00730         public:
00732                 mgamma() : mpdf_internal<egamma>(), k (0),
00733                                 _beta (iepdf._beta()) {
00734                 }
00735 
00737                 void set_parameters (double k, const vec &beta0);
00738 
00739                 void condition (const vec &val) {_beta = k / val;};
00749                 void from_setting (const Setting &set) {
00750                         mpdf::from_setting (set); 
00751                         vec betatmp; 
00752                         UI::get (betatmp, set, "beta", UI::compulsory);
00753                         UI::get (k, set, "k", UI::compulsory);
00754                         set_parameters (k, betatmp);
00755                 }
00756 };
00757 UIREGISTER (mgamma);
00758 SHAREDPTR (mgamma);
00759 
00769 class migamma : public mpdf_internal<eigamma>
00770 {
00771         protected:
00773                 double k;
00774 
00776                 vec &_alpha;
00777 
00779                 vec &_beta;
00780 
00781         public:
00784                 migamma() : mpdf_internal<eigamma>(),
00785                                 k (0),
00786                                 _alpha (iepdf._alpha()),
00787                                 _beta (iepdf._beta()) {
00788                 }
00789 
00790                 migamma (const migamma &m) : mpdf_internal<eigamma>(),
00791                                 k (0),
00792                                 _alpha (iepdf._alpha()),
00793                                 _beta (iepdf._beta()) {
00794                 }
00796 
00798                 void set_parameters (int len, double k0) {
00799                         k = k0;
00800                         iepdf.set_parameters ( (1.0 / (k*k) + 2.0) *ones (len) , ones (len) );
00801                         dimc = dimension();
00802                 };
00803                 void condition (const vec &val) {
00804                         _beta = elem_mult (val, (_alpha - 1.0));
00805                 };
00806 };
00807 
00808 
00820 class mgamma_fix : public mgamma
00821 {
00822         protected:
00824                 double l;
00826                 vec refl;
00827         public:
00829                 mgamma_fix () : mgamma (), refl () {};
00831                 void set_parameters (double k0 , vec ref0, double l0) {
00832                         mgamma::set_parameters (k0, ref0);
00833                         refl = pow (ref0, 1.0 - l0);l = l0;
00834                         dimc = dimension();
00835                 };
00836 
00837                 void condition (const vec &val) {vec mean = elem_mult (refl, pow (val, l)); _beta = k / mean;};
00838 };
00839 
00840 
00853 class migamma_ref : public migamma
00854 {
00855         protected:
00857                 double l;
00859                 vec refl;
00860         public:
00862                 migamma_ref () : migamma (), refl () {};
00864                 void set_parameters (double k0 , vec ref0, double l0) {
00865                         migamma::set_parameters (ref0.length(), k0);
00866                         refl = pow (ref0, 1.0 - l0);
00867                         l = l0;
00868                         dimc = dimension();
00869                 };
00870 
00871                 void condition (const vec &val) {
00872                         vec mean = elem_mult (refl, pow (val, l));
00873                         migamma::condition (mean);
00874                 };
00875 
00896                 void from_setting (const Setting &set);
00897 
00898                 
00899 };
00900 
00901 
00902 UIREGISTER (migamma_ref);
00903 SHAREDPTR (migamma_ref);
00904 
00914 class elognorm: public enorm<ldmat>
00915 {
00916         public:
00917                 vec sample() const {return exp (enorm<ldmat>::sample());};
00918                 vec mean() const {vec var = enorm<ldmat>::variance();return exp (mu - 0.5*var);};
00919 
00920 };
00921 
00933 class mlognorm : public mpdf_internal<elognorm>
00934 {
00935         protected:
00937                 double sig2;
00938 
00940                 vec μ
00941         public:
00943                 mlognorm() : mpdf_internal<elognorm>(),
00944                                 sig2 (0),
00945                                 mu (iepdf._mu()) {
00946                 }
00947 
00949                 void set_parameters (int size, double k) {
00950                         sig2 = 0.5 * log (k * k + 1);
00951                         iepdf.set_parameters (zeros (size), 2*sig2*eye (size));
00952 
00953                         dimc = size;
00954                 };
00955 
00956                 void condition (const vec &val) {
00957                         mu = log (val) - sig2;
00958                 };
00959 
00978                 void from_setting (const Setting &set);
00979 
00980                 
00981 
00982 };
00983 
00984 UIREGISTER (mlognorm);
00985 SHAREDPTR (mlognorm);
00986 
00990 class eWishartCh : public epdf
00991 {
00992         protected:
00994                 chmat Y;
00996                 int p;
00998                 double delta;
00999         public:
01001                 void set_parameters (const mat &Y0, const double delta0) {Y = chmat (Y0);delta = delta0; p = Y.rows(); dim = p * p; }
01003                 mat sample_mat() const {
01004                         mat X = zeros (p, p);
01005 
01006                         
01007                         for (int i = 0;i < p;i++) {
01008                                 GamRNG.setup (0.5* (delta - i) , 0.5);   
01009 #pragma omp critical
01010                                 X (i, i) = sqrt (GamRNG());
01011                         }
01012                         
01013                         for (int i = 0;i < p;i++) {
01014                                 for (int j = i + 1;j < p;j++) {
01015 #pragma omp critical
01016                                         X (i, j) = NorRNG.sample();
01017                                 }
01018                         }
01019                         return X*Y._Ch();
01020                 }
01021                 vec sample () const {
01022                         return vec (sample_mat()._data(), p*p);
01023                 }
01025                 void setY (const mat &Ch0) {copy_vector (dim, Ch0._data(), Y._Ch()._data());}
01027                 void _setY (const vec &ch0) {copy_vector (dim, ch0._data(), Y._Ch()._data()); }
01029                 const chmat& getY() const {return Y;}
01030 };
01031 
01033 
01035 class eiWishartCh: public epdf
01036 {
01037         protected:
01039                 eWishartCh W;
01041                 int p;
01043                 double delta;
01044         public:
01046                 void set_parameters (const mat &Y0, const double delta0) {
01047                         delta = delta0;
01048                         W.set_parameters (inv (Y0), delta0);
01049                         dim = W.dimension(); p = Y0.rows();
01050                 }
01051                 vec sample() const {mat iCh; iCh = inv (W.sample_mat()); return vec (iCh._data(), dim);}
01053                 void _setY (const vec &y0) {
01054                         mat Ch (p, p);
01055                         mat iCh (p, p);
01056                         copy_vector (dim, y0._data(), Ch._data());
01057 
01058                         iCh = inv (Ch);
01059                         W.setY (iCh);
01060                 }
01061                 virtual double evallog (const vec &val) const {
01062                         chmat X (p);
01063                         const chmat& Y = W.getY();
01064 
01065                         copy_vector (p*p, val._data(), X._Ch()._data());
01066                         chmat iX (p);X.inv (iX);
01067                         
01068 
01069                         mat M = Y.to_mat() * iX.to_mat();
01070 
01071                         double log1 = 0.5 * p * (2 * Y.logdet()) - 0.5 * (delta + p + 1) * (2 * X.logdet()) - 0.5 * trace (M);
01072                         
01073 
01074                         
01075 
01076 
01077 
01078 
01079 
01080 
01081                         return log1;
01082                 };
01083 
01084 };
01085 
01087 class rwiWishartCh : public mpdf_internal<eiWishartCh>
01088 {
01089         protected:
01091                 double sqd;
01093                 vec refl;
01095                 double l;
01097                 int p;
01098 
01099         public:
01100                 rwiWishartCh() : sqd (0), l (0), p (0) {}
01102                 void set_parameters (int p0, double k, vec ref0, double l0) {
01103                         p = p0;
01104                         double delta = 2 / (k * k) + p + 3;
01105                         sqd = sqrt (delta - p - 1);
01106                         l = l0;
01107                         refl = pow (ref0, 1 - l);
01108 
01109                         iepdf.set_parameters (eye (p), delta);
01110                         dimc = iepdf.dimension();
01111                 }
01112                 void condition (const vec &c) {
01113                         vec z = c;
01114                         int ri = 0;
01115                         for (int i = 0;i < p*p;i += (p + 1)) {
01116                                 z (i) = pow (z (i), l) * refl (ri);
01117                                 ri++;
01118                         }
01119 
01120                         iepdf._setY (sqd*z);
01121                 }
01122 };
01123 
01125 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
01131 class eEmp: public epdf
01132 {
01133         protected :
01135                 int n;
01137                 vec w;
01139                 Array<vec> samples;
01140         public:
01143                 eEmp () : epdf (), w (), samples () {};
01145                 eEmp (const eEmp &e) : epdf (e), w (e.w), samples (e.samples) {};
01147 
01149                 void set_statistics (const vec &w0, const epdf &pdf0);
01151                 void set_statistics (const epdf &pdf0 , int n) {set_statistics (ones (n) / n, pdf0);};
01153                 void set_samples (const epdf* pdf0);
01155                 void set_parameters (int n0, bool copy = true) {n = n0; w.set_size (n0, copy);samples.set_size (n0, copy);};
01157                 void set_parameters (const Array<vec> &Av) {
01158                         bdm_assert_debug(Av.size()>0,"Empty samples"); 
01159                         n = Av.size(); 
01160                         epdf::set_parameters(Av(0).length());
01161                         w=1/n*ones(n);
01162                         samples=Av;
01163                 };
01165                 vec& _w()  {return w;};
01167                 const vec& _w() const {return w;};
01169                 Array<vec>& _samples() {return samples;};
01171                 const Array<vec>& _samples() const {return samples;};
01173                 ivec resample (RESAMPLING_METHOD method = SYSTEMATIC);
01174 
01176                 vec sample() const {
01177                         bdm_error ("Not implemented");
01178                         return vec();
01179                 }
01180 
01182                 double evallog (const vec &val) const {
01183                         bdm_error ("Not implemented");
01184                         return 0.0;
01185                 }
01186 
01187                 vec mean() const {
01188                         vec pom = zeros (dim);
01189                         for (int i = 0;i < n;i++) {pom += samples (i) * w (i);}
01190                         return pom;
01191                 }
01192                 vec variance() const {
01193                         vec pom = zeros (dim);
01194                         for (int i = 0;i < n;i++) {pom += pow (samples (i), 2) * w (i);}
01195                         return pom -pow (mean(), 2);
01196                 }
01198                 void qbounds (vec &lb, vec &ub, double perc = 0.95) const {
01199                         
01200                         lb.set_size (dim);
01201                         ub.set_size (dim);
01202                         lb = std::numeric_limits<double>::infinity();
01203                         ub = -std::numeric_limits<double>::infinity();
01204                         int j;
01205                         for (int i = 0;i < n;i++) {
01206                                 for (j = 0;j < dim; j++) {
01207                                         if (samples (i) (j) < lb (j)) {lb (j) = samples (i) (j);}
01208                                         if (samples (i) (j) > ub (j)) {ub (j) = samples (i) (j);}
01209                                 }
01210                         }
01211                 }
01212 };
01213 
01214 
01216 
01217 template<class sq_T>
01218 void enorm<sq_T>::set_parameters (const vec &mu0, const sq_T &R0)
01219 {
01220 
01221         mu = mu0;
01222         R = R0;
01223         validate();
01224 };
01225 
01226 template<class sq_T>
01227 void enorm<sq_T>::from_setting (const Setting &set)
01228 {
01229         epdf::from_setting (set); 
01230 
01231         UI::get (mu, set, "mu", UI::compulsory);
01232         mat Rtmp;
01233         UI::get (Rtmp, set, "R", UI::compulsory);
01234         R = Rtmp; 
01235         validate();
01236 }
01237 
01238 template<class sq_T>
01239 void enorm<sq_T>::dupdate (mat &v, double nu)
01240 {
01241         
01242 };
01243 
01244 
01245 
01246 
01247 
01248 
01249 template<class sq_T>
01250 vec enorm<sq_T>::sample() const
01251 {
01252         vec x (dim);
01253 #pragma omp critical
01254         NorRNG.sample_vector (dim, x);
01255         vec smp = R.sqrt_mult (x);
01256 
01257         smp += mu;
01258         return smp;
01259 };
01260 
01261 
01262 
01263 
01264 
01265 
01266 
01267 
01268 
01269 template<class sq_T>
01270 double enorm<sq_T>::evallog_nn (const vec &val) const
01271 {
01272         
01273         double tmp = -0.5 * (R.invqform (mu - val));
01274         return  tmp;
01275 };
01276 
01277 template<class sq_T>
01278 inline double enorm<sq_T>::lognc () const
01279 {
01280         
01281         double tmp = 0.5 * (R.cols() * 1.83787706640935 + R.logdet());
01282         return tmp;
01283 };
01284 
01285 
01286 
01287 
01288 
01289 
01290 
01291 
01292 
01293 
01294 
01295 
01296 
01297 
01298 
01299 
01300 
01301 
01302 
01303 
01304 
01305 
01306 
01307 
01308 
01309 
01310 
01311 
01312 template<class sq_T>
01313 shared_ptr<epdf> enorm<sq_T>::marginal ( const RV &rvn ) const
01314 {
01315         enorm<sq_T> *tmp = new enorm<sq_T> ();
01316         shared_ptr<epdf> narrow(tmp);
01317         marginal ( rvn, *tmp );
01318         return narrow;
01319 }
01320 
01321 template<class sq_T>
01322 void enorm<sq_T>::marginal ( const RV &rvn, enorm<sq_T> &target ) const
01323 {
01324         bdm_assert_debug (isnamed(), "rv description is not assigned");
01325         ivec irvn = rvn.dataind (rv);
01326 
01327         sq_T Rn (R, irvn);  
01328 
01329         target.set_rv ( rvn );
01330         target.set_parameters (mu (irvn), Rn);
01331 }
01332 
01333 template<class sq_T>
01334 shared_ptr<mpdf> enorm<sq_T>::condition ( const RV &rvn ) const
01335 {
01336         mlnorm<sq_T> *tmp = new mlnorm<sq_T> ();
01337         shared_ptr<mpdf> narrow(tmp);
01338         condition ( rvn, *tmp );
01339         return narrow;
01340 }
01341 
01342 template<class sq_T>
01343 void enorm<sq_T>::condition ( const RV &rvn, mpdf &target ) const
01344 {
01345         typedef mlnorm<sq_T> TMlnorm;
01346 
01347         bdm_assert_debug (isnamed(), "rvs are not assigned");
01348         TMlnorm &uptarget = dynamic_cast<TMlnorm &>(target);
01349 
01350         RV rvc = rv.subt (rvn);
01351         bdm_assert_debug ( (rvc._dsize() + rvn._dsize() == rv._dsize()), "wrong rvn");
01352         
01353         ivec irvn = rvn.dataind (rv);
01354         ivec irvc = rvc.dataind (rv);
01355         ivec perm = concat (irvn , irvc);
01356         sq_T Rn (R, perm);
01357 
01358         
01359         mat S = Rn.to_mat();
01360         
01361         int n = rvn._dsize() - 1;
01362         int end = R.rows() - 1;
01363         mat S11 = S.get (0, n, 0, n);
01364         mat S12 = S.get (0, n , rvn._dsize(), end);
01365         mat S22 = S.get (rvn._dsize(), end, rvn._dsize(), end);
01366 
01367         vec mu1 = mu (irvn);
01368         vec mu2 = mu (irvc);
01369         mat A = S12 * inv (S22);
01370         sq_T R_n (S11 - A *S12.T());
01371 
01372         uptarget.set_rv (rvn);
01373         uptarget.set_rvc (rvc);
01374         uptarget.set_parameters (A, mu1 - A*mu2, R_n);
01375 }
01376 
01379 template<class sq_T>
01380 void mgnorm<sq_T >::set_parameters (const shared_ptr<fnc> &g0, const sq_T &R0) {
01381         g = g0;
01382         this->iepdf.set_parameters (zeros (g->dimension()), R0);
01383 }
01384 
01385 template<class sq_T>
01386 void mgnorm<sq_T >::condition (const vec &cond) {this->iepdf._mu() = g->eval (cond);};
01387 
01389 template<class sq_T>
01390 std::ostream &operator<< (std::ostream &os,  mlnorm<sq_T> &ml)
01391 {
01392         os << "A:" << ml.A << endl;
01393         os << "mu:" << ml.mu_const << endl;
01394         os << "R:" << ml._R() << endl;
01395         return os;
01396 };
01397 
01398 }
01399 #endif //EF_H