Changeset 488 for library/bdm

Show
Ignore:
Timestamp:
08/08/09 13:43:13 (15 years ago)
Author:
smidl
Message:

changes in mpdf -> compile OK, broken tests!

Location:
library/bdm
Files:
8 modified

Legend:

Unmodified
Added
Removed
  • library/bdm/base/bdmbase.cpp

    r487 r488  
    140140} 
    141141 
    142 template<class EPDF> 
    143 vec mpdf_internal<EPDF>::samplecond ( const vec &cond ) { 
    144         condition ( cond ); 
    145         vec temp = iepdf.sample(); 
    146         return temp; 
    147 } 
    148  
    149 template<class EPDF> 
    150 mat mpdf_internal<EPDF>::samplecond_m ( const vec &cond, int N ) { 
    151         condition ( cond ); 
    152         mat temp ( dimension(), N ); 
    153         vec smp ( dimension() ); 
    154         for ( int i = 0; i < N; i++ ) { 
    155                 smp = iepdf.sample(); 
    156                 temp.set_col ( i, smp ); 
    157         } 
    158  
    159         return temp; 
    160 } 
    161  
    162 template<class EPDF> 
    163 double mpdf_internal<EPDF>::evallogcond ( const vec &dt, const vec &cond ) { 
    164         double tmp; 
    165         condition ( cond ); 
    166         tmp = iepdf.evallog ( dt ); 
    167         // it_assert_debug(std::isfinite(tmp), "Infinite value"); 
    168         return tmp; 
    169 } 
    170  
    171 template<class EPDF> 
    172 vec mpdf_internal<EPDF>::evallogcond_m ( const mat &Dt, const vec &cond ) { 
    173         condition ( cond ); 
    174         return iepdf.evallog_m ( Dt ); 
    175 } 
    176  
    177 template<class EPDF> 
    178                 vec mpdf_internal<EPDF>::evallogcond_m ( const Array<vec> &Dt, const vec &cond ) { 
    179         condition ( cond ); 
    180         return iepdf.evallog_m ( Dt ); 
    181 } 
    182142 
    183143void mpdf::from_setting ( const Setting &set ) { 
  • library/bdm/base/bdmbase.h

    r487 r488  
    2525using namespace std; 
    2626 
    27 namespace bdm { 
     27namespace bdm 
     28{ 
    2829 
    2930typedef std::map<string, int> RVmap; 
     
    3233 
    3334//! Structure of RV, i.e. RVs expanded into a flat list of IDs, used for debugging. 
    34 class str { 
    35 public: 
    36         //! vector id ids (non-unique!) 
    37         ivec ids; 
    38         //! vector of times 
    39         ivec times; 
    40         //!Default constructor 
    41         str ( ivec ids0, ivec times0 ) : ids ( ids0 ), times ( times0 ) { 
    42                 it_assert_debug ( times0.length() == ids0.length(), "Incompatible input" ); 
    43         }; 
     35class str 
     36{ 
     37        public: 
     38                //! vector id ids (non-unique!) 
     39                ivec ids; 
     40                //! vector of times 
     41                ivec times; 
     42                //!Default constructor 
     43                str (ivec ids0, ivec times0) : ids (ids0), times (times0) { 
     44                        it_assert_debug (times0.length() == ids0.length(), "Incompatible input"); 
     45                }; 
    4446}; 
    4547 
     
    8284*/ 
    8385 
    84 class RV : public root { 
    85 protected: 
    86         //! size of the data vector 
    87         int dsize; 
    88         //! number of individual rvs 
    89         int len; 
    90         //! Vector of unique IDs 
    91         ivec ids; 
    92         //! Vector of shifts from current time 
    93         ivec times; 
    94  
    95 private: 
    96         //! auxiliary function used in constructor 
    97         void init ( const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times ); 
    98         int init ( const string &name, int size ); 
    99 public: 
    100         //! \name Constructors 
    101         //!@{ 
    102  
    103         //! Full constructor 
    104         RV ( const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times ) { 
    105                 init ( in_names, in_sizes, in_times ); 
    106         } 
    107  
    108         //! Constructor with times=0 
    109         RV ( const Array<std::string> &in_names, const ivec &in_sizes ) { 
    110                 init ( in_names, in_sizes, zeros_i ( in_names.length() ) ); 
    111         } 
    112  
    113         //! Constructor with sizes=1, times=0 
    114         RV ( const Array<std::string> &in_names ) { 
    115                 init ( in_names, ones_i ( in_names.length() ), zeros_i ( in_names.length() ) ); 
    116         } 
    117  
    118         //! Constructor of empty RV 
    119         RV() : dsize ( 0 ), len ( 0 ), ids ( 0 ), times ( 0 ) {} 
    120         //! Constructor of a single RV with given id 
    121         RV ( string name, int sz, int tm = 0 ); 
    122         //!@} 
    123  
    124         //! \name Access functions 
    125         //!@{ 
    126  
    127         //! State output, e.g. for debugging. 
    128         friend std::ostream &operator<< ( std::ostream &os, const RV &rv ); 
    129  
    130         int _dsize() const { 
    131                 return dsize; 
    132         } 
    133  
    134         //! Recount size of the corresponding data vector 
    135         int countsize() const; 
    136         ivec cumsizes() const; 
    137         int length() const { 
    138                 return len; 
    139         } 
    140         int id ( int at ) const { 
    141                 return ids ( at ); 
    142         } 
    143         int size ( int at ) const { 
    144                 return RV_SIZES ( ids ( at ) ); 
    145         } 
    146         int time ( int at ) const { 
    147                 return times ( at ); 
    148         } 
    149         std::string name ( int at ) const { 
    150                 return RV_NAMES ( ids ( at ) ); 
    151         } 
    152         void set_time ( int at, int time0 ) { 
    153                 times ( at ) = time0; 
    154         } 
    155         //!@} 
    156  
    157         //TODO why not inline and later?? 
    158  
    159         //! \name Algebra on Random Variables 
    160         //!@{ 
    161  
    162         //! Find indices of self in another rv, \return ivec of the same size as self. 
    163         ivec findself ( const RV &rv2 ) const; 
    164         //! Compare if \c rv2 is identical to this \c RV 
    165         bool equal ( const RV &rv2 ) const; 
    166         //! Add (concat) another variable to the current one, \return true if all rv2 were added, false if rv2 is in conflict 
    167         bool add ( const RV &rv2 ); 
    168         //! Subtract  another variable from the current one 
    169         RV subt ( const RV &rv2 ) const; 
    170         //! Select only variables at indices ind 
    171         RV subselect ( const ivec &ind ) const; 
    172  
    173         //! Select only variables at indices ind 
    174         RV operator() ( const ivec &ind ) const { 
    175                 return subselect ( ind ); 
    176         } 
    177  
    178         //! Select from data vector starting at di1 to di2 
    179         RV operator() ( int di1, int di2 ) const; 
    180  
    181         //! Shift \c time by delta. 
    182         void t ( int delta ); 
    183         //!@} 
    184  
    185         //!\name Relation to vectors 
    186         //!@{ 
    187  
    188         //! generate \c str from rv, by expanding sizes TODO to_string.. 
    189         str tostr() const; 
    190         //! when this rv is a part of bigger rv, this function returns indices of self in the data vector of the bigger crv. 
    191         //! Then, data can be copied via: data_of_this = cdata(ind); 
    192         ivec dataind ( const RV &crv ) const; 
    193         //! generate mutual indices when copying data between self and crv. 
    194         //! Data are copied via: data_of_this(selfi) = data_of_rv2(rv2i) 
    195         void dataind ( const RV &rv2, ivec &selfi, ivec &rv2i ) const; 
    196         //! Minimum time-offset 
    197         int mint() const { 
    198                 return min ( times ); 
    199         } 
    200         //!@} 
    201  
    202         // TODO aktualizovat dle soucasneho UI 
    203         /*! \brief UI for class RV (description of data vectors) 
    204  
    205         \code 
    206         rv = { 
    207           type = "rv"; //identifier of the description 
    208           // UNIQUE IDENTIFIER same names = same variable 
    209           names = ["a", "b", "c", ...];   // which will be used e.g. in loggers 
    210  
    211           //optional arguments 
    212           sizes = [1, 2, 3, ...];         // (optional) default = ones() 
    213           times = [-1, -2, 0, ...];       // time shifts with respect to current time (optional) default = zeros() 
    214         } 
    215         \endcode 
    216         */ 
    217         void from_setting ( const Setting &set ); 
    218  
    219         // TODO dodelat void to_setting( Setting &set ) const; 
    220  
    221         //! Invalidate all named RVs. Use before initializing any RV instances, with care... 
    222         static void clear_all(); 
    223 }; 
    224 UIREGISTER ( RV ); 
     86class RV : public root 
     87{ 
     88        protected: 
     89                //! size of the data vector 
     90                int dsize; 
     91                //! number of individual rvs 
     92                int len; 
     93                //! Vector of unique IDs 
     94                ivec ids; 
     95                //! Vector of shifts from current time 
     96                ivec times; 
     97 
     98        private: 
     99                //! auxiliary function used in constructor 
     100                void init (const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times); 
     101                int init (const string &name, int size); 
     102        public: 
     103                //! \name Constructors 
     104                //!@{ 
     105 
     106                //! Full constructor 
     107                RV (const Array<std::string> &in_names, const ivec &in_sizes, const ivec &in_times) { 
     108                        init (in_names, in_sizes, in_times); 
     109                } 
     110 
     111                //! Constructor with times=0 
     112                RV (const Array<std::string> &in_names, const ivec &in_sizes) { 
     113                        init (in_names, in_sizes, zeros_i (in_names.length())); 
     114                } 
     115 
     116                //! Constructor with sizes=1, times=0 
     117                RV (const Array<std::string> &in_names) { 
     118                        init (in_names, ones_i (in_names.length()), zeros_i (in_names.length())); 
     119                } 
     120 
     121                //! Constructor of empty RV 
     122                RV() : dsize (0), len (0), ids (0), times (0) {} 
     123                //! Constructor of a single RV with given id 
     124                RV (string name, int sz, int tm = 0); 
     125                //!@} 
     126 
     127                //! \name Access functions 
     128                //!@{ 
     129 
     130                //! State output, e.g. for debugging. 
     131                friend std::ostream &operator<< (std::ostream &os, const RV &rv); 
     132 
     133                int _dsize() const { 
     134                        return dsize; 
     135                } 
     136 
     137                //! Recount size of the corresponding data vector 
     138                int countsize() const; 
     139                ivec cumsizes() const; 
     140                int length() const { 
     141                        return len; 
     142                } 
     143                int id (int at) const { 
     144                        return ids (at); 
     145                } 
     146                int size (int at) const { 
     147                        return RV_SIZES (ids (at)); 
     148                } 
     149                int time (int at) const { 
     150                        return times (at); 
     151                } 
     152                std::string name (int at) const { 
     153                        return RV_NAMES (ids (at)); 
     154                } 
     155                void set_time (int at, int time0) { 
     156                        times (at) = time0; 
     157                } 
     158                //!@} 
     159 
     160                //TODO why not inline and later?? 
     161 
     162                //! \name Algebra on Random Variables 
     163                //!@{ 
     164 
     165                //! Find indices of self in another rv, \return ivec of the same size as self. 
     166                ivec findself (const RV &rv2) const; 
     167                //! Compare if \c rv2 is identical to this \c RV 
     168                bool equal (const RV &rv2) const; 
     169                //! Add (concat) another variable to the current one, \return true if all rv2 were added, false if rv2 is in conflict 
     170                bool add (const RV &rv2); 
     171                //! Subtract  another variable from the current one 
     172                RV subt (const RV &rv2) const; 
     173                //! Select only variables at indices ind 
     174                RV subselect (const ivec &ind) const; 
     175 
     176                //! Select only variables at indices ind 
     177                RV operator() (const ivec &ind) const { 
     178                        return subselect (ind); 
     179                } 
     180 
     181                //! Select from data vector starting at di1 to di2 
     182                RV operator() (int di1, int di2) const; 
     183 
     184                //! Shift \c time by delta. 
     185                void t (int delta); 
     186                //!@} 
     187 
     188                //!\name Relation to vectors 
     189                //!@{ 
     190 
     191                //! generate \c str from rv, by expanding sizes TODO to_string.. 
     192                str tostr() const; 
     193                //! when this rv is a part of bigger rv, this function returns indices of self in the data vector of the bigger crv. 
     194                //! Then, data can be copied via: data_of_this = cdata(ind); 
     195                ivec dataind (const RV &crv) const; 
     196                //! generate mutual indices when copying data between self and crv. 
     197                //! Data are copied via: data_of_this(selfi) = data_of_rv2(rv2i) 
     198                void dataind (const RV &rv2, ivec &selfi, ivec &rv2i) const; 
     199                //! Minimum time-offset 
     200                int mint() const { 
     201                        return min (times); 
     202                } 
     203                //!@} 
     204 
     205                // TODO aktualizovat dle soucasneho UI 
     206                /*! \brief UI for class RV (description of data vectors) 
     207 
     208                \code 
     209                rv = { 
     210                  type = "rv"; //identifier of the description 
     211                  // UNIQUE IDENTIFIER same names = same variable 
     212                  names = ["a", "b", "c", ...];   // which will be used e.g. in loggers 
     213 
     214                  //optional arguments 
     215                  sizes = [1, 2, 3, ...];         // (optional) default = ones() 
     216                  times = [-1, -2, 0, ...];       // time shifts with respect to current time (optional) default = zeros() 
     217                } 
     218                \endcode 
     219                */ 
     220                void from_setting (const Setting &set); 
     221 
     222                // TODO dodelat void to_setting( Setting &set ) const; 
     223 
     224                //! Invalidate all named RVs. Use before initializing any RV instances, with care... 
     225                static void clear_all(); 
     226}; 
     227UIREGISTER (RV); 
    225228 
    226229//! Concat two random variables 
    227 RV concat ( const RV &rv1, const RV &rv2 ); 
     230RV concat (const RV &rv1, const RV &rv2); 
    228231 
    229232//!Default empty RV that can be used as default argument 
     
    232235//! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv 
    233236 
    234 class fnc : public root { 
    235 protected: 
    236         //! Length of the output vector 
    237         int dimy; 
    238 public: 
    239         //!default constructor 
    240         fnc() {}; 
    241         //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond 
    242         virtual vec eval ( const vec &cond ) { 
    243                 return vec ( 0 ); 
    244         }; 
    245  
    246         //! function substitutes given value into an appropriate position 
    247         virtual void condition ( const vec &val ) {}; 
    248  
    249         //! access function 
    250         int dimension() const { 
    251                 return dimy; 
    252         } 
     237class fnc : public root 
     238{ 
     239        protected: 
     240                //! Length of the output vector 
     241                int dimy; 
     242        public: 
     243                //!default constructor 
     244                fnc() {}; 
     245                //! function evaluates numerical value of \f$f(x)\f$ at \f$x=\f$ \c cond 
     246                virtual vec eval (const vec &cond) { 
     247                        return vec (0); 
     248                }; 
     249 
     250                //! function substitutes given value into an appropriate position 
     251                virtual void condition (const vec &val) {}; 
     252 
     253                //! access function 
     254                int dimension() const { 
     255                        return dimy; 
     256                } 
    253257}; 
    254258 
     
    257261//! Probability density function with numerical statistics, e.g. posterior density. 
    258262 
    259 class epdf : public root { 
    260 protected: 
    261         //! dimension of the random variable 
    262         int dim; 
    263         //! Description of the random variable 
    264         RV rv; 
    265  
    266 public: 
    267         /*! \name Constructors 
    268          Construction of each epdf should support two types of constructors: 
    269         \li empty constructor, 
    270         \li copy constructor, 
    271  
    272         The following constructors should be supported for convenience: 
    273         \li constructor followed by calling \c set_parameters() 
    274         \li constructor accepting random variables calling \c set_rv() 
    275  
    276          All internal data structures are constructed as empty. Their values (including sizes) will be set by method \c set_parameters(). This way references can be initialized in constructors. 
    277         @{*/ 
    278         epdf() : dim ( 0 ), rv() {}; 
    279         epdf ( const epdf &e ) : dim ( e.dim ), rv ( e.rv ) {}; 
    280         epdf ( const RV &rv0 ) : dim ( rv0._dsize() ) { 
    281                 set_rv ( rv0 ); 
    282         }; 
    283         void set_parameters ( int dim0 ) { 
    284                 dim = dim0; 
    285         } 
    286         //!@} 
    287  
    288         //! \name Matematical Operations 
    289         //!@{ 
    290  
    291         //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$ 
    292         virtual vec sample() const { 
    293                 it_error ( "not implemneted" ); 
    294                 return vec ( 0 ); 
    295         }; 
    296         //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$  from density \f$ f_x(rv)\f$ 
    297         virtual mat sample_m ( int N ) const; 
    298         //! Compute log-probability of argument \c val 
    299         //! In case the argument is out of suport return -Infinity 
    300         virtual double evallog ( const vec &val ) const { 
    301                 it_error ( "not implemneted" ); 
    302                 return 0.0; 
    303         }; 
    304         //! Compute log-probability of multiple values argument \c val 
    305         virtual vec evallog_m ( const mat &Val ) const { 
    306                 vec x ( Val.cols() ); 
    307                 for ( int i = 0; i < Val.cols(); i++ ) { 
    308                         x ( i ) = evallog ( Val.get_col ( i ) ) ; 
    309                 } 
    310                 return x; 
    311         } 
    312         //! Compute log-probability of multiple values argument \c val 
    313         virtual vec evallog_m ( const Array<vec> &Avec ) const { 
    314                 vec x ( Avec.size() ); 
    315                 for ( int i = 0; i < Avec.size(); i++ ) { 
    316                         x ( i ) = evallog ( Avec ( i ) ) ; 
    317                 } 
    318                 return x; 
    319         } 
    320         //! Return conditional density on the given RV, the remaining rvs will be in conditioning 
    321         virtual mpdf* condition ( const RV &rv ) const  { 
    322                 it_warning ( "Not implemented" ); 
    323                 return NULL; 
    324         } 
    325  
    326         //! Return marginal density on the given RV, the remainig rvs are intergrated out 
    327         virtual epdf* marginal ( const RV &rv ) const { 
    328                 it_warning ( "Not implemented" ); 
    329                 return NULL; 
    330         } 
    331  
    332         //! return expected value 
    333         virtual vec mean() const { 
    334                 it_error ( "not implemneted" ); 
    335                 return vec ( 0 ); 
    336         }; 
    337  
    338         //! return expected variance (not covariance!) 
    339         virtual vec variance() const { 
    340                 it_error ( "not implemneted" ); 
    341                 return vec ( 0 ); 
    342         }; 
    343         //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default 
    344         virtual void qbounds ( vec &lb, vec &ub, double percentage = 0.95 ) const { 
    345                 vec mea = mean(); 
    346                 vec std = sqrt ( variance() ); 
    347                 lb = mea - 2 * std; 
    348                 ub = mea + 2 * std; 
    349         }; 
    350         //!@} 
    351  
    352         //! \name Connection to other classes 
    353         //! Description of the random quantity via attribute \c rv is optional. 
    354         //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization 
    355         //! and \c conditioning \c rv has to be set. NB: 
    356         //! @{ 
    357  
    358         //!Name its rv 
    359         void set_rv ( const RV &rv0 ) { 
    360                 rv = rv0; 
    361         }   //it_assert_debug(isnamed(),""); }; 
    362         //! True if rv is assigned 
    363         bool isnamed() const { 
    364                 bool b = ( dim == rv._dsize() ); 
    365                 return b; 
    366         } 
    367         //! Return name (fails when isnamed is false) 
    368         const RV& _rv() const { 
    369                 it_assert_debug ( isnamed(), "" ); 
    370                 return rv; 
    371         } 
    372         //!@} 
    373  
    374         //! \name Access to attributes 
    375         //! @{ 
    376  
    377         //! Size of the random variable 
    378         int dimension() const { 
    379                 return dim; 
    380         } 
    381         //! Load from structure with elements: 
    382         //!  \code 
    383         //! { rv = {class="RV", names=(...),}; // RV describing meaning of random variable 
    384         //!   // elements of offsprings 
    385         //! } 
    386         //! \endcode 
    387         //!@} 
    388         void from_setting ( const Setting &set ) { 
    389                 RV* r = UI::build<RV> ( set, "rv" ); 
    390                 if ( r ) { 
    391                         set_rv ( *r ); 
    392                         delete r; 
    393                 } 
    394         } 
     263class epdf : public root 
     264{ 
     265        protected: 
     266                //! dimension of the random variable 
     267                int dim; 
     268                //! Description of the random variable 
     269                RV rv; 
     270 
     271        public: 
     272                /*! \name Constructors 
     273                 Construction of each epdf should support two types of constructors: 
     274                \li empty constructor, 
     275                \li copy constructor, 
     276 
     277                The following constructors should be supported for convenience: 
     278                \li constructor followed by calling \c set_parameters() 
     279                \li constructor accepting random variables calling \c set_rv() 
     280 
     281                 All internal data structures are constructed as empty. Their values (including sizes) will be set by method \c set_parameters(). This way references can be initialized in constructors. 
     282                @{*/ 
     283                epdf() : dim (0), rv() {}; 
     284                epdf (const epdf &e) : dim (e.dim), rv (e.rv) {}; 
     285                epdf (const RV &rv0) : dim (rv0._dsize()) { 
     286                        set_rv (rv0); 
     287                }; 
     288                void set_parameters (int dim0) { 
     289                        dim = dim0; 
     290                } 
     291                //!@} 
     292 
     293                //! \name Matematical Operations 
     294                //!@{ 
     295 
     296                //! Returns a sample, \f$ x \f$ from density \f$ f_x()\f$ 
     297                virtual vec sample() const { 
     298                        it_error ("not implemneted"); 
     299                        return vec (0); 
     300                }; 
     301                //! Returns N samples, \f$ [x_1 , x_2 , \ldots \ \f$  from density \f$ f_x(rv)\f$ 
     302                virtual mat sample_m (int N) const; 
     303                //! Compute log-probability of argument \c val 
     304                //! In case the argument is out of suport return -Infinity 
     305                virtual double evallog (const vec &val) const { 
     306                        it_error ("not implemneted"); 
     307                        return 0.0; 
     308                }; 
     309                //! Compute log-probability of multiple values argument \c val 
     310                virtual vec evallog_m (const mat &Val) const { 
     311                        vec x (Val.cols()); 
     312                        for (int i = 0; i < Val.cols(); i++) { 
     313                                x (i) = evallog (Val.get_col (i)) ; 
     314                        } 
     315                        return x; 
     316                } 
     317                //! Compute log-probability of multiple values argument \c val 
     318                virtual vec evallog_m (const Array<vec> &Avec) const { 
     319                        vec x (Avec.size()); 
     320                        for (int i = 0; i < Avec.size(); i++) { 
     321                                x (i) = evallog (Avec (i)) ; 
     322                        } 
     323                        return x; 
     324                } 
     325                //! Return conditional density on the given RV, the remaining rvs will be in conditioning 
     326                virtual mpdf* condition (const RV &rv) const  { 
     327                        it_warning ("Not implemented"); 
     328                        return NULL; 
     329                } 
     330 
     331                //! Return marginal density on the given RV, the remainig rvs are intergrated out 
     332                virtual epdf* marginal (const RV &rv) const { 
     333                        it_warning ("Not implemented"); 
     334                        return NULL; 
     335                } 
     336 
     337                //! return expected value 
     338                virtual vec mean() const { 
     339                        it_error ("not implemneted"); 
     340                        return vec (0); 
     341                }; 
     342 
     343                //! return expected variance (not covariance!) 
     344                virtual vec variance() const { 
     345                        it_error ("not implemneted"); 
     346                        return vec (0); 
     347                }; 
     348                //! Lower and upper bounds of \c percentage % quantile, returns mean-2*sigma as default 
     349                virtual void qbounds (vec &lb, vec &ub, double percentage = 0.95) const { 
     350                        vec mea = mean(); 
     351                        vec std = sqrt (variance()); 
     352                        lb = mea - 2 * std; 
     353                        ub = mea + 2 * std; 
     354                }; 
     355                //!@} 
     356 
     357                //! \name Connection to other classes 
     358                //! Description of the random quantity via attribute \c rv is optional. 
     359                //! For operations such as sampling \c rv does not need to be set. However, for \c marginalization 
     360                //! and \c conditioning \c rv has to be set. NB: 
     361                //! @{ 
     362 
     363                //!Name its rv 
     364                void set_rv (const RV &rv0) { 
     365                        rv = rv0; 
     366                }   //it_assert_debug(isnamed(),""); }; 
     367                //! True if rv is assigned 
     368                bool isnamed() const { 
     369                        bool b = (dim == rv._dsize()); 
     370                        return b; 
     371                } 
     372                //! Return name (fails when isnamed is false) 
     373                const RV& _rv() const { 
     374                        it_assert_debug (isnamed(), ""); 
     375                        return rv; 
     376                } 
     377                //!@} 
     378 
     379                //! \name Access to attributes 
     380                //! @{ 
     381 
     382                //! Size of the random variable 
     383                int dimension() const { 
     384                        return dim; 
     385                } 
     386                //! Load from structure with elements: 
     387                //!  \code 
     388                //! { rv = {class="RV", names=(...),}; // RV describing meaning of random variable 
     389                //!   // elements of offsprings 
     390                //! } 
     391                //! \endcode 
     392                //!@} 
     393                void from_setting (const Setting &set) { 
     394                        RV* r = UI::build<RV> (set, "rv"); 
     395                        if (r) { 
     396                                set_rv (*r); 
     397                                delete r; 
     398                        } 
     399                } 
    395400 
    396401}; 
     
    399404//! Conditional probability density, e.g. modeling some dependencies. 
    400405//TODO Samplecond can be generalized 
    401 class mpdf : public root { 
    402 protected: 
    403         //!dimension of the condition 
    404         int dimc; 
    405         //! random variable in condition 
    406         RV rvc; 
    407 private: 
    408         //! internal epdf, used only as cache to avoid virtual calls of \c _rv() and \c _dimension() 
    409         epdf* ep; 
    410          
    411 protected: 
    412         void set_ep(epdf &iepdf) { 
    413                 ep = &iepdf; 
    414         } 
    415  
    416 public: 
    417         //! \name Constructors 
    418         //! @{ 
    419  
    420         mpdf() : dimc ( 0 ), rvc(), ep(NULL) { } 
    421  
    422         mpdf ( const mpdf &m ) : dimc ( m.dimc ), rvc ( m.rvc ), ep ( m.ep ) { } 
    423         //!@} 
    424  
    425         //! \name Matematical operations 
    426         //!@{ 
    427  
    428         //! Returns a sample from the density conditioned on \c cond, \f$x \sim epdf(rv|cond)\f$. \param cond is numeric value of \c rv 
    429         virtual vec samplecond ( const vec &cond ){it_error("Not implemented");return vec(0);}; 
    430  
    431         //! Returns \param N samples from the density conditioned on \c cond, \f$x \sim epdf(rv|cond)\f$. \param cond is numeric value of \c rv 
    432         virtual mat samplecond_m ( const vec &cond, int N ){it_error("Not implemented");return mat();} 
    433  
    434  
    435         //! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently. 
    436         virtual double evallogcond ( const vec &dt, const vec &cond ){it_error("Not implemented");return 0.0;} 
    437  
    438         //! Matrix version of evallogcond 
    439         virtual vec evallogcond_m ( const mat &Dt, const vec &cond ){it_error("Not implemented");return vec(0);} 
    440  
    441         //! Array<vec> version of evallogcond 
    442         virtual vec evallogcond_m ( const Array<vec> &Dt, const vec &cond ){it_error("Not implemented");return vec(0);} 
    443  
    444         //! \name Access to attributes 
    445         //! @{ 
    446  
    447         RV _rv() { 
    448                 return ep->_rv(); 
    449         } 
    450         RV _rvc() { 
    451                 it_assert_debug ( isnamed(), "" ); 
    452                 return rvc; 
    453         } 
    454         int dimension() { 
    455                 return ep->dimension(); 
    456         } 
    457         int dimensionc() { 
    458                 return dimc; 
    459         } 
    460  
    461         //! Load from structure with elements: 
    462         //!  \code 
    463         //! { class = "mpdf_offspring", 
    464         //!   rv = {class="RV", names=(...),}; // RV describing meaning of random variable 
    465         //!   rvc= {class="RV", names=(...),}; // RV describing meaning of random variable in condition 
    466         //!   // elements of offsprings 
    467         //! } 
    468         //! \endcode 
    469         //!@} 
    470         void from_setting ( const Setting &set ); 
    471         //!@} 
    472  
    473         //! \name Connection to other objects 
    474         //!@{ 
    475         void set_rvc ( const RV &rvc0 ) { 
    476                 rvc = rvc0; 
    477         } 
    478         void set_rv ( const RV &rv0 ) { 
    479                 ep->set_rv ( rv0 ); 
    480         } 
    481         bool isnamed() { 
    482                 return ( ep->isnamed() ) && ( dimc == rvc._dsize() ); 
    483         } 
    484         //!@} 
     406class mpdf : public root 
     407{ 
     408        protected: 
     409                //!dimension of the condition 
     410                int dimc; 
     411                //! random variable in condition 
     412                RV rvc; 
     413        private: 
     414                //! internal epdf, used only as cache to avoid virtual calls of \c _rv() and \c _dimension() 
     415                epdf* ep; 
     416 
     417        protected: 
     418                void set_ep (epdf &iepdf) { 
     419                        ep = &iepdf; 
     420                } 
     421 
     422        public: 
     423                //! \name Constructors 
     424                //! @{ 
     425 
     426                mpdf() : dimc (0), rvc(), ep (NULL) { } 
     427 
     428                mpdf (const mpdf &m) : dimc (m.dimc), rvc (m.rvc), ep (m.ep) { } 
     429                //!@} 
     430 
     431                //! \name Matematical operations 
     432                //!@{ 
     433 
     434                //! Returns a sample from the density conditioned on \c cond, \f$x \sim epdf(rv|cond)\f$. \param cond is numeric value of \c rv 
     435                virtual vec samplecond (const vec &cond) {it_error ("Not implemented");return vec (0);}; 
     436 
     437                //! Returns \param N samples from the density conditioned on \c cond, \f$x \sim epdf(rv|cond)\f$. \param cond is numeric value of \c rv 
     438                virtual mat samplecond_m (const vec &cond, int N) {it_error ("Not implemented");return mat();} 
     439 
     440 
     441                //! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently. 
     442                virtual double evallogcond (const vec &dt, const vec &cond) {it_error ("Not implemented");return 0.0;} 
     443 
     444                //! Matrix version of evallogcond 
     445                virtual vec evallogcond_m (const mat &Dt, const vec &cond) {it_error ("Not implemented");return vec (0);} 
     446 
     447                //! Array<vec> version of evallogcond 
     448                virtual vec evallogcond_m (const Array<vec> &Dt, const vec &cond) {it_error ("Not implemented");return vec (0);} 
     449 
     450                //! \name Access to attributes 
     451                //! @{ 
     452 
     453                RV _rv() { 
     454                        return ep->_rv(); 
     455                } 
     456                RV _rvc() { 
     457                        it_assert_debug (isnamed(), ""); 
     458                        return rvc; 
     459                } 
     460                int dimension() { 
     461                        return ep->dimension(); 
     462                } 
     463                int dimensionc() { 
     464                        return dimc; 
     465                } 
     466 
     467                //! Load from structure with elements: 
     468                //!  \code 
     469                //! { class = "mpdf_offspring", 
     470                //!   rv = {class="RV", names=(...),}; // RV describing meaning of random variable 
     471                //!   rvc= {class="RV", names=(...),}; // RV describing meaning of random variable in condition 
     472                //!   // elements of offsprings 
     473                //! } 
     474                //! \endcode 
     475                //!@} 
     476                void from_setting (const Setting &set); 
     477                //!@} 
     478 
     479                //! \name Connection to other objects 
     480                //!@{ 
     481                void set_rvc (const RV &rvc0) { 
     482                        rvc = rvc0; 
     483                } 
     484                void set_rv (const RV &rv0) { 
     485                        ep->set_rv (rv0); 
     486                } 
     487                bool isnamed() { 
     488                        return (ep->isnamed()) && (dimc == rvc._dsize()); 
     489                } 
     490                //!@} 
    485491}; 
    486492 
    487493template <class EPDF> 
    488 class mpdf_internal: public mpdf{ 
     494class mpdf_internal: public mpdf 
     495{ 
    489496        protected : 
    490497                EPDF iepdf; 
    491498        public: 
    492499                //! constructor 
    493                 mpdf_internal(): mpdf(),iepdf(){set_ep(iepdf);} 
     500                mpdf_internal() : mpdf(), iepdf() {set_ep (iepdf);} 
    494501                //! Update \c iepdf so that it represents this mpdf conditioned on \c rvc = cond 
    495502                //! This function provides convenient reimplementation in offsprings 
    496                         virtual void condition ( const vec &cond ) { 
    497                                 it_error ( "Not implemented" ); 
    498                         }; 
     503                virtual void condition (const vec &cond) { 
     504                        it_error ("Not implemented"); 
     505                }; 
    499506                //!access function to iepdf 
    500                 EPDF& e(){return iepdf;} 
    501                          
     507                EPDF& e() {return iepdf;} 
     508 
    502509                //! Reimplements samplecond using \c condition() 
    503                 vec samplecond ( const vec &cond ); 
     510                vec samplecond (const vec &cond); 
    504511                //! Reimplements evallogcond using \c condition() 
    505                 double evallogcond ( const vec &val, const vec &cond ); 
    506                 //! Efficient version of evallogcond for matrices  
    507                 virtual vec evallogcond_m ( const mat &Dt, const vec &cond ); 
     512                double evallogcond (const vec &val, const vec &cond); 
     513                //! Efficient version of evallogcond for matrices 
     514                virtual vec evallogcond_m (const mat &Dt, const vec &cond); 
    508515                //! Efficient version of evallogcond for Array<vec> 
    509                 virtual vec evallogcond_m ( const Array<vec> &Dt, const vec &cond ); 
    510                 //! Efficient version of samplecond  
    511                 virtual mat samplecond_m ( const vec &cond, int N ); 
     516                virtual vec evallogcond_m (const Array<vec> &Dt, const vec &cond); 
     517                //! Efficient version of samplecond 
     518                virtual mat samplecond_m (const vec &cond, int N); 
    512519}; 
    513520 
     
    537544 
    538545*/ 
    539 class datalink { 
    540 protected: 
    541         //! Remember how long val should be 
    542         int downsize; 
    543  
    544         //! Remember how long val of "Up" should be 
    545         int upsize; 
    546  
    547         //! val-to-val link, indices of the upper val 
    548         ivec v2v_up; 
    549  
    550 public: 
    551         //! Constructor 
    552         datalink() : downsize ( 0 ), upsize ( 0 ) { } 
    553         datalink ( const RV &rv, const RV &rv_up ) { 
    554                 set_connection ( rv, rv_up ); 
    555         } 
    556  
    557         //! set connection, rv must be fully present in rv_up 
    558         void set_connection ( const RV &rv, const RV &rv_up ) { 
    559                 downsize = rv._dsize(); 
    560                 upsize = rv_up._dsize(); 
    561                 v2v_up = rv.dataind ( rv_up ); 
    562  
    563                 it_assert_debug ( v2v_up.length() == downsize, "rv is not fully in rv_up" ); 
    564         } 
    565  
    566         //! set connection using indices 
    567         void set_connection ( int ds, int us, const ivec &upind ) { 
    568                 downsize = ds; 
    569                 upsize = us; 
    570                 v2v_up = upind; 
    571  
    572                 it_assert_debug ( v2v_up.length() == downsize, "rv is not fully in rv_up" ); 
    573         } 
    574  
    575         //! Get val for myself from val of "Up" 
    576         vec pushdown ( const vec &val_up ) { 
    577                 it_assert_debug ( upsize == val_up.length(), "Wrong val_up" ); 
    578                 return get_vec ( val_up, v2v_up ); 
    579         } 
    580  
    581         //! Fill val of "Up" by my pieces 
    582         void pushup ( vec &val_up, const vec &val ) { 
    583                 it_assert_debug ( downsize == val.length(), "Wrong val" ); 
    584                 it_assert_debug ( upsize == val_up.length(), "Wrong val_up" ); 
    585                 set_subvector ( val_up, v2v_up, val ); 
    586         } 
     546class datalink 
     547{ 
     548        protected: 
     549                //! Remember how long val should be 
     550                int downsize; 
     551 
     552                //! Remember how long val of "Up" should be 
     553                int upsize; 
     554 
     555                //! val-to-val link, indices of the upper val 
     556                ivec v2v_up; 
     557 
     558        public: 
     559                //! Constructor 
     560                datalink() : downsize (0), upsize (0) { } 
     561                datalink (const RV &rv, const RV &rv_up) { 
     562                        set_connection (rv, rv_up); 
     563                } 
     564 
     565                //! set connection, rv must be fully present in rv_up 
     566                void set_connection (const RV &rv, const RV &rv_up) { 
     567                        downsize = rv._dsize(); 
     568                        upsize = rv_up._dsize(); 
     569                        v2v_up = rv.dataind (rv_up); 
     570 
     571                        it_assert_debug (v2v_up.length() == downsize, "rv is not fully in rv_up"); 
     572                } 
     573 
     574                //! set connection using indices 
     575                void set_connection (int ds, int us, const ivec &upind) { 
     576                        downsize = ds; 
     577                        upsize = us; 
     578                        v2v_up = upind; 
     579 
     580                        it_assert_debug (v2v_up.length() == downsize, "rv is not fully in rv_up"); 
     581                } 
     582 
     583                //! Get val for myself from val of "Up" 
     584                vec pushdown (const vec &val_up) { 
     585                        it_assert_debug (upsize == val_up.length(), "Wrong val_up"); 
     586                        return get_vec (val_up, v2v_up); 
     587                } 
     588 
     589                //! Fill val of "Up" by my pieces 
     590                void pushup (vec &val_up, const vec &val) { 
     591                        it_assert_debug (downsize == val.length(), "Wrong val"); 
     592                        it_assert_debug (upsize == val_up.length(), "Wrong val_up"); 
     593                        set_subvector (val_up, v2v_up, val); 
     594                } 
    587595}; 
    588596 
    589597//! Data link with a condition. 
    590 class datalink_m2e: public datalink { 
    591 protected: 
    592         //! Remember how long cond should be 
    593         int condsize; 
    594  
    595         //!upper_val-to-local_cond link, indices of the upper val 
    596         ivec v2c_up; 
    597  
    598         //!upper_val-to-local_cond link, indices of the local cond 
    599         ivec v2c_lo; 
    600  
    601 public: 
    602         //! Constructor 
    603         datalink_m2e() : condsize ( 0 ) { } 
    604  
    605         void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up ) { 
    606                 datalink::set_connection ( rv, rv_up ); 
    607                 condsize = rvc._dsize(); 
    608                 //establish v2c connection 
    609                 rvc.dataind ( rv_up, v2c_lo, v2c_up ); 
    610         } 
    611  
    612         //!Construct condition 
    613         vec get_cond ( const vec &val_up ) { 
    614                 vec tmp ( condsize ); 
    615                 set_subvector ( tmp, v2c_lo, val_up ( v2c_up ) ); 
    616                 return tmp; 
    617         } 
    618  
    619         void pushup_cond ( vec &val_up, const vec &val, const vec &cond ) { 
    620                 it_assert_debug ( downsize == val.length(), "Wrong val" ); 
    621                 it_assert_debug ( upsize == val_up.length(), "Wrong val_up" ); 
    622                 set_subvector ( val_up, v2v_up, val ); 
    623                 set_subvector ( val_up, v2c_up, cond ); 
    624         } 
     598class datalink_m2e: public datalink 
     599{ 
     600        protected: 
     601                //! Remember how long cond should be 
     602                int condsize; 
     603 
     604                //!upper_val-to-local_cond link, indices of the upper val 
     605                ivec v2c_up; 
     606 
     607                //!upper_val-to-local_cond link, indices of the local cond 
     608                ivec v2c_lo; 
     609 
     610        public: 
     611                //! Constructor 
     612                datalink_m2e() : condsize (0) { } 
     613 
     614                void set_connection (const RV &rv, const RV &rvc, const RV &rv_up) { 
     615                        datalink::set_connection (rv, rv_up); 
     616                        condsize = rvc._dsize(); 
     617                        //establish v2c connection 
     618                        rvc.dataind (rv_up, v2c_lo, v2c_up); 
     619                } 
     620 
     621                //!Construct condition 
     622                vec get_cond (const vec &val_up) { 
     623                        vec tmp (condsize); 
     624                        set_subvector (tmp, v2c_lo, val_up (v2c_up)); 
     625                        return tmp; 
     626                } 
     627 
     628                void pushup_cond (vec &val_up, const vec &val, const vec &cond) { 
     629                        it_assert_debug (downsize == val.length(), "Wrong val"); 
     630                        it_assert_debug (upsize == val_up.length(), "Wrong val_up"); 
     631                        set_subvector (val_up, v2v_up, val); 
     632                        set_subvector (val_up, v2c_up, cond); 
     633                } 
    625634}; 
    626635 
    627636//!DataLink is a connection between mpdf and its superordinate (Up) 
    628637//! This class links 
    629 class datalink_m2m: public datalink_m2e { 
    630 protected: 
    631         //!cond-to-cond link, indices of the upper cond 
    632         ivec c2c_up; 
    633         //!cond-to-cond link, indices of the local cond 
    634         ivec c2c_lo; 
    635  
    636 public: 
    637         //! Constructor 
    638         datalink_m2m() {}; 
    639         void set_connection ( const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up ) { 
    640                 datalink_m2e::set_connection ( rv, rvc, rv_up ); 
    641                 //establish c2c connection 
    642                 rvc.dataind ( rvc_up, c2c_lo, c2c_up ); 
    643                 it_assert_debug ( c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given" ); 
    644         } 
    645  
    646         //! Get cond for myself from val and cond of "Up" 
    647         vec get_cond ( const vec &val_up, const vec &cond_up ) { 
    648                 vec tmp ( condsize ); 
    649                 set_subvector ( tmp, v2c_lo, val_up ( v2c_up ) ); 
    650                 set_subvector ( tmp, c2c_lo, cond_up ( c2c_up ) ); 
    651                 return tmp; 
    652         } 
    653         //! Fill 
     638class datalink_m2m: public datalink_m2e 
     639{ 
     640        protected: 
     641                //!cond-to-cond link, indices of the upper cond 
     642                ivec c2c_up; 
     643                //!cond-to-cond link, indices of the local cond 
     644                ivec c2c_lo; 
     645 
     646        public: 
     647                //! Constructor 
     648                datalink_m2m() {}; 
     649                void set_connection (const RV &rv, const RV &rvc, const RV &rv_up, const RV &rvc_up) { 
     650                        datalink_m2e::set_connection (rv, rvc, rv_up); 
     651                        //establish c2c connection 
     652                        rvc.dataind (rvc_up, c2c_lo, c2c_up); 
     653                        it_assert_debug (c2c_lo.length() + v2c_lo.length() == condsize, "cond is not fully given"); 
     654                } 
     655 
     656                //! Get cond for myself from val and cond of "Up" 
     657                vec get_cond (const vec &val_up, const vec &cond_up) { 
     658                        vec tmp (condsize); 
     659                        set_subvector (tmp, v2c_lo, val_up (v2c_up)); 
     660                        set_subvector (tmp, c2c_lo, cond_up (c2c_up)); 
     661                        return tmp; 
     662                } 
     663                //! Fill 
    654664 
    655665}; 
     
    660670This class abstracts logging of results from implementation. This class replaces direct logging of results (e.g. to files or to global variables) by calling methods of a logger. Specializations of this abstract class for specific storage method are designed. 
    661671 */ 
    662 class logger : public root { 
    663 protected: 
    664         //! RVs of all logged variables. 
    665         Array<RV> entries; 
    666         //! Names of logged quantities, e.g. names of algorithm variants 
    667         Array<string> names; 
    668 public: 
    669         //!Default constructor 
    670         logger() : entries ( 0 ), names ( 0 ) {} 
    671  
    672         //! returns an identifier which will be later needed for calling the \c logit() function 
    673         //! For empty RV it returns -1, this entry will be ignored by \c logit(). 
    674         virtual int add ( const RV &rv, string prefix = "" ) { 
    675                 int id; 
    676                 if ( rv._dsize() > 0 ) { 
    677                         id = entries.length(); 
    678                         names = concat ( names, prefix ); // diff 
    679                         entries.set_length ( id + 1, true ); 
    680                         entries ( id ) = rv; 
    681                 } else { 
    682                         id = -1; 
    683                 } 
    684                 return id; // identifier of the last entry 
    685         } 
    686  
    687         //! log this vector 
    688         virtual void logit ( int id, const vec &v ) = 0; 
    689         //! log this double 
    690         virtual void logit ( int id, const double &d ) = 0; 
    691  
    692         //! Shifts storage position for another time step. 
    693         virtual void step() = 0; 
    694  
    695         //! Finalize storing information 
    696         virtual void finalize() {}; 
    697  
    698         //! Initialize the storage 
    699         virtual void init() {}; 
     672class logger : public root 
     673{ 
     674        protected: 
     675                //! RVs of all logged variables. 
     676                Array<RV> entries; 
     677                //! Names of logged quantities, e.g. names of algorithm variants 
     678                Array<string> names; 
     679        public: 
     680                //!Default constructor 
     681                logger() : entries (0), names (0) {} 
     682 
     683                //! returns an identifier which will be later needed for calling the \c logit() function 
     684                //! For empty RV it returns -1, this entry will be ignored by \c logit(). 
     685                virtual int add (const RV &rv, string prefix = "") { 
     686                        int id; 
     687                        if (rv._dsize() > 0) { 
     688                                id = entries.length(); 
     689                                names = concat (names, prefix);   // diff 
     690                                entries.set_length (id + 1, true); 
     691                                entries (id) = rv; 
     692                        } else { 
     693                                id = -1; 
     694                        } 
     695                        return id; // identifier of the last entry 
     696                } 
     697 
     698                //! log this vector 
     699                virtual void logit (int id, const vec &v) = 0; 
     700                //! log this double 
     701                virtual void logit (int id, const double &d) = 0; 
     702 
     703                //! Shifts storage position for another time step. 
     704                virtual void step() = 0; 
     705 
     706                //! Finalize storing information 
     707                virtual void finalize() {}; 
     708 
     709                //! Initialize the storage 
     710                virtual void init() {}; 
    700711 
    701712}; 
     
    704715 
    705716*/ 
    706 class mepdf : public mpdf { 
    707  
    708 shared_ptr<epdf> ipdf; 
    709 public: 
    710         //!Default constructor 
    711         mepdf() { } 
    712  
    713         mepdf ( shared_ptr<epdf> em ) { 
    714                 ipdf = em; 
    715                 set_ep(*ipdf.get()); 
    716                 dimc = 0; 
    717         } 
    718  
    719         //! empty 
    720         void condition ( const vec &cond ); 
    721  
    722         //! Load from structure with elements: 
    723         //!  \code 
    724         //! { class = "mepdf", 
    725         //!   epdf = {class="epdf_offspring",...} 
    726         //! } 
    727         //! \endcode 
    728         //!@} 
    729         void from_setting ( const Setting &set ); 
    730 }; 
    731 UIREGISTER ( mepdf ); 
     717class mepdf : public mpdf 
     718{ 
     719 
     720                shared_ptr<epdf> ipdf; 
     721        public: 
     722                //!Default constructor 
     723                mepdf() { } 
     724 
     725                mepdf (shared_ptr<epdf> em) { 
     726                        ipdf = em; 
     727                        set_ep (*ipdf.get()); 
     728                        dimc = 0; 
     729                } 
     730 
     731                //! empty 
     732                void condition (const vec &cond); 
     733 
     734                //! Load from structure with elements: 
     735                //!  \code 
     736                //! { class = "mepdf", 
     737                //!   epdf = {class="epdf_offspring",...} 
     738                //! } 
     739                //! \endcode 
     740                //!@} 
     741                void from_setting (const Setting &set); 
     742}; 
     743UIREGISTER (mepdf); 
    732744 
    733745//!\brief Chain rule of pdfs - abstract part common for mprod and merger. 
    734746//!this abstract class is common to epdf and mpdf 
    735747//!\todo Think of better design - global functions rv=get_rv(Array<mpdf*> mpdfs); ?? 
    736 class compositepdf { 
    737 protected: 
    738         //! Elements of composition 
    739         Array<mpdf*> mpdfs; 
    740         bool owning_mpdfs; 
    741 public: 
    742         compositepdf() : mpdfs ( 0 ) {}; 
    743         compositepdf ( Array<mpdf*> A0, bool own = false ) { 
    744                 set_elements ( A0, own ); 
    745         }; 
    746         void set_elements ( Array<mpdf*> A0, bool own = false ) { 
    747                 mpdfs = A0; 
    748                 owning_mpdfs = own; 
    749         }; 
    750         //! find common rv, flag \param checkoverlap modifies whether overlaps are acceptable 
    751         RV getrv ( bool checkoverlap = false ); 
    752         //! common rvc of all mpdfs is written to rvc 
    753         void setrvc ( const RV &rv, RV &rvc ); 
    754         ~compositepdf() { 
    755                 if ( owning_mpdfs ) for ( int i = 0; i < mpdfs.length(); i++ ) { 
    756                                 delete mpdfs ( i ); 
    757                         } 
    758         }; 
     748class compositepdf 
     749{ 
     750        protected: 
     751                //! Elements of composition 
     752                Array<mpdf*> mpdfs; 
     753                bool owning_mpdfs; 
     754        public: 
     755                compositepdf() : mpdfs (0) {}; 
     756                compositepdf (Array<mpdf*> A0, bool own = false) { 
     757                        set_elements (A0, own); 
     758                }; 
     759                void set_elements (Array<mpdf*> A0, bool own = false) { 
     760                        mpdfs = A0; 
     761                        owning_mpdfs = own; 
     762                }; 
     763                //! find common rv, flag \param checkoverlap modifies whether overlaps are acceptable 
     764                RV getrv (bool checkoverlap = false); 
     765                //! common rvc of all mpdfs is written to rvc 
     766                void setrvc (const RV &rv, RV &rvc); 
     767                ~compositepdf() { 
     768                        if (owning_mpdfs) for (int i = 0; i < mpdfs.length(); i++) { 
     769                                        delete mpdfs (i); 
     770                                } 
     771                }; 
    759772}; 
    760773 
     
    766779*/ 
    767780 
    768 class DS : public root { 
    769 protected: 
    770         int dtsize; 
    771         int utsize; 
    772         //!Description of data returned by \c getdata(). 
    773         RV Drv; 
    774         //!Description of data witten by by \c write(). 
    775         RV Urv; // 
    776         //! Remember its own index in Logger L 
    777         int L_dt, L_ut; 
    778 public: 
    779         //! default constructors 
    780         DS() : Drv(), Urv() {}; 
    781         //! Returns full vector of observed data=[output, input] 
    782         virtual void getdata ( vec &dt ) { 
    783                 it_error ( "abstract class" ); 
    784         }; 
    785         //! Returns data records at indeces. 
    786         virtual void getdata ( vec &dt, const ivec &indeces ) { 
    787                 it_error ( "abstract class" ); 
    788         }; 
    789         //! Accepts action variable and schedule it for application. 
    790         virtual void write ( vec &ut ) { 
    791                 it_error ( "abstract class" ); 
    792         }; 
    793         //! Accepts action variables at specific indeces 
    794         virtual void write ( vec &ut, const ivec &indeces ) { 
    795                 it_error ( "abstract class" ); 
    796         }; 
    797  
    798         //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system. 
    799         virtual void step() = 0; 
    800  
    801         //! Register DS for logging into logger L 
    802         virtual void log_add ( logger &L ) { 
    803                 it_assert_debug ( dtsize == Drv._dsize(), "" ); 
    804                 it_assert_debug ( utsize == Urv._dsize(), "" ); 
    805  
    806                 L_dt = L.add ( Drv, "" ); 
    807                 L_ut = L.add ( Urv, "" ); 
    808         } 
    809         //! Register DS for logging into logger L 
    810         virtual void logit ( logger &L ) { 
    811                 vec tmp ( Drv._dsize() + Urv._dsize() ); 
    812                 getdata ( tmp ); 
    813                 // d is first in getdata 
    814                 L.logit ( L_dt, tmp.left ( Drv._dsize() ) ); 
    815                 // u follows after d in getdata 
    816                 L.logit ( L_ut, tmp.mid ( Drv._dsize(), Urv._dsize() ) ); 
    817         } 
    818         //!access function 
    819         virtual RV _drv() const { 
    820                 return concat ( Drv, Urv ); 
    821         } 
    822         //!access function 
    823         const RV& _urv() const { 
    824                 return Urv; 
    825         } 
    826         //! set random rvariables 
    827         virtual void set_drv ( const  RV &drv, const RV &urv ) { 
    828                 Drv = drv; 
    829                 Urv = urv; 
    830         } 
     781class DS : public root 
     782{ 
     783        protected: 
     784                int dtsize; 
     785                int utsize; 
     786                //!Description of data returned by \c getdata(). 
     787                RV Drv; 
     788                //!Description of data witten by by \c write(). 
     789                RV Urv; // 
     790                //! Remember its own index in Logger L 
     791                int L_dt, L_ut; 
     792        public: 
     793                //! default constructors 
     794                DS() : Drv(), Urv() {}; 
     795                //! Returns full vector of observed data=[output, input] 
     796                virtual void getdata (vec &dt) { 
     797                        it_error ("abstract class"); 
     798                }; 
     799                //! Returns data records at indeces. 
     800                virtual void getdata (vec &dt, const ivec &indeces) { 
     801                        it_error ("abstract class"); 
     802                }; 
     803                //! Accepts action variable and schedule it for application. 
     804                virtual void write (vec &ut) { 
     805                        it_error ("abstract class"); 
     806                }; 
     807                //! Accepts action variables at specific indeces 
     808                virtual void write (vec &ut, const ivec &indeces) { 
     809                        it_error ("abstract class"); 
     810                }; 
     811 
     812                //! Moves from \f$ t \f$ to \f$ t+1 \f$, i.e. perfroms the actions and reads response of the system. 
     813                virtual void step() = 0; 
     814 
     815                //! Register DS for logging into logger L 
     816                virtual void log_add (logger &L) { 
     817                        it_assert_debug (dtsize == Drv._dsize(), ""); 
     818                        it_assert_debug (utsize == Urv._dsize(), ""); 
     819 
     820                        L_dt = L.add (Drv, ""); 
     821                        L_ut = L.add (Urv, ""); 
     822                } 
     823                //! Register DS for logging into logger L 
     824                virtual void logit (logger &L) { 
     825                        vec tmp (Drv._dsize() + Urv._dsize()); 
     826                        getdata (tmp); 
     827                        // d is first in getdata 
     828                        L.logit (L_dt, tmp.left (Drv._dsize())); 
     829                        // u follows after d in getdata 
     830                        L.logit (L_ut, tmp.mid (Drv._dsize(), Urv._dsize())); 
     831                } 
     832                //!access function 
     833                virtual RV _drv() const { 
     834                        return concat (Drv, Urv); 
     835                } 
     836                //!access function 
     837                const RV& _urv() const { 
     838                        return Urv; 
     839                } 
     840                //! set random rvariables 
     841                virtual void set_drv (const  RV &drv, const RV &urv) { 
     842                        Drv = drv; 
     843                        Urv = urv; 
     844                } 
    831845}; 
    832846 
     
    852866*/ 
    853867 
    854 class BM : public root { 
    855 protected: 
    856         //! Random variable of the data (optional) 
    857         RV drv; 
    858         //!Logarithm of marginalized data likelihood. 
    859         double ll; 
    860         //!  If true, the filter will compute likelihood of the data record and store it in \c ll . Set to false if you want to save computational time. 
    861         bool evalll; 
    862 public: 
    863         //! \name Constructors 
    864         //! @{ 
    865  
    866         BM() : ll ( 0 ), evalll ( true ), LIDs ( 4 ), LFlags ( 4 ) { 
    867                 LIDs = -1;/*empty IDs*/ 
    868                 LFlags = 0; 
    869                 LFlags ( 0 ) = 1;/*log only mean*/ 
    870         }; 
    871         BM ( const BM &B ) :  drv ( B.drv ), ll ( B.ll ), evalll ( B.evalll ) {} 
    872         //! Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually! 
    873         //! Prototype: \code BM* _copy_() const {return new BM(*this);} \endcode 
    874         virtual BM* _copy_() const { 
    875                 return NULL; 
    876         }; 
    877         //!@} 
    878  
    879         //! \name Mathematical operations 
    880         //!@{ 
    881  
    882         /*! \brief Incremental Bayes rule 
    883         @param dt vector of input data 
    884         */ 
    885         virtual void bayes ( const vec &dt ) = 0; 
    886         //! Batch Bayes rule (columns of Dt are observations) 
    887         virtual void bayesB ( const mat &Dt ); 
    888         //! Evaluates predictive log-likelihood of the given data record 
    889         //! I.e. marginal likelihood of the data with the posterior integrated out. 
    890         virtual double logpred ( const vec &dt ) const { 
    891                 it_error ( "Not implemented" ); 
    892                 return 0.0; 
     868class BM : public root 
     869{ 
     870        protected: 
     871                //! Random variable of the data (optional) 
     872                RV drv; 
     873                //!Logarithm of marginalized data likelihood. 
     874                double ll; 
     875                //!  If true, the filter will compute likelihood of the data record and store it in \c ll . Set to false if you want to save computational time. 
     876                bool evalll; 
     877        public: 
     878                //! \name Constructors 
     879                //! @{ 
     880 
     881                BM() : ll (0), evalll (true), LIDs (4), LFlags (4) { 
     882                        LIDs = -1;/*empty IDs*/ 
     883                        LFlags = 0; 
     884                        LFlags (0) = 1;  /*log only mean*/ 
     885                }; 
     886                BM (const BM &B) :  drv (B.drv), ll (B.ll), evalll (B.evalll) {} 
     887                //! Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually! 
     888                //! Prototype: \code BM* _copy_() const {return new BM(*this);} \endcode 
     889                virtual BM* _copy_() const { 
     890                        return NULL; 
     891                }; 
     892                //!@} 
     893 
     894                //! \name Mathematical operations 
     895                //!@{ 
     896 
     897                /*! \brief Incremental Bayes rule 
     898                @param dt vector of input data 
     899                */ 
     900                virtual void bayes (const vec &dt) = 0; 
     901                //! Batch Bayes rule (columns of Dt are observations) 
     902                virtual void bayesB (const mat &Dt); 
     903                //! Evaluates predictive log-likelihood of the given data record 
     904                //! I.e. marginal likelihood of the data with the posterior integrated out. 
     905                virtual double logpred (const vec &dt) const { 
     906                        it_error ("Not implemented"); 
     907                        return 0.0; 
     908                } 
     909                //! Matrix version of logpred 
     910                vec logpred_m (const mat &dt) const { 
     911                        vec tmp (dt.cols()); 
     912                        for (int i = 0; i < dt.cols(); i++) { 
     913                                tmp (i) = logpred (dt.get_col (i)); 
     914                        } 
     915                        return tmp; 
     916                } 
     917 
     918                //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$ 
     919                virtual epdf* epredictor() const { 
     920                        it_error ("Not implemented"); 
     921                        return NULL; 
     922                }; 
     923                //!Constructs a conditional density 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) 
     924                virtual mpdf* predictor() const { 
     925                        it_error ("Not implemented"); 
     926                        return NULL; 
     927                }; 
     928                //!@} 
     929 
     930                //! \name Extension to conditional BM 
     931                //! This extension is useful e.g. in Marginalized Particle Filter (\ref bdm::MPF). 
     932                //! Alternatively, it can be used for automated connection to DS when the condition is observed 
     933                //!@{ 
     934 
     935                //! Name of extension variable 
     936                RV rvc; 
     937                //! access function 
     938                const RV& _rvc() const { 
     939                        return rvc; 
     940                } 
     941 
     942                //! Substitute \c val for \c rvc. 
     943                virtual void condition (const vec &val) { 
     944                        it_error ("Not implemented!"); 
     945                }; 
     946 
     947                //!@} 
     948 
     949 
     950                //! \name Access to attributes 
     951                //!@{ 
     952 
     953                const RV& _drv() const { 
     954                        return drv; 
     955                } 
     956                void set_drv (const RV &rv) { 
     957                        drv = rv; 
     958                } 
     959                void set_rv (const RV &rv) { 
     960                        const_cast<epdf&> (posterior()).set_rv (rv); 
     961                } 
     962                double _ll() const { 
     963                        return ll; 
     964                } 
     965                void set_evalll (bool evl0) { 
     966                        evalll = evl0; 
     967                } 
     968                virtual const epdf& posterior() const = 0; 
     969                virtual const epdf* _e() const = 0; 
     970                //!@} 
     971 
     972                //! \name Logging of results 
     973                //!@{ 
     974 
     975                //! Set boolean options from a string, recognized are: "logbounds,logll" 
     976                virtual void set_options (const string &opt) { 
     977                        LFlags (0) = 1; 
     978                        if (opt.find ("logbounds") != string::npos) { 
     979                                LFlags (1) = 1; 
     980                                LFlags (2) = 1; 
     981                        } 
     982                        if (opt.find ("logll") != string::npos) { 
     983                                LFlags (3) = 1; 
     984                        } 
     985                } 
     986                //! IDs of storages in loggers 4:[1=mean,2=lb,3=ub,4=ll] 
     987                ivec LIDs; 
     988 
     989                //! Flags for logging - same size as LIDs, each entry correspond to the same in LIDs 
     990                ivec LFlags; 
     991                //! Add all logged variables to a logger 
     992                virtual void log_add (logger &L, const string &name = "") { 
     993                        // internal 
     994                        RV r; 
     995                        if (posterior().isnamed()) { 
     996                                r = posterior()._rv(); 
     997                        } else { 
     998                                r = RV ("est", posterior().dimension()); 
     999                        }; 
     1000 
     1001                        // Add mean value 
     1002                        if (LFlags (0)) LIDs (0) = L.add (r, name + "mean_"); 
     1003                        if (LFlags (1)) LIDs (1) = L.add (r, name + "lb_"); 
     1004                        if (LFlags (2)) LIDs (2) = L.add (r, name + "ub_"); 
     1005                        if (LFlags (3)) LIDs (3) = L.add (RV ("ll", 1), name);              //TODO: "local" RV 
     1006                } 
     1007                virtual void logit (logger &L) { 
     1008                        L.logit (LIDs (0), posterior().mean()); 
     1009                        if (LFlags (1) || LFlags (2)) {        //if one of them is off, its LID==-1 and will not be stored 
     1010                                vec ub, lb; 
     1011                                posterior().qbounds (lb, ub); 
     1012                                L.logit (LIDs (1), lb); 
     1013                                L.logit (LIDs (2), ub); 
     1014                        } 
     1015                        if (LFlags (3)) L.logit (LIDs (3), ll); 
     1016                } 
     1017                //!@} 
     1018}; 
     1019 
     1020template<class EPDF> 
     1021vec mpdf_internal<EPDF>::samplecond (const vec &cond) 
     1022{ 
     1023        condition (cond); 
     1024        vec temp = iepdf.sample(); 
     1025        return temp; 
     1026} 
     1027 
     1028template<class EPDF> 
     1029mat mpdf_internal<EPDF>::samplecond_m (const vec &cond, int N) 
     1030{ 
     1031        condition (cond); 
     1032        mat temp (dimension(), N); 
     1033        vec smp (dimension()); 
     1034        for (int i = 0; i < N; i++) { 
     1035                smp = iepdf.sample(); 
     1036                temp.set_col (i, smp); 
    8931037        } 
    894         //! Matrix version of logpred 
    895         vec logpred_m ( const mat &dt ) const { 
    896                 vec tmp ( dt.cols() ); 
    897                 for ( int i = 0; i < dt.cols(); i++ ) { 
    898                         tmp ( i ) = logpred ( dt.get_col ( i ) ); 
    899                 } 
    900                 return tmp; 
    901         } 
    902  
    903         //!Constructs a predictive density \f$ f(d_{t+1} |d_{t}, \ldots d_{0}) \f$ 
    904         virtual epdf* epredictor() const { 
    905                 it_error ( "Not implemented" ); 
    906                 return NULL; 
    907         }; 
    908         //!Constructs a conditional density 1-step ahead predictor \f$ f(d_{t+1} |d_{t+h-1}, \ldots d_{t}) 
    909         virtual mpdf* predictor() const { 
    910                 it_error ( "Not implemented" ); 
    911                 return NULL; 
    912         }; 
    913         //!@} 
    914  
    915         //! \name Extension to conditional BM 
    916         //! This extension is useful e.g. in Marginalized Particle Filter (\ref bdm::MPF). 
    917         //! Alternatively, it can be used for automated connection to DS when the condition is observed 
    918         //!@{ 
    919  
    920         //! Name of extension variable 
    921         RV rvc; 
    922         //! access function 
    923         const RV& _rvc() const { 
    924                 return rvc; 
    925         } 
    926  
    927         //! Substitute \c val for \c rvc. 
    928         virtual void condition ( const vec &val ) { 
    929                 it_error ( "Not implemented!" ); 
    930         }; 
    931  
    932         //!@} 
    933  
    934  
    935         //! \name Access to attributes 
    936         //!@{ 
    937  
    938         const RV& _drv() const { 
    939                 return drv; 
    940         } 
    941         void set_drv ( const RV &rv ) { 
    942                 drv = rv; 
    943         } 
    944         void set_rv ( const RV &rv ) { 
    945                 const_cast<epdf&> ( posterior() ).set_rv ( rv ); 
    946         } 
    947         double _ll() const { 
    948                 return ll; 
    949         } 
    950         void set_evalll ( bool evl0 ) { 
    951                 evalll = evl0; 
    952         } 
    953         virtual const epdf& posterior() const = 0; 
    954         virtual const epdf* _e() const = 0; 
    955         //!@} 
    956  
    957         //! \name Logging of results 
    958         //!@{ 
    959  
    960         //! Set boolean options from a string, recognized are: "logbounds,logll" 
    961         virtual void set_options ( const string &opt ) { 
    962                 LFlags ( 0 ) = 1; 
    963                 if ( opt.find ( "logbounds" ) != string::npos ) { 
    964                         LFlags ( 1 ) = 1; 
    965                         LFlags ( 2 ) = 1; 
    966                 } 
    967                 if ( opt.find ( "logll" ) != string::npos ) { 
    968                         LFlags ( 3 ) = 1; 
    969                 } 
    970         } 
    971         //! IDs of storages in loggers 4:[1=mean,2=lb,3=ub,4=ll] 
    972         ivec LIDs; 
    973  
    974         //! Flags for logging - same size as LIDs, each entry correspond to the same in LIDs 
    975         ivec LFlags; 
    976         //! Add all logged variables to a logger 
    977         virtual void log_add ( logger &L, const string &name = "" ) { 
    978                 // internal 
    979                 RV r; 
    980                 if ( posterior().isnamed() ) { 
    981                         r = posterior()._rv(); 
    982                 } else { 
    983                         r = RV ( "est", posterior().dimension() ); 
    984                 }; 
    985  
    986                 // Add mean value 
    987                 if ( LFlags ( 0 ) ) LIDs ( 0 ) = L.add ( r, name + "mean_" ); 
    988                 if ( LFlags ( 1 ) ) LIDs ( 1 ) = L.add ( r, name + "lb_" ); 
    989                 if ( LFlags ( 2 ) ) LIDs ( 2 ) = L.add ( r, name + "ub_" ); 
    990                 if ( LFlags ( 3 ) ) LIDs ( 3 ) = L.add ( RV ( "ll", 1 ), name );    //TODO: "local" RV 
    991         } 
    992         virtual void logit ( logger &L ) { 
    993                 L.logit ( LIDs ( 0 ), posterior().mean() ); 
    994                 if ( LFlags ( 1 ) || LFlags ( 2 ) ) {  //if one of them is off, its LID==-1 and will not be stored 
    995                         vec ub, lb; 
    996                         posterior().qbounds ( lb, ub ); 
    997                         L.logit ( LIDs ( 1 ), lb ); 
    998                         L.logit ( LIDs ( 2 ), ub ); 
    999                 } 
    1000                 if ( LFlags ( 3 ) ) L.logit ( LIDs ( 3 ), ll ); 
    1001         } 
    1002         //!@} 
    1003 }; 
    1004  
     1038 
     1039        return temp; 
     1040} 
     1041 
     1042template<class EPDF> 
     1043double mpdf_internal<EPDF>::evallogcond (const vec &dt, const vec &cond) 
     1044{ 
     1045        double tmp; 
     1046        condition (cond); 
     1047        tmp = iepdf.evallog (dt); 
     1048        // it_assert_debug(std::isfinite(tmp), "Infinite value"); 
     1049        return tmp; 
     1050} 
     1051 
     1052template<class EPDF> 
     1053vec mpdf_internal<EPDF>::evallogcond_m (const mat &Dt, const vec &cond) 
     1054{ 
     1055        condition (cond); 
     1056        return iepdf.evallog_m (Dt); 
     1057} 
     1058 
     1059template<class EPDF> 
     1060vec mpdf_internal<EPDF>::evallogcond_m (const Array<vec> &Dt, const vec &cond) 
     1061{ 
     1062        condition (cond); 
     1063        return iepdf.evallog_m (Dt); 
     1064} 
    10051065 
    10061066}; //namespace 
  • library/bdm/estim/particles.h

    r487 r488  
    6767                resmethod = rm; 
    6868        }; 
    69         void set_statistics ( const vec w0, epdf *epdf0 ) { 
     69        void set_statistics ( const vec w0, const epdf &epdf0 ) { 
    7070                est.set_statistics ( w0, epdf0 ); 
    7171        }; 
     
    201201                BMs.set_length ( n0 ); 
    202202        } 
    203         void set_statistics ( epdf *epdf0, const BM_T* BMcond0 ) { 
     203        void set_statistics ( const epdf &epdf0, const BM_T* BMcond0 ) { 
    204204 
    205205                PF::set_statistics ( ones ( n ) / n, epdf0 ); 
  • library/bdm/stat/emix.cpp

    r477 r488  
    199199        return aprgiw; 
    200200}; 
     201 
     202vec mmix::samplecond(const vec &cond) { 
     203        //Sample which component 
     204        vec cumDist = cumsum ( w ); 
     205        double u0; 
     206#pragma omp critical 
     207        u0 = UniRNG.sample(); 
     208 
     209        int i = 0; 
     210        while ( ( cumDist ( i ) < u0 ) && ( i < ( w.length() - 1 ) ) ) { 
     211                i++; 
     212        } 
     213 
     214        return Coms ( i )->samplecond(cond); 
     215} 
    201216 
    202217} 
  • library/bdm/stat/emix.h

    r487 r488  
    472472 
    473473 
    474 /*! \brief Mixture of mpdfs with constant weights, all mpdfs are of equal type 
     474/*! \brief Mixture of mpdfs with constant weights, all mpdfs are of equal RV and RVC 
    475475 
    476476*/ 
    477 // class mmix : public mpdf { 
    478 // protected: 
    479 //      //! Component (epdfs) 
    480 //      Array<mpdf*> Coms; 
    481 //  
    482 //      //!Internal epdf 
    483 //      emix iepdf; 
    484 //  
    485 // public: 
    486 //      //!Default constructor 
    487 //      mmix() : iepdf ( ) { 
    488 //              set_ep ( iepdf ); 
    489 //      } 
    490 //  
    491 //      //! Set weights \c w and components \c R 
    492 //      void set_parameters ( const vec &w, const Array<mpdf*> &Coms ) { 
    493 //              Array<epdf*> Eps ( Coms.length() ); 
    494 //  
    495 //              for ( int i = 0; i < Coms.length(); i++ ) { 
    496 //                      Eps ( i ) = Coms ( i )->e(); 
    497 //              } 
    498 //  
    499 //              iepdf->set_parameters ( w, Eps ); 
    500 //      } 
    501 //  
    502 //      void condition ( const vec &cond ) { 
    503 //              for ( int i = 0; i < Coms.length(); i++ ) { 
    504 //                      Coms ( i )->condition ( cond ); 
    505 //              } 
    506 //      }; 
    507 // }; 
     477class mmix : public mpdf { 
     478protected: 
     479        //! Component (mpdfs) 
     480        Array<shared_ptr<mpdf> > Coms; 
     481        //!weights of the components 
     482        vec w; 
     483        //! dummy epdfs 
     484        epdf dummy_epdf; 
     485public: 
     486        //!Default constructor 
     487        mmix() : Coms(0), dummy_epdf() { set_ep(dummy_epdf);    } 
     488 
     489        //! Set weights \c w and components \c R 
     490        void set_parameters ( const vec &w0, const Array<shared_ptr<mpdf> > &Coms0 ) { 
     491                //!\TODO check if all components are OK 
     492                Coms = Coms0; 
     493                w=w0;    
     494                 
     495                set_rv(Coms(0)->_rv()); 
     496                set_rvc(Coms(0)->_rvc()); 
     497        } 
     498        double evallogcond (const vec &dt, const vec &cond) { 
     499                double ll=0.0; 
     500                for (int i=0;i<Coms.length();i++){ 
     501                        ll+=Coms(i)->evallogcond(dt,cond); 
     502                } 
     503                return ll; 
     504        } 
     505 
     506        vec samplecond (const vec &cond); 
     507 
     508}; 
    508509 
    509510} 
  • library/bdm/stat/exp_family.cpp

    r487 r488  
    305305} 
    306306 
    307 void eEmp::set_statistics ( const vec &w0, const epdf* epdf0 ) { 
     307void eEmp::set_statistics ( const vec &w0, const epdf &epdf0 ) { 
    308308        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0"); 
    309         dim = epdf0->dimension(); 
     309        dim = epdf0.dimension(); 
    310310        w = w0; 
    311311        w /= sum ( w0 );//renormalize 
    312312        n = w.length(); 
    313313        samples.set_size ( n ); 
    314         dim = epdf0->dimension(); 
    315314 
    316315        for ( int i = 0; i < n; i++ ) { 
    317                 samples ( i ) = epdf0->sample(); 
     316                samples ( i ) = epdf0.sample(); 
    318317        } 
    319318} 
  • library/bdm/stat/exp_family.h

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

    r477 r488  
    178178        //! Set support points from a pdf by drawing N samples 
    179179        void set_support ( const epdf &overall, int N ) { 
    180                 eSmp.set_statistics ( &overall, N ); 
     180                eSmp.set_statistics ( overall, N ); 
    181181                Npoints = N; 
    182182        }