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

Revision 471, 34.8 kB (checked in by mido, 15 years ago)

1) ad UserInfo?: UI::get a UI::build predelany tak, ze vraci fals / NULL v pripade neexistence pozadovaneho Settingu, pridana enumericky typ UI::SettingPresence?, predelany stavajici UI implementace, dodelana UI dokumentace
2) dokoncena konfigurace ASTYLERU, brzy bude aplikovan
3) doxygen nastaven tak, ze vytvari soubor doxy_warnings.txt

  • 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
17#include "../shared_ptr.h"
18#include "../base/bdmbase.h"
19#include "../math/chmat.h"
20
21namespace bdm
22{
23
24
25//! Global Uniform_RNG
26        extern Uniform_RNG UniRNG;
27//! Global Normal_RNG
28        extern Normal_RNG NorRNG;
29//! Global Gamma_RNG
30        extern Gamma_RNG GamRNG;
31
32        /*!
33        * \brief General conjugate exponential family posterior density.
34
35        * More?...
36        */
37
38        class eEF : public epdf
39        {
40                public:
41//      eEF() :epdf() {};
42                        //! default constructor
43                        eEF ( ) :epdf ( ) {};
44                        //! logarithm of the normalizing constant, \f$\mathcal{I}\f$
45                        virtual double lognc() const =0;
46                        //!TODO decide if it is really needed
47                        virtual void dupdate ( mat &v ) {it_error ( "Not implemented" );};
48                        //!Evaluate normalized log-probability
49                        virtual double evallog_nn ( const vec &val ) const{it_error ( "Not implemented" );return 0.0;};
50                        //!Evaluate normalized log-probability
51                        virtual double evallog ( const vec &val ) const {
52                                double tmp;
53                                tmp= evallog_nn ( val )-lognc();
54//                              it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
55                                return tmp;}
56                        //!Evaluate normalized log-probability for many samples
57                        virtual vec evallog ( const mat &Val ) const
58                        {
59                                vec x ( Val.cols() );
60                                for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evallog_nn ( Val.get_col ( i ) ) ;}
61                                return x-lognc();
62                        }
63                        //!Power of the density, used e.g. to flatten the density
64                        virtual void pow ( double p ) {it_error ( "Not implemented" );};
65        };
66
67        /*!
68        * \brief Exponential family model.
69
70        * More?...
71        */
72
73        class mEF : public mpdf
74        {
75
76                public:
77                        //! Default constructor
78                        mEF ( ) :mpdf ( ) {};
79        };
80
81//! Estimator for Exponential family
82        class BMEF : public BM
83        {
84                protected:
85                        //! forgetting factor
86                        double frg;
87                        //! cached value of lognc() in the previous step (used in evaluation of \c ll )
88                        double last_lognc;
89                public:
90                        //! Default constructor (=empty constructor)
91                        BMEF ( double frg0=1.0 ) :BM ( ), frg ( frg0 ) {}
92                        //! Copy constructor
93                        BMEF ( const BMEF &B ) :BM ( B ), frg ( B.frg ), last_lognc ( B.last_lognc ) {}
94                        //!get statistics from another model
95                        virtual void set_statistics ( const BMEF* BM0 ) {it_error ( "Not implemented" );};
96                        //! Weighted update of sufficient statistics (Bayes rule)
97                        virtual void bayes ( const vec &data, const double w ) {};
98                        //original Bayes
99                        void bayes ( const vec &dt );
100                        //!Flatten the posterior according to the given BMEF (of the same type!)
101                        virtual void flatten ( const BMEF * B ) {it_error ( "Not implemented" );}
102                        //!Flatten the posterior as if to keep nu0 data
103//      virtual void flatten ( double nu0 ) {it_error ( "Not implemented" );}
104
105                        BMEF* _copy_ () const {it_error ( "function _copy_ not implemented for this BM" ); return NULL;};
106        };
107
108        template<class sq_T>
109        class mlnorm;
110
111        /*!
112        * \brief Gaussian density with positive definite (decomposed) covariance matrix.
113
114        * More?...
115        */
116        template<class sq_T>
117        class enorm : public eEF
118        {
119                protected:
120                        //! mean value
121                        vec mu;
122                        //! Covariance matrix in decomposed form
123                        sq_T R;
124                public:
125                        //!\name Constructors
126                        //!@{
127
128                        enorm ( ) :eEF ( ), mu ( ),R ( ) {};
129                        enorm ( const vec &mu,const sq_T &R ) {set_parameters ( mu,R );}
130                        void set_parameters ( const vec &mu,const sq_T &R );
131                        void from_setting(const Setting &root);
132                        void validate() {
133                                it_assert(mu.length()==R.rows(),"parameters mismatch");
134                                dim = mu.length();
135                        }
136                        //!@}
137
138                        //! \name Mathematical operations
139                        //!@{
140
141                        //! dupdate in exponential form (not really handy)
142                        void dupdate ( mat &v,double nu=1.0 );
143
144                        vec sample() const;
145
146                        double evallog_nn ( const vec &val ) const;
147                        double lognc () const;
148                        vec mean() const {return mu;}
149                        vec variance() const {return diag ( R.to_mat() );}
150//      mlnorm<sq_T>* condition ( const RV &rvn ) const ; <=========== fails to cmpile. Why?
151                        mpdf* condition ( const RV &rvn ) const ;
152                        enorm<sq_T>* marginal ( const RV &rv ) const;
153//                      epdf* marginal ( const RV &rv ) const;
154                        //!@}
155
156                        //! \name Access to attributes
157                        //!@{
158
159                        vec& _mu() {return mu;}
160                        void set_mu ( const vec mu0 ) { mu=mu0;}
161                        sq_T& _R() {return R;}
162                        const sq_T& _R() const {return R;}
163                        //!@}
164
165        };
166        UIREGISTER(enorm<chmat>);
167        UIREGISTER(enorm<ldmat>);
168        UIREGISTER(enorm<fsqmat>);
169
170
171        /*!
172        * \brief Gauss-inverse-Wishart density stored in LD form
173
174        * For \f$p\f$-variate densities, given rv.count() should be \f$p\times\f$ V.rows().
175        *
176        */
177        class egiw : public eEF
178        {
179                protected:
180                        //! Extended information matrix of sufficient statistics
181                        ldmat V;
182                        //! Number of data records (degrees of freedom) of sufficient statistics
183                        double nu;
184                        //! Dimension of the output
185                        int dimx;
186                        //! Dimension of the regressor
187                        int nPsi;
188                public:
189                        //!\name Constructors
190                        //!@{
191                        egiw() :eEF() {};
192                        egiw ( int dimx0, ldmat V0, double nu0=-1.0 ) :eEF() {set_parameters ( dimx0,V0, nu0 );};
193
194                        void set_parameters ( int dimx0, ldmat V0, double nu0=-1.0 )
195                        {
196                                dimx=dimx0;
197                                nPsi = V0.rows()-dimx;
198                                dim = dimx* ( dimx+nPsi ); // size(R) + size(Theta)
199
200                                V=V0;
201                                if ( nu0<0 )
202                                {
203                                        nu = 0.1 +nPsi +2*dimx +2; // +2 assures finite expected value of R
204                                        // terms before that are sufficient for finite normalization
205                                }
206                                else
207                                {
208                                        nu=nu0;
209                                }
210                        }
211                        //!@}
212
213                        vec sample() const;
214                        vec mean() const;
215                        vec variance() const;
216
217                        //! LS estimate of \f$\theta\f$
218                        vec est_theta() const;
219
220                        //! Covariance of the LS estimate
221                        ldmat est_theta_cov() const;
222
223                        void mean_mat ( mat &M, mat&R ) const;
224                        //! In this instance, val= [theta, r]. For multivariate instances, it is stored columnwise val = [theta_1 theta_2 ... r_1 r_2 ]
225                        double evallog_nn ( const vec &val ) const;
226                        double lognc () const;
227                        void pow ( double p ) {V*=p;nu*=p;};
228
229                        //! \name Access attributes
230                        //!@{
231
232                        ldmat& _V() {return V;}
233                        const ldmat& _V() const {return V;}
234                        double& _nu()  {return nu;}
235                        const double& _nu() const {return nu;}
236                        void from_setting(const Setting &set){
237                                UI::get(nu,set,"nu");
238                                UI::get(dimx,set,"dimx");
239                                set.lookupValue("nu",nu);
240                                set.lookupValue("dimx",dimx);
241                                mat V;
242                                UI::get(V,set,"V", UI::compulsory);
243                                set_parameters(dimx, V, nu);
244                                RV* rv=UI::build<RV>(set,"rv", UI::compulsory);
245                                set_rv(*rv);
246                                delete rv;
247                        }
248                        //!@}
249        };
250        UIREGISTER(egiw);
251
252        /*! \brief Dirichlet posterior density
253
254        Continuous Dirichlet density of \f$n\f$-dimensional variable \f$x\f$
255        \f[
256        f(x|\beta) = \frac{\Gamma[\gamma]}{\prod_{i=1}^{n}\Gamma(\beta_i)} \prod_{i=1}^{n}x_i^{\beta_i-1}
257        \f]
258        where \f$\gamma=\sum_i \beta_i\f$.
259        */
260        class eDirich: public eEF
261        {
262                protected:
263                        //!sufficient statistics
264                        vec beta;
265                public:
266                        //!\name Constructors
267                        //!@{
268
269                        eDirich () : eEF ( ) {};
270                        eDirich ( const eDirich &D0 ) : eEF () {set_parameters ( D0.beta );};
271                        eDirich ( const vec &beta0 ) {set_parameters ( beta0 );};
272                        void set_parameters ( const vec &beta0 )
273                        {
274                                beta= beta0;
275                                dim = beta.length();
276                        }
277                        //!@}
278
279                        vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
280                        vec mean() const {return beta/sum(beta);};
281                        vec variance() const {double gamma =sum(beta); return elem_mult ( beta, ( beta+1 ) ) / ( gamma* ( gamma+1 ) );}
282                        //! In this instance, val is ...
283                        double evallog_nn ( const vec &val ) const
284                        {
285                                double tmp; tmp= ( beta-1 ) *log ( val );
286//                              it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
287                                return tmp;
288                        };
289                        double lognc () const
290                        {
291                                double tmp;
292                                double gam=sum ( beta );
293                                double lgb=0.0;
294                                for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
295                                tmp= lgb-lgamma ( gam );
296//                              it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
297                                return tmp;
298                        };
299                        //!access function
300                        vec& _beta()  {return beta;}
301                        //!Set internal parameters
302        };
303
304//! \brief Estimator for Multinomial density
305        class multiBM : public BMEF
306        {
307                protected:
308                        //! Conjugate prior and posterior
309                        eDirich est;
310                        //! Pointer inside est to sufficient statistics
311                        vec &beta;
312                public:
313                        //!Default constructor
314                        multiBM ( ) : BMEF ( ),est ( ),beta ( est._beta() )
315                        {
316                                if ( beta.length() >0 ) {last_lognc=est.lognc();}
317                                else{last_lognc=0.0;}
318                        }
319                        //!Copy constructor
320                        multiBM ( const multiBM &B ) : BMEF ( B ),est ( B.est ),beta ( est._beta() ) {}
321                        //! Sets sufficient statistics to match that of givefrom mB0
322                        void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;}
323                        void bayes ( const vec &dt )
324                        {
325                                if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();}
326                                beta+=dt;
327                                if ( evalll ) {ll=est.lognc()-last_lognc;}
328                        }
329                        double logpred ( const vec &dt ) const
330                        {
331                                eDirich pred ( est );
332                                vec &beta = pred._beta();
333
334                                double lll;
335                                if ( frg<1.0 )
336                                        {beta*=frg;lll=pred.lognc();}
337                                else
338                                        if ( evalll ) {lll=last_lognc;}
339                                        else{lll=pred.lognc();}
340
341                                beta+=dt;
342                                return pred.lognc()-lll;
343                        }
344                        void flatten ( const BMEF* B )
345                        {
346                                const multiBM* E=dynamic_cast<const multiBM*> ( B );
347                                // sum(beta) should be equal to sum(B.beta)
348                                const vec &Eb=E->beta;//const_cast<multiBM*> ( E )->_beta();
349                                beta*= ( sum ( Eb ) /sum ( beta ) );
350                                if ( evalll ) {last_lognc=est.lognc();}
351                        }
352                        const epdf& posterior() const {return est;};
353                        const eDirich* _e() const {return &est;};
354                        void set_parameters ( const vec &beta0 )
355                        {
356                                est.set_parameters ( beta0 );
357                                if ( evalll ) {last_lognc=est.lognc();}
358                        }
359        };
360
361        /*!
362         \brief Gamma posterior density
363
364         Multivariate Gamma density as product of independent univariate densities.
365         \f[
366         f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i)
367         \f]
368        */
369
370        class egamma : public eEF
371        {
372                protected:
373                        //! Vector \f$\alpha\f$
374                        vec alpha;
375                        //! Vector \f$\beta\f$
376                        vec beta;
377                public :
378                        //! \name Constructors
379                        //!@{
380                        egamma ( ) :eEF ( ), alpha ( 0 ), beta ( 0 ) {};
381                        egamma ( const vec &a, const vec &b ) {set_parameters ( a, b );};
382                        void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;dim = alpha.length();};
383                        //!@}
384
385                        vec sample() const;
386                        //! TODO: is it used anywhere?
387//      mat sample ( int N ) const;
388                        double evallog ( const vec &val ) const;
389                        double lognc () const;
390                        //! Returns poiter to alpha and beta. Potentially dengerous: use with care!
391                        vec& _alpha() {return alpha;}
392                        vec& _beta() {return beta;}
393                        vec mean() const {return elem_div ( alpha,beta );}
394                        vec variance() const {return elem_div ( alpha,elem_mult ( beta,beta ) ); }
395                       
396                        //! Load from structure with elements:
397                        //!  \code
398                        //! { alpha = [...];         // vector of alpha
399                        //!   beta = [...];          // vector of beta
400                        //!   rv = {class="RV",...}  // description
401                        //! }
402                        //! \endcode
403                        //!@}
404                        void from_setting(const Setting &set){
405                                epdf::from_setting(set); // reads rv
406                                UI::get(alpha,set,"alpha", UI::compulsory);
407                                UI::get(beta,set,"beta", UI::compulsory);
408                                validate();
409                        }
410                        void validate(){
411                                it_assert(alpha.length() ==beta.length(), "parameters do not match");
412                                dim =alpha.length();
413                        }
414        };
415UIREGISTER(egamma);
416        /*!
417         \brief Inverse-Gamma posterior density
418
419         Multivariate inverse-Gamma density as product of independent univariate densities.
420         \f[
421         f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i)
422         \f]
423
424        Vector \f$\beta\f$ has different meaning (in fact it is 1/beta as used in definition of iG)
425
426         Inverse Gamma can be converted to Gamma using \f[
427         x\sim iG(a,b) => 1/x\sim G(a,1/b)
428        \f]
429        This relation is used in sampling.
430         */
431
432        class eigamma : public egamma
433        {
434                protected:
435                public :
436                        //! \name Constructors
437                        //! All constructors are inherited
438                        //!@{
439                        //!@}
440
441                        vec sample() const {return 1.0/egamma::sample();};
442                        //! Returns poiter to alpha and beta. Potentially dangerous: use with care!
443                        vec mean() const {return elem_div ( beta,alpha-1 );}
444                        vec variance() const {vec mea=mean(); return elem_div ( elem_mult ( mea,mea ),alpha-2 );}
445        };
446        /*
447        //! Weighted mixture of epdfs with external owned components.
448        class emix : public epdf {
449        protected:
450                int n;
451                vec &w;
452                Array<epdf*> Coms;
453        public:
454        //! Default constructor
455                emix ( const RV &rv, vec &w0): epdf(rv), n(w0.length()), w(w0), Coms(n) {};
456                void set_parameters( int &i, double wi, epdf* ep){w(i)=wi;Coms(i)=ep;}
457                vec mean(){vec pom; for(int i=0;i<n;i++){pom+=Coms(i)->mean()*w(i);} return pom;};
458                vec sample() {it_error ( "Not implemented" );return 0;}
459        };
460        */
461
462//!  Uniform distributed density on a rectangular support
463
464        class euni: public epdf
465        {
466                protected:
467//! lower bound on support
468                        vec low;
469//! upper bound on support
470                        vec high;
471//! internal
472                        vec distance;
473//! normalizing coefficients
474                        double nk;
475//! cache of log( \c nk )
476                        double lnk;
477                public:
478                        //! \name Constructors
479                        //!@{
480                        euni ( ) :epdf ( ) {}
481                        euni ( const vec &low0, const vec &high0 ) {set_parameters ( low0,high0 );}
482                        void set_parameters ( const vec &low0, const vec &high0 )
483                        {
484                                distance = high0-low0;
485                                it_assert_debug ( min ( distance ) >0.0,"bad support" );
486                                low = low0;
487                                high = high0;
488                                nk = prod ( 1.0/distance );
489                                lnk = log ( nk );
490                                dim = low.length();
491                        }
492                        //!@}
493
494                        double eval ( const vec &val ) const  {return nk;}
495                        double evallog ( const vec &val ) const  {
496                                if (any(val<low) && any(val>high)) {return inf;}
497                                else return lnk;
498                        }
499                        vec sample() const
500                        {
501                                vec smp ( dim );
502#pragma omp critical
503                                UniRNG.sample_vector ( dim ,smp );
504                                return low+elem_mult ( distance,smp );
505                        }
506                        //! set values of \c low and \c high
507                        vec mean() const {return ( high-low ) /2.0;}
508                        vec variance() const {return ( pow ( high,2 ) +pow ( low,2 ) +elem_mult ( high,low ) ) /3.0;}
509                        //! Load from structure with elements:
510                        //!  \code
511                        //! { high = [...];          // vector of upper bounds
512                        //!   low = [...];           // vector of lower bounds
513                        //!   rv = {class="RV",...}  // description of RV
514                        //! }
515                        //! \endcode
516                        //!@}
517                        void from_setting(const Setting &set){
518                                epdf::from_setting(set); // reads rv and rvc
519
520                                UI::get(high,set,"high", UI::compulsory);
521                                UI::get(low,set,"low", UI::compulsory);
522                        }
523        };
524
525
526        /*!
527         \brief Normal distributed linear function with linear function of mean value;
528
529         Mean value \f$mu=A*rvc+mu_0\f$.
530        */
531        template<class sq_T>
532        class mlnorm : public mEF
533        {
534                protected:
535                        //! Internal epdf that arise by conditioning on \c rvc
536                        shared_ptr<enorm<sq_T> > iepdf;
537                        mat A;
538                        vec mu_const;
539                        vec& _mu; //cached epdf.mu;
540                public:
541                        //! \name Constructors
542                        //!@{
543                        mlnorm():iepdf(new enorm<sq_T>()), _mu(iepdf->_mu()) { set_ep(iepdf); };
544                        mlnorm (const mat &A, const vec &mu0, const sq_T &R ) :iepdf(new enorm<sq_T>()), _mu(iepdf->_mu())
545                        {
546                                set_ep(iepdf); set_parameters ( A,mu0,R );
547                        }
548
549                        //! Set \c A and \c R
550                        void set_parameters ( const  mat &A, const vec &mu0, const sq_T &R );
551                        //!@}
552                        //! Set value of \c rvc . Result of this operation is stored in \c epdf use function \c _ep to access it.
553                        void condition ( const vec &cond );
554
555                        //!access function
556                        vec& _mu_const() {return mu_const;}
557                        //!access function
558                        mat& _A() {return A;}
559                        //!access function
560                        mat _R() { return iepdf->_R().to_mat(); }
561
562                        template<class sq_M>
563                        friend std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_M> &ml );
564                       
565                        void from_setting(const Setting &set){
566                                mpdf::from_setting(set);       
567
568                                UI::get(A,set,"A", UI::compulsory);
569                                UI::get(mu_const,set,"const", UI::compulsory);
570                                mat R0;
571                                UI::get(R0,set,"R", UI::compulsory);
572                                set_parameters(A,mu_const,R0);
573                        };
574        };
575        UIREGISTER(mlnorm<ldmat>);
576        UIREGISTER(mlnorm<fsqmat>);
577        UIREGISTER(mlnorm<chmat>);
578
579//! Mpdf with general function for mean value
580        template<class sq_T>
581        class mgnorm : public mEF
582        {
583                protected:
584                        //! Internal epdf that arise by conditioning on \c rvc
585                        shared_ptr<enorm<sq_T> > iepdf;
586                        vec &mu;
587                        fnc* g;
588                public:
589                        //!default constructor
590                        mgnorm():iepdf(new enorm<sq_T>()), mu(iepdf->_mu()) { set_ep(iepdf); }
591                        //!set mean function
592                        void set_parameters ( fnc* g0, const sq_T &R0 ) {g=g0; iepdf->set_parameters ( zeros ( g->dimension() ), R0 );}
593                        void condition ( const vec &cond ) {mu=g->eval ( cond );};
594
595
596                        /*! UI for mgnorm
597
598                        The mgnorm is constructed from a structure with fields:
599                        \code
600                        system = {
601                                type = "mgnorm";
602                                // function for mean value evolution
603                                g = {type="fnc"; ... }
604
605                                // variance
606                                R = [1, 0,
607                                         0, 1];
608                                // --OR --
609                                dR = [1, 1];
610
611                                // == OPTIONAL ==
612
613                                // description of y variables
614                                y = {type="rv"; names=["y", "u"];};
615                                // description of u variable
616                                u = {type="rv"; names=[];}
617                        };
618                        \endcode
619
620                        Result if
621                        */
622
623                        void from_setting( const Setting &set ) 
624                        {       
625                                fnc* g = UI::build<fnc>( set, "g", UI::compulsory );
626
627                                mat R;                                 
628                                vec dR;                                 
629                                if ( UI::get( dR, set, "dR" ) )
630                                        R=diag(dR);
631                                else 
632                                        UI::get( R, set, "R", UI::compulsory); 
633               
634                                set_parameters(g,R);
635                        }
636        };
637
638        UIREGISTER(mgnorm<chmat>);
639
640
641        /*! (Approximate) Student t density with linear function of mean value
642
643        The internal epdf of this class is of the type of a Gaussian (enorm).
644        However, each conditioning is trying to assure the best possible approximation by taking into account the zeta function. See [] for reference.
645
646        Perhaps a moment-matching technique?
647        */
648        class mlstudent : public mlnorm<ldmat>
649        {
650                protected:
651                        ldmat Lambda;
652                        ldmat &_R;
653                        ldmat Re;
654                public:
655                        mlstudent ( ) :mlnorm<ldmat> (),
656                                        Lambda (),      _R ( iepdf->_R() ) {}
657                        void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0 )
658                        {
659                                it_assert_debug ( A0.rows() ==mu0.length(),"" );
660                                it_assert_debug ( R0.rows() ==A0.rows(),"" );
661
662                                iepdf->set_parameters ( mu0,Lambda ); //
663                                A = A0;
664                                mu_const = mu0;
665                                Re=R0;
666                                Lambda = Lambda0;
667                        }
668                        void condition ( const vec &cond )
669                        {
670                                _mu = A*cond + mu_const;
671                                double zeta;
672                                //ugly hack!
673                                if ( ( cond.length() +1 ) ==Lambda.rows() )
674                                {
675                                        zeta = Lambda.invqform ( concat ( cond, vec_1 ( 1.0 ) ) );
676                                }
677                                else
678                                {
679                                        zeta = Lambda.invqform ( cond );
680                                }
681                                _R = Re;
682                                _R*= ( 1+zeta );// / ( nu ); << nu is in Re!!!!!!
683                        };
684
685        };
686        /*!
687        \brief  Gamma random walk
688
689        Mean value, \f$\mu\f$, of this density is given by \c rvc .
690        Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
691        This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
692
693        The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
694        */
695        class mgamma : public mEF
696        {
697                protected:
698                        //! Internal epdf that arise by conditioning on \c rvc
699                        shared_ptr<egamma> iepdf;
700
701                        //! Constant \f$k\f$
702                        double k;
703
704                        //! cache of iepdf.beta
705                        vec &_beta;
706
707                public:
708                        //! Constructor
709                        mgamma():iepdf(new egamma()), k(0),
710                            _beta(iepdf->_beta()) {
711                            set_ep(iepdf);
712                        }
713
714                        //! Set value of \c k
715                        void set_parameters(double k, const vec &beta0);
716
717                        void condition ( const vec &val ) {_beta=k/val;};
718                        //! Load from structure with elements:
719                        //!  \code
720                        //! { alpha = [...];         // vector of alpha
721                        //!   k = 1.1;               // multiplicative constant k
722                        //!   rv = {class="RV",...}  // description of RV
723                        //!   rvc = {class="RV",...} // description of RV in condition
724                        //! }
725                        //! \endcode
726                        //!@}
727                        void from_setting(const Setting &set){
728                                mpdf::from_setting(set); // reads rv and rvc
729                                vec betatmp; // ugly but necessary
730                                UI::get(betatmp,set,"beta", UI::compulsory);
731                                UI::get(k,set,"k", UI::compulsory);
732                                set_parameters(k,betatmp);
733                        }
734        };
735        UIREGISTER(mgamma);
736       
737        /*!
738        \brief  Inverse-Gamma random walk
739
740        Mean value, \f$ \mu \f$, of this density is given by \c rvc .
741        Standard deviation of the random walk is proportional to one \f$ k \f$-th the mean.
742        This is achieved by setting \f$ \alpha=\mu/k^2+2 \f$ and \f$ \beta=\mu(\alpha-1)\f$.
743
744        The standard deviation of the walk is then: \f$ \mu/\sqrt(k)\f$.
745         */
746        class migamma : public mEF
747        {
748                protected:
749                        //! Internal epdf that arise by conditioning on \c rvc
750                        shared_ptr<eigamma> iepdf;
751
752                        //! Constant \f$k\f$
753                        double k;
754
755                        //! cache of iepdf.alpha
756                        vec &_alpha;
757
758                        //! cache of iepdf.beta
759                        vec &_beta;
760
761                public:
762                        //! \name Constructors
763                        //!@{
764                        migamma():iepdf(new eigamma()),
765                            k(0),
766                            _alpha(iepdf->_alpha()),
767                            _beta(iepdf->_beta()) {
768                            set_ep(iepdf);
769                        }
770
771                        migamma(const migamma &m):iepdf(m.iepdf),
772                            k(0),
773                            _alpha(iepdf->_alpha()),
774                            _beta(iepdf->_beta()) {
775                            set_ep(iepdf);
776                        }
777                        //!@}
778
779                        //! Set value of \c k
780                        void set_parameters ( int len, double k0 )
781                        {
782                                k=k0;
783                                iepdf->set_parameters ( ( 1.0/ ( k*k ) +2.0 ) *ones ( len ) /*alpha*/, ones ( len ) /*beta*/ );
784                                dimc = dimension();
785                        };
786                        void condition ( const vec &val )
787                        {
788                                _beta=elem_mult ( val, ( _alpha-1.0 ) );
789                        };
790        };
791
792
793        /*!
794        \brief  Gamma random walk around a fixed point
795
796        Mean 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
797        \f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f]
798
799        Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
800        This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
801
802        The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
803        */
804        class mgamma_fix : public mgamma
805        {
806                protected:
807                        //! parameter l
808                        double l;
809                        //! reference vector
810                        vec refl;
811                public:
812                        //! Constructor
813                        mgamma_fix ( ) : mgamma ( ),refl () {};
814                        //! Set value of \c k
815                        void set_parameters ( double k0 , vec ref0, double l0 )
816                        {
817                                mgamma::set_parameters ( k0, ref0 );
818                                refl=pow ( ref0,1.0-l0 );l=l0;
819                                dimc=dimension();
820                        };
821
822                        void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); _beta=k/mean;};
823        };
824
825
826        /*!
827        \brief  Inverse-Gamma random walk around a fixed point
828
829        Mean 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
830        \f[ \mu = \mu_{t-1} ^{l} p^{1-l}\f]
831
832        ==== Check == vv =
833        Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
834        This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
835
836        The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
837         */
838        class migamma_ref : public migamma
839        {
840                protected:
841                        //! parameter l
842                        double l;
843                        //! reference vector
844                        vec refl;
845                public:
846                        //! Constructor
847                        migamma_ref ( ) : migamma (),refl ( ) {};
848                        //! Set value of \c k
849                        void set_parameters ( double k0 , vec ref0, double l0 )
850                        {
851                                migamma::set_parameters ( ref0.length(), k0 );
852                                refl=pow ( ref0,1.0-l0 );
853                                l=l0;
854                                dimc = dimension();
855                        };
856
857                        void condition ( const vec &val )
858                        {
859                                vec mean=elem_mult ( refl,pow ( val,l ) );
860                                migamma::condition ( mean );
861                        };
862
863                        /*! UI for migamma_ref
864
865                        The migamma_ref is constructed from a structure with fields:
866                        \code
867                        system = {
868                                type = "migamma_ref";
869                                ref = [1e-5; 1e-5; 1e-2 1e-3];            // reference vector
870                                l = 0.999;                                // constant l
871                                k = 0.1;                                  // constant k
872                               
873                                // == OPTIONAL ==
874                                // description of y variables
875                                y = {type="rv"; names=["y", "u"];};
876                                // description of u variable
877                                u = {type="rv"; names=[];}
878                        };
879                        \endcode
880
881                        Result if
882                         */
883                        void from_setting( const Setting &set );
884
885                        // TODO dodelat void to_setting( Setting &set ) const;
886        };
887
888
889        UIREGISTER(migamma_ref);
890
891        /*! Log-Normal probability density
892         only allow diagonal covariances!
893
894        Density of the form \f$ \log(x)\sim \mathcal{N}(\mu,\sigma^2) \f$ , i.e.
895        \f[
896        x \sim \frac{1}{x\sigma\sqrt{2\pi}}\exp{-\frac{1}{2\sigma^2}(\log(x)-\mu)}
897        \f]
898
899        */
900        class elognorm: public enorm<ldmat>
901        {
902                public:
903                        vec sample() const {return exp ( enorm<ldmat>::sample() );};
904                        vec mean() const {vec var=enorm<ldmat>::variance();return exp ( mu - 0.5*var );};
905
906        };
907
908        /*!
909        \brief  Log-Normal random walk
910
911        Mean value, \f$\mu\f$, is...
912
913        ==== Check == vv =
914        Standard deviation of the random walk is proportional to one \f$k\f$-th the mean.
915        This is achieved by setting \f$\alpha=k\f$ and \f$\beta=k/\mu\f$.
916
917        The standard deviation of the walk is then: \f$\mu/\sqrt(k)\f$.
918         */
919        class mlognorm : public mpdf
920        {
921                protected:
922                        shared_ptr<elognorm> eno;
923
924                        //! parameter 1/2*sigma^2
925                        double sig2;
926
927                        //! access
928                        vec &mu;
929                public:
930                        //! Constructor
931                        mlognorm():eno(new elognorm()),
932                            sig2(0),
933                            mu(eno->_mu()) {
934                            set_ep(eno);
935                        }
936
937                        //! Set value of \c k
938                        void set_parameters ( int size, double k )
939                        {
940                                sig2 = 0.5*log ( k*k+1 );
941                                eno->set_parameters ( zeros ( size ),2*sig2*eye ( size ) );
942
943                                dimc = size;
944                        };
945
946                        void condition ( const vec &val )
947                        {
948                                mu=log ( val )-sig2;//elem_mult ( refl,pow ( val,l ) );
949                        };
950
951                        /*! UI for mlognorm
952
953                        The mlognorm is constructed from a structure with fields:
954                        \code
955                        system = {
956                                type = "mlognorm";
957                                k = 0.1;                                  // constant k
958                                mu0 = [1., 1.];
959                               
960                                // == OPTIONAL ==
961                                // description of y variables
962                                y = {type="rv"; names=["y", "u"];};
963                                // description of u variable
964                                u = {type="rv"; names=[];}
965                        };
966                        \endcode
967
968                         */
969                        void from_setting( const Setting &set );
970
971                        // TODO dodelat void to_setting( Setting &set ) const;
972
973        };
974       
975        UIREGISTER(mlognorm);
976
977        /*! inverse Wishart density defined on Choleski decomposition
978
979        */
980        class eWishartCh : public epdf
981        {
982                protected:
983                        //! Upper-Triagle of Choleski decomposition of \f$ \Psi \f$
984                        chmat Y;
985                        //! dimension of matrix  \f$ \Psi \f$
986                        int p;
987                        //! degrees of freedom  \f$ \nu \f$
988                        double delta;
989                public:
990                        void set_parameters ( const mat &Y0, const double delta0 ) {Y=chmat ( Y0 );delta=delta0; p=Y.rows(); dim = p*p; }
991                        mat sample_mat() const
992                        {
993                                mat X=zeros ( p,p );
994
995                                //sample diagonal
996                                for ( int i=0;i<p;i++ )
997                                {
998                                        GamRNG.setup ( 0.5* ( delta-i ) , 0.5 ); // no +1 !! index if from 0
999#pragma omp critical
1000                                        X ( i,i ) =sqrt ( GamRNG() );
1001                                }
1002                                //do the rest
1003                                for ( int i=0;i<p;i++ )
1004                                {
1005                                        for ( int j=i+1;j<p;j++ )
1006                                        {
1007#pragma omp critical
1008                                                X ( i,j ) =NorRNG.sample();
1009                                        }
1010                                }
1011                                return X*Y._Ch();// return upper triangular part of the decomposition
1012                        }
1013                        vec sample () const
1014                        {
1015                                return vec ( sample_mat()._data(),p*p );
1016                        }
1017                        //! fast access function y0 will be copied into Y.Ch.
1018                        void setY ( const mat &Ch0 ) {copy_vector ( dim,Ch0._data(), Y._Ch()._data() );}
1019                        //! fast access function y0 will be copied into Y.Ch.
1020                        void _setY ( const vec &ch0 ) {copy_vector ( dim, ch0._data(), Y._Ch()._data() ); }
1021                        //! access function
1022                        const chmat& getY()const {return Y;}
1023        };
1024
1025        class eiWishartCh: public epdf
1026        {
1027                protected:
1028                        eWishartCh W;
1029                        int p;
1030                        double delta;
1031                public:
1032                        void set_parameters ( const mat &Y0, const double delta0) {
1033                                delta = delta0;
1034                                W.set_parameters ( inv ( Y0 ),delta0 ); 
1035                                dim = W.dimension(); p=Y0.rows();
1036                        }
1037                        vec sample() const {mat iCh; iCh=inv ( W.sample_mat() ); return vec ( iCh._data(),dim );}
1038                        void _setY ( const vec &y0 )
1039                        {
1040                                mat Ch ( p,p );
1041                                mat iCh ( p,p );
1042                                copy_vector ( dim, y0._data(), Ch._data() );
1043                               
1044                                iCh=inv ( Ch );
1045                                W.setY ( iCh );
1046                        }
1047                        virtual double evallog ( const vec &val ) const {
1048                                chmat X(p);
1049                                const chmat& Y=W.getY();
1050                                 
1051                                copy_vector(p*p,val._data(),X._Ch()._data());
1052                                chmat iX(p);X.inv(iX);
1053                                // compute 
1054//                              \frac{ |\Psi|^{m/2}|X|^{-(m+p+1)/2}e^{-tr(\Psi X^{-1})/2} }{ 2^{mp/2}\Gamma_p(m/2)},
1055                                mat M=Y.to_mat()*iX.to_mat();
1056                               
1057                                double log1 = 0.5*p*(2*Y.logdet())-0.5*(delta+p+1)*(2*X.logdet())-0.5*trace(M); 
1058                                //Fixme! Multivariate gamma omitted!! it is ok for sampling, but not otherwise!!
1059                               
1060/*                              if (0) {
1061                                        mat XX=X.to_mat();
1062                                        mat YY=Y.to_mat();
1063                                       
1064                                        double log2 = 0.5*p*log(det(YY))-0.5*(delta+p+1)*log(det(XX))-0.5*trace(YY*inv(XX));
1065                                        cout << log1 << "," << log2 << endl;
1066                                }*/
1067                                return log1;                           
1068                        };
1069                       
1070        };
1071
1072        class rwiWishartCh : public mpdf
1073        {
1074                protected:
1075                        shared_ptr<eiWishartCh> eiW;
1076                        //!square root of \f$ \nu-p-1 \f$ - needed for computation of \f$ \Psi \f$ from conditions
1077                        double sqd;
1078                        //reference point for diagonal
1079                        vec refl;
1080                        double l;
1081                        int p;
1082
1083                public:
1084                        rwiWishartCh():eiW(new eiWishartCh()),
1085                            sqd(0), l(0), p(0) {
1086                            set_ep(eiW);
1087                        }
1088
1089                        void set_parameters ( int p0, double k, vec ref0, double l0  )
1090                        {
1091                                p=p0;
1092                                double delta = 2/(k*k)+p+3;
1093                                sqd=sqrt ( delta-p-1 );
1094                                l=l0;
1095                                refl=pow(ref0,1-l);
1096                               
1097                                eiW->set_parameters ( eye ( p ),delta );
1098                                dimc=eiW->dimension();
1099                        }
1100                        void condition ( const vec &c ) {
1101                                vec z=c;
1102                                int ri=0;
1103                                for(int i=0;i<p*p;i+=(p+1)){//trace diagonal element
1104                                        z(i) = pow(z(i),l)*refl(ri);
1105                                        ri++;
1106                                }
1107
1108                                eiW->_setY ( sqd*z );
1109                        }
1110        };
1111
1112//! Switch between various resampling methods.
1113        enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
1114        /*!
1115        \brief Weighted empirical density
1116
1117        Used e.g. in particle filters.
1118        */
1119        class eEmp: public epdf
1120        {
1121                protected :
1122                        //! Number of particles
1123                        int n;
1124                        //! Sample weights \f$w\f$
1125                        vec w;
1126                        //! Samples \f$x^{(i)}, i=1..n\f$
1127                        Array<vec> samples;
1128                public:
1129                        //! \name Constructors
1130                        //!@{
1131                        eEmp ( ) :epdf ( ),w ( ),samples ( ) {};
1132                        //! copy constructor
1133                        eEmp ( const eEmp &e ) : epdf ( e ), w ( e.w ), samples ( e.samples ) {};
1134                        //!@}
1135
1136                        //! Set samples and weights
1137                        void set_statistics ( const vec &w0, const epdf* pdf0 );
1138                        //! Set samples and weights
1139                        void set_statistics ( const epdf* pdf0 , int n ) {set_statistics ( ones ( n ) /n,pdf0 );};
1140                        //! Set sample
1141                        void set_samples ( const epdf* pdf0 );
1142                        //! Set sample
1143                        void set_parameters ( int n0, bool copy=true ) {n=n0; w.set_size ( n0,copy );samples.set_size ( n0,copy );};
1144                        //! Potentially dangerous, use with care.
1145                        vec& _w()  {return w;};
1146                        //! Potentially dangerous, use with care.
1147                        const vec& _w() const {return w;};
1148                        //! access function
1149                        Array<vec>& _samples() {return samples;};
1150                        //! access function
1151                        const Array<vec>& _samples() const {return samples;};
1152                        //! 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.
1153                        ivec resample ( RESAMPLING_METHOD method=SYSTEMATIC );
1154                        //! inherited operation : NOT implemneted
1155                        vec sample() const {it_error ( "Not implemented" );return 0;}
1156                        //! inherited operation : NOT implemneted
1157                        double evallog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
1158                        vec mean() const
1159                        {
1160                                vec pom=zeros ( dim );
1161                                for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
1162                                return pom;
1163                        }
1164                        vec variance() const
1165                        {
1166                                vec pom=zeros ( dim );
1167                                for ( int i=0;i<n;i++ ) {pom+=pow ( samples ( i ),2 ) *w ( i );}
1168                                return pom-pow ( mean(),2 );
1169                        }
1170                        //! For this class, qbounds are minimum and maximum value of the population!
1171                        void qbounds ( vec &lb, vec &ub, double perc=0.95 ) const
1172                        {
1173                                // lb in inf so than it will be pushed below;
1174                                lb.set_size ( dim );
1175                                ub.set_size ( dim );
1176                                lb = std::numeric_limits<double>::infinity();
1177                                ub = -std::numeric_limits<double>::infinity();
1178                                int j;
1179                                for ( int i=0;i<n;i++ )
1180                                {
1181                                        for ( j=0;j<dim; j++ )
1182                                        {
1183                                                if ( samples ( i ) ( j ) <lb ( j ) ) {lb ( j ) =samples ( i ) ( j );}
1184                                                if ( samples ( i ) ( j ) >ub ( j ) ) {ub ( j ) =samples ( i ) ( j );}
1185                                        }
1186                                }
1187                        }
1188        };
1189
1190
1191////////////////////////
1192
1193        template<class sq_T>
1194        void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 )
1195        {
1196//Fixme test dimensions of mu0 and R0;
1197                mu = mu0;
1198                R = R0;
1199                validate();
1200        };
1201
1202        template<class sq_T>
1203        void enorm<sq_T>::from_setting(const Setting &set){
1204                epdf::from_setting(set); //reads rv
1205               
1206                UI::get(mu,set,"mu", UI::compulsory);
1207                mat Rtmp;// necessary for conversion
1208                UI::get(Rtmp,set,"R", UI::compulsory);
1209                R=Rtmp; // conversion
1210                validate();
1211        }
1212
1213        template<class sq_T>
1214        void enorm<sq_T>::dupdate ( mat &v, double nu )
1215        {
1216                //
1217        };
1218
1219// template<class sq_T>
1220// void enorm<sq_T>::tupdate ( double phi, mat &vbar, double nubar ) {
1221//      //
1222// };
1223
1224        template<class sq_T>
1225        vec enorm<sq_T>::sample() const
1226        {
1227                vec x ( dim );
1228#pragma omp critical
1229                NorRNG.sample_vector ( dim,x );
1230                vec smp = R.sqrt_mult ( x );
1231
1232                smp += mu;
1233                return smp;
1234        };
1235
1236// template<class sq_T>
1237// double enorm<sq_T>::eval ( const vec &val ) const {
1238//      double pdfl,e;
1239//      pdfl = evallog ( val );
1240//      e = exp ( pdfl );
1241//      return e;
1242// };
1243
1244        template<class sq_T>
1245        double enorm<sq_T>::evallog_nn ( const vec &val ) const
1246        {
1247                // 1.83787706640935 = log(2pi)
1248                double tmp=-0.5* ( R.invqform ( mu-val ) );// - lognc();
1249                return  tmp;
1250        };
1251
1252        template<class sq_T>
1253        inline double enorm<sq_T>::lognc () const
1254        {
1255                // 1.83787706640935 = log(2pi)
1256                double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
1257                return tmp;
1258        };
1259
1260        template<class sq_T>
1261        void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 )
1262        {
1263                it_assert_debug ( A0.rows() ==mu0.length(),"" );
1264                it_assert_debug ( A0.rows() ==R0.rows(),"" );
1265
1266                iepdf->set_parameters(zeros(A0.rows()), R0);
1267                A = A0;
1268                mu_const = mu0;
1269                dimc = A0.cols();
1270        }
1271
1272// template<class sq_T>
1273// vec mlnorm<sq_T>::samplecond (const  vec &cond, double &lik ) {
1274//      this->condition ( cond );
1275//      vec smp = epdf.sample();
1276//      lik = epdf.eval ( smp );
1277//      return smp;
1278// }
1279
1280// template<class sq_T>
1281// mat mlnorm<sq_T>::samplecond (const vec &cond, vec &lik, int n ) {
1282//      int i;
1283//      int dim = rv.count();
1284//      mat Smp ( dim,n );
1285//      vec smp ( dim );
1286//      this->condition ( cond );
1287//
1288//      for ( i=0; i<n; i++ ) {
1289//              smp = epdf.sample();
1290//              lik ( i ) = epdf.eval ( smp );
1291//              Smp.set_col ( i ,smp );
1292//      }
1293//
1294//      return Smp;
1295// }
1296
1297        template<class sq_T>
1298        void mlnorm<sq_T>::condition ( const vec &cond )
1299        {
1300                _mu = A*cond + mu_const;
1301//R is already assigned;
1302        }
1303
1304        template<class sq_T>
1305        enorm<sq_T>* enorm<sq_T>::marginal ( const RV &rvn ) const
1306        {
1307                it_assert_debug ( isnamed(), "rv description is not assigned" );
1308                ivec irvn = rvn.dataind ( rv );
1309
1310                sq_T Rn ( R,irvn ); //select rows and columns of R
1311
1312                enorm<sq_T>* tmp = new enorm<sq_T>;
1313                tmp->set_rv ( rvn );
1314                tmp->set_parameters ( mu ( irvn ), Rn );
1315                return tmp;
1316        }
1317
1318        template<class sq_T>
1319        mpdf* enorm<sq_T>::condition ( const RV &rvn ) const
1320        {
1321
1322                it_assert_debug ( isnamed(),"rvs are not assigned" );
1323
1324                RV rvc = rv.subt ( rvn );
1325                it_assert_debug ( ( rvc._dsize() +rvn._dsize() ==rv._dsize() ),"wrong rvn" );
1326                //Permutation vector of the new R
1327                ivec irvn = rvn.dataind ( rv );
1328                ivec irvc = rvc.dataind ( rv );
1329                ivec perm=concat ( irvn , irvc );
1330                sq_T Rn ( R,perm );
1331
1332                //fixme - could this be done in general for all sq_T?
1333                mat S=Rn.to_mat();
1334                //fixme
1335                int n=rvn._dsize()-1;
1336                int end=R.rows()-1;
1337                mat S11 = S.get ( 0,n, 0, n );
1338                mat S12 = S.get ( 0, n , rvn._dsize(), end );
1339                mat S22 = S.get ( rvn._dsize(), end, rvn._dsize(), end );
1340
1341                vec mu1 = mu ( irvn );
1342                vec mu2 = mu ( irvc );
1343                mat A=S12*inv ( S22 );
1344                sq_T R_n ( S11 - A *S12.T() );
1345
1346                mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( );
1347                tmp->set_rv ( rvn ); tmp->set_rvc ( rvc );
1348                tmp->set_parameters ( A,mu1-A*mu2,R_n );
1349                return tmp;
1350        }
1351
1352///////////
1353
1354        template<class sq_T>
1355        std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_T> &ml )
1356        {
1357                os << "A:"<< ml.A<<endl;
1358                os << "mu:"<< ml.mu_const<<endl;
1359                os << "R:" << ml.iepdf->_R().to_mat() <<endl;
1360                return os;
1361        };
1362
1363}
1364#endif //EF_H
Note: See TracBrowser for help on using the browser.