root/bdm/stat/libEF.h @ 200

Revision 200, 19.5 kB (checked in by smidl, 16 years ago)

BM has now function _e() returning posterior of correct type

  • Property svn:eol-style set to native
Line 
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
16#include <itpp/itbase.h>
17#include "../math/libDC.h"
18#include "libBM.h"
19#include "../itpp_ext.h"
20//#include <std>
21
22using namespace itpp;
23
24
25//! Global Uniform_RNG
26extern Uniform_RNG UniRNG;
27//! Global Normal_RNG
28extern Normal_RNG NorRNG;
29//! Global Gamma_RNG
30extern Gamma_RNG GamRNG;
31
32/*!
33* \brief General conjugate exponential family posterior density.
34
35* More?...
36*/
37
38class eEF : public epdf {
39public:
40//      eEF() :epdf() {};
41        //! default constructor
42        eEF ( const RV &rv ) :epdf ( rv ) {};
43        //! logarithm of the normalizing constant, \f$\mathcal{I}\f$
44        virtual double lognc() const =0;
45        //!TODO decide if it is really needed
46        virtual void dupdate ( mat &v ) {it_error ( "Not implemented" );};
47        //!Evaluate normalized log-probability
48        virtual double evalpdflog_nn ( const vec &val ) const{it_error ( "Not implemented" );return 0.0;};
49        //!Evaluate normalized log-probability
50        virtual double evalpdflog ( const vec &val ) const {return evalpdflog_nn ( val )-lognc();}
51        //!Evaluate normalized log-probability for many samples
52        virtual vec evalpdflog ( const mat &Val ) const {
53                vec x ( Val.cols() );
54                for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evalpdflog_nn ( Val.get_col ( i ) ) ;}
55                return x-lognc();
56        }
57        //!Power of the density, used e.g. to flatten the density
58        virtual void pow ( double p ) {it_error ( "Not implemented" );};
59};
60
61/*!
62* \brief Exponential family model.
63
64* More?...
65*/
66
67class mEF : public mpdf {
68
69public:
70        //! Default constructor
71        mEF ( const RV &rv0, const RV &rvc0 ) :mpdf ( rv0,rvc0 ) {};
72};
73
74//! Estimator for Exponential family
75class BMEF : public BM {
76protected:
77        //! forgetting factor
78        double frg;
79        //! cached value of lognc() in the previous step (used in evaluation of \c ll )
80        double last_lognc;
81public:
82        //! Default constructor
83        BMEF ( const RV &rv, double frg0=1.0 ) :BM ( rv ), frg ( frg0 ) {}
84        //! Copy constructor
85        BMEF ( const BMEF &B ) :BM ( B ), frg ( B.frg ), last_lognc ( B.last_lognc ) {}
86        //!get statistics from another model
87        virtual void set_statistics ( const BMEF* BM0 ) {it_error ( "Not implemented" );};
88        //! Weighted update of sufficient statistics (Bayes rule)
89        virtual void bayes ( const vec &data, const double w ) {};
90        //original Bayes
91        void bayes ( const vec &dt );
92        //!Flatten the posterior according to the given BMEF (of the same type!)
93        virtual void flatten ( const BMEF * B ) {it_error ( "Not implemented" );}
94        //!Flatten the posterior as if to keep nu0 data
95//      virtual void flatten ( double nu0 ) {it_error ( "Not implemented" );}
96
97        BMEF* _copy_ ( bool changerv=false ) {it_error ( "function _copy_ not implemented for this BM" ); return NULL;};
98};
99
100template<class sq_T>
101class mlnorm;
102
103/*!
104* \brief Gaussian density with positive definite (decomposed) covariance matrix.
105
106* More?...
107*/
108template<class sq_T>
109class enorm : public eEF {
110protected:
111        //! mean value
112        vec mu;
113        //! Covariance matrix in decomposed form
114        sq_T R;
115        //! dimension (redundant from rv.count() for easier coding )
116        int dim;
117public:
118        //!Default constructor
119        enorm ( const RV &rv );
120        //! Set mean value \c mu and covariance \c R
121        void set_parameters ( const vec &mu,const sq_T &R );
122        ////! tupdate in exponential form (not really handy)
123        //void tupdate ( double phi, mat &vbar, double nubar );
124        //! dupdate in exponential form (not really handy)
125        void dupdate ( mat &v,double nu=1.0 );
126
127        vec sample() const;
128        //! TODO is it used?
129        mat sample ( int N ) const;
130        double eval ( const vec &val ) const ;
131        double evalpdflog_nn ( const vec &val ) const;
132        double lognc () const;
133        vec mean() const {return mu;}
134//      mlnorm<sq_T>* condition ( const RV &rvn ) const ;
135        mpdf* condition ( const RV &rvn ) const ;
136//      enorm<sq_T>* marginal ( const RV &rv ) const;
137        epdf* marginal ( const RV &rv ) const;
138//Access methods
139        //! returns a pointer to the internal mean value. Use with Care!
140        vec& _mu() {return mu;}
141
142        //! access function
143        void set_mu ( const vec mu0 ) { mu=mu0;}
144
145        //! returns pointers to the internal variance and its inverse. Use with Care!
146        sq_T& _R() {return R;}
147
148        //! access method
149//      mat getR () {return R.to_mat();}
150};
151
152/*!
153* \brief Gauss-inverse-Wishart density stored in LD form
154
155* For \f$p\f$-variate densities, given rv.count() should be \f$p\times\f$ V.rows().
156*
157*/
158class egiw : public eEF {
159protected:
160        //! Extended information matrix of sufficient statistics
161        ldmat V;
162        //! Number of data records (degrees of freedom) of sufficient statistics
163        double nu;
164        //! Dimension of the output
165        int xdim;
166        //! Dimension of the regressor
167        int nPsi;
168public:
169        //!Default constructor, if nu0<0 a minimal nu0 will be computed
170        egiw ( RV rv, mat V0, double nu0=-1.0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) {
171                xdim = rv.count() /V.rows();
172                it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." );
173                nPsi = V.rows()-xdim;
174                //set mu to have proper normalization and
175                if (nu0<0){
176                        nu = 0.1 +nPsi +2*xdim +2; // +2 assures finite expected value of R
177                        // terms before that are sufficient for finite normalization
178                }
179        }
180        //!Full constructor for V in ldmat form
181        egiw ( RV rv, ldmat V0, double nu0=-1.0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) {
182                xdim = rv.count() /V.rows();
183                it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." );
184                nPsi = V.rows()-xdim;
185                if (nu0<0){
186                        nu = 0.1 +nPsi +2*xdim +2; // +2 assures finite expected value of R
187                        // terms before that are sufficient for finite normalization
188                }
189        }
190
191        vec sample() const;
192        vec mean() const;
193        void mean_mat ( mat &M, mat&R ) const;
194        //! In this instance, val= [theta, r]. For multivariate instances, it is stored columnwise val = [theta_1 theta_2 ... r_1 r_2 ]
195        double evalpdflog_nn ( const vec &val ) const;
196        double lognc () const;
197
198        //Access
199        //! returns a pointer to the internal statistics. Use with Care!
200        ldmat& _V() {return V;}
201        //! returns a pointer to the internal statistics. Use with Care!
202        double& _nu() {return nu;}
203        void pow ( double p ) {V*=p;nu*=p;};
204};
205
206/*! \brief Dirichlet posterior density
207
208Continuous Dirichlet density of \f$n\f$-dimensional variable \f$x\f$
209\f[
210f(x|\beta) = \frac{\Gamma[\gamma]}{\prod_{i=1}^{n}\Gamma(\beta_i)} \prod_{i=1}^{n}x_i^{\beta_i-1}
211\f]
212where \f$\gamma=\sum_i \beta_i\f$.
213*/
214class eDirich: public eEF {
215protected:
216        //!sufficient statistics
217        vec beta;
218public:
219        //!Default constructor
220        eDirich ( const RV &rv, const vec &beta0 ) : eEF ( rv ),beta ( beta0 ) {it_assert_debug ( rv.count() ==beta.length(),"Incompatible statistics" ); };
221        //! Copy constructor
222        eDirich ( const eDirich &D0 ) : eEF ( D0.rv ),beta ( D0.beta ) {};
223        vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
224        vec mean() const {return beta/sum ( beta );};
225        //! In this instance, val is ...
226        double evalpdflog_nn ( const vec &val ) const {return ( beta-1 ) *log ( val );};
227        double lognc () const {
228                double gam=sum ( beta );
229                double lgb=0.0;
230                for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
231                return lgb-lgamma ( gam );
232        };
233        //!access function
234        vec& _beta()  {return beta;}
235        //!Set internal parameters
236        void set_parameters ( const vec &beta0 ) {
237                if ( beta0.length() !=beta.length() ) {
238                        it_assert_debug ( rv.length() ==1,"Undefined" );
239                        rv.set_size ( 0,beta0.length() );
240                }
241                beta= beta0;
242        }
243};
244
245//! \brief Estimator for Multinomial density
246class multiBM : public BMEF {
247protected:
248        //! Conjugate prior and posterior
249        eDirich est;
250        //! Pointer inside est to sufficient statistics
251        vec &beta;
252public:
253        //!Default constructor
254        multiBM ( const RV &rv, const vec beta0 ) : BMEF ( rv ),est ( rv,beta0 ),beta ( est._beta() ) {last_lognc=est.lognc();}
255        //!Copy constructor
256        multiBM ( const multiBM &B ) : BMEF ( B ),est ( rv,B.beta ),beta ( est._beta() ) {}
257        //! Sets sufficient statistics to match that of givefrom mB0
258        void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;}
259        void bayes ( const vec &dt ) {
260                if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();}
261                beta+=dt;
262                if ( evalll ) {ll=est.lognc()-last_lognc;}
263        }
264        double logpred ( const vec &dt ) const {
265                eDirich pred ( est );
266                vec &beta = pred._beta();
267
268                double lll;
269                if ( frg<1.0 )
270                        {beta*=frg;lll=pred.lognc();}
271                else
272                        if ( evalll ) {lll=last_lognc;}
273                        else{lll=pred.lognc();}
274
275                beta+=dt;
276                return pred.lognc()-lll;
277        }
278        void flatten ( const BMEF* B ) {
279                const multiBM* E=dynamic_cast<const multiBM*> ( B );
280                // sum(beta) should be equal to sum(B.beta)
281                const vec &Eb=E->beta;//const_cast<multiBM*> ( E )->_beta();
282                beta*= ( sum ( Eb ) /sum ( beta ) );
283                if ( evalll ) {last_lognc=est.lognc();}
284        }
285        const epdf& _epdf() const {return est;};
286        const eDirich* _e() const {return &est;};
287        void set_parameters ( const vec &beta0 ) {
288                est.set_parameters ( beta0 );
289                rv = est._rv();
290                if ( evalll ) {last_lognc=est.lognc();}
291        }
292};
293
294/*!
295 \brief Gamma posterior density
296
297 Multivariate Gamma density as product of independent univariate densities.
298 \f[
299 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i)
300 \f]
301*/
302
303class egamma : public eEF {
304protected:
305        //! Vector \f$\alpha\f$
306        vec alpha;
307        //! Vector \f$\beta\f$
308        vec beta;
309public :
310        //! Default constructor
311        egamma ( const RV &rv ) :eEF ( rv ) {};
312        //! Sets parameters
313        void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;};
314        vec sample() const;
315        //! TODO: is it used anywhere?
316//      mat sample ( int N ) const;
317        double evalpdflog ( const vec &val ) const;
318        double lognc () const;
319        //! Returns poiter to alpha and beta. Potentially dengerous: use with care!
320        void _param ( vec* &a, vec* &b ) {a=&alpha;b=&beta;};
321        vec mean() const {vec pom ( alpha ); pom/=beta; return pom;}
322};
323/*
324//! Weighted mixture of epdfs with external owned components.
325class emix : public epdf {
326protected:
327        int n;
328        vec &w;
329        Array<epdf*> Coms;
330public:
331//! Default constructor
332        emix ( const RV &rv, vec &w0): epdf(rv), n(w0.length()), w(w0), Coms(n) {};
333        void set_parameters( int &i, double wi, epdf* ep){w(i)=wi;Coms(i)=ep;}
334        vec mean(){vec pom; for(int i=0;i<n;i++){pom+=Coms(i)->mean()*w(i);} return pom;};
335        vec sample() {it_error ( "Not implemented" );return 0;}
336};
337*/
338
339//!  Uniform distributed density on a rectangular support
340
341class euni: public epdf {
342protected:
343//! lower bound on support
344        vec low;
345//! upper bound on support
346        vec high;
347//! internal
348        vec distance;
349//! normalizing coefficients
350        double nk;
351//! cache of log( \c nk )
352        double lnk;
353public:
354        //! Defualt constructor
355        euni ( const RV rv ) :epdf ( rv ) {}
356        double eval ( const vec &val ) const  {return nk;}
357        double evalpdflog ( const vec &val ) const  {return lnk;}
358        vec sample() const {
359                vec smp ( rv.count() );
360#pragma omp critical
361                UniRNG.sample_vector ( rv.count(),smp );
362                return low+elem_mult ( distance,smp );
363        }
364        //! set values of \c low and \c high
365        void set_parameters ( const vec &low0, const vec &high0 ) {
366                distance = high0-low0;
367                it_assert_debug ( min ( distance ) >0.0,"bad support" );
368                low = low0;
369                high = high0;
370                nk = prod ( 1.0/distance );
371                lnk = log ( nk );
372        }
373        vec mean() const {vec pom=high; pom-=low; pom/=2.0; return pom;}
374};
375
376
377/*!
378 \brief Normal distributed linear function with linear function of mean value;
379
380 Mean value \f$mu=A*rvc+mu_0\f$.
381*/
382template<class sq_T>
383class mlnorm : public mEF {
384protected:
385        //! Internal epdf that arise by conditioning on \c rvc
386        enorm<sq_T> epdf;
387        mat A;
388        vec mu_const;
389        vec& _mu; //cached epdf.mu;
390public:
391        //! Constructor
392        mlnorm ( const RV &rv, const RV &rvc );
393        //! Set \c A and \c R
394        void set_parameters ( const  mat &A, const vec &mu0, const sq_T &R );
395//      //!Generate one sample of the posterior
396//      vec samplecond (const vec &cond, double &lik );
397//      //!Generate matrix of samples of the posterior
398//      mat samplecond (const vec &cond, vec &lik, int n );
399        //! Set value of \c rvc . Result of this operation is stored in \c epdf use function \c _ep to access it.
400        void condition ( const vec &cond );
401
402        //!access function
403        vec& _mu_const() {return mu_const;}
404        //!access function
405        mat& _A() {return A;}
406        //!access function
407        mat _R() {return epdf._R().to_mat();}
408
409        template<class sq_M>
410        friend std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_M> &ml );
411};
412
413/*! (Approximate) Student t density with linear function of mean value
414*/
415class mlstudent : public mlnorm<ldmat> {
416protected:
417        ldmat Lambda;
418        ldmat &_R;
419        ldmat Re;
420public:
421        mlstudent ( const RV &rv0, const RV &rvc0 ) :mlnorm<ldmat> ( rv0,rvc0 ),
422                        Lambda ( rv0.count() ),
423                        _R ( epdf._R() ) {}
424        void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0) {
425                epdf.set_parameters ( zeros ( rv.count() ),Lambda );
426                A = A0;
427                mu_const = mu0;
428                Re=R0;
429                Lambda = Lambda0;
430        }
431        void condition ( const vec &cond ) {
432                _mu = A*cond + mu_const;
433                double zeta;
434                //ugly hack!
435                if ((cond.length()+1)==Lambda.rows()){
436                        zeta = Lambda.invqform ( concat(cond, vec_1(1.0)) );
437                } else {
438                        zeta = Lambda.invqform ( cond );
439                }
440                _R = Re;
441                _R*=( 1+zeta );// / ( nu ); << nu is in Re!!!!!!
442               
443                cout << _mu <<" +- " << sqrt(_R.to_mat()) << endl;
444        };
445
446};
447/*!
448\brief  Gamma random walk
449
450Mean value, \f$\mu\f$, of this density is given by \c rvc .
451Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
452This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
453
454The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
455*/
456class mgamma : public mEF {
457protected:
458        //! Internal epdf that arise by conditioning on \c rvc
459        egamma epdf;
460        //! Constant \f$k\f$
461        double k;
462        //! cache of epdf.beta
463        vec* _beta;
464
465public:
466        //! Constructor
467        mgamma ( const RV &rv,const RV &rvc );
468        //! Set value of \c k
469        void set_parameters ( double k );
470        void condition ( const vec &val ) {*_beta=k/val;};
471};
472
473/*!
474\brief  Gamma random walk around a fixed point
475
476Mean 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
477\f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f]
478
479Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
480This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
481
482The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
483*/
484class mgamma_fix : public mgamma {
485protected:
486        //! parameter l
487        double l;
488        //! reference vector
489        vec refl;
490public:
491        //! Constructor
492        mgamma_fix ( const RV &rv,const RV &rvc ) : mgamma ( rv,rvc ),refl ( rv.count() ) {};
493        //! Set value of \c k
494        void set_parameters ( double k0 , vec ref0, double l0 ) {
495                mgamma::set_parameters ( k0 );
496                refl=pow ( ref0,1.0-l0 );l=l0;
497        };
498
499        void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); *_beta=k/mean;};
500};
501
502//! Switch between various resampling methods.
503enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
504/*!
505\brief Weighted empirical density
506
507Used e.g. in particle filters.
508*/
509class eEmp: public epdf {
510protected :
511        //! Number of particles
512        int n;
513        //! Sample weights \f$w\f$
514        vec w;
515        //! Samples \f$x^{(i)}, i=1..n\f$
516        Array<vec> samples;
517public:
518        //! Default constructor
519        eEmp ( const RV &rv0 ,int n0 ) :epdf ( rv0 ),n ( n0 ),w ( n ),samples ( n ) {};
520        //! Set samples and weights
521        void set_parameters ( const vec &w0, const epdf* pdf0 );
522        //! Set sample
523        void set_samples ( const epdf* pdf0 );
524        //! Potentially dangerous, use with care.
525        vec& _w()  {return w;};
526        //! access function
527        Array<vec>& _samples() {return samples;};
528        //! 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.
529        ivec resample ( RESAMPLING_METHOD method = SYSTEMATIC );
530        //! inherited operation : NOT implemneted
531        vec sample() const {it_error ( "Not implemented" );return 0;}
532        //! inherited operation : NOT implemneted
533        double evalpdflog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
534        vec mean() const {
535                vec pom=zeros ( rv.count() );
536                for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
537                return pom;
538        }
539};
540
541
542////////////////////////
543
544template<class sq_T>
545enorm<sq_T>::enorm ( const RV &rv ) :eEF ( rv ), mu ( rv.count() ),R ( rv.count() ),dim ( rv.count() ) {};
546
547template<class sq_T>
548void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 ) {
549//Fixme test dimensions of mu0 and R0;
550        mu = mu0;
551        R = R0;
552};
553
554template<class sq_T>
555void enorm<sq_T>::dupdate ( mat &v, double nu ) {
556        //
557};
558
559// template<class sq_T>
560// void enorm<sq_T>::tupdate ( double phi, mat &vbar, double nubar ) {
561//      //
562// };
563
564template<class sq_T>
565vec enorm<sq_T>::sample() const {
566        vec x ( dim );
567        NorRNG.sample_vector ( dim,x );
568        vec smp = R.sqrt_mult ( x );
569
570        smp += mu;
571        return smp;
572};
573
574template<class sq_T>
575mat enorm<sq_T>::sample ( int N ) const {
576        mat X ( dim,N );
577        vec x ( dim );
578        vec pom;
579        int i;
580
581        for ( i=0;i<N;i++ ) {
582                NorRNG.sample_vector ( dim,x );
583                pom = R.sqrt_mult ( x );
584                pom +=mu;
585                X.set_col ( i, pom );
586        }
587
588        return X;
589};
590
591template<class sq_T>
592double enorm<sq_T>::eval ( const vec &val ) const {
593        double pdfl,e;
594        pdfl = evalpdflog ( val );
595        e = exp ( pdfl );
596        return e;
597};
598
599template<class sq_T>
600double enorm<sq_T>::evalpdflog_nn ( const vec &val ) const {
601        // 1.83787706640935 = log(2pi)
602        double tmp=-0.5* ( R.invqform ( mu-val ) );// - lognc();
603        return  tmp;
604};
605
606template<class sq_T>
607inline double enorm<sq_T>::lognc () const {
608        // 1.83787706640935 = log(2pi)
609        double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
610        return tmp;
611};
612
613template<class sq_T>
614mlnorm<sq_T>::mlnorm ( const RV &rv0, const RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu ( epdf._mu() ) {
615        ep =&epdf;
616}
617
618template<class sq_T>
619void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 ) {
620        epdf.set_parameters ( zeros ( rv.count() ),R0 );
621        A = A0;
622        mu_const = mu0;
623}
624
625// template<class sq_T>
626// vec mlnorm<sq_T>::samplecond (const  vec &cond, double &lik ) {
627//      this->condition ( cond );
628//      vec smp = epdf.sample();
629//      lik = epdf.eval ( smp );
630//      return smp;
631// }
632
633// template<class sq_T>
634// mat mlnorm<sq_T>::samplecond (const vec &cond, vec &lik, int n ) {
635//      int i;
636//      int dim = rv.count();
637//      mat Smp ( dim,n );
638//      vec smp ( dim );
639//      this->condition ( cond );
640//
641//      for ( i=0; i<n; i++ ) {
642//              smp = epdf.sample();
643//              lik ( i ) = epdf.eval ( smp );
644//              Smp.set_col ( i ,smp );
645//      }
646//
647//      return Smp;
648// }
649
650template<class sq_T>
651void mlnorm<sq_T>::condition ( const vec &cond ) {
652        _mu = A*cond + mu_const;
653//R is already assigned;
654}
655
656template<class sq_T>
657epdf* enorm<sq_T>::marginal ( const RV &rvn ) const {
658        ivec irvn = rvn.dataind ( rv );
659
660        sq_T Rn ( R,irvn );
661        enorm<sq_T>* tmp = new enorm<sq_T> ( rvn );
662        tmp->set_parameters ( mu ( irvn ), Rn );
663        return tmp;
664}
665
666template<class sq_T>
667mpdf* enorm<sq_T>::condition ( const RV &rvn ) const {
668
669        RV rvc = rv.subt ( rvn );
670        it_assert_debug ( ( rvc.count() +rvn.count() ==rv.count() ),"wrong rvn" );
671        //Permutation vector of the new R
672        ivec irvn = rvn.dataind ( rv );
673        ivec irvc = rvc.dataind ( rv );
674        ivec perm=concat ( irvn , irvc );
675        sq_T Rn ( R,perm );
676
677        //fixme - could this be done in general for all sq_T?
678        mat S=Rn.to_mat();
679        //fixme
680        int n=rvn.count()-1;
681        int end=R.rows()-1;
682        mat S11 = S.get ( 0,n, 0, n );
683        mat S12 = S.get ( 0, n , rvn.count(), end );
684        mat S22 = S.get ( rvn.count(), end, rvn.count(), end );
685
686        vec mu1 = mu ( irvn );
687        vec mu2 = mu ( irvc );
688        mat A=S12*inv ( S22 );
689        sq_T R_n ( S11 - A *S12.T() );
690
691        mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( rvn,rvc );
692
693        tmp->set_parameters ( A,mu1-A*mu2,R_n );
694        return tmp;
695}
696
697///////////
698
699template<class sq_T>
700std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_T> &ml ) {
701        os << "A:"<< ml.A<<endl;
702        os << "mu:"<< ml.mu_const<<endl;
703        os << "R:" << ml.epdf._R().to_mat() <<endl;
704        return os;
705};
706
707#endif //EF_H
Note: See TracBrowser for help on using the browser.