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);
00145                 void from_setting (const Setting &root);
00146                 void validate() {
00147                         bdm_assert (mu.length() == R.rows(), "mu and R parameters do not match");
00148                         dim = mu.length();
00149                 }
00151 
00154 
00156                 void dupdate (mat &v, double nu = 1.0);
00157 
00158                 vec sample() const;
00159 
00160                 double evallog_nn (const vec &val) const;
00161                 double lognc () const;
00162                 vec mean() const {return mu;}
00163                 vec variance() const {return diag (R.to_mat());}
00164 
00165                 shared_ptr<mpdf> condition ( const RV &rvn ) const;
00166 
00167                 
00168                 
00169                 
00170                 
00171                 void condition ( const RV &rvn, mpdf &target ) const;
00172 
00173                 shared_ptr<epdf> marginal (const RV &rvn ) const;
00174                 void marginal ( const RV &rvn, enorm<sq_T> &target ) const;
00176 
00179 
00180                 vec& _mu() {return mu;}
00181                 const vec& _mu() const {return mu;}
00182                 void set_mu (const vec mu0) { mu = mu0;}
00183                 sq_T& _R() {return R;}
00184                 const sq_T& _R() const {return R;}
00186 
00187 };
00188 UIREGISTER2 (enorm, chmat);
00189 SHAREDPTR2 ( enorm, chmat );
00190 UIREGISTER2 (enorm, ldmat);
00191 SHAREDPTR2 ( enorm, ldmat );
00192 UIREGISTER2 (enorm, fsqmat);
00193 SHAREDPTR2 ( enorm, fsqmat );
00194 
00195 
00202 class egiw : public eEF
00203 {
00204         protected:
00206                 ldmat V;
00208                 double nu;
00210                 int dimx;
00212                 int nPsi;
00213         public:
00216                 egiw() : eEF() {};
00217                 egiw (int dimx0, ldmat V0, double nu0 = -1.0) : eEF() {set_parameters (dimx0, V0, nu0);};
00218 
00219                 void set_parameters (int dimx0, ldmat V0, double nu0 = -1.0);
00221 
00222                 vec sample() const;
00223                 vec mean() const;
00224                 vec variance() const;
00225 
00227                 vec est_theta() const;
00228 
00230                 ldmat est_theta_cov() const;
00231 
00233                 void mean_mat (mat &M, mat&R) const;
00235                 double evallog_nn (const vec &val) const;
00236                 double lognc () const;
00237                 void pow (double p) {V *= p;nu *= p;};
00238 
00241 
00242                 ldmat& _V() {return V;}
00243                 const ldmat& _V() const {return V;}
00244                 double& _nu()  {return nu;}
00245                 const double& _nu() const {return nu;}
00260                 void from_setting (const Setting &set) {
00261                         epdf::from_setting(set);
00262                         if (!UI::get (nu, set, "nu", UI::compulsory)) {nu=-1;}
00263                         UI::get (dimx, set, "dimx", UI::compulsory);
00264                         mat V;
00265                         UI::get (V, set, "V", UI::compulsory);
00266                         set_parameters (dimx, V, nu);
00267                 }
00269 };
00270 UIREGISTER ( egiw );
00271 SHAREDPTR ( egiw );
00272 
00281 class eDirich: public eEF
00282 {
00283         protected:
00285                 vec beta;
00286         public:
00289 
00290                 eDirich () : eEF () {};
00291                 eDirich (const eDirich &D0) : eEF () {set_parameters (D0.beta);};
00292                 eDirich (const vec &beta0) {set_parameters (beta0);};
00293                 void set_parameters (const vec &beta0) {
00294                         beta = beta0;
00295                         dim = beta.length();
00296                 }
00298 
00300                 vec sample() const {
00301                         vec y(beta.length());
00302                         for (int i=0; i<beta.length(); i++){
00303                                 GamRNG.setup(beta(i),1);
00304                                 y(i)=GamRNG.sample();
00305                         }
00306                         return y/sum(y);
00307                 }
00308 
00309                 vec mean() const {return beta / sum (beta);};
00310                 vec variance() const {double gamma = sum (beta); return elem_mult (beta, (gamma-beta)) / (gamma*gamma* (gamma + 1));}
00312                 double evallog_nn (const vec &val) const {
00313                         double tmp; tmp = (beta - 1) * log (val);
00314                         return tmp;
00315                 }
00316 
00317                 double lognc () const {
00318                         double tmp;
00319                         double gam = sum (beta);
00320                         double lgb = 0.0;
00321                         for (int i = 0;i < beta.length();i++) {lgb += lgamma (beta (i));}
00322                         tmp = lgb - lgamma (gam);
00323                         return tmp;
00324                 }
00325 
00327                 vec& _beta()  {return beta;}
00334                 void from_setting(const Setting &set){
00335                         epdf::from_setting(set);
00336                         UI::get(beta,set, "beta", UI::compulsory);
00337                         validate();
00338                 }
00339                 void validate() {
00340                         
00341                         dim = beta.length();
00342                 }
00343 };
00344 UIREGISTER(eDirich);
00345 
00357 class mDirich: public mpdf_internal<eDirich> {
00358         protected:
00360                 double k;
00362                 vec &_beta;
00364                 vec betac;
00365         public:
00366                 mDirich(): mpdf_internal<eDirich>(), _beta(iepdf._beta()){};
00367                 void condition (const vec &val) {_beta =  val/k+betac; };
00380                 void from_setting (const Setting &set) {
00381                         mpdf::from_setting (set); 
00382                         if (_rv()._dsize()>0){
00383                                 rvc = _rv().copy_t(-1);
00384                         }
00385                         vec beta0; 
00386                         if (!UI::get (beta0, set, "beta0", UI::optional)){
00387                                 beta0 = ones(_rv()._dsize());
00388                         }
00389                         if (!UI::get (betac, set, "betac", UI::optional)){
00390                                 betac = 0.1*ones(_rv()._dsize());
00391                         }
00392                         _beta = beta0;
00393                         
00394                         UI::get (k, set, "k", UI::compulsory);
00395                         validate();
00396                 }
00397                 void validate() { 
00398                         iepdf.validate();
00399                         bdm_assert(_beta.length()==betac.length(),"beta0 and betac are not compatible");
00400                         if (_rv()._dsize()>0){
00401                                 bdm_assert( (_rv()._dsize()==dimension()) , "Size of rv does not match with beta");
00402                         }
00403                         dimc = _beta.length();
00404                 };
00405 };
00406 UIREGISTER(mDirich);
00407 
00409 class multiBM : public BMEF
00410 {
00411         protected:
00413                 eDirich est;
00415                 vec β
00416         public:
00418                 multiBM () : BMEF (), est (), beta (est._beta()) {
00419                         if (beta.length() > 0) {last_lognc = est.lognc();}
00420                         else{last_lognc = 0.0;}
00421                 }
00423                 multiBM (const multiBM &B) : BMEF (B), est (B.est), beta (est._beta()) {}
00425                 void set_statistics (const BM* mB0) {const multiBM* mB = dynamic_cast<const multiBM*> (mB0); beta = mB->beta;}
00426                 void bayes (const vec &dt) {
00427                         if (frg < 1.0) {beta *= frg;last_lognc = est.lognc();}
00428                         beta += dt;
00429                         if (evalll) {ll = est.lognc() - last_lognc;}
00430                 }
00431                 double logpred (const vec &dt) const {
00432                         eDirich pred (est);
00433                         vec &beta = pred._beta();
00434 
00435                         double lll;
00436                         if (frg < 1.0)
00437                                 {beta *= frg;lll = pred.lognc();}
00438                         else
00439                                 if (evalll) {lll = last_lognc;}
00440                                 else{lll = pred.lognc();}
00441 
00442                         beta += dt;
00443                         return pred.lognc() - lll;
00444                 }
00445                 void flatten (const BMEF* B) {
00446                         const multiBM* E = dynamic_cast<const multiBM*> (B);
00447                         
00448                         const vec &Eb = E->beta;
00449                         beta *= (sum (Eb) / sum (beta));
00450                         if (evalll) {last_lognc = est.lognc();}
00451                 }
00453                 const eDirich& posterior() const {return est;};
00455                 void set_parameters (const vec &beta0) {
00456                         est.set_parameters (beta0);
00457                         if (evalll) {last_lognc = est.lognc();}
00458                 }
00459 };
00460 
00470 class egamma : public eEF
00471 {
00472         protected:
00474                 vec alpha;
00476                 vec beta;
00477         public :
00480                 egamma () : eEF (), alpha (0), beta (0) {};
00481                 egamma (const vec &a, const vec &b) {set_parameters (a, b);};
00482                 void set_parameters (const vec &a, const vec &b) {alpha = a, beta = b;dim = alpha.length();};
00484 
00485                 vec sample() const;
00486                 double evallog (const vec &val) const;
00487                 double lognc () const;
00489                 vec& _alpha() {return alpha;}
00491                 vec& _beta() {return beta;}
00492                 vec mean() const {return elem_div (alpha, beta);}
00493                 vec variance() const {return elem_div (alpha, elem_mult (beta, beta)); }
00494 
00505                 void from_setting (const Setting &set) {
00506                         epdf::from_setting (set); 
00507                         UI::get (alpha, set, "alpha", UI::compulsory);
00508                         UI::get (beta, set, "beta", UI::compulsory);
00509                         validate();
00510                 }
00511                 void validate() {
00512                         bdm_assert (alpha.length() == beta.length(), "parameters do not match");
00513                         dim = alpha.length();
00514                 }
00515 };
00516 UIREGISTER (egamma);
00517 SHAREDPTR ( egamma );
00518 
00535 class eigamma : public egamma
00536 {
00537         protected:
00538         public :
00543 
00544                 vec sample() const {return 1.0 / egamma::sample();};
00546                 vec mean() const {return elem_div (beta, alpha - 1);}
00547                 vec variance() const {vec mea = mean(); return elem_div (elem_mult (mea, mea), alpha - 2);}
00548 };
00549 
00551 
00552 
00553 
00554 
00555 
00556 
00558 
00559 
00560 
00561 
00562 
00563 
00565 
00566 class euni: public epdf
00567 {
00568         protected:
00570                 vec low;
00572                 vec high;
00574                 vec distance;
00576                 double nk;
00578                 double lnk;
00579         public:
00582                 euni () : epdf () {}
00583                 euni (const vec &low0, const vec &high0) {set_parameters (low0, high0);}
00584                 void set_parameters (const vec &low0, const vec &high0) {
00585                         distance = high0 - low0;
00586                         low = low0;
00587                         high = high0;
00588                         nk = prod (1.0 / distance);
00589                         lnk = log (nk);
00590                         dim = low.length();
00591                 }
00593 
00594                 double evallog (const vec &val) const  {
00595                         if (any (val < low) && any (val > high)) {return inf;}
00596                         else return lnk;
00597                 }
00598                 vec sample() const {
00599                         vec smp (dim);
00600 #pragma omp critical
00601                         UniRNG.sample_vector (dim , smp);
00602                         return low + elem_mult (distance, smp);
00603                 }
00605                 vec mean() const {return (high -low) / 2.0;}
00606                 vec variance() const {return (pow (high, 2) + pow (low, 2) + elem_mult (high, low)) / 3.0;}
00617                 void from_setting (const Setting &set) {
00618                         epdf::from_setting (set); 
00619 
00620                         UI::get (high, set, "high", UI::compulsory);
00621                         UI::get (low, set, "low", UI::compulsory);
00622                         set_parameters(low,high);
00623                         validate();
00624                 }
00625                 void validate() {
00626                         bdm_assert(high.length()==low.length(), "Incompatible high and low vectors");
00627                         dim = high.length();
00628                         bdm_assert (min (distance) > 0.0, "bad support");
00629                 }
00630 };
00631 UIREGISTER(euni);
00632 
00638 template < class sq_T, template <typename> class TEpdf = enorm >
00639 class mlnorm : public mpdf_internal< TEpdf<sq_T> >
00640 {
00641         protected:
00643                 mat A;
00645                 vec mu_const;
00646 
00647         public:
00650                 mlnorm() : mpdf_internal< TEpdf<sq_T> >() {};
00651                 mlnorm (const mat &A, const vec &mu0, const sq_T &R) : mpdf_internal< TEpdf<sq_T> >() {
00652                         set_parameters (A, mu0, R);
00653                 }
00654 
00656                 void set_parameters (const  mat &A0, const vec &mu0, const sq_T &R0) {  
00657                         this->iepdf.set_parameters (zeros (A0.rows()), R0);
00658                         A = A0;
00659                         mu_const = mu0;
00660                         this->dimc = A0.cols();
00661                 }
00664                 void condition (const vec &cond) {
00665                         this->iepdf._mu() = A * cond + mu_const;
00666 
00667                 }
00668 
00670                 const vec& _mu_const() const {return mu_const;}
00672                 const mat& _A() const {return A;}
00674                 mat _R() const { return this->iepdf._R().to_mat(); }
00675 
00677                 template<typename sq_M>
00678                 friend std::ostream &operator<< (std::ostream &os,  mlnorm<sq_M, enorm> &ml);
00679 
00690                 void from_setting (const Setting &set) {
00691                         mpdf::from_setting (set);
00692 
00693                         UI::get (A, set, "A", UI::compulsory);
00694                         UI::get (mu_const, set, "const", UI::compulsory);
00695                         mat R0;
00696                         UI::get (R0, set, "R", UI::compulsory);
00697                         set_parameters (A, mu_const, R0);
00698                         validate();
00699                 };
00700                 void validate() {
00701                         bdm_assert (A.rows() == mu_const.length(), "mlnorm: A vs. mu mismatch");
00702                         bdm_assert (A.rows() == _R().rows(), "mlnorm: A vs. R mismatch");
00703                         
00704                 }
00705 };
00706 UIREGISTER2 (mlnorm,ldmat);
00707 SHAREDPTR2 ( mlnorm, ldmat );
00708 UIREGISTER2 (mlnorm,fsqmat);
00709 SHAREDPTR2 ( mlnorm, fsqmat );
00710 UIREGISTER2 (mlnorm, chmat);
00711 SHAREDPTR2 ( mlnorm, chmat );
00712 
00714 template<class sq_T>
00715 class mgnorm : public mpdf_internal< enorm< sq_T > >
00716 {
00717         private:
00718 
00719                 shared_ptr<fnc> g;
00720 
00721         public:
00723                 mgnorm() : mpdf_internal<enorm<sq_T> >() { }
00725                 inline void set_parameters (const shared_ptr<fnc> &g0, const sq_T &R0);
00726                 inline void condition (const vec &cond);
00727 
00728 
00747                 void from_setting (const Setting &set) {
00748                         mpdf::from_setting(set);
00749                         shared_ptr<fnc> g = UI::build<fnc> (set, "g", UI::compulsory);
00750 
00751                         mat R;
00752                         vec dR;
00753                         if (UI::get (dR, set, "dR"))
00754                                 R = diag (dR);
00755                         else
00756                                 UI::get (R, set, "R", UI::compulsory);
00757 
00758                         set_parameters (g, R);
00759                         validate();
00760                 }
00761                 void validate() {
00762                         bdm_assert(g->dimension()==this->dimension(),"incompatible function");
00763                 }
00764 };
00765 
00766 UIREGISTER2 (mgnorm, chmat);
00767 SHAREDPTR2 ( mgnorm, chmat );
00768 
00769 
00777 class mlstudent : public mlnorm<ldmat, enorm>
00778 {
00779         protected:
00781                 ldmat Lambda;
00783                 ldmat &_R;
00785                 ldmat Re;
00786         public:
00787                 mlstudent () : mlnorm<ldmat, enorm> (),
00788                                 Lambda (),      _R (iepdf._R()) {}
00790                 void set_parameters (const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0) {
00791                         iepdf.set_parameters (mu0, R0);
00792                         A = A0;
00793                         mu_const = mu0;
00794                         Re = R0;
00795                         Lambda = Lambda0;
00796                 }
00797                 void condition (const vec &cond) {
00798                         iepdf._mu() = A * cond + mu_const;
00799                         double zeta;
00800                         
00801                         if ( (cond.length() + 1) == Lambda.rows()) {
00802                                 zeta = Lambda.invqform (concat (cond, vec_1 (1.0)));
00803                         } else {
00804                                 zeta = Lambda.invqform (cond);
00805                         }
00806                         _R = Re;
00807                         _R *= (1 + zeta);
00808                 };
00809 
00810                 void validate() {
00811                         bdm_assert (A.rows() == mu_const.length(), "mlstudent: A vs. mu mismatch");
00812                         bdm_assert (_R.rows() == A.rows(), "mlstudent: A vs. R mismatch");
00813                         
00814                 }
00815 };
00825 class mgamma : public mpdf_internal<egamma>
00826 {
00827         protected:
00828 
00830                 double k;
00831 
00833                 vec &_beta;
00834 
00835         public:
00837                 mgamma() : mpdf_internal<egamma>(), k (0),
00838                                 _beta (iepdf._beta()) {
00839                 }
00840 
00842                 void set_parameters (double k, const vec &beta0);
00843 
00844                 void condition (const vec &val) {_beta = k / val;};
00856                 void from_setting (const Setting &set) {
00857                         mpdf::from_setting (set); 
00858                         vec betatmp; 
00859                         UI::get (betatmp, set, "beta", UI::compulsory);
00860                         UI::get (k, set, "k", UI::compulsory);
00861                         set_parameters (k, betatmp);
00862                 }
00863 };
00864 UIREGISTER (mgamma);
00865 SHAREDPTR (mgamma);
00866 
00876 class migamma : public mpdf_internal<eigamma>
00877 {
00878         protected:
00880                 double k;
00881 
00883                 vec &_alpha;
00884 
00886                 vec &_beta;
00887 
00888         public:
00891                 migamma() : mpdf_internal<eigamma>(),
00892                                 k (0),
00893                                 _alpha (iepdf._alpha()),
00894                                 _beta (iepdf._beta()) {
00895                 }
00896 
00897                 migamma (const migamma &m) : mpdf_internal<eigamma>(),
00898                                 k (0),
00899                                 _alpha (iepdf._alpha()),
00900                                 _beta (iepdf._beta()) {
00901                 }
00903 
00905                 void set_parameters (int len, double k0) {
00906                         k = k0;
00907                         iepdf.set_parameters ( (1.0 / (k*k) + 2.0) *ones (len) , ones (len) );
00908                         dimc = dimension();
00909                 };
00910                 void condition (const vec &val) {
00911                         _beta = elem_mult (val, (_alpha - 1.0));
00912                 };
00913 };
00914 
00915 
00927 class mgamma_fix : public mgamma
00928 {
00929         protected:
00931                 double l;
00933                 vec refl;
00934         public:
00936                 mgamma_fix () : mgamma (), refl () {};
00938                 void set_parameters (double k0 , vec ref0, double l0) {
00939                         mgamma::set_parameters (k0, ref0);
00940                         refl = pow (ref0, 1.0 - l0);l = l0;
00941                         dimc = dimension();
00942                 };
00943 
00944                 void condition (const vec &val) {vec mean = elem_mult (refl, pow (val, l)); _beta = k / mean;};
00945 };
00946 
00947 
00960 class migamma_ref : public migamma
00961 {
00962         protected:
00964                 double l;
00966                 vec refl;
00967         public:
00969                 migamma_ref () : migamma (), refl () {};
00971                 void set_parameters (double k0 , vec ref0, double l0) {
00972                         migamma::set_parameters (ref0.length(), k0);
00973                         refl = pow (ref0, 1.0 - l0);
00974                         l = l0;
00975                         dimc = dimension();
00976                 };
00977 
00978                 void condition (const vec &val) {
00979                         vec mean = elem_mult (refl, pow (val, l));
00980                         migamma::condition (mean);
00981                 };
00982 
00983 
00996                 void from_setting (const Setting &set);
00997 
00998                 
00999 };
01000 
01001 
01002 UIREGISTER (migamma_ref);
01003 SHAREDPTR (migamma_ref);
01004 
01015 class elognorm: public enorm<ldmat>
01016 {
01017         public:
01018                 vec sample() const {return exp (enorm<ldmat>::sample());};
01019                 vec mean() const {vec var = enorm<ldmat>::variance();return exp (mu - 0.5*var);};
01020 
01021 };
01022 
01029 class mlognorm : public mpdf_internal<elognorm>
01030 {
01031         protected:
01033                 double sig2;
01034 
01036                 vec μ
01037         public:
01039                 mlognorm() : mpdf_internal<elognorm>(),
01040                                 sig2 (0),
01041                                 mu (iepdf._mu()) {
01042                 }
01043 
01045                 void set_parameters (int size, double k) {
01046                         sig2 = 0.5 * log (k * k + 1);
01047                         iepdf.set_parameters (zeros (size), 2*sig2*eye (size));
01048 
01049                         dimc = size;
01050                 };
01051 
01052                 void condition (const vec &val) {
01053                         mu = log (val) - sig2;
01054                 };
01055 
01067                 void from_setting (const Setting &set);
01068 
01069                 
01070 
01071 };
01072 
01073 UIREGISTER (mlognorm);
01074 SHAREDPTR (mlognorm);
01075 
01079 class eWishartCh : public epdf
01080 {
01081         protected:
01083                 chmat Y;
01085                 int p;
01087                 double delta;
01088         public:
01090                 void set_parameters (const mat &Y0, const double delta0) {Y = chmat (Y0);delta = delta0; p = Y.rows(); dim = p * p; }
01092                 mat sample_mat() const {
01093                         mat X = zeros (p, p);
01094 
01095                         
01096                         for (int i = 0;i < p;i++) {
01097                                 GamRNG.setup (0.5* (delta - i) , 0.5);   
01098 #pragma omp critical
01099                                 X (i, i) = sqrt (GamRNG());
01100                         }
01101                         
01102                         for (int i = 0;i < p;i++) {
01103                                 for (int j = i + 1;j < p;j++) {
01104 #pragma omp critical
01105                                         X (i, j) = NorRNG.sample();
01106                                 }
01107                         }
01108                         return X*Y._Ch();
01109                 }
01110                 vec sample () const {
01111                         return vec (sample_mat()._data(), p*p);
01112                 }
01114                 void setY (const mat &Ch0) {copy_vector (dim, Ch0._data(), Y._Ch()._data());}
01116                 void _setY (const vec &ch0) {copy_vector (dim, ch0._data(), Y._Ch()._data()); }
01118                 const chmat& getY() const {return Y;}
01119 };
01120 
01122 
01124 class eiWishartCh: public epdf
01125 {
01126         protected:
01128                 eWishartCh W;
01130                 int p;
01132                 double delta;
01133         public:
01135                 void set_parameters (const mat &Y0, const double delta0) {
01136                         delta = delta0;
01137                         W.set_parameters (inv (Y0), delta0);
01138                         dim = W.dimension(); p = Y0.rows();
01139                 }
01140                 vec sample() const {mat iCh; iCh = inv (W.sample_mat()); return vec (iCh._data(), dim);}
01142                 void _setY (const vec &y0) {
01143                         mat Ch (p, p);
01144                         mat iCh (p, p);
01145                         copy_vector (dim, y0._data(), Ch._data());
01146 
01147                         iCh = inv (Ch);
01148                         W.setY (iCh);
01149                 }
01150                 virtual double evallog (const vec &val) const {
01151                         chmat X (p);
01152                         const chmat& Y = W.getY();
01153 
01154                         copy_vector (p*p, val._data(), X._Ch()._data());
01155                         chmat iX (p);X.inv (iX);
01156                         
01157 
01158                         mat M = Y.to_mat() * iX.to_mat();
01159 
01160                         double log1 = 0.5 * p * (2 * Y.logdet()) - 0.5 * (delta + p + 1) * (2 * X.logdet()) - 0.5 * trace (M);
01161                         
01162 
01163                         
01164 
01165 
01166 
01167 
01168 
01169 
01170                         return log1;
01171                 };
01172 
01173 };
01174 
01176 class rwiWishartCh : public mpdf_internal<eiWishartCh>
01177 {
01178         protected:
01180                 double sqd;
01182                 vec refl;
01184                 double l;
01186                 int p;
01187 
01188         public:
01189                 rwiWishartCh() : sqd (0), l (0), p (0) {}
01191                 void set_parameters (int p0, double k, vec ref0, double l0) {
01192                         p = p0;
01193                         double delta = 2 / (k * k) + p + 3;
01194                         sqd = sqrt (delta - p - 1);
01195                         l = l0;
01196                         refl = pow (ref0, 1 - l);
01197 
01198                         iepdf.set_parameters (eye (p), delta);
01199                         dimc = iepdf.dimension();
01200                 }
01201                 void condition (const vec &c) {
01202                         vec z = c;
01203                         int ri = 0;
01204                         for (int i = 0;i < p*p;i += (p + 1)) {
01205                                 z (i) = pow (z (i), l) * refl (ri);
01206                                 ri++;
01207                         }
01208 
01209                         iepdf._setY (sqd*z);
01210                 }
01211 };
01212 
01214 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
01220 class eEmp: public epdf
01221 {
01222         protected :
01224                 int n;
01226                 vec w;
01228                 Array<vec> samples;
01229         public:
01232                 eEmp () : epdf (), w (), samples () {};
01234                 eEmp (const eEmp &e) : epdf (e), w (e.w), samples (e.samples) {};
01236 
01238                 void set_statistics (const vec &w0, const epdf &pdf0);
01240                 void set_statistics (const epdf &pdf0 , int n) {set_statistics (ones (n) / n, pdf0);};
01242                 void set_samples (const epdf* pdf0);
01244                 void set_parameters (int n0, bool copy = true) {n = n0; w.set_size (n0, copy);samples.set_size (n0, copy);};
01246                 void set_parameters (const Array<vec> &Av) {
01247                         bdm_assert(Av.size()>0,"Empty samples"); 
01248                         n = Av.size(); 
01249                         epdf::set_parameters(Av(0).length());
01250                         w=1/n*ones(n);
01251                         samples=Av;
01252                 };
01254                 vec& _w()  {return w;};
01256                 const vec& _w() const {return w;};
01258                 Array<vec>& _samples() {return samples;};
01260                 const vec& _sample(int i) const {return samples(i);};
01262                 const Array<vec>& _samples() const {return samples;};
01265                 void resample ( ivec &index, RESAMPLING_METHOD method = SYSTEMATIC);
01266 
01268                 void resample (RESAMPLING_METHOD method = SYSTEMATIC){ivec ind; resample(ind,method);};
01269                 
01271                 vec sample() const {
01272                         bdm_error ("Not implemented");
01273                         return vec();
01274                 }
01275 
01277                 double evallog (const vec &val) const {
01278                         bdm_error ("Not implemented");
01279                         return 0.0;
01280                 }
01281 
01282                 vec mean() const {
01283                         vec pom = zeros (dim);
01284                         for (int i = 0;i < n;i++) {pom += samples (i) * w (i);}
01285                         return pom;
01286                 }
01287                 vec variance() const {
01288                         vec pom = zeros (dim);
01289                         for (int i = 0;i < n;i++) {pom += pow (samples (i), 2) * w (i);}
01290                         return pom -pow (mean(), 2);
01291                 }
01293                 void qbounds (vec &lb, vec &ub, double perc = 0.95) const {
01294                         
01295                         lb.set_size (dim);
01296                         ub.set_size (dim);
01297                         lb = std::numeric_limits<double>::infinity();
01298                         ub = -std::numeric_limits<double>::infinity();
01299                         int j;
01300                         for (int i = 0;i < n;i++) {
01301                                 for (j = 0;j < dim; j++) {
01302                                         if (samples (i) (j) < lb (j)) {lb (j) = samples (i) (j);}
01303                                         if (samples (i) (j) > ub (j)) {ub (j) = samples (i) (j);}
01304                                 }
01305                         }
01306                 }
01307 };
01308 
01309 
01311 
01312 template<class sq_T>
01313 void enorm<sq_T>::set_parameters (const vec &mu0, const sq_T &R0)
01314 {
01315 
01316         mu = mu0;
01317         R = R0;
01318         validate();
01319 };
01320 
01321 template<class sq_T>
01322 void enorm<sq_T>::from_setting (const Setting &set)
01323 {
01324         epdf::from_setting (set); 
01325 
01326         UI::get (mu, set, "mu", UI::compulsory);
01327         mat Rtmp;
01328         UI::get (Rtmp, set, "R", UI::compulsory);
01329         R = Rtmp; 
01330         validate();
01331 }
01332 
01333 template<class sq_T>
01334 void enorm<sq_T>::dupdate (mat &v, double nu)
01335 {
01336         
01337 };
01338 
01339 
01340 
01341 
01342 
01343 
01344 template<class sq_T>
01345 vec enorm<sq_T>::sample() const
01346 {
01347         vec x (dim);
01348 #pragma omp critical
01349         NorRNG.sample_vector (dim, x);
01350         vec smp = R.sqrt_mult (x);
01351 
01352         smp += mu;
01353         return smp;
01354 };
01355 
01356 
01357 
01358 
01359 
01360 
01361 
01362 
01363 
01364 template<class sq_T>
01365 double enorm<sq_T>::evallog_nn (const vec &val) const
01366 {
01367         
01368         double tmp = -0.5 * (R.invqform (mu - val));
01369         return  tmp;
01370 };
01371 
01372 template<class sq_T>
01373 inline double enorm<sq_T>::lognc () const
01374 {
01375         
01376         double tmp = 0.5 * (R.cols() * 1.83787706640935 + R.logdet());
01377         return tmp;
01378 };
01379 
01380 
01381 
01382 
01383 
01384 
01385 
01386 
01387 
01388 
01389 
01390 
01391 
01392 
01393 
01394 
01395 
01396 
01397 
01398 
01399 
01400 
01401 
01402 
01403 
01404 
01405 
01406 
01407 template<class sq_T>
01408 shared_ptr<epdf> enorm<sq_T>::marginal ( const RV &rvn ) const
01409 {
01410         enorm<sq_T> *tmp = new enorm<sq_T> ();
01411         shared_ptr<epdf> narrow(tmp);
01412         marginal ( rvn, *tmp );
01413         return narrow;
01414 }
01415 
01416 template<class sq_T>
01417 void enorm<sq_T>::marginal ( const RV &rvn, enorm<sq_T> &target ) const
01418 {
01419         bdm_assert (isnamed(), "rv description is not assigned");
01420         ivec irvn = rvn.dataind (rv);
01421 
01422         sq_T Rn (R, irvn);  
01423 
01424         target.set_rv ( rvn );
01425         target.set_parameters (mu (irvn), Rn);
01426 }
01427 
01428 template<class sq_T>
01429 shared_ptr<mpdf> enorm<sq_T>::condition ( const RV &rvn ) const
01430 {
01431         mlnorm<sq_T> *tmp = new mlnorm<sq_T> ();
01432         shared_ptr<mpdf> narrow(tmp);
01433         condition ( rvn, *tmp );
01434         return narrow;
01435 }
01436 
01437 template<class sq_T>
01438 void enorm<sq_T>::condition ( const RV &rvn, mpdf &target ) const
01439 {
01440         typedef mlnorm<sq_T> TMlnorm;
01441 
01442         bdm_assert (isnamed(), "rvs are not assigned");
01443         TMlnorm &uptarget = dynamic_cast<TMlnorm &>(target);
01444 
01445         RV rvc = rv.subt (rvn);
01446         bdm_assert ( (rvc._dsize() + rvn._dsize() == rv._dsize()), "wrong rvn");
01447         
01448         ivec irvn = rvn.dataind (rv);
01449         ivec irvc = rvc.dataind (rv);
01450         ivec perm = concat (irvn , irvc);
01451         sq_T Rn (R, perm);
01452 
01453         
01454         mat S = Rn.to_mat();
01455         
01456         int n = rvn._dsize() - 1;
01457         int end = R.rows() - 1;
01458         mat S11 = S.get (0, n, 0, n);
01459         mat S12 = S.get (0, n , rvn._dsize(), end);
01460         mat S22 = S.get (rvn._dsize(), end, rvn._dsize(), end);
01461 
01462         vec mu1 = mu (irvn);
01463         vec mu2 = mu (irvc);
01464         mat A = S12 * inv (S22);
01465         sq_T R_n (S11 - A *S12.T());
01466 
01467         uptarget.set_rv (rvn);
01468         uptarget.set_rvc (rvc);
01469         uptarget.set_parameters (A, mu1 - A*mu2, R_n);
01470 }
01471 
01474 template<class sq_T>
01475 void mgnorm<sq_T >::set_parameters (const shared_ptr<fnc> &g0, const sq_T &R0) {
01476         g = g0;
01477         this->iepdf.set_parameters (zeros (g->dimension()), R0);
01478 }
01479 
01480 template<class sq_T>
01481 void mgnorm<sq_T >::condition (const vec &cond) {this->iepdf._mu() = g->eval (cond);};
01482 
01484 template<class sq_T>
01485 std::ostream &operator<< (std::ostream &os,  mlnorm<sq_T> &ml)
01486 {
01487         os << "A:" << ml.A << endl;
01488         os << "mu:" << ml.mu_const << endl;
01489         os << "R:" << ml._R() << endl;
01490         return os;
01491 };
01492 
01493 }
01494 #endif //EF_H