root/library/bdm/stat/exp_family.h @ 1068

Revision 1068, 55.0 kB (checked in by mido, 14 years ago)

patch of documentation - all conditional pdfs revised

  • Property svn:eol-style set to native
RevLine 
[8]1/*!
2  \file
3  \brief Probability distributions for Exponential Family models.
4  \author Vaclav Smidl.
5
6  -----------------------------------
7  BDM++ - C++ library for Bayesian Decision Making under Uncertainty
8
9  Using IT++ for numerical operations
10  -----------------------------------
11*/
12
13#ifndef EF_H
14#define EF_H
15
[262]16
[461]17#include "../shared_ptr.h"
[384]18#include "../base/bdmbase.h"
[262]19#include "../math/chmat.h"
[8]20
[737]21namespace bdm {
[8]22
[32]23
24//! Global Uniform_RNG
[488]25extern Uniform_RNG UniRNG;
[33]26//! Global Normal_RNG
[488]27extern Normal_RNG NorRNG;
[33]28//! Global Gamma_RNG
[488]29extern Gamma_RNG GamRNG;
[32]30
[488]31/*!
[1063]32* \brief Abstract class of general conjugate exponential family posterior density.
[8]33
[488]34* More?...
35*/
[737]36class eEF : public epdf {
37public:
[1066]38//    eEF() :epdf() {};
[1064]39    //! default constructor
40    eEF () : epdf () {};
41    //! logarithm of the normalizing constant, \f$\mathcal{I}\f$
42    virtual double lognc() const = 0;
[565]43
[1064]44    //!Evaluate normalized log-probability
45    virtual double evallog_nn ( const vec &val ) const NOT_IMPLEMENTED(0);
[565]46
[1064]47    //!Evaluate normalized log-probability
48    virtual double evallog ( const vec &val ) const {
49        double tmp;
50        tmp = evallog_nn ( val ) - lognc();
51        return tmp;
52    }
53    //!Evaluate normalized log-probability for many samples
54    virtual vec evallog_mat ( const mat &Val ) const {
55        vec x ( Val.cols() );
56        for ( int i = 0; i < Val.cols(); i++ ) {
57            x ( i ) = evallog_nn ( Val.get_col ( i ) ) ;
58        }
59        return x - lognc();
60    }
61    //!Evaluate normalized log-probability for many samples
62    virtual vec evallog_mat ( const Array<vec> &Val ) const {
63        vec x ( Val.length() );
64        for ( int i = 0; i < Val.length(); i++ ) {
65            x ( i ) = evallog_nn ( Val ( i ) ) ;
66        }
67        return x - lognc();
68    }
[565]69
[1064]70    //!Power of the density, used e.g. to flatten the density
71    virtual void pow ( double p ) NOT_IMPLEMENTED_VOID;
[488]72};
[8]73
[33]74
[170]75//! Estimator for Exponential family
[737]76class BMEF : public BM {
77public:
[1064]78    //! forgetting factor
79    double frg;
80protected:
81    //! cached value of lognc() in the previous step (used in evaluation of \c ll )
82    double last_lognc;
83    //! factor k = [0..1] for scheduling of forgetting factor: \f$ frg_t = (1-k) * frg_{t-1} + k \f$, default 0
84    double frg_sched_factor;
85public:
86    //! Default constructor (=empty constructor)
87    BMEF ( double frg0 = 1.0 ) : BM (), frg ( frg0 ), last_lognc(0.0),frg_sched_factor(0.0) {}
88    //! Copy constructor
89    BMEF ( const BMEF &B ) : BM ( B ), frg ( B.frg ), last_lognc ( B.last_lognc ),frg_sched_factor(B.frg_sched_factor) {}
90    //!get statistics from another model
91    virtual void set_statistics ( const BMEF* BM0 ) NOT_IMPLEMENTED_VOID;
[565]92
[1064]93    //! Weighted update of sufficient statistics (Bayes rule)
94    virtual void bayes_weighted ( const vec &data, const vec &cond = empty_vec, const double w = 1.0 ) {
95        if (frg_sched_factor>0) {
96            frg = frg*(1-frg_sched_factor)+frg_sched_factor;
97        }
98    };
99    //original Bayes
100    void bayes ( const vec &yt, const vec &cond = empty_vec );
[565]101
[1064]102    //!Flatten the posterior according to the given BMEF (of the same type!)
103    virtual void flatten ( const BMEF * B, double weight=1.0 ) NOT_IMPLEMENTED_VOID;;
[198]104
[746]105
[1064]106    void to_setting ( Setting &set ) const
107    {
108        BM::to_setting( set );
109        UI::save(frg, set, "frg");
110        UI::save( frg_sched_factor, set, "frg_sched_factor" );
111    }
[907]112
[1064]113    void from_setting( const Setting &set) {
114        BM::from_setting(set);
115        if ( !UI::get ( frg, set, "frg" ) )
116            frg = 1.0;
117        UI::get ( frg_sched_factor, set, "frg_sched_factor",UI::optional );
118    }
[850]119
[1064]120    void validate() {
121        BM::validate();
122    }
[850]123
[488]124};
[170]125
[1068]126/*! \brief Dirac delta density with predefined transformation
[797]127
128Density of the type:\f[ f(x_t | y_t) = \delta (x_t - g(y_t)) \f]
129where \f$ x_t \f$ is the \c rv, \f$ y_t \f$ is the \c rvc and g is a deterministic transformation of class fn.
130*/
[1064]131class mgdirac: public pdf {
132protected:
133    shared_ptr<fnc> g;
134public:
135    vec samplecond(const vec &cond) {
136        bdm_assert_debug(cond.length()==g->dimensionc(),"given cond in not compatible with g");
137        vec tmp = g->eval(cond);
138        return tmp;
139    }
140    double evallogcond ( const vec &yt, const vec &cond ) {
141        return std::numeric_limits< double >::max();
142    }
[1068]143
144    /*! Create object from the following structure
145
146    \code
147    class = 'mgdirac';
148    g = function bdm::fnc;      % any offspring of fnc, bdm::fnc::from_setting
149    --- inherited fields ---
150    bdm::pdf::from_setting
151    \endcode
152    */
[1064]153    void from_setting(const Setting& set);
154    void to_setting(Setting &set) const;
155    void validate();
[797]156};
157UIREGISTER(mgdirac);
158
159
[504]160template<class sq_T, template <typename> class TEpdf>
[488]161class mlnorm;
[178]162
[488]163/*!
164* \brief Gaussian density with positive definite (decomposed) covariance matrix.
[8]165
[488]166* More?...
167*/
168template<class sq_T>
[737]169class enorm : public eEF {
170protected:
[1064]171    //! mean value
172    vec mu;
173    //! Covariance matrix in decomposed form
174    sq_T R;
[737]175public:
[1064]176    //!\name Constructors
177    //!@{
[270]178
[1064]179    enorm () : eEF (), mu (), R () {};
180    enorm ( const vec &mu, const sq_T &R ) {
181        set_parameters ( mu, R );
182    }
183    void set_parameters ( const vec &mu, const sq_T &R );
184    /*! Create Normal density
185    \f[ f(rv) = N(\mu, R) \f]
186    from structure
187    \code
188    class = 'enorm<ldmat>', (OR) 'enorm<chmat>', (OR) 'enorm<fsqmat>';
189    mu    = [];                  // mean value
190    R     = [];                  // variance, square matrix of appropriate dimension
191    \endcode
192    */
193    void from_setting ( const Setting &root );
194    void to_setting ( Setting &root ) const ;
[270]195
[1064]196    void validate();
197    //!@}
[270]198
[1064]199    //! \name Mathematical operations
200    //!@{
[28]201
[1064]202    //! dupdate in exponential form (not really handy)
203    void dupdate ( mat &v, double nu = 1.0 );
[450]204
[1064]205    //! evaluate bhattacharya distance
206    double bhattacharyya(const enorm<sq_T> &e2) {
207        bdm_assert(dim == e2.dimension(), "enorms of differnt dimensions");
208        sq_T P=R;
209        P.add(e2._R());
[504]210
[1064]211        double tmp = 0.125*P.invqform(mu - e2._mu()) + 0.5*(P.logdet() - 0.5*(R.logdet() + e2._R().logdet()));
212        return tmp;
213    }
[504]214
[1064]215    vec sample() const;
[270]216
[1064]217    double evallog_nn ( const vec &val ) const;
218    double lognc () const;
219    vec mean() const {
220        return mu;
221    }
222    vec variance() const {
223        return diag ( R.to_mat() );
224    }
225    mat covariance() const {
226        return R.to_mat();
227    }
[1066]228    //    mlnorm<sq_T>* condition ( const RV &rvn ) const ; <=========== fails to cmpile. Why?
[1064]229    shared_ptr<pdf> condition ( const RV &rvn ) const;
[270]230
[1064]231    // target not typed to mlnorm<sq_T, enorm<sq_T> > &
232    // because that doesn't compile (perhaps because we
233    // haven't finished defining enorm yet), but the type
234    // is required
235    void condition ( const RV &rvn, pdf &target ) const;
[28]236
[1064]237    shared_ptr<epdf> marginal ( const RV &rvn ) const;
238    void marginal ( const RV &rvn, enorm<sq_T> &target ) const;
239    //!@}
240
241    //! \name Access to attributes
242    //!@{
243
244    vec& _mu() {
245        return mu;
246    }
247    const vec& _mu() const {
248        return mu;
249    }
250    void set_mu ( const vec mu0 ) {
251        mu = mu0;
252    }
253    sq_T& _R() {
254        return R;
255    }
256    const sq_T& _R() const {
257        return R;
258    }
259    //!@}
260
[488]261};
[737]262UIREGISTER2 ( enorm, chmat );
[529]263SHAREDPTR2 ( enorm, chmat );
[737]264UIREGISTER2 ( enorm, ldmat );
[529]265SHAREDPTR2 ( enorm, ldmat );
[737]266UIREGISTER2 ( enorm, fsqmat );
[529]267SHAREDPTR2 ( enorm, fsqmat );
[8]268
[1064]269//! \class bdm::egauss
[948]270//!\brief Gaussian (Normal) distribution. Same as enorm<fsqmat>.
[887]271typedef enorm<ldmat> egauss;
272UIREGISTER(egauss);
273
274
[802]275//forward declaration
276class mstudent;
[388]277
[802]278/*! distribution of multivariate Student t density
279
[1064]280Based on article by Genest and Zidek,
[802]281*/
282template<class sq_T>
[1064]283class estudent : public eEF {
284protected:
285    //! mena value
286    vec mu;
287    //! matrix H
288    sq_T H;
289    //! degrees of freedom
290    double delta;
291public:
292    double evallog_nn(const vec &val) const {
293        double tmp = -0.5*H.logdet() - 0.5*(delta + dim) * log(1+ H.invqform(val - mu)/delta);
294        return tmp;
295    }
296    double lognc() const {
297        //log(pi) = 1.14472988584940
298        double tmp = -lgamma(0.5*(delta+dim))+lgamma(0.5*delta) + 0.5*dim*(log(delta) + 1.14472988584940);
299        return tmp;
300    }
301    void marginal (const RV &rvm, estudent<sq_T> &marg) const {
302        ivec ind = rvm.findself_ids(rv); // indices of rvm in rv
303        marg._mu() = mu(ind);
304        marg._H() = sq_T(H,ind);
305        marg._delta() = delta;
306        marg.validate();
307    }
308    shared_ptr<epdf> marginal(const RV &rvm) const {
309        shared_ptr<estudent<sq_T> > tmp = new estudent<sq_T>;
310        marginal(rvm, *tmp);
311        return tmp;
312    }
313    vec sample() const NOT_IMPLEMENTED(vec(0))
314
315    vec mean() const {
316        return mu;
317    }
318    mat covariance() const {
319        return delta/(delta-2)*H.to_mat();
320    }
321    vec variance() const {
322        return diag(covariance());
323    }
324    //! \name access
325    //! @{
326    //! access function
327    vec& _mu() {
328        return mu;
329    }
330    //! access function
331    sq_T& _H() {
332        return H;
333    }
334    //! access function
335    double& _delta() {
336        return delta;
337    }
338    //!@}
339    //! todo
340    void from_setting(const Setting &set) {
341        epdf::from_setting(set);
342        mat H0;
343        UI::get(H0,set, "H");
344        H= H0; // conversion!!
345        UI::get(delta,set,"delta");
346        UI::get(mu,set,"mu");
347    }
348    void to_setting(Setting &set) const {
349        epdf::to_setting(set);
350        UI::save(H.to_mat(), set, "H");
351        UI::save(delta, set, "delta");
352        UI::save(mu, set, "mu");
353    }
354    void validate() {
355        eEF::validate();
356        dim = H.rows();
357    }
[802]358};
359UIREGISTER2(estudent,fsqmat);
360UIREGISTER2(estudent,ldmat);
361UIREGISTER2(estudent,chmat);
362
[488]363/*!
364* \brief Gauss-inverse-Wishart density stored in LD form
[96]365
[488]366* For \f$p\f$-variate densities, given rv.count() should be \f$p\times\f$ V.rows().
367*
368*/
[737]369class egiw : public eEF {
[1064]370    //! \var log_level_enums logvartheta
371    //! Log variance of the theta part
[870]372
[1064]373    LOG_LEVEL(egiw,logvartheta);
[907]374
[737]375protected:
[1064]376    //! Extended information matrix of sufficient statistics
377    ldmat V;
378    //! Number of data records (degrees of freedom) of sufficient statistics
379    double nu;
380    //! Dimension of the output
381    int dimx;
382    //! Dimension of the regressor
383    int nPsi;
[737]384public:
[1064]385    //!\name Constructors
386    //!@{
387    egiw() : eEF(),dimx(0) {};
388    egiw ( int dimx0, ldmat V0, double nu0 = -1.0 ) : eEF(),dimx(0) {
389        set_parameters ( dimx0, V0, nu0 );
390        validate();
391    };
[270]392
[1064]393    void set_parameters ( int dimx0, ldmat V0, double nu0 = -1.0 );
394    //!@}
[96]395
[1064]396    vec sample() const;
397    mat sample_mat ( int n ) const;
398    vec mean() const;
399    vec variance() const;
400    //mat covariance() const;
401    void sample_mat ( mat &Mi, chmat &Ri ) const;
[330]402
[1064]403    void factorize ( mat &M, ldmat &Vz, ldmat &Lam ) const;
404    //! LS estimate of \f$\theta\f$
405    vec est_theta() const;
[330]406
[1064]407    //! Covariance of the LS estimate
408    ldmat est_theta_cov() const;
[96]409
[1064]410    //! expected values of the linear coefficient and the covariance matrix are written to \c M and \c R , respectively
411    void mean_mat ( mat &M, mat&R ) const;
412    //! In this instance, val= [theta, r]. For multivariate instances, it is stored columnwise val = [theta_1 theta_2 ... r_1 r_2 ]
413    double evallog_nn ( const vec &val ) const;
414    double lognc () const;
415    void pow ( double p ) {
416        V *= p;
417        nu *= p;
418    };
[270]419
[1064]420    //! marginal density (only student for now)
421    shared_ptr<epdf> marginal(const RV &rvm) const {
422        bdm_assert(dimx==1, "Not supported");
423        //TODO - this is too trivial!!!
424        ivec ind = rvm.findself_ids(rv);
425        if (min(ind)==0) { //assume it si
426            shared_ptr<estudent<ldmat> > tmp = new estudent<ldmat>;
427            mat M;
428            ldmat Vz;
429            ldmat Lam;
430            factorize(M,Vz,Lam);
[737]431
[1064]432            tmp->_mu() = M.get_col(0);
433            ldmat H;
434            Vz.inv(H);
435            H *=Lam._D()(0)/nu;
436            tmp->_H() = H;
437            tmp->_delta() = nu;
438            tmp->validate();
439            return tmp;
440        }
441        return NULL;
442    }
443    //! \name Access attributes
444    //!@{
[737]445
[1064]446    ldmat& _V() {
447        return V;
448    }
449    const ldmat& _V() const {
450        return V;
451    }
452    double& _nu()  {
453        return nu;
454    }
455    const double& _nu() const {
456        return nu;
457    }
458    const int & _dimx() const {
459        return dimx;
460    }
[889]461
[1066]462    /*! Create object from the following structure
[1064]463    \code
[1066]464
[1064]465    class = 'egiw';
[1066]466    dimx    = [...];       % dimension of the wishart part
467    V.L     = [...];       % L part of matrix V
468    V.D     = [...];       % D part of matrix V
469    -or- V  = [...];       % full matrix V
470    -or- dV = [...];       % vector of diagonal of V (when V not given)
471
472    rv = RV({'names',...},[sizes,...],[times,...]);   % description of RV
473    rvc = RV({'names',...},[sizes,...],[times,...]);  % description of RV in condition
474
475    --- optional fields ---
476    nu      = [];             % scalar \nu ((almost) degrees of freedom)
477    --- inherited fields ---
478    bdm::eEF::from_setting
[1064]479    \endcode
[737]480
[1066]481    fulfilling formula \f[ f(rv) = GiW(V,\nu) \f]
482
483    If \nu is not given, it will be computed to obtain proper pdf.
484
[1064]485    \sa log_level_enums
486    */
487    void from_setting ( const Setting &set );
488    //! see egiw::from_setting
489    void to_setting ( Setting& set ) const;
490    void validate();
491    void log_register ( bdm::logger& L, const string& prefix );
492
493    void log_write() const;
494    //!@}
[488]495};
[529]496UIREGISTER ( egiw );
497SHAREDPTR ( egiw );
[96]498
[488]499/*! \brief Dirichlet posterior density
[173]500
[488]501Continuous Dirichlet density of \f$n\f$-dimensional variable \f$x\f$
502\f[
503f(x|\beta) = \frac{\Gamma[\gamma]}{\prod_{i=1}^{n}\Gamma(\beta_i)} \prod_{i=1}^{n}x_i^{\beta_i-1}
504\f]
505where \f$\gamma=\sum_i \beta_i\f$.
506*/
[737]507class eDirich: public eEF {
508protected:
[1064]509    //!sufficient statistics
510    vec beta;
[737]511public:
[1064]512    //!\name Constructors
513    //!@{
[270]514
[1064]515    eDirich () : eEF () {};
516    eDirich ( const eDirich &D0 ) : eEF () {
517        set_parameters ( D0.beta );
518        validate();
519    };
520    eDirich ( const vec &beta0 ) {
521        set_parameters ( beta0 );
522        validate();
523    };
524    void set_parameters ( const vec &beta0 ) {
525        beta = beta0;
526        dim = beta.length();
527    }
528    //!@}
[270]529
[1064]530    //! using sampling procedure from wikipedia
531    vec sample() const {
532        vec y ( beta.length() );
533        for ( int i = 0; i < beta.length(); i++ ) {
534            GamRNG.setup ( beta ( i ), 1 );
[737]535#pragma omp critical
[1064]536            y ( i ) = GamRNG();
537        }
538        return y / sum ( y );
539    }
[565]540
[1064]541    vec mean() const {
542        return beta / sum ( beta );
543    };
544    vec variance() const {
545        double gamma = sum ( beta );
546        return elem_mult ( beta, ( gamma - beta ) ) / ( gamma*gamma* ( gamma + 1 ) );
547    }
548    //! In this instance, val is ...
549    double evallog_nn ( const vec &val ) const {
550        double tmp;
551        tmp = ( beta - 1 ) * log ( val );
552        return tmp;
553    }
[565]554
[1064]555    double lognc () const {
556        double tmp;
557        double gam = sum ( beta );
558        double lgb = 0.0;
559        for ( int i = 0; i < beta.length(); i++ ) {
560            lgb += lgamma ( beta ( i ) );
561        }
562        tmp = lgb - lgamma ( gam );
563        return tmp;
564    }
[565]565
[1064]566    //!access function
567    vec& _beta()  {
568        return beta;
569    }
[1063]570
[1064]571    /*! Create object from the following structure
572    \code
573    class = 'eDirich';
574    beta  = [...];           % vector parameter beta
575    --- inherited fields ---
576    bdm::eEF::from_setting
577    \endcode
578    */
579    void from_setting ( const Setting &set );
[1063]580
[1064]581    void validate();
[1063]582
[1064]583    void to_setting ( Setting &set ) const;
[488]584};
[737]585UIREGISTER ( eDirich );
[96]586
[1063]587/*! \brief Product of Beta distributions
[1033]588
589Continuous Dirichlet density of \f$n\f$-dimensional variable \f$x\f$
590\f[
[1064]591f(x|\alpha,\beta)  = \frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)}\, x^{\alpha-1}(1-x)^{\beta-1}
[1033]592\f]
593is a simplification of Dirichlet to univariate case.
594*/
595class eBeta: public eEF {
[1064]596public:
597    //!sufficient statistics
598    vec alpha;
599    //!sufficient statistics
600    vec beta;
601public:
602    //!\name Constructors
603    //!@{
[1063]604
[1064]605    eBeta () : eEF () {};
606    eBeta ( const eBeta &B0 ) : eEF (), alpha(B0.alpha),beta(B0.beta) {
607        validate();
608    };
609    //!@}
[1063]610
[1064]611    //! using sampling procedure from wikipedia
612    vec sample() const {
613        vec y ( beta.length() ); // all vectors
614        for ( int i = 0; i < beta.length(); i++ ) {
615            GamRNG.setup ( alpha ( i ), 1 );
616#pragma omp critical
617            double Ga = GamRNG();
[1063]618
[1064]619            GamRNG.setup ( beta ( i ), 1 );
620#pragma omp critical
621            double Gb = GamRNG();
622
623            y ( i ) = Ga/(Ga+Gb);
624        }
625        return y;
626    }
627
628    vec mean() const {
629        return elem_div(alpha, alpha + beta); // dot-division
630    };
631    vec variance() const {
632        vec apb=alpha+beta;
633        return elem_div (elem_mult ( alpha, beta) ,
634                         elem_mult ( elem_mult(apb,apb), apb+1 ) );
635    }
636    //! In this instance, val is ...
637    double evallog_nn ( const vec &val ) const {
638        double tmp;
639        tmp = ( alpha - 1 ) * log ( val ) + (beta-1)*log(1-val);
640        return tmp;
641    }
642
643    double lognc () const {
644        double lgb = 0.0;
645        for ( int i = 0; i < beta.length(); i++ ) {
646            lgb += -lgamma ( alpha(i)+beta(i) ) + lgamma(alpha(i)) + lgamma(beta(i));
647        }
648        return lgb;
649    }
650
651    /*! Create object from the following structure
652
653    \code
654    class = 'eBeta';
655    alpha = [...];           % vector parameter alpha
656    beta  = [...];           % vector parameter beta of the same length as alpha
657    \endcode
658
659    Class does not call bdm::eEF::from_setting
660    */
661    void from_setting ( const Setting &set ) {
662        UI::get(alpha, set, "alpha", UI::compulsory);
663        UI::get(beta, set, "beta", UI::compulsory);
664    }
665
666    void validate() {
667        bdm_assert(alpha.length()==beta.length(), "eBeta:: alpha and beta length do not match");
668        dim = alpha.length();
669    }
670
671    void to_setting ( Setting &set ) const {
672        UI::save(alpha, set, "alpha");
673        UI::save(beta, set, "beta");
674    }
[1033]675};
676UIREGISTER ( eBeta );
677
[1068]678/*! \brief Random Walk on Dirichlet
679
[737]680Using simple assignment
[637]681 \f[ \beta = rvc / k + \beta_c \f]
682 hence, mean value = rvc, variance = (k+1)*mean*mean;
[737]683
[637]684 The greater k is, the greater is the variance of the random walk;
[737]685
[637]686 \f$ \beta_c \f$ is used as regularizing element to avoid corner cases, i.e. when one element of rvc is zero.
687 By default is it set to 0.1;
688*/
[693]689class mDirich: public pdf_internal<eDirich> {
[737]690protected:
[1064]691    //! constant \f$ k \f$ of the random walk
692    double k;
693    //! cache of beta_i
694    vec &_beta;
695    //! stabilizing coefficient \f$ \beta_c \f$
696    vec betac;
[737]697public:
[1064]698    mDirich() : pdf_internal<eDirich>(), _beta ( iepdf._beta() ) {};
699    void condition ( const vec &val ) {
700        _beta =  val / k + betac;
701    };
[1068]702
703    /*! Create object from the following structure
[1064]704    \code
705    class = 'mDirich';
[1068]706    k = 1;                      % multiplicative constant k
[1064]707    --- optional ---
[1068]708    beta0 = [...];              % initial values of beta
709    betac = [...];              % initial values of beta stabilizing coefficients
710    --- inherited fields ---
711    bdm::pdf::from_setting
[1064]712    \endcode
[1068]713    fulfilling form  \f[ f(rv|rvc) = Di(rvc*k) \f]
714
715    If the optional fields are not given, they will be filled as follows:
716    \code
717    beta0 = [1,1,1,...];               
718    betac = 0.1 * [1,1,1,...];
719    \endcode
[1064]720    */
721    void from_setting ( const Setting &set );
[1066]722    void     to_setting  (Setting  &set) const;
[1064]723    void validate();
[637]724};
[737]725UIREGISTER ( mDirich );
[637]726
[1033]727/*! \brief Random Walk with vector Beta distribution
[1068]728
[1033]729Using simple assignment
[1064]730\f{eqnarray*}
[1063]731\alpha & = & rvc / k + \beta_c \\
732\beta & = &(1-rvc) / k + \beta_c \\
733\f}
[1033]734for each element of alpha and beta, mean value = rvc, variance = (k+1)*mean*mean;
[977]735
[1033]736The greater \f$ k \f$ is, the greater is the variance of the random walk;
737
738\f$ \beta_c \f$ is used as regularizing element to avoid corner cases, i.e. when one element of rvc is zero.
739By default is it set to 0.1;
740*/
[1064]741class mBeta: public pdf_internal<eBeta> {
742    //! vector of constants \f$ k \f$ of the random walk
743    vec k;
744    //! stabilizing coefficient \f$ \beta_c \f$
745    vec betac;
[1033]746
[1064]747public:
748    void condition ( const vec &val ) {
749        this->iepdf.alpha =  elem_div(val , k) + betac;
750        this->iepdf.beta =  elem_div (1-val , k) + betac;
751    };
[1063]752
[1068]753    /*! Create object from the following structure
[1064]754    \code
755    class = 'mBeta';
[1068]756    k = [...];          % vector of multiplicative constants k
757    --- optional fields ---
758    beta  = [...];      % initial values of beta
759    betac = [...];      % initial values of beta stabilizing constants
760    --- inherited fields ---
761    bdm::pdf::from_setting
[1064]762    \endcode
[1068]763    fulfilling form \f[ f(rv|rvc) = \prod Beta(rvc,k) \f]
764
765    If the optional fields are not given, they will be filled as follows:
766    \code
767    beta  = [1,1,1,...];
768    betac = 0.1 * [1,1,1,...];
769    \endcode
770   
[1064]771    */
772    void from_setting ( const Setting &set );
[1063]773
[1064]774    void to_setting  (Setting  &set) const;
775
776    void validate() {
777        pdf_internal<eBeta>::validate();
778        bdm_assert(betac.length()==dimension(),"Incomaptible betac");
779        bdm_assert(k.length()==dimension(),"Incomaptible k");
780        dimc = iepdf.dimension();
781    }
782    //!
[1033]783};
784UIREGISTER(mBeta);
785
[181]786//! \brief Estimator for Multinomial density
[737]787class multiBM : public BMEF {
788protected:
[1064]789    //! Conjugate prior and posterior
790    eDirich est;
791    //! Pointer inside est to sufficient statistics
792    vec &beta;
[737]793public:
[1064]794    //!Default constructor
795    multiBM () : BMEF (), est (), beta ( est._beta() ) {
796        if ( beta.length() > 0 ) {
797            last_lognc = est.lognc();
798        } else {
799            last_lognc = 0.0;
800        }
801    }
802    //!Copy constructor
803    multiBM ( const multiBM &B ) : BMEF ( B ), est ( B.est ), beta ( est._beta() ) {}
804    //! Sets sufficient statistics to match that of givefrom mB0
805    void set_statistics ( const BM* mB0 ) {
806        const multiBM* mB = dynamic_cast<const multiBM*> ( mB0 );
807        beta = mB->beta;
808    }
809    void bayes ( const vec &yt, const vec &cond = empty_vec );
[176]810
[1064]811    double logpred ( const vec &yt ) const;
[170]812
[1064]813    void flatten ( const BMEF* B , double weight);
[739]814
[1064]815    //! return correctly typed posterior (covariant return)
816    const eDirich& posterior() const {
817        return est;
818    };
819    //! constructor function
820    void set_parameters ( const vec &beta0 ) {
821        est.set_parameters ( beta0 );
822        est.validate();
823        if ( evalll ) {
824            last_lognc = est.lognc();
825        }
826    }
[746]827
[1064]828    void to_setting ( Setting &set ) const {
829        BMEF::to_setting ( set );
830        UI::save( &est, set, "prior" );
831    }
832    void from_setting (const Setting &set )  {
833        BMEF::from_setting ( set );
834        UI::get( est, set, "prior" );
835    }
[488]836};
[746]837UIREGISTER( multiBM );
[170]838
[488]839/*!
840 \brief Gamma posterior density
[32]841
[488]842 Multivariate Gamma density as product of independent univariate densities.
843 \f[
844 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i)
845 \f]
846*/
[32]847
[737]848class egamma : public eEF {
849protected:
[1064]850    //! Vector \f$\alpha\f$
851    vec alpha;
852    //! Vector \f$\beta\f$
853    vec beta;
[737]854public :
[1064]855    //! \name Constructors
856    //!@{
857    egamma () : eEF (), alpha ( 0 ), beta ( 0 ) {};
858    egamma ( const vec &a, const vec &b ) {
859        set_parameters ( a, b );
860        validate();
861    };
862    void set_parameters ( const vec &a, const vec &b ) {
863        alpha = a, beta = b;
864    };
865    //!@}
[270]866
[1064]867    vec sample() const;
868    double evallog ( const vec &val ) const;
869    double lognc () const;
870    //! Returns pointer to internal alpha. Potentially dengerous: use with care!
871    vec& _alpha() {
872        return alpha;
873    }
874    //! Returns pointer to internal beta. Potentially dengerous: use with care!
875    vec& _beta() {
876        return beta;
877    }
878    vec mean() const {
879        return elem_div ( alpha, beta );
880    }
881    vec variance() const {
882        return elem_div ( alpha, elem_mult ( beta, beta ) );
883    }
[225]884
[1064]885    /*! Create object from the following structure
[1063]886
[1064]887    \code
888    class = 'egamma';
[1066]889    alpha = [...];         % vector alpha
890    beta = [...];          % vector beta
[1064]891    --- inherited fields ---
892    bdm::eEF::from_setting
893    \endcode
894     fulfilling formula \f[ f(rv|rvc) = \Gamma(\alpha, \beta) \f]
895    */
896    void from_setting ( const Setting &set );
[1063]897
[1064]898    void to_setting ( Setting &set ) const;
899    void validate();
[488]900};
[737]901UIREGISTER ( egamma );
[529]902SHAREDPTR ( egamma );
903
[488]904/*!
905 \brief Inverse-Gamma posterior density
[225]906
[488]907 Multivariate inverse-Gamma density as product of independent univariate densities.
908 \f[
909 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i)
910 \f]
[283]911
[488]912Vector \f$\beta\f$ has different meaning (in fact it is 1/beta as used in definition of iG)
[225]913
[488]914 Inverse Gamma can be converted to Gamma using \f[
915 x\sim iG(a,b) => 1/x\sim G(a,1/b)
916\f]
917This relation is used in sampling.
918 */
[270]919
[737]920class eigamma : public egamma {
921protected:
922public :
[1064]923    //! \name Constructors
924    //! All constructors are inherited
925    //!@{
926    //!@}
[32]927
[1064]928    vec sample() const {
929        return 1.0 / egamma::sample();
930    };
931    //! Returns poiter to alpha and beta. Potentially dangerous: use with care!
932    vec mean() const {
933        return elem_div ( beta, alpha - 1 );
934    }
935    vec variance() const {
936        vec mea = mean();
937        return elem_div ( elem_mult ( mea, mea ), alpha - 2 );
938    }
[488]939};
940/*
941//! Weighted mixture of epdfs with external owned components.
942class emix : public epdf {
943protected:
[1066]944    int n;
945    vec &w;
946    Array<epdf*> Coms;
[488]947public:
948//! Default constructor
[1066]949    emix ( const RV &rv, vec &w0): epdf(rv), n(w0.length()), w(w0), Coms(n) {};
950    void set_parameters( int &i, double wi, epdf* ep){w(i)=wi;Coms(i)=ep;}
951    vec mean(){vec pom; for(int i=0;i<n;i++){pom+=Coms(i)->mean()*w(i);} return pom;};
[488]952};
953*/
954
[1068]955//! \brief Uniform distributed density on a rectangular support
[737]956class euni: public epdf {
957protected:
[32]958//! lower bound on support
[1064]959    vec low;
[32]960//! upper bound on support
[1064]961    vec high;
[32]962//! internal
[1064]963    vec distance;
[32]964//! normalizing coefficients
[1064]965    double nk;
[33]966//! cache of log( \c nk )
[1064]967    double lnk;
[737]968public:
[1064]969    //! \name Constructors
970    //!@{
971    euni () : epdf () {}
972    euni ( const vec &low0, const vec &high0 ) {
973        set_parameters ( low0, high0 );
974    }
975    void set_parameters ( const vec &low0, const vec &high0 ) {
976        distance = high0 - low0;
977        low = low0;
978        high = high0;
979        nk = prod ( 1.0 / distance );
980        lnk = log ( nk );
981    }
982    //!@}
[270]983
[1064]984    double evallog ( const vec &val ) const  {
985        if ( any ( val < low ) && any ( val > high ) ) {
986            return -inf;
987        } else return lnk;
988    }
989    vec sample() const {
990        vec smp ( dim );
[270]991#pragma omp critical
[1064]992        UniRNG.sample_vector ( dim , smp );
993        return low + elem_mult ( distance, smp );
994    }
995    //! set values of \c low and \c high
996    vec mean() const {
997        return ( high - low ) / 2.0;
998    }
999    vec variance() const {
1000        return ( pow ( high, 2 ) + pow ( low, 2 ) + elem_mult ( high, low ) ) / 3.0;
1001    }
[1068]1002
1003
1004     /*! Create object from the following structure
[1064]1005     \code
[1068]1006   
[1064]1007     class = 'euni'
[1068]1008     high = [...];          % vector of upper bounds
1009     low = [...];           % vector of lower bounds     
1010      rv = RV({'names',...},[sizes,...],[times,...]);   % description of RV
1011     --- inherited fields ---
1012     bdm::epdf::from_setting
[1064]1013     \endcode
[1068]1014
1015     fulfilling form \f[ f(rv) = U(low,high) \f]
[1064]1016     */
1017    void from_setting ( const Setting &set );
[1066]1018    void     to_setting  (Setting  &set) const;
[1064]1019    void validate();
[488]1020};
[737]1021UIREGISTER ( euni );
[32]1022
[665]1023//! Uniform density with conditional mean value
[737]1024class mguni : public pdf_internal<euni> {
[1064]1025    //! function of the mean value
1026    shared_ptr<fnc> mean;
1027    //! distance from mean to both sides
1028    vec delta;
[737]1029public:
[1064]1030    void condition ( const vec &cond ) {
1031        vec mea = mean->eval ( cond );
1032        iepdf.set_parameters ( mea - delta, mea + delta );
1033    }
[1068]1034
1035    /*! Create object from the following structure
1036    \code
1037    class = 'mguni';
1038    mean = function bdm::fnc;       % any offspring of fnc, bdm::fnc::from_setting
1039    delta = [...];                  % distance from mean to both sides
1040    --- inherited fields ---
1041    bdm::pdf::from_setting
1042    \endcode
1043    */
[1064]1044    void from_setting ( const Setting &set ) {
1045        pdf::from_setting ( set ); //reads rv and rvc
1046        UI::get ( delta, set, "delta", UI::compulsory );
1047        mean = UI::build<fnc> ( set, "mean", UI::compulsory );
1048        iepdf.set_parameters ( -delta, delta );
1049    }
[1066]1050    void     to_setting  (Setting  &set) const {
[1064]1051        pdf::to_setting ( set );
1052        UI::save( iepdf.mean(), set, "delta");
1053        UI::save(mean, set, "mean");
1054    }
1055    void validate() {
1056        pdf_internal<euni>::validate();
1057        dimc = mean->dimensionc();
[878]1058
[1064]1059    }
1060
[665]1061};
[737]1062UIREGISTER ( mguni );
[488]1063/*!
1064 \brief Normal distributed linear function with linear function of mean value;
[32]1065
[536]1066 Mean value \f$ \mu=A*\mbox{rvc}+\mu_0 \f$.
[488]1067*/
1068template < class sq_T, template <typename> class TEpdf = enorm >
[737]1069class mlnorm : public pdf_internal< TEpdf<sq_T> > {
1070protected:
[1064]1071    //! Internal epdf that arise by conditioning on \c rvc
1072    mat A;
1073    //! Constant additive term
1074    vec mu_const;
[1066]1075//            vec& _mu; //cached epdf.mu; !!!!!! WHY NOT?
[737]1076public:
[1064]1077    //! \name Constructors
1078    //!@{
1079    mlnorm() : pdf_internal< TEpdf<sq_T> >() {};
1080    mlnorm ( const mat &A, const vec &mu0, const sq_T &R ) : pdf_internal< TEpdf<sq_T> >() {
1081        set_parameters ( A, mu0, R );
1082        validate();
1083    }
[461]1084
[1064]1085    //! Set \c A and \c R
1086    void set_parameters ( const  mat &A0, const vec &mu0, const sq_T &R0 ) {
1087        this->iepdf.set_parameters ( zeros ( A0.rows() ), R0 );
1088        A = A0;
1089        mu_const = mu0;
1090    }
[878]1091
[1064]1092    //!@}
1093    //! Set value of \c rvc . Result of this operation is stored in \c epdf use function \c _ep to access it.
1094    void condition ( const vec &cond ) {
1095        this->iepdf._mu() = A * cond + mu_const;
[487]1096//R is already assigned;
[1064]1097    }
[198]1098
[1064]1099    //!access function
1100    const vec& _mu_const() const {
1101        return mu_const;
1102    }
1103    //!access function
1104    const mat& _A() const {
1105        return A;
1106    }
1107    //!access function
1108    mat _R() const {
1109        return this->iepdf._R().to_mat();
1110    }
1111    //!access function
1112    sq_T __R() const {
1113        return this->iepdf._R();
1114    }
[8]1115
[1064]1116    //! Debug stream
1117    template<typename sq_M>
1118    friend std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_M, enorm> &ml );
[488]1119
[1064]1120    /*! Create Normal density with linear function of mean value
1121     \f[ f(rv|rvc) = N(A*rvc+const, R) \f]
1122    from structure
1123    \code
1124    class = 'mlnorm<ldmat>', (OR) 'mlnorm<chmat>', (OR) 'mlnorm<fsqmat>';
1125    A     = [];                  // matrix or vector of appropriate dimension
1126    R     = [];                  // square matrix of appropriate dimension
1127    --- optional ---
1128    const = zeros(A.rows);       // vector of constant term
1129    \endcode
1130    */
1131    void from_setting ( const Setting &set ) {
1132        pdf::from_setting ( set );
[737]1133
[1064]1134        UI::get ( A, set, "A", UI::compulsory );
1135        UI::get ( mu_const, set, "const", UI::optional);
1136        mat R0;
1137        UI::get ( R0, set, "R", UI::compulsory );
1138        set_parameters ( A, mu_const, R0 );
1139    }
[956]1140
[1064]1141    void to_setting (Setting &set) const {
1142        pdf::to_setting(set);
1143        UI::save ( A, set, "A");
1144        UI::save ( mu_const, set, "const");
1145        UI::save ( _R(), set, "R");
1146    }
[956]1147
[1064]1148    void validate() {
1149        pdf_internal<TEpdf<sq_T> >::validate();
1150        if (mu_const.length()==0) { // default in from_setting
1151            mu_const=zeros(A.rows());
1152        }
1153        bdm_assert ( A.rows() == mu_const.length(), "mlnorm: A vs. mu mismatch" );
1154        bdm_assert ( A.rows() == _R().rows(), "mlnorm: A vs. R mismatch" );
1155        this->dimc = A.cols();
[737]1156
[1064]1157    }
[488]1158};
[737]1159UIREGISTER2 ( mlnorm, ldmat );
[529]1160SHAREDPTR2 ( mlnorm, ldmat );
[737]1161UIREGISTER2 ( mlnorm, fsqmat );
[529]1162SHAREDPTR2 ( mlnorm, fsqmat );
[737]1163UIREGISTER2 ( mlnorm, chmat );
[529]1164SHAREDPTR2 ( mlnorm, chmat );
[488]1165
[1064]1166//! \class mlgauss
[948]1167//!\brief Normal distribution with linear function of mean value. Same as mlnorm<fsqmat>.
1168typedef mlnorm<fsqmat> mlgauss;
1169UIREGISTER(mlgauss);
1170
[693]1171//! pdf with general function for mean value
[488]1172template<class sq_T>
[737]1173class mgnorm : public pdf_internal< enorm< sq_T > > {
1174private:
[1066]1175//            vec &mu; WHY NOT?
[1064]1176    shared_ptr<fnc> g;
[527]1177
[737]1178public:
[1064]1179    //!default constructor
1180    mgnorm() : pdf_internal<enorm<sq_T> >() { }
1181    //!set mean function
1182    inline void set_parameters ( const shared_ptr<fnc> &g0, const sq_T &R0 );
1183    inline void condition ( const vec &cond );
[357]1184
1185
[1064]1186    /*! Create Normal density with given function of mean value
1187    \f[ f(rv|rvc) = N( g(rvc), R) \f]
1188    from structure
1189    \code
1190    class = 'mgnorm';
1191    g.class =  'fnc';      // function for mean value evolution
1192    g._fields_of_fnc = ...;
[357]1193
[1064]1194    R = [1, 0;             // covariance matrix
[1066]1195        0, 1];
1196        --OR --
[1064]1197    dR = [1, 1];           // diagonal of cavariance matrix
[357]1198
[1064]1199    rv = RV({'name'})      // description of RV
1200    rvc = RV({'name'})     // description of RV in condition
1201    \endcode
1202    */
[357]1203
[956]1204
[1064]1205    void from_setting ( const Setting &set ) {
1206        pdf::from_setting ( set );
1207        shared_ptr<fnc> g = UI::build<fnc> ( set, "g", UI::compulsory );
[357]1208
[1064]1209        mat R;
1210        vec dR;
1211        if ( UI::get ( dR, set, "dR" ) )
1212            R = diag ( dR );
1213        else
1214            UI::get ( R, set, "R", UI::compulsory );
[280]1215
[1064]1216        set_parameters ( g, R );
1217        //validate();
1218    }
[956]1219
1220
[1064]1221    void to_setting  (Setting  &set) const {
1222        UI::save( g,set, "g");
1223        UI::save(this->iepdf._R().to_mat(),set, "R");
[956]1224
[1064]1225    }
[956]1226
1227
[1064]1228
1229    void validate() {
1230        this->iepdf.validate();
1231        bdm_assert ( g->dimension() == this->iepdf.dimension(), "incompatible function" );
1232        this->dim = g->dimension();
1233        this->dimc = g->dimensionc();
1234        this->iepdf.validate();
1235    }
1236
[488]1237};
[357]1238
[737]1239UIREGISTER2 ( mgnorm, chmat );
[944]1240UIREGISTER2 ( mgnorm, ldmat );
[529]1241SHAREDPTR2 ( mgnorm, chmat );
[357]1242
[262]1243
[1068]1244/*! \brief (Approximate) Student t density with linear function of mean value
[262]1245
[488]1246The internal epdf of this class is of the type of a Gaussian (enorm).
1247However, each conditioning is trying to assure the best possible approximation by taking into account the zeta function. See [] for reference.
[270]1248
[488]1249Perhaps a moment-matching technique?
1250*/
[737]1251class mlstudent : public mlnorm<ldmat, enorm> {
1252protected:
[1064]1253    //! Variable \f$ \Lambda \f$ from theory
1254    ldmat Lambda;
1255    //! Reference to variable \f$ R \f$
1256    ldmat &_R;
1257    //! Variable \f$ R_e \f$
1258    ldmat Re;
[737]1259public:
[1064]1260    mlstudent () : mlnorm<ldmat, enorm> (),
[1066]1261        Lambda (),    _R ( iepdf._R() ) {}
[1064]1262    //! constructor function
1263    void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0 ) {
1264        iepdf.set_parameters ( mu0, R0 );// was Lambda, why?
1265        A = A0;
1266        mu_const = mu0;
1267        Re = R0;
1268        Lambda = Lambda0;
1269    }
[294]1270
[1064]1271    void condition ( const vec &cond );
[739]1272
[1064]1273    void validate() {
1274        mlnorm<ldmat, enorm>::validate();
1275        bdm_assert ( A.rows() == mu_const.length(), "mlstudent: A vs. mu mismatch" );
1276        bdm_assert ( _R.rows() == A.rows(), "mlstudent: A vs. R mismatch" );
[737]1277
[1064]1278    }
[488]1279};
[811]1280
[488]1281/*!
1282\brief  Gamma random walk
[198]1283
[488]1284Mean value, \f$\mu\f$, of this density is given by \c rvc .
1285Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
1286This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
[32]1287
[488]1288The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
1289*/
[737]1290class mgamma : public pdf_internal<egamma> {
1291protected:
[461]1292
[1064]1293    //! Constant \f$k\f$
1294    double k;
[461]1295
[1064]1296    //! cache of iepdf.beta
1297    vec &_beta;
[32]1298
[737]1299public:
[1064]1300    //! Constructor
1301    mgamma() : pdf_internal<egamma>(), k ( 0 ),
1302        _beta ( iepdf._beta() ) {
1303    }
[461]1304
[1064]1305    //! Set value of \c k
1306    void set_parameters ( double k, const vec &beta0 );
[461]1307
[1064]1308    void condition ( const vec &val ) {
1309        _beta = k / val;
1310    };
[1068]1311
1312    /*! Create object from the following structure
[1064]1313    \code
[1068]1314    class = 'mgamma';   
1315    beta = [...];      % vector of initial beta
1316    k = x;             %  multiplicative scalar constant k
1317    --- inherited fields ---
1318    bdm::pdf::from_setting
1319    \endcode
1320    fulfilling form \f[ f(rv|rvc) = \Gamma(k, k/rvc) \f]
[1064]1321    */
1322    void from_setting ( const Setting &set );
[1066]1323    void     to_setting  (Setting  &set) const;
[1064]1324    void validate();
[488]1325};
[737]1326UIREGISTER ( mgamma );
1327SHAREDPTR ( mgamma );
[32]1328
[488]1329/*!
1330\brief  Inverse-Gamma random walk
[225]1331
[488]1332Mean value, \f$ \mu \f$, of this density is given by \c rvc .
1333Standard deviation of the random walk is proportional to one \f$ k \f$-th the mean.
1334This is achieved by setting \f$ \alpha=\mu/k^2+2 \f$ and \f$ \beta=\mu(\alpha-1)\f$.
[461]1335
[488]1336The standard deviation of the walk is then: \f$ \mu/\sqrt(k)\f$.
1337 */
[737]1338class migamma : public pdf_internal<eigamma> {
1339protected:
[1064]1340    //! Constant \f$k\f$
1341    double k;
[461]1342
[1064]1343    //! cache of iepdf.alpha
1344    vec &_alpha;
[225]1345
[1064]1346    //! cache of iepdf.beta
1347    vec &_beta;
[461]1348
[737]1349public:
[1064]1350    //! \name Constructors
1351    //!@{
1352    migamma() : pdf_internal<eigamma>(),
1353        k ( 0 ),
1354        _alpha ( iepdf._alpha() ),
1355        _beta ( iepdf._beta() ) {
1356    }
[225]1357
[1064]1358    migamma ( const migamma &m ) : pdf_internal<eigamma>(),
1359        k ( 0 ),
1360        _alpha ( iepdf._alpha() ),
1361        _beta ( iepdf._beta() ) {
1362    }
1363    //!@}
[225]1364
[1064]1365    //! Set value of \c k
1366    void set_parameters ( int len, double k0 ) {
1367        k = k0;
1368        iepdf.set_parameters ( ( 1.0 / ( k*k ) + 2.0 ) *ones ( len ) /*alpha*/, ones ( len ) /*beta*/ );
1369    };
[878]1370
[1066]1371    void     validate () {
[1064]1372        pdf_internal<eigamma>::validate();
1373        dimc = dimension();
1374    };
[878]1375
[1064]1376    void condition ( const vec &val ) {
1377        _beta = elem_mult ( val, ( _alpha - 1.0 ) );
1378    };
[488]1379};
[357]1380
[488]1381/*!
1382\brief  Gamma random walk around a fixed point
[60]1383
[488]1384Mean value, \f$\mu\f$, of this density is given by a geometric combination of \c rvc and given fixed point, \f$p\f$. \f$l\f$ is the coefficient of the geometric combimation
1385\f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f]
[60]1386
[488]1387Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
1388This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
[294]1389
[488]1390The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
1391*/
[737]1392class mgamma_fix : public mgamma {
1393protected:
[1064]1394    //! parameter l
1395    double l;
1396    //! reference vector
1397    vec refl;
[737]1398public:
[1064]1399    //! Constructor
1400    mgamma_fix () : mgamma (), refl () {};
1401    //! Set value of \c k
1402    void set_parameters ( double k0 , vec ref0, double l0 ) {
1403        mgamma::set_parameters ( k0, ref0 );
1404        refl = pow ( ref0, 1.0 - l0 );
1405        l = l0;
1406    };
[878]1407
[1068]1408    void validate () {
[1064]1409        mgamma::validate();
1410        dimc = dimension();
1411    };
[60]1412
[1064]1413    void condition ( const vec &val ) {
1414        vec mean = elem_mult ( refl, pow ( val, l ) );
1415        _beta = k / mean;
1416    };
[488]1417};
[60]1418
[225]1419
[488]1420/*!
1421\brief  Inverse-Gamma random walk around a fixed point
[225]1422
[488]1423Mean value, \f$\mu\f$, of this density is given by a geometric combination of \c rvc and given fixed point, \f$p\f$. \f$l\f$ is the coefficient of the geometric combimation
1424\f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f]
[225]1425
[488]1426==== Check == vv =
1427Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
1428This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
[225]1429
[488]1430The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
1431 */
[737]1432class migamma_ref : public migamma {
1433protected:
[1064]1434    //! parameter l
1435    double l;
1436    //! reference vector
1437    vec refl;
[737]1438public:
[1064]1439    //! Constructor
1440    migamma_ref () : migamma (), refl () {};
[878]1441
[1064]1442    //! Set value of \c k
1443    void set_parameters ( double k0 , vec ref0, double l0 ) {
1444        migamma::set_parameters ( ref0.length(), k0 );
1445        refl = pow ( ref0, 1.0 - l0 );
1446        l = l0;
1447    };
[357]1448
[1064]1449    void validate() {
1450        migamma::validate();
1451        dimc = dimension();
1452    };
[357]1453
[1064]1454    void condition ( const vec &val ) {
1455        vec mean = elem_mult ( refl, pow ( val, l ) );
1456        migamma::condition ( mean );
1457    };
[957]1458
[1068]1459    /*! Create object from the following structure
[1064]1460    \code
1461    class = 'migamma_ref';
[1068]1462    ref = [...];           % reference vector
1463    l = [];                % constant scalar l
1464    k = [];                % constant scalar k   
1465    --- inherited fields ---
1466    bdm::migamma::from_setting
[1064]1467    \endcode
[1068]1468    fulfilling form \f[ f(rv|rvc) = i\Gamma(k, k/(rvc^l \circ ref^{(1-l)}) \f]
[1064]1469     */
1470    void from_setting ( const Setting &set );
1471
1472    void to_setting  (Setting  &set) const;
[488]1473};
[357]1474
1475
[737]1476UIREGISTER ( migamma_ref );
1477SHAREDPTR ( migamma_ref );
[294]1478
[1068]1479/*! \brief Log-Normal probability density - it allows only diagonal covariances!
[294]1480
[488]1481Density of the form \f$ \log(x)\sim \mathcal{N}(\mu,\sigma^2) \f$ , i.e.
1482\f[
1483x \sim \frac{1}{x\sigma\sqrt{2\pi}}\exp{-\frac{1}{2\sigma^2}(\log(x)-\mu)}
1484\f]
[294]1485
[621]1486Function from_setting loads mu and R in the same way as it does for enorm<>!
[488]1487*/
[737]1488class elognorm: public enorm<ldmat> {
1489public:
[1064]1490    vec sample() const {
1491        return exp ( enorm<ldmat>::sample() );
1492    };
1493    vec mean() const {
1494        vec var = enorm<ldmat>::variance();
1495        return exp ( mu - 0.5*var );
1496    };
[285]1497
[488]1498};
[285]1499
[488]1500/*!
1501\brief  Log-Normal random walk
[285]1502
[488]1503Mean value, \f$\mu\f$, is...
[285]1504
[488]1505 */
[737]1506class mlognorm : public pdf_internal<elognorm> {
1507protected:
[1064]1508    //! parameter 1/2*sigma^2
1509    double sig2;
[461]1510
[1064]1511    //! access
1512    vec &mu;
[737]1513public:
[1064]1514    //! Constructor
1515    mlognorm() : pdf_internal<elognorm>(),
1516        sig2 ( 0 ),
1517        mu ( iepdf._mu() ) {
1518    }
[285]1519
[1064]1520    //! Set value of \c k
1521    void set_parameters ( int size, double k ) {
1522        sig2 = 0.5 * log ( k * k + 1 );
1523        iepdf.set_parameters ( zeros ( size ), 2*sig2*eye ( size ) );
1524    };
[357]1525
[1064]1526    void validate() {
1527        pdf_internal<elognorm>::validate();
1528        dimc = iepdf.dimension();
1529    }
[357]1530
[1064]1531    void condition ( const vec &val ) {
1532        mu = log ( val ) - sig2;//elem_mult ( refl,pow ( val,l ) );
1533    };
1534
[1068]1535    /*! Create object from the following structure
[1064]1536    \code
1537    class = 'mlognorm';
[1068]1538    k   = [];               % "variance" k
1539    mu0 = [];               % initial value of mean
1540    --- inherited fields ---
1541    bdm::pdf_internal<elognorm>::from_setting
[1064]1542    \endcode
[1068]1543    fulfilling form \f[ f(rv|rvc) = log\mathcal{N}( \log(rvc)-0.5\log(k^2+1), k I) \f]
[1064]1544    */
1545    void from_setting ( const Setting &set );
1546
1547    void to_setting  (Setting  &set) const;
[488]1548};
[294]1549
[737]1550UIREGISTER ( mlognorm );
1551SHAREDPTR ( mlognorm );
[294]1552
[1068]1553/*! \brief Inverse Wishart density defined on Choleski decomposition
[488]1554*/
[737]1555class eWishartCh : public epdf {
1556protected:
[1064]1557    //! Upper-Triagle of Choleski decomposition of \f$ \Psi \f$
1558    chmat Y;
1559    //! dimension of matrix  \f$ \Psi \f$
1560    int p;
1561    //! degrees of freedom  \f$ \nu \f$
1562    double delta;
[737]1563public:
[1064]1564    //! Set internal structures
1565    void set_parameters ( const mat &Y0, const double delta0 ) {
1566        Y = chmat ( Y0 );
1567        delta = delta0;
1568        p = Y.rows();
1569    }
1570    //! Set internal structures
1571    void set_parameters ( const chmat &Y0, const double delta0 ) {
1572        Y = Y0;
1573        delta = delta0;
1574        p = Y.rows();
1575    }
[878]1576
[1064]1577    virtual void validate () {
1578        epdf::validate();
1579        dim = p * p;
1580    }
[488]1581
[1064]1582    //! Sample matrix argument
1583    mat sample_mat() const {
1584        mat X = zeros ( p, p );
1585
1586        //sample diagonal
1587        for ( int i = 0; i < p; i++ ) {
1588            GamRNG.setup ( 0.5* ( delta - i ) , 0.5 );   // no +1 !! index if from 0
[294]1589#pragma omp critical
[1064]1590            X ( i, i ) = sqrt ( GamRNG() );
1591        }
1592        //do the rest
1593        for ( int i = 0; i < p; i++ ) {
1594            for ( int j = i + 1; j < p; j++ ) {
[294]1595#pragma omp critical
[1064]1596                X ( i, j ) = NorRNG.sample();
1597            }
1598        }
1599        return X*Y._Ch();// return upper triangular part of the decomposition
1600    }
[766]1601
[1064]1602    vec sample () const {
1603        return vec ( sample_mat()._data(), p*p );
1604    }
[766]1605
[1064]1606    virtual vec mean() const NOT_IMPLEMENTED(0);
[766]1607
[1064]1608    //! return expected variance (not covariance!)
1609    virtual vec variance() const NOT_IMPLEMENTED(0);
[766]1610
[1064]1611    virtual double evallog ( const vec &val ) const NOT_IMPLEMENTED(0);
[766]1612
[1064]1613    //! fast access function y0 will be copied into Y.Ch.
1614    void setY ( const mat &Ch0 ) {
1615        copy_vector ( dim, Ch0._data(), Y._Ch()._data() );
1616    }
[766]1617
[1064]1618    //! fast access function y0 will be copied into Y.Ch.
1619    void _setY ( const vec &ch0 ) {
1620        copy_vector ( dim, ch0._data(), Y._Ch()._data() );
1621    }
[766]1622
[1064]1623    //! access function
1624    const chmat& getY() const {
1625        return Y;
1626    }
[488]1627};
[294]1628
[536]1629//! Inverse Wishart on Choleski decomposition
1630/*! Being computed by conversion from `standard' Wishart
1631*/
[737]1632class eiWishartCh: public epdf {
1633protected:
[1064]1634    //! Internal instance of Wishart density
1635    eWishartCh W;
1636    //! size of Ch
1637    int p;
1638    //! parameter delta
1639    double delta;
[737]1640public:
[1064]1641    //! constructor function
1642    void set_parameters ( const mat &Y0, const double delta0 ) {
1643        delta = delta0;
1644        W.set_parameters ( inv ( Y0 ), delta0 );
1645        p = Y0.rows();
1646    }
[488]1647
[1066]1648    virtual void     validate () {
[1064]1649        epdf::validate();
1650        W.validate();
1651        dim = W.dimension();
1652    }
[766]1653
[488]1654
[1064]1655    vec sample() const {
1656        mat iCh;
1657        iCh = inv ( W.sample_mat() );
1658        return vec ( iCh._data(), dim );
1659    }
1660    //! access function
1661    void _setY ( const vec &y0 ) {
1662        mat Ch ( p, p );
1663        mat iCh ( p, p );
1664        copy_vector ( dim, y0._data(), Ch._data() );
1665
1666        iCh = inv ( Ch );
1667        W.setY ( iCh );
1668    }
1669
1670    virtual double evallog ( const vec &val ) const {
1671        chmat X ( p );
1672        const chmat& Y = W.getY();
1673
1674        copy_vector ( p*p, val._data(), X._Ch()._data() );
1675        chmat iX ( p );
1676        X.inv ( iX );
1677        // compute
[1066]1678//                 \frac{ |\Psi|^{m/2}|X|^{-(m+p+1)/2}e^{-tr(\Psi X^{-1})/2} }{ 2^{mp/2}\Gamma_p(m/2)},
[1064]1679        mat M = Y.to_mat() * iX.to_mat();
[285]1680
[1064]1681        double log1 = 0.5 * p * ( 2 * Y.logdet() ) - 0.5 * ( delta + p + 1 ) * ( 2 * X.logdet() ) - 0.5 * trace ( M );
1682        //Fixme! Multivariate gamma omitted!! it is ok for sampling, but not otherwise!!
[461]1683
[1066]1684        /*                if (0) {
1685                            mat XX=X.to_mat();
1686                            mat YY=Y.to_mat();
[461]1687
[1066]1688                            double log2 = 0.5*p*log(det(YY))-0.5*(delta+p+1)*log(det(XX))-0.5*trace(YY*inv(XX));
1689                            cout << log1 << "," << log2 << endl;
1690                        }*/
[1064]1691        return log1;
1692    };
[285]1693
[1064]1694    virtual vec mean() const NOT_IMPLEMENTED(0);
[766]1695
[1064]1696    //! return expected variance (not covariance!)
1697    virtual vec variance() const NOT_IMPLEMENTED(0);
[488]1698};
1699
[536]1700//! Random Walk on inverse Wishart
[737]1701class rwiWishartCh : public pdf_internal<eiWishartCh> {
1702protected:
[1064]1703    //!square root of \f$ \nu-p-1 \f$ - needed for computation of \f$ \Psi \f$ from conditions
1704    double sqd;
1705    //!reference point for diagonal
1706    vec refl;
1707    //! power of the reference
1708    double l;
1709    //! dimension
1710    int p;
[488]1711
[737]1712public:
[1064]1713    rwiWishartCh() : sqd ( 0 ), l ( 0 ), p ( 0 ) {}
1714    //! constructor function
1715    void set_parameters ( int p0, double k, vec ref0, double l0 ) {
1716        p = p0;
1717        double delta = 2 / ( k * k ) + p + 3;
1718        sqd = sqrt ( delta - p - 1 );
1719        l = l0;
1720        refl = pow ( ref0, 1 - l );
1721        iepdf.set_parameters ( eye ( p ), delta );
1722    };
[285]1723
[1064]1724    void validate() {
1725        pdf_internal<eiWishartCh>::validate();
1726        dimc = iepdf.dimension();
1727    }
1728
1729    void condition ( const vec &c ) {
1730        vec z = c;
1731        int ri = 0;
1732        for ( int i = 0; i < p*p; i += ( p + 1 ) ) {//trace diagonal element
1733            z ( i ) = pow ( z ( i ), l ) * refl ( ri );
1734            ri++;
1735        }
1736
1737        iepdf._setY ( sqd*z );
1738    }
[488]1739};
1740
[32]1741//! Switch between various resampling methods.
[488]1742enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
[887]1743
[1064]1744//! Shortcut for multinomial.sample(int n). Various simplifications are allowed see RESAMPLING_METHOD
[887]1745void resample(const vec &w, ivec &ind, RESAMPLING_METHOD=SYSTEMATIC);
1746
[1063]1747/*! \brief Weighted empirical density
[32]1748
[488]1749Used e.g. in particle filters.
1750*/
[737]1751class eEmp: public epdf {
1752protected :
[1064]1753    //! Number of particles
1754    int n;
1755    //! Sample weights \f$w\f$
1756    vec w;
1757    //! Samples \f$x^{(i)}, i=1..n\f$
1758    Array<vec> samples;
[737]1759public:
[1064]1760    //! \name Constructors
1761    //!@{
1762    eEmp () : epdf (), w (), samples () {};
1763    //! copy constructor
1764    eEmp ( const eEmp &e ) : epdf ( e ), w ( e.w ), samples ( e.samples ) {};
1765    //!@}
[280]1766
[1064]1767    //! Set samples and weights
1768    void set_statistics ( const vec &w0, const epdf &pdf0 );
1769    //! Set samples and weights
1770    void set_statistics ( const epdf &pdf0 , int n ) {
1771        set_statistics ( ones ( n ) / n, pdf0 );
1772    };
1773    //! Set sample
1774    void set_samples ( const epdf* pdf0 );
1775    //! Set sample
1776    void set_parameters ( int n0, bool copy = true ) {
1777        n = n0;
1778        w.set_size ( n0, copy );
1779        samples.set_size ( n0, copy );
1780    };
1781    //! Set samples
1782    void set_parameters ( const Array<vec> &Av ) {
1783        n = Av.size();
1784        w = 1 / n * ones ( n );
1785        samples = Av;
1786    };
[1066]1787    virtual void     validate ();
[1064]1788    //! Potentially dangerous, use with care.
1789    vec& _w()  {
1790        return w;
1791    };
1792    //! Potentially dangerous, use with care.
1793    const vec& _w() const {
1794        return w;
1795    };
1796    //! access function
1797    Array<vec>& _samples() {
1798        return samples;
1799    };
1800    //! access function
1801    const vec& _sample ( int i ) const {
1802        return samples ( i );
1803    };
1804    //! access function
1805    const Array<vec>& _samples() const {
1806        return samples;
1807    };
1808    //! Function performs resampling, i.e. removal of low-weight samples and duplication of high-weight samples such that the new samples represent the same density.
1809    void resample ( RESAMPLING_METHOD method = SYSTEMATIC );
[565]1810
[1064]1811    //! inherited operation : NOT implemented
1812    vec sample() const NOT_IMPLEMENTED(0);
[565]1813
[1064]1814    //! inherited operation : NOT implemented
1815    double evallog ( const vec &val ) const NOT_IMPLEMENTED(0);
[737]1816
[1064]1817    vec mean() const {
1818        vec pom = zeros ( dim );
1819        for ( int i = 0; i < n; i++ ) {
1820            pom += samples ( i ) * w ( i );
1821        }
1822        return pom;
1823    }
1824    vec variance() const {
1825        vec pom = zeros ( dim );
1826        for ( int i = 0; i < n; i++ ) {
1827            pom += pow ( samples ( i ), 2 ) * w ( i );
1828        }
1829        return pom - pow ( mean(), 2 );
1830    }
1831    //! For this class, qbounds are minimum and maximum value of the population!
1832    void qbounds ( vec &lb, vec &ub, double perc = 0.95 ) const;
[760]1833
[1064]1834    void to_setting ( Setting &set ) const;
[1063]1835
[1064]1836    /*! Create object from the following structure
1837
1838    \code
1839    class = 'eEmp';
[1066]1840    samples = [...];  % array of samples
1841    w = [...];        % weights of samples stored in vector
[1064]1842    --- inherited fields ---
1843    bdm::epdf::from_setting
1844    \endcode
1845    */
1846    void from_setting ( const Setting &set );
[488]1847};
[760]1848UIREGISTER(eEmp);
[32]1849
1850
[8]1851////////////////////////
1852
[488]1853template<class sq_T>
[737]1854void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 ) {
[28]1855//Fixme test dimensions of mu0 and R0;
[1064]1856    mu = mu0;
1857    R = R0;
1858    validate();
[488]1859};
[8]1860
[488]1861template<class sq_T>
[737]1862void enorm<sq_T>::from_setting ( const Setting &set ) {
[1064]1863    epdf::from_setting ( set ); //reads rv
[384]1864
[1064]1865    UI::get ( mu, set, "mu", UI::compulsory );
1866    mat Rtmp;// necessary for conversion
1867    UI::get ( Rtmp, set, "R", UI::compulsory );
1868    R = Rtmp; // conversion
[488]1869}
[8]1870
[488]1871template<class sq_T>
[956]1872void enorm<sq_T>::validate() {
[1064]1873    eEF::validate();
1874    bdm_assert ( mu.length() == R.rows(), "mu and R parameters do not match" );
1875    dim = mu.length();
1876}
[956]1877
1878template<class sq_T>
[773]1879void enorm<sq_T>::to_setting ( Setting &set ) const {
[1064]1880    epdf::to_setting ( set ); //reads rv
1881    UI::save ( mu, set, "mu");
1882    UI::save ( R.to_mat(), set, "R");
[773]1883}
1884
[956]1885
1886
[773]1887template<class sq_T>
[737]1888void enorm<sq_T>::dupdate ( mat &v, double nu ) {
[1064]1889    //
[488]1890};
1891
[178]1892// template<class sq_T>
1893// void enorm<sq_T>::tupdate ( double phi, mat &vbar, double nubar ) {
[1066]1894//     //
[178]1895// };
[8]1896
[488]1897template<class sq_T>
[737]1898vec enorm<sq_T>::sample() const {
[1064]1899    vec x ( dim );
[270]1900#pragma omp critical
[1064]1901    NorRNG.sample_vector ( dim, x );
1902    vec smp = R.sqrt_mult ( x );
[12]1903
[1064]1904    smp += mu;
1905    return smp;
[488]1906};
[8]1907
[214]1908// template<class sq_T>
1909// double enorm<sq_T>::eval ( const vec &val ) const {
[1066]1910//     double pdfl,e;
1911//     pdfl = evallog ( val );
1912//     e = exp ( pdfl );
1913//     return e;
[214]1914// };
[8]1915
[488]1916template<class sq_T>
[737]1917double enorm<sq_T>::evallog_nn ( const vec &val ) const {
[1064]1918    // 1.83787706640935 = log(2pi)
1919    double tmp = -0.5 * ( R.invqform ( mu - val ) );// - lognc();
1920    return  tmp;
[488]1921};
[28]1922
[488]1923template<class sq_T>
[737]1924inline double enorm<sq_T>::lognc () const {
[1064]1925    // 1.83787706640935 = log(2pi)
1926    double tmp = 0.5 * ( R.cols() * 1.83787706640935 + R.logdet() );
1927    return tmp;
[488]1928};
[28]1929
[8]1930
[192]1931// template<class sq_T>
1932// vec mlnorm<sq_T>::samplecond (const  vec &cond, double &lik ) {
[1066]1933//     this->condition ( cond );
1934//     vec smp = epdf.sample();
1935//     lik = epdf.eval ( smp );
1936//     return smp;
[192]1937// }
[8]1938
[192]1939// template<class sq_T>
1940// mat mlnorm<sq_T>::samplecond (const vec &cond, vec &lik, int n ) {
[1066]1941//     int i;
1942//     int dim = rv.count();
1943//     mat Smp ( dim,n );
1944//     vec smp ( dim );
1945//     this->condition ( cond );
[198]1946//
[1066]1947//     for ( i=0; i<n; i++ ) {
1948//         smp = epdf.sample();
1949//         lik ( i ) = epdf.eval ( smp );
1950//         Smp.set_col ( i ,smp );
1951//     }
[198]1952//
[1066]1953//     return Smp;
[192]1954// }
[28]1955
[8]1956
[488]1957template<class sq_T>
[737]1958shared_ptr<epdf> enorm<sq_T>::marginal ( const RV &rvn ) const {
[1064]1959    enorm<sq_T> *tmp = new enorm<sq_T> ();
1960    shared_ptr<epdf> narrow ( tmp );
1961    marginal ( rvn, *tmp );
1962    return narrow;
[504]1963}
1964
1965template<class sq_T>
[737]1966void enorm<sq_T>::marginal ( const RV &rvn, enorm<sq_T> &target ) const {
[1064]1967    bdm_assert ( isnamed(), "rv description is not assigned" );
1968    ivec irvn = rvn.dataind ( rv );
[178]1969
[1064]1970    sq_T Rn ( R, irvn );  // select rows and columns of R
[280]1971
[1064]1972    target.set_rv ( rvn );
1973    target.set_parameters ( mu ( irvn ), Rn );
[488]1974}
[178]1975
[488]1976template<class sq_T>
[737]1977shared_ptr<pdf> enorm<sq_T>::condition ( const RV &rvn ) const {
[1064]1978    mlnorm<sq_T> *tmp = new mlnorm<sq_T> ();
1979    shared_ptr<pdf> narrow ( tmp );
1980    condition ( rvn, *tmp );
1981    return narrow;
[504]1982}
[178]1983
[504]1984template<class sq_T>
[737]1985void enorm<sq_T>::condition ( const RV &rvn, pdf &target ) const {
[1064]1986    typedef mlnorm<sq_T> TMlnorm;
[504]1987
[1064]1988    bdm_assert ( isnamed(), "rvs are not assigned" );
1989    TMlnorm &uptarget = dynamic_cast<TMlnorm &> ( target );
[270]1990
[1064]1991    RV rvc = rv.subt ( rvn );
1992    bdm_assert ( ( rvc._dsize() + rvn._dsize() == rv._dsize() ), "wrong rvn" );
1993    //Permutation vector of the new R
1994    ivec irvn = rvn.dataind ( rv );
1995    ivec irvc = rvc.dataind ( rv );
1996    ivec perm = concat ( irvn , irvc );
1997    sq_T Rn ( R, perm );
[178]1998
[1064]1999    //fixme - could this be done in general for all sq_T?
2000    mat S = Rn.to_mat();
2001    //fixme
2002    int n = rvn._dsize() - 1;
2003    int end = R.rows() - 1;
2004    mat S11 = S.get ( 0, n, 0, n );
2005    mat S12 = S.get ( 0, n , rvn._dsize(), end );
2006    mat S22 = S.get ( rvn._dsize(), end, rvn._dsize(), end );
[178]2007
[1064]2008    vec mu1 = mu ( irvn );
2009    vec mu2 = mu ( irvc );
2010    mat A = S12 * inv ( S22 );
2011    sq_T R_n ( S11 - A *S12.T() );
[178]2012
[1064]2013    uptarget.set_rv ( rvn );
2014    uptarget.set_rvc ( rvc );
2015    uptarget.set_parameters ( A, mu1 - A*mu2, R_n );
2016    uptarget.validate();
[488]2017}
[178]2018
[1063]2019/*! \brief Dirac delta function distribution */
[1064]2020class dirac: public epdf {
2021public:
2022    vec point;
2023public:
2024    double evallog (const vec &dt) const {
2025        return -inf;
2026    }
2027    vec mean () const {
2028        return point;
2029    }
2030    vec variance () const {
2031        return zeros(point.length());
2032    }
2033    void qbounds ( vec &lb, vec &ub, double percentage = 0.95 ) const {
2034        lb = point;
2035        ub = point;
2036    }
2037    //! access
2038    const vec& _point() {
2039        return point;
2040    }
2041    void set_point(const vec& p) {
2042        point =p;
2043        dim=p.length();
2044    }
2045    vec sample() const {
2046        return point;
2047    }
2048};
[887]2049
[1063]2050
2051///////////
2052
[488]2053template<class sq_T>
[737]2054void mgnorm<sq_T >::set_parameters ( const shared_ptr<fnc> &g0, const sq_T &R0 ) {
[1064]2055    g = g0;
2056    this->iepdf.set_parameters ( zeros ( g->dimension() ), R0 );
[527]2057}
2058
[488]2059template<class sq_T>
[737]2060void mgnorm<sq_T >::condition ( const vec &cond ) {
[1064]2061    this->iepdf._mu() = g->eval ( cond );
[737]2062};
[28]2063
[536]2064//! \todo unify this stuff with to_string()
[488]2065template<class sq_T>
[737]2066std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_T> &ml ) {
[1064]2067    os << "A:" << ml.A << endl;
2068    os << "mu:" << ml.mu_const << endl;
2069    os << "R:" << ml._R() << endl;
2070    return os;
[488]2071};
[28]2072
[254]2073}
[8]2074#endif //EF_H
Note: See TracBrowser for help on using the browser.