Changeset 477 for library/bdm/stat

Show
Ignore:
Timestamp:
08/05/09 14:40:03 (15 years ago)
Author:
mido
Message:

panove, vite, jak jsem peclivej na upravu kodu.. snad se vam bude libit:) konfigurace je v souboru /system/astylerc

Location:
library/bdm/stat
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • library/bdm/stat/emix.cpp

    r464 r477  
    11#include "emix.h" 
    22 
    3 namespace bdm{ 
     3namespace bdm { 
    44 
    55void emix::set_parameters ( const vec &w0, const Array<epdf*> &Coms0, bool copy ) { 
    6         w = w0/sum ( w0 ); 
    7         dim = Coms0(0)->dimension(); 
    8         bool isnamed = Coms0(0)->isnamed(); 
     6        w = w0 / sum ( w0 ); 
     7        dim = Coms0 ( 0 )->dimension(); 
     8        bool isnamed = Coms0 ( 0 )->isnamed(); 
    99        int i; 
    1010        RV tmp_rv; 
    11         if (isnamed) tmp_rv=Coms0(0)->_rv(); 
    12          
    13         for ( i=0;i<w.length();i++ ) { 
    14                 it_assert_debug ( dim== ( Coms0 ( i )->dimension() ),"Component sizes do not match!" );  
    15                 it_assert_debug ( !isnamed || tmp_rv.equal( Coms0 ( i )->_rv() ),"Component RVs do not match!" ); 
     11        if ( isnamed ) tmp_rv = Coms0 ( 0 )->_rv(); 
     12 
     13        for ( i = 0; i < w.length(); i++ ) { 
     14                it_assert_debug ( dim == ( Coms0 ( i )->dimension() ), "Component sizes do not match!" ); 
     15                it_assert_debug ( !isnamed || tmp_rv.equal ( Coms0 ( i )->_rv() ), "Component RVs do not match!" ); 
    1616        } 
    1717        if ( copy ) { 
    18                 Coms.set_length(Coms0.length()); 
    19                 for ( i=0;i<w.length();i++ ) {it_error("Not imp..."); 
    20                         *Coms ( i ) =*Coms0 ( i );} 
    21                 destroyComs=true; 
    22         } 
    23         else { 
     18                Coms.set_length ( Coms0.length() ); 
     19                for ( i = 0; i < w.length(); i++ ) { 
     20                        it_error ( "Not imp..." ); 
     21                        *Coms ( i ) = *Coms0 ( i ); 
     22                } 
     23                destroyComs = true; 
     24        } else { 
    2425                Coms = Coms0; 
    25                 destroyComs=false; 
    26         } 
    27         if (isnamed) epdf::set_rv(tmp_rv); //coms aer already OK, no need for set_rv 
     26                destroyComs = false; 
     27        } 
     28        if ( isnamed ) epdf::set_rv ( tmp_rv ); //coms aer already OK, no need for set_rv 
    2829} 
    2930 
     
    3233        vec cumDist = cumsum ( w ); 
    3334        double u0; 
    34         #pragma omp critical 
     35#pragma omp critical 
    3536        u0 = UniRNG.sample(); 
    3637 
    37         int i=0; 
    38         while ( ( cumDist ( i ) <u0 ) && ( i< ( w.length()-1 ) ) ) {i++;} 
     38        int i = 0; 
     39        while ( ( cumDist ( i ) < u0 ) && ( i < ( w.length() - 1 ) ) ) { 
     40                i++; 
     41        } 
    3942 
    4043        return Coms ( i )->sample(); 
    4144} 
    4245 
    43 emix* emix::marginal(const RV &rv) const{ 
    44         it_assert_debug(isnamed(), "rvs are not assigned"); 
    45                          
    46         Array<epdf*> Cn(Coms.length()); 
    47         for(int i=0;i<Coms.length();i++){Cn(i)=Coms(i)->marginal(rv);} 
     46emix* emix::marginal ( const RV &rv ) const { 
     47        it_assert_debug ( isnamed(), "rvs are not assigned" ); 
     48 
     49        Array<epdf*> Cn ( Coms.length() ); 
     50        for ( int i = 0; i < Coms.length(); i++ ) { 
     51                Cn ( i ) = Coms ( i )->marginal ( rv ); 
     52        } 
    4853        emix* tmp = new emix(); 
    49         tmp->set_parameters(w,Cn,false); 
     54        tmp->set_parameters ( w, Cn, false ); 
    5055        tmp->ownComs(); 
    5156        return tmp; 
    5257} 
    5358 
    54 mratio* emix::condition(const RV &rv) const{ 
    55         it_assert_debug(isnamed(), "rvs are not assigned"); 
    56         return new mratio(this,rv); 
     59mratio* emix::condition ( const RV &rv ) const { 
     60        it_assert_debug ( isnamed(), "rvs are not assigned" ); 
     61        return new mratio ( this, rv ); 
    5762}; 
    5863 
    5964void egiwmix::set_parameters ( const vec &w0, const Array<egiw*> &Coms0, bool copy ) { 
    60         w = w0/sum ( w0 ); 
    61         dim = Coms0(0)->dimension(); 
     65        w = w0 / sum ( w0 ); 
     66        dim = Coms0 ( 0 )->dimension(); 
    6267        int i; 
    63         for ( i=0;i<w.length();i++ ) { 
    64                 it_assert_debug ( dim== ( Coms0 ( i )->dimension() ),"Component sizes do not match!" ); 
     68        for ( i = 0; i < w.length(); i++ ) { 
     69                it_assert_debug ( dim == ( Coms0 ( i )->dimension() ), "Component sizes do not match!" ); 
    6570        } 
    6671        if ( copy ) { 
    67                 Coms.set_length(Coms0.length()); 
    68                 for ( i=0;i<w.length();i++ ) {it_error("Not imp..."); 
    69                         *Coms ( i ) =*Coms0 ( i );} 
    70                 destroyComs=true; 
    71         } 
    72         else { 
     72                Coms.set_length ( Coms0.length() ); 
     73                for ( i = 0; i < w.length(); i++ ) { 
     74                        it_error ( "Not imp..." ); 
     75                        *Coms ( i ) = *Coms0 ( i ); 
     76                } 
     77                destroyComs = true; 
     78        } else { 
    7379                Coms = Coms0; 
    74                 destroyComs=false; 
     80                destroyComs = false; 
    7581        } 
    7682} 
     
    8086        vec cumDist = cumsum ( w ); 
    8187        double u0; 
    82         #pragma omp critical 
     88#pragma omp critical 
    8389        u0 = UniRNG.sample(); 
    8490 
    85         int i=0; 
    86         while ( ( cumDist ( i ) <u0 ) && ( i< ( w.length()-1 ) ) ) {i++;} 
     91        int i = 0; 
     92        while ( ( cumDist ( i ) < u0 ) && ( i < ( w.length() - 1 ) ) ) { 
     93                i++; 
     94        } 
    8795 
    8896        return Coms ( i )->sample(); 
     
    9098 
    9199vec egiwmix::mean() const { 
    92         int i; vec mu = zeros ( dim ); 
    93         for ( i = 0;i < w.length();i++ ) {mu += w ( i ) * Coms ( i )->mean(); } 
     100        int i; 
     101        vec mu = zeros ( dim ); 
     102        for ( i = 0; i < w.length(); i++ ) { 
     103                mu += w ( i ) * Coms ( i )->mean(); 
     104        } 
    94105        return mu; 
    95106} 
     
    98109        // non-central moment 
    99110        vec mom2 = zeros ( dim ); 
    100         for ( int i = 0;i < w.length();i++ ) { 
     111        for ( int i = 0; i < w.length(); i++ ) { 
    101112                // pow is overloaded, we have to use another approach 
    102                 mom2 += w ( i ) * (Coms(i)->variance() + elem_mult ( Coms(i)->mean(), Coms(i)->mean() ));  
     113                mom2 += w ( i ) * ( Coms ( i )->variance() + elem_mult ( Coms ( i )->mean(), Coms ( i )->mean() ) ); 
    103114        } 
    104115        // central moment 
    105116        // pow is overloaded, we have to use another approach 
    106         return mom2 - elem_mult( mean(), mean() ); 
    107 } 
    108  
    109 emix* egiwmix::marginal(const RV &rv) const{ 
    110         it_assert_debug(isnamed(), "rvs are not assigned"); 
    111                          
    112         Array<epdf*> Cn(Coms.length()); 
    113         for(int i=0;i<Coms.length();i++){Cn(i)=Coms(i)->marginal(rv);} 
     117        return mom2 - elem_mult ( mean(), mean() ); 
     118} 
     119 
     120emix* egiwmix::marginal ( const RV &rv ) const { 
     121        it_assert_debug ( isnamed(), "rvs are not assigned" ); 
     122 
     123        Array<epdf*> Cn ( Coms.length() ); 
     124        for ( int i = 0; i < Coms.length(); i++ ) { 
     125                Cn ( i ) = Coms ( i )->marginal ( rv ); 
     126        } 
    114127        emix* tmp = new emix(); 
    115         tmp->set_parameters(w,Cn,false); 
     128        tmp->set_parameters ( w, Cn, false ); 
    116129        tmp->ownComs(); 
    117130        return tmp; 
     
    124137 
    125138        double sumVecCommon;                            // common part for many terms in eq. 
    126         int len = w.length();                           // no. of mix components         
    127         int dimLS = Coms(1)->_V()._D().length() - 1;    // dim of LS 
    128         vec vecNu(len);                                 // vector of dfms of components 
    129         vec vecD(len);                                  // vector of LS reminders of comps. 
    130         vec vecCommon(len);                             // vector of common parts 
     139        int len = w.length();                           // no. of mix components 
     140        int dimLS = Coms ( 1 )->_V()._D().length() - 1;         // dim of LS 
     141        vec vecNu ( len );                                      // vector of dfms of components 
     142        vec vecD ( len );                                       // vector of LS reminders of comps. 
     143        vec vecCommon ( len );                          // vector of common parts 
    131144        mat matVecsTheta;                               // matrix which rows are theta vects. 
    132145 
    133146        // fill in the vectors vecNu, vecD and matVecsTheta 
    134         for ( int i=0; i<len; i++ ) { 
    135                 vecNu.shift_left( Coms(i)->_nu() ); 
    136                 vecD.shift_left( Coms(i)->_V()._D()(0) ); 
    137                 matVecsTheta.append_row( Coms(i)->est_theta() ); 
     147        for ( int i = 0; i < len; i++ ) { 
     148                vecNu.shift_left ( Coms ( i )->_nu() ); 
     149                vecD.shift_left ( Coms ( i )->_V()._D() ( 0 ) ); 
     150                matVecsTheta.append_row ( Coms ( i )->est_theta() ); 
    138151        } 
    139152 
    140153        // calculate the common parts and their sum 
    141         vecCommon = elem_mult ( w, elem_div(vecNu, vecD) ); 
    142         sumVecCommon = sum(vecCommon); 
     154        vecCommon = elem_mult ( w, elem_div ( vecNu, vecD ) ); 
     155        sumVecCommon = sum ( vecCommon ); 
    143156 
    144157        // LS estimator of theta 
    145         vec aprEstTheta(dimLS);  aprEstTheta.zeros(); 
    146         for ( int i=0; i<len; i++ ) { 
    147                 aprEstTheta +=  matVecsTheta.get_row( i ) * vecCommon ( i ); 
     158        vec aprEstTheta ( dimLS ); 
     159        aprEstTheta.zeros(); 
     160        for ( int i = 0; i < len; i++ ) { 
     161                aprEstTheta +=  matVecsTheta.get_row ( i ) * vecCommon ( i ); 
    148162        } 
    149163        aprEstTheta /= sumVecCommon; 
    150          
    151          
     164 
     165 
    152166        // LS estimator of dfm 
    153167        double aprNu; 
    154         double A = log( sumVecCommon );         // Term 'A' in equation 
    155  
    156         for ( int i=0; i<len; i++ ) { 
    157                 A += w(i) * ( log( vecD(i) ) - psi( 0.5 * vecNu(i) ) ); 
    158         } 
    159  
    160         aprNu = ( 1 + sqrt(1 + 2 * (A - LOG2)/3 ) ) / ( 2 * (A - LOG2) ); 
     168        double A = log ( sumVecCommon );                // Term 'A' in equation 
     169 
     170        for ( int i = 0; i < len; i++ ) { 
     171                A += w ( i ) * ( log ( vecD ( i ) ) - psi ( 0.5 * vecNu ( i ) ) ); 
     172        } 
     173 
     174        aprNu = ( 1 + sqrt ( 1 + 2 * ( A - LOG2 ) / 3 ) ) / ( 2 * ( A - LOG2 ) ); 
    161175 
    162176 
     
    167181        // the following code is very numerically sensitive, thus 
    168182        // we have to eliminate decompositions etc. as much as possible 
    169         mat aprC = zeros(dimLS, dimLS); 
    170         for ( int i=0; i<len; i++ ) { 
    171                 aprC += Coms(i)->est_theta_cov().to_mat() * w(i);  
    172                 vec tmp = ( matVecsTheta.get_row(i) - aprEstTheta ); 
    173                 aprC += vecCommon(i) * outer_product( tmp, tmp); 
     183        mat aprC = zeros ( dimLS, dimLS ); 
     184        for ( int i = 0; i < len; i++ ) { 
     185                aprC += Coms ( i )->est_theta_cov().to_mat() * w ( i ); 
     186                vec tmp = ( matVecsTheta.get_row ( i ) - aprEstTheta ); 
     187                aprC += vecCommon ( i ) * outer_product ( tmp, tmp ); 
    174188        } 
    175189 
    176190        // Construct GiW pdf :: BEGIN 
    177         ldmat aprCinv ( inv(aprC) ); 
    178         vec D = concat( aprD, aprCinv._D() ); 
    179         mat L = eye(dimLS+1); 
    180         L.set_submatrix(1,0, aprCinv._L() * aprEstTheta); 
    181         L.set_submatrix(1,1, aprCinv._L()); 
    182         ldmat aprLD (L, D); 
    183  
    184         egiw* aprgiw = new egiw(1, aprLD, aprNu); 
     191        ldmat aprCinv ( inv ( aprC ) ); 
     192        vec D = concat ( aprD, aprCinv._D() ); 
     193        mat L = eye ( dimLS + 1 ); 
     194        L.set_submatrix ( 1, 0, aprCinv._L() * aprEstTheta ); 
     195        L.set_submatrix ( 1, 1, aprCinv._L() ); 
     196        ldmat aprLD ( L, D ); 
     197 
     198        egiw* aprgiw = new egiw ( 1, aprLD, aprNu ); 
    185199        return aprgiw; 
    186200}; 
  • library/bdm/stat/emix.h

    r471 r477  
    1414#define EMIX_H 
    1515 
    16 #define LOG2  0.69314718055995   
     16#define LOG2  0.69314718055995 
    1717 
    1818#include "../shared_ptr.h" 
     
    4848        //!Default constructor. By default, the given epdf is not copied! 
    4949        //! It is assumed that this function will be used only temporarily. 
    50         mratio ( const epdf* nom0, const RV &rv, bool copy=false ) :mpdf ( ), dl ( ) { 
     50        mratio ( const epdf* nom0, const RV &rv, bool copy = false ) : mpdf ( ), dl ( ) { 
    5151                // adjust rv and rvc 
    5252                rvc = nom0->_rv().subt ( rv ); 
    5353                dimc = rvc._dsize(); 
    54                 set_ep(shared_ptr<epdf>(new epdf)); 
    55                 e()->set_parameters(rv._dsize()); 
    56                 e()->set_rv(rv); 
    57                  
     54                set_ep ( shared_ptr<epdf> ( new epdf ) ); 
     55                e()->set_parameters ( rv._dsize() ); 
     56                e()->set_rv ( rv ); 
     57 
    5858                //prepare data structures 
    59                 if ( copy ) {it_error ( "todo" ); destroynom=true; } 
    60                 else { nom = nom0; destroynom = false; } 
    61                 it_assert_debug ( rvc.length() >0,"Makes no sense to use this object!" );                
    62                  
     59                if ( copy ) { 
     60                        it_error ( "todo" ); 
     61                        destroynom = true; 
     62                } else { 
     63                        nom = nom0; 
     64                        destroynom = false; 
     65                } 
     66                it_assert_debug ( rvc.length() > 0, "Makes no sense to use this object!" ); 
     67 
    6368                // build denominator 
    6469                den = nom->marginal ( rvc ); 
    65                 dl.set_connection(rv,rvc,nom0->_rv()); 
     70                dl.set_connection ( rv, rvc, nom0->_rv() ); 
    6671        }; 
    6772        double evallogcond ( const vec &val, const vec &cond ) { 
    6873                double tmp; 
    6974                vec nom_val ( e()->dimension() + dimc ); 
    70                 dl.pushup_cond ( nom_val,val,cond ); 
     75                dl.pushup_cond ( nom_val, val, cond ); 
    7176                tmp = exp ( nom->evallog ( nom_val ) - den->evallog ( cond ) ); 
    72                 it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); 
     77                it_assert_debug ( std::isfinite ( tmp ), "Infinite value" ); 
    7378                return tmp; 
    7479        } 
    7580        //! Object takes ownership of nom and will destroy it 
    76         void ownnom() {destroynom=true;} 
     81        void ownnom() { 
     82                destroynom = true; 
     83        } 
    7784        //! Default destructor 
    78         ~mratio() {delete den; if ( destroynom ) {delete nom;}} 
     85        ~mratio() { 
     86                delete den; 
     87                if ( destroynom ) { 
     88                        delete nom; 
     89                } 
     90        } 
    7991}; 
    8092 
     
    102114        //! Set weights \c w and components \c Coms 
    103115        //!By default Coms are copied inside. Parameter \c copy can be set to false if Coms live externally. Use method ownComs() if Coms should be destroyed by the destructor. 
    104         void set_parameters ( const vec &w, const Array<epdf*> &Coms, bool copy=false ); 
     116        void set_parameters ( const vec &w, const Array<epdf*> &Coms, bool copy = false ); 
    105117 
    106118        vec sample() const; 
    107119        vec mean() const { 
    108                 int i; vec mu = zeros ( dim ); 
    109                 for ( i = 0;i < w.length();i++ ) {mu += w ( i ) * Coms ( i )->mean(); } 
     120                int i; 
     121                vec mu = zeros ( dim ); 
     122                for ( i = 0; i < w.length(); i++ ) { 
     123                        mu += w ( i ) * Coms ( i )->mean(); 
     124                } 
    110125                return mu; 
    111126        } 
     
    113128                //non-central moment 
    114129                vec mom2 = zeros ( dim ); 
    115                 for ( int i = 0;i < w.length();i++ ) {mom2 += w ( i ) * (Coms(i)->variance() + pow ( Coms ( i )->mean(),2 )); } 
     130                for ( int i = 0; i < w.length(); i++ ) { 
     131                        mom2 += w ( i ) * ( Coms ( i )->variance() + pow ( Coms ( i )->mean(), 2 ) ); 
     132                } 
    116133                //central moment 
    117                 return mom2-pow ( mean(),2 ); 
     134                return mom2 - pow ( mean(), 2 ); 
    118135        } 
    119136        double evallog ( const vec &val ) const { 
    120137                int i; 
    121138                double sum = 0.0; 
    122                 for ( i = 0;i < w.length();i++ ) {sum += w ( i ) * exp ( Coms ( i )->evallog ( val ) );} 
    123                 if ( sum==0.0 ) {sum=std::numeric_limits<double>::epsilon();} 
    124                 double tmp=log ( sum ); 
    125                 it_assert_debug ( std::isfinite ( tmp ),"Infinite" ); 
     139                for ( i = 0; i < w.length(); i++ ) { 
     140                        sum += w ( i ) * exp ( Coms ( i )->evallog ( val ) ); 
     141                } 
     142                if ( sum == 0.0 ) { 
     143                        sum = std::numeric_limits<double>::epsilon(); 
     144                } 
     145                double tmp = log ( sum ); 
     146                it_assert_debug ( std::isfinite ( tmp ), "Infinite" ); 
    126147                return tmp; 
    127148        }; 
    128149        vec evallog_m ( const mat &Val ) const { 
    129                 vec x=zeros ( Val.cols() ); 
     150                vec x = zeros ( Val.cols() ); 
    130151                for ( int i = 0; i < w.length(); i++ ) { 
    131                         x+= w ( i ) *exp ( Coms ( i )->evallog_m ( Val ) ); 
     152                        x += w ( i ) * exp ( Coms ( i )->evallog_m ( Val ) ); 
    132153                } 
    133154                return log ( x ); 
     
    147168//Access methods 
    148169        //! returns a pointer to the internal mean value. Use with Care! 
    149         vec& _w() {return w;} 
    150         virtual ~emix() {if ( destroyComs ) {for ( int i=0;i<Coms.length();i++ ) {delete Coms ( i );}}} 
     170        vec& _w() { 
     171                return w; 
     172        } 
     173        virtual ~emix() { 
     174                if ( destroyComs ) { 
     175                        for ( int i = 0; i < Coms.length(); i++ ) { 
     176                                delete Coms ( i ); 
     177                        } 
     178                } 
     179        } 
    151180        //! Auxiliary function for taking ownership of the Coms() 
    152         void ownComs() {destroyComs=true;} 
     181        void ownComs() { 
     182                destroyComs = true; 
     183        } 
    153184 
    154185        //!access function 
    155         epdf* _Coms ( int i ) {return Coms ( i );} 
    156         void set_rv(const RV &rv){ 
    157                 epdf::set_rv(rv); 
    158                 for(int i=0;i<Coms.length();i++){Coms(i)->set_rv(rv);} 
     186        epdf* _Coms ( int i ) { 
     187                return Coms ( i ); 
     188        } 
     189        void set_rv ( const RV &rv ) { 
     190                epdf::set_rv ( rv ); 
     191                for ( int i = 0; i < Coms.length(); i++ ) { 
     192                        Coms ( i )->set_rv ( rv ); 
     193                } 
    159194        } 
    160195}; 
     
    179214        //! Set weights \c w and components \c Coms 
    180215        //!By default Coms are copied inside. Parameter \c copy can be set to false if Coms live externally. Use method ownComs() if Coms should be destroyed by the destructor. 
    181         void set_parameters ( const vec &w, const Array<egiw*> &Coms, bool copy=false ); 
     216        void set_parameters ( const vec &w, const Array<egiw*> &Coms, bool copy = false ); 
    182217 
    183218        //!return expected value 
     
    188223 
    189224        //!return the expected variance 
    190         vec variance() const; 
     225        vec variance() const; 
    191226 
    192227        // TODO!!! Defined to follow ANSI and/or for future development 
    193228        void mean_mat ( mat &M, mat&R ) const {}; 
    194         double evallog_nn ( const vec &val ) const {return 0;}; 
    195         double lognc () const {return 0;}; 
     229        double evallog_nn ( const vec &val ) const { 
     230                return 0; 
     231        }; 
     232        double lognc () const { 
     233                return 0; 
     234        }; 
    196235        emix* marginal ( const RV &rv ) const; 
    197236 
    198237//Access methods 
    199238        //! returns a pointer to the internal mean value. Use with Care! 
    200         vec& _w() {return w;} 
    201         virtual ~egiwmix() {if ( destroyComs ) {for ( int i=0;i<Coms.length();i++ ) {delete Coms ( i );}}} 
     239        vec& _w() { 
     240                return w; 
     241        } 
     242        virtual ~egiwmix() { 
     243                if ( destroyComs ) { 
     244                        for ( int i = 0; i < Coms.length(); i++ ) { 
     245                                delete Coms ( i ); 
     246                        } 
     247                } 
     248        } 
    202249        //! Auxiliary function for taking ownership of the Coms() 
    203         void ownComs() {destroyComs=true;} 
     250        void ownComs() { 
     251                destroyComs = true; 
     252        } 
    204253 
    205254        //!access function 
    206         egiw* _Coms ( int i ) {return Coms ( i );} 
    207  
    208         void set_rv(const RV &rv){ 
    209                 egiw::set_rv(rv); 
    210                 for(int i=0;i<Coms.length();i++){Coms(i)->set_rv(rv);} 
     255        egiw* _Coms ( int i ) { 
     256                return Coms ( i ); 
     257        } 
     258 
     259        void set_rv ( const RV &rv ) { 
     260                egiw::set_rv ( rv ); 
     261                for ( int i = 0; i < Coms.length(); i++ ) { 
     262                        Coms ( i )->set_rv ( rv ); 
     263                } 
    211264        } 
    212265 
     
    236289        /*!\brief Constructor from list of mFacs, 
    237290        */ 
    238         mprod():dummy(new epdf()) { } 
    239         mprod (Array<mpdf*> mFacs): 
    240             dummy(new epdf()) { 
    241             set_elements(mFacs); 
    242         } 
    243  
    244         void set_elements(Array<mpdf*> mFacs , bool own=false) { 
    245                  
    246                 compositepdf::set_elements(mFacs,own); 
    247                 dls.set_size(mFacs.length()); 
    248                 epdfs.set_size(mFacs.length()); 
    249                                  
    250                 set_ep(dummy); 
    251                 RV rv=getrv ( true ); 
     291        mprod() : dummy ( new epdf() ) { } 
     292        mprod ( Array<mpdf*> mFacs ) : 
     293                        dummy ( new epdf() ) { 
     294                set_elements ( mFacs ); 
     295        } 
     296 
     297        void set_elements ( Array<mpdf*> mFacs , bool own = false ) { 
     298 
     299                compositepdf::set_elements ( mFacs, own ); 
     300                dls.set_size ( mFacs.length() ); 
     301                epdfs.set_size ( mFacs.length() ); 
     302 
     303                set_ep ( dummy ); 
     304                RV rv = getrv ( true ); 
    252305                set_rv ( rv ); 
    253                 dummy->set_parameters(rv._dsize()); 
    254                 setrvc(e()->_rv(), rvc); 
     306                dummy->set_parameters ( rv._dsize() ); 
     307                setrvc ( e()->_rv(), rvc ); 
    255308                // rv and rvc established = > we can link them with mpdfs 
    256                 for ( int i = 0;i < mpdfs.length(); i++ ) { 
     309                for ( int i = 0; i < mpdfs.length(); i++ ) { 
    257310                        dls ( i ) = new datalink_m2m; 
    258                         dls(i)->set_connection( mpdfs ( i )->_rv(), mpdfs ( i )->_rvc(), _rv(), _rvc() ); 
    259                 } 
    260  
    261                 for ( int i=0; i<mpdfs.length(); i++ ) { 
    262                         epdfs(i) = mpdfs(i)->e(); 
     311                        dls ( i )->set_connection ( mpdfs ( i )->_rv(), mpdfs ( i )->_rvc(), _rv(), _rvc() ); 
     312                } 
     313 
     314                for ( int i = 0; i < mpdfs.length(); i++ ) { 
     315                        epdfs ( i ) = mpdfs ( i )->e(); 
    263316                } 
    264317        }; 
     
    267320                int i; 
    268321                double res = 0.0; 
    269                 for ( i = mpdfs.length() - 1;i >= 0;i-- ) { 
     322                for ( i = mpdfs.length() - 1; i >= 0; i-- ) { 
    270323                        /*                      if ( mpdfs(i)->_rvc().count() >0) { 
    271324                                                        mpdfs ( i )->condition ( dls ( i )->get_cond ( val,cond ) ); 
     
    280333                return res; 
    281334        } 
    282         vec evallogcond_m(const mat &Dt, const vec &cond) { 
    283                 vec tmp(Dt.cols()); 
    284                 for(int i=0;i<Dt.cols(); i++){ 
    285                         tmp(i) = evallogcond(Dt.get_col(i),cond); 
    286                 } 
    287                 return tmp; 
    288         }; 
    289         vec evallogcond_m(const Array<vec> &Dt, const vec &cond) { 
    290                 vec tmp(Dt.length()); 
    291                 for(int i=0;i<Dt.length(); i++){ 
    292                         tmp(i) = evallogcond(Dt(i),cond); 
    293                 } 
    294                 return tmp;              
     335        vec evallogcond_m ( const mat &Dt, const vec &cond ) { 
     336                vec tmp ( Dt.cols() ); 
     337                for ( int i = 0; i < Dt.cols(); i++ ) { 
     338                        tmp ( i ) = evallogcond ( Dt.get_col ( i ), cond ); 
     339                } 
     340                return tmp; 
     341        }; 
     342        vec evallogcond_m ( const Array<vec> &Dt, const vec &cond ) { 
     343                vec tmp ( Dt.length() ); 
     344                for ( int i = 0; i < Dt.length(); i++ ) { 
     345                        tmp ( i ) = evallogcond ( Dt ( i ), cond ); 
     346                } 
     347                return tmp; 
    295348        }; 
    296349 
     
    298351        //TODO smarter... 
    299352        vec samplecond ( const vec &cond ) { 
    300             //! Ugly hack to help to discover if mpfs are not in proper order. Correct solution = check that explicitely. 
    301             vec smp= std::numeric_limits<double>::infinity() * ones ( e()->dimension() ); 
     353                //! Ugly hack to help to discover if mpfs are not in proper order. Correct solution = check that explicitely. 
     354                vec smp = std::numeric_limits<double>::infinity() * ones ( e()->dimension() ); 
    302355                vec smpi; 
    303356                // Hard assumption here!!! We are going backwards, to assure that samples that are needed from smp are already generated! 
    304                 for ( int i = ( mpdfs.length() - 1 );i >= 0;i-- ) { 
     357                for ( int i = ( mpdfs.length() - 1 ); i >= 0; i-- ) { 
    305358                        if ( mpdfs ( i )->dimensionc() ) { 
    306                                 mpdfs ( i )->condition ( dls ( i )->get_cond ( smp ,cond ) ); // smp is val here!! 
     359                                mpdfs ( i )->condition ( dls ( i )->get_cond ( smp , cond ) ); // smp is val here!! 
    307360                        } 
    308361                        smpi = epdfs ( i )->sample(); 
     
    314367        } 
    315368        mat samplecond ( const vec &cond,  int N ) { 
    316                 mat Smp ( dimension(),N ); 
    317                 for ( int i=0;i<N;i++ ) {Smp.set_col ( i,samplecond ( cond ) );} 
     369                mat Smp ( dimension(), N ); 
     370                for ( int i = 0; i < N; i++ ) { 
     371                        Smp.set_col ( i, samplecond ( cond ) ); 
     372                } 
    318373                return Smp; 
    319374        } 
     
    327382        //! \endcode 
    328383        //!@} 
    329         void from_setting(const Setting &set){ 
     384        void from_setting ( const Setting &set ) { 
    330385                Array<mpdf*> Atmp; //temporary Array 
    331                 UI::get(Atmp,set, "mpdfs", UI::compulsory); 
    332                 set_elements(Atmp,true); 
    333         } 
    334          
     386                UI::get ( Atmp, set, "mpdfs", UI::compulsory ); 
     387                set_elements ( Atmp, true ); 
     388        } 
     389 
    335390}; 
    336 UIREGISTER(mprod); 
     391UIREGISTER ( mprod ); 
    337392 
    338393//! Product of independent epdfs. For dependent pdfs, use mprod. 
     
    344399        Array<datalink*> dls; 
    345400public: 
    346         eprod () : epdfs ( 0 ),dls ( 0 ) {}; 
    347         void set_parameters ( const Array<const epdf*> &epdfs0, bool named=true ) { 
    348                 epdfs=epdfs0;//.set_length ( epdfs0.length() ); 
     401        eprod () : epdfs ( 0 ), dls ( 0 ) {}; 
     402        void set_parameters ( const Array<const epdf*> &epdfs0, bool named = true ) { 
     403                epdfs = epdfs0;//.set_length ( epdfs0.length() ); 
    349404                dls.set_length ( epdfs.length() ); 
    350405 
    351                 bool independent=true; 
     406                bool independent = true; 
    352407                if ( named ) { 
    353                         for ( int i=0;i<epdfs.length();i++ ) { 
    354                                 independent=rv.add ( epdfs ( i )->_rv() ); 
    355                                 it_assert_debug ( independent==true, "eprod:: given components are not independent." ); 
     408                        for ( int i = 0; i < epdfs.length(); i++ ) { 
     409                                independent = rv.add ( epdfs ( i )->_rv() ); 
     410                                it_assert_debug ( independent == true, "eprod:: given components are not independent." ); 
    356411                        } 
    357                         dim=rv._dsize(); 
    358                 } 
    359                 else { 
    360                         dim =0; for ( int i=0;i<epdfs.length();i++ ) { 
    361                                 dim+=epdfs ( i )->dimension(); 
     412                        dim = rv._dsize(); 
     413                } else { 
     414                        dim = 0; 
     415                        for ( int i = 0; i < epdfs.length(); i++ ) { 
     416                                dim += epdfs ( i )->dimension(); 
    362417                        } 
    363418                } 
    364419                // 
    365                 int cumdim=0; 
    366                 int dimi=0; 
     420                int cumdim = 0; 
     421                int dimi = 0; 
    367422                int i; 
    368                 for ( i=0;i<epdfs.length();i++ ) { 
     423                for ( i = 0; i < epdfs.length(); i++ ) { 
    369424                        dls ( i ) = new datalink; 
    370                         if ( named ) {dls ( i )->set_connection ( epdfs ( i )->_rv() , rv );} 
    371                         else { 
     425                        if ( named ) { 
     426                                dls ( i )->set_connection ( epdfs ( i )->_rv() , rv ); 
     427                        } else { 
    372428                                dimi = epdfs ( i )->dimension(); 
    373                                 dls ( i )->set_connection ( dimi, dim, linspace ( cumdim,cumdim+dimi-1 ) ); 
    374                                 cumdim+=dimi; 
     429                                dls ( i )->set_connection ( dimi, dim, linspace ( cumdim, cumdim + dimi - 1 ) ); 
     430                                cumdim += dimi; 
    375431                        } 
    376432                } 
     
    379435        vec mean() const { 
    380436                vec tmp ( dim ); 
    381                 for ( int i=0;i<epdfs.length();i++ ) { 
     437                for ( int i = 0; i < epdfs.length(); i++ ) { 
    382438                        vec pom = epdfs ( i )->mean(); 
    383439                        dls ( i )->pushup ( tmp, pom ); 
     
    387443        vec variance() const { 
    388444                vec tmp ( dim ); //second moment 
    389                 for ( int i=0;i<epdfs.length();i++ ) { 
     445                for ( int i = 0; i < epdfs.length(); i++ ) { 
    390446                        vec pom = epdfs ( i )->mean(); 
    391                         dls ( i )->pushup ( tmp, pow ( pom,2 ) ); 
    392                 } 
    393                 return tmp-pow ( mean(),2 ); 
     447                        dls ( i )->pushup ( tmp, pow ( pom, 2 ) ); 
     448                } 
     449                return tmp - pow ( mean(), 2 ); 
    394450        } 
    395451        vec sample() const { 
    396452                vec tmp ( dim ); 
    397                 for ( int i=0;i<epdfs.length();i++ ) { 
     453                for ( int i = 0; i < epdfs.length(); i++ ) { 
    398454                        vec pom = epdfs ( i )->sample(); 
    399455                        dls ( i )->pushup ( tmp, pom ); 
     
    402458        } 
    403459        double evallog ( const vec &val ) const { 
    404                 double tmp=0; 
    405                 for ( int i=0;i<epdfs.length();i++ ) { 
    406                         tmp+=epdfs ( i )->evallog ( dls ( i )->pushdown ( val ) ); 
    407                 } 
    408                 it_assert_debug ( std::isfinite ( tmp ),"Infinite" ); 
     460                double tmp = 0; 
     461                for ( int i = 0; i < epdfs.length(); i++ ) { 
     462                        tmp += epdfs ( i )->evallog ( dls ( i )->pushdown ( val ) ); 
     463                } 
     464                it_assert_debug ( std::isfinite ( tmp ), "Infinite" ); 
    409465                return tmp; 
    410466        } 
    411467        //!access function 
    412         const epdf* operator () ( int i ) const {it_assert_debug ( i<epdfs.length(),"wrong index" );return epdfs ( i );} 
     468        const epdf* operator () ( int i ) const { 
     469                it_assert_debug ( i < epdfs.length(), "wrong index" ); 
     470                return epdfs ( i ); 
     471        } 
    413472 
    414473        //!Destructor 
    415         ~eprod() {for ( int i=0;i<epdfs.length();i++ ) {delete dls ( i );}} 
     474        ~eprod() { 
     475                for ( int i = 0; i < epdfs.length(); i++ ) { 
     476                        delete dls ( i ); 
     477                } 
     478        } 
    416479}; 
    417480 
     
    430493public: 
    431494        //!Default constructor 
    432         mmix():iepdf(new emix()) { 
    433             set_ep(iepdf); 
     495        mmix() : iepdf ( new emix() ) { 
     496                set_ep ( iepdf ); 
    434497        } 
    435498 
     
    438501                Array<epdf*> Eps ( Coms.length() ); 
    439502 
    440                 for ( int i = 0;i < Coms.length();i++ ) { 
    441                         Eps(i) = Coms(i)->e(); 
    442                 } 
    443  
    444                 iepdf->set_parameters(w, Eps); 
     503                for ( int i = 0; i < Coms.length(); i++ ) { 
     504                        Eps ( i ) = Coms ( i )->e(); 
     505                } 
     506 
     507                iepdf->set_parameters ( w, Eps ); 
    445508        } 
    446509 
    447510        void condition ( const vec &cond ) { 
    448                 for ( int i = 0;i < Coms.length();i++ ) {Coms ( i )->condition ( cond );} 
     511                for ( int i = 0; i < Coms.length(); i++ ) { 
     512                        Coms ( i )->condition ( cond ); 
     513                } 
    449514        }; 
    450515}; 
  • library/bdm/stat/exp_family.cpp

    r471 r477  
    44#include "exp_family.h" 
    55 
    6 namespace bdm{ 
     6namespace bdm { 
    77 
    88Uniform_RNG UniRNG; 
     
    1212using std::cout; 
    1313 
    14 void BMEF::bayes ( const vec &dt ) {this->bayes ( dt,1.0 );}; 
     14void BMEF::bayes ( const vec &dt ) { 
     15        this->bayes ( dt, 1.0 ); 
     16}; 
    1517 
    1618vec egiw::sample() const { 
     
    2022 
    2123double egiw::evallog_nn ( const vec &val ) const { 
    22         int vend = val.length()-1; 
    23  
    24         if ( dimx==1 ) { //same as the following, just quicker. 
     24        int vend = val.length() - 1; 
     25 
     26        if ( dimx == 1 ) { //same as the following, just quicker. 
    2527                double r = val ( vend ); //last entry! 
    26                 if (r<0) return -inf; 
    27                 vec Psi ( nPsi+dimx ); 
     28                if ( r < 0 ) return -inf; 
     29                vec Psi ( nPsi + dimx ); 
    2830                Psi ( 0 ) = -1.0; 
    29                 Psi.set_subvector ( 1,val ( 0,vend-1 ) ); // fill the rest 
    30  
    31                 double Vq=V.qform ( Psi ); 
    32                 return -0.5* ( nu*log ( r ) + Vq /r ); 
    33         } 
    34         else { 
    35                 mat Th= reshape ( val ( 0,nPsi*dimx-1 ),nPsi,dimx ); 
    36                 fsqmat R ( reshape ( val ( nPsi*dimx,vend ),dimx,dimx ) ); 
    37                 double ldetR=R.logdet(); 
    38                 if (ldetR) return -inf; 
    39                 mat Tmp=concat_vertical ( -eye ( dimx ),Th ); 
     31                Psi.set_subvector ( 1, val ( 0, vend - 1 ) ); // fill the rest 
     32 
     33                double Vq = V.qform ( Psi ); 
     34                return -0.5* ( nu*log ( r ) + Vq / r ); 
     35        } else { 
     36                mat Th = reshape ( val ( 0, nPsi * dimx - 1 ), nPsi, dimx ); 
     37                fsqmat R ( reshape ( val ( nPsi*dimx, vend ), dimx, dimx ) ); 
     38                double ldetR = R.logdet(); 
     39                if ( ldetR ) return -inf; 
     40                mat Tmp = concat_vertical ( -eye ( dimx ), Th ); 
    4041                fsqmat iR ( dimx ); 
    4142                R.inv ( iR ); 
     
    4849        const vec& D = V._D(); 
    4950 
    50         double m = nu - nPsi -dimx-1; 
     51        double m = nu - nPsi - dimx - 1; 
    5152#define log2  0.693147180559945286226763983 
    5253#define logpi 1.144729885849400163877476189 
     
    5455#define Inf std::numeric_limits<double>::infinity() 
    5556 
    56         double nkG = 0.5* dimx* ( -nPsi *log2pi + sum ( log ( D ( dimx,D.length()-1 ) ) ) ); 
     57        double nkG = 0.5 * dimx * ( -nPsi * log2pi + sum ( log ( D ( dimx, D.length() - 1 ) ) ) ); 
    5758        // temporary for lgamma in Wishart 
    58         double lg=0; 
    59         for ( int i =0; i<dimx;i++ ) {lg+=lgamma ( 0.5* ( m-i ) );} 
    60  
    61         double nkW = 0.5* ( m*sum ( log ( D ( 0,dimx-1 ) ) ) ) \ 
    62                      - 0.5*dimx* ( m*log2 + 0.5* ( dimx-1 ) *log2pi )  - lg; 
    63  
    64         it_assert_debug ( ( ( -nkG-nkW ) >-Inf ) && ( ( -nkG-nkW ) <Inf ), "ARX improper" ); 
    65         return -nkG-nkW; 
     59        double lg = 0; 
     60        for ( int i = 0; i < dimx; i++ ) { 
     61                lg += lgamma ( 0.5 * ( m - i ) ); 
     62        } 
     63 
     64        double nkW = 0.5 * ( m * sum ( log ( D ( 0, dimx - 1 ) ) ) ) \ 
     65                     - 0.5 * dimx * ( m * log2 + 0.5 * ( dimx - 1 ) * log2pi )  - lg; 
     66 
     67        it_assert_debug ( ( ( -nkG - nkW ) > -Inf ) && ( ( -nkG - nkW ) < Inf ), "ARX improper" ); 
     68        return -nkG - nkW; 
    6669} 
    6770 
    6871vec egiw::est_theta() const { 
    69         if ( dimx==1 ) { 
     72        if ( dimx == 1 ) { 
    7073                const mat &L = V._L(); 
    7174                int end = L.rows() - 1; 
    7275 
    73                 mat iLsub = ltuinv ( L ( dimx,end,dimx,end ) ); 
    74  
    75                 vec L0 = L.get_col(0); 
    76  
    77                 return iLsub * L0(1,end); 
    78         } 
    79         else { 
    80                 it_error("ERROR: est_theta() not implemented for dimx>1"); 
     76                mat iLsub = ltuinv ( L ( dimx, end, dimx, end ) ); 
     77 
     78                vec L0 = L.get_col ( 0 ); 
     79 
     80                return iLsub * L0 ( 1, end ); 
     81        } else { 
     82                it_error ( "ERROR: est_theta() not implemented for dimx>1" ); 
    8183                return 0; 
    8284        } 
     
    8991                int end = D.length() - 1; 
    9092 
    91                 mat Lsub = L ( 1, end, 1, end); 
    92                 mat Dsub = diag(D(1, end)); 
    93  
    94                 return inv( transpose(Lsub) * Dsub * Lsub ); 
    95  
    96         } 
    97         else { 
    98                 it_error("ERROR: est_theta_cov() not implemented for dimx>1"); 
     93                mat Lsub = L ( 1, end, 1, end ); 
     94                mat Dsub = diag ( D ( 1, end ) ); 
     95 
     96                return inv ( transpose ( Lsub ) * Dsub * Lsub ); 
     97 
     98        } else { 
     99                it_error ( "ERROR: est_theta_cov() not implemented for dimx>1" ); 
    99100                return 0; 
    100101        } 
     
    104105vec egiw::mean() const { 
    105106 
    106         if ( dimx==1 ) { 
    107                 const vec &D= V._D(); 
    108                 int end = D.length()-1; 
     107        if ( dimx == 1 ) { 
     108                const vec &D = V._D(); 
     109                int end = D.length() - 1; 
    109110 
    110111                vec m ( dim ); 
    111112                m.set_subvector ( 0, est_theta() ); 
    112                 m ( end ) = D ( 0 ) / ( nu -nPsi -2*dimx -2 ); 
     113                m ( end ) = D ( 0 ) / ( nu - nPsi - 2 * dimx - 2 ); 
    113114                return m; 
    114         } 
    115         else { 
     115        } else { 
    116116                mat M; 
    117117                mat R; 
    118                 mean_mat ( M,R ); 
    119                 return cvectorize ( concat_vertical ( M,R ) ); 
     118                mean_mat ( M, R ); 
     119                return cvectorize ( concat_vertical ( M, R ) ); 
    120120        } 
    121121 
     
    124124vec egiw::variance() const { 
    125125 
    126         if ( dimx==1 ) { 
    127                 int l=V.rows(); 
    128                 const ldmat tmp(V,linspace(1,l-1)); 
    129                 ldmat itmp(l); 
    130                 tmp.inv(itmp); 
    131                 double cove = V._D() ( 0 ) / ( nu -nPsi -2*dimx -2 ); 
    132                  
    133                 vec var(l); 
    134                 var.set_subvector(0,diag(itmp.to_mat())*cove); 
    135                 var(l-1)=cove*cove/( nu -nPsi -2*dimx -2 ); 
     126        if ( dimx == 1 ) { 
     127                int l = V.rows(); 
     128                const ldmat tmp ( V, linspace ( 1, l - 1 ) ); 
     129                ldmat itmp ( l ); 
     130                tmp.inv ( itmp ); 
     131                double cove = V._D() ( 0 ) / ( nu - nPsi - 2 * dimx - 2 ); 
     132 
     133                vec var ( l ); 
     134                var.set_subvector ( 0, diag ( itmp.to_mat() ) *cove ); 
     135                var ( l - 1 ) = cove * cove / ( nu - nPsi - 2 * dimx - 2 ); 
    136136                return var; 
    137         } 
    138         else {it_error("not implemented"); return vec(0);} 
     137        } else { 
     138                it_error ( "not implemented" ); 
     139                return vec ( 0 ); 
     140        } 
    139141} 
    140142 
    141143void egiw::mean_mat ( mat &M, mat&R ) const { 
    142         const mat &L= V._L(); 
    143         const vec &D= V._D(); 
    144         int end = L.rows()-1; 
    145  
    146         ldmat ldR ( L ( 0,dimx-1,0,dimx-1 ), D ( 0,dimx-1 ) / ( nu -nPsi -2*dimx -2 ) ); //exp val of R 
    147         mat iLsub=ltuinv ( L ( dimx,end,dimx,end ) ); 
     144        const mat &L = V._L(); 
     145        const vec &D = V._D(); 
     146        int end = L.rows() - 1; 
     147 
     148        ldmat ldR ( L ( 0, dimx - 1, 0, dimx - 1 ), D ( 0, dimx - 1 ) / ( nu - nPsi - 2*dimx - 2 ) ); //exp val of R 
     149        mat iLsub = ltuinv ( L ( dimx, end, dimx, end ) ); 
    148150 
    149151        // set mean value 
    150         mat Lpsi = L ( dimx,end,0,dimx-1 ); 
    151         M= iLsub*Lpsi; 
    152         R= ldR.to_mat()  ; 
     152        mat Lpsi = L ( dimx, end, 0, dimx - 1 ); 
     153        M = iLsub * Lpsi; 
     154        R = ldR.to_mat()  ; 
    153155} 
    154156 
    155157vec egamma::sample() const { 
    156         vec smp ( dim); 
     158        vec smp ( dim ); 
    157159        int i; 
    158160 
    159         for ( i=0; i<dim; i++ ) { 
    160                 if ( beta ( i ) >std::numeric_limits<double>::epsilon() ) { 
    161                         GamRNG.setup ( alpha ( i ),beta ( i ) ); 
    162                 } 
    163                 else { 
    164                         GamRNG.setup ( alpha ( i ),std::numeric_limits<double>::epsilon() ); 
     161        for ( i = 0; i < dim; i++ ) { 
     162                if ( beta ( i ) > std::numeric_limits<double>::epsilon() ) { 
     163                        GamRNG.setup ( alpha ( i ), beta ( i ) ); 
     164                } else { 
     165                        GamRNG.setup ( alpha ( i ), std::numeric_limits<double>::epsilon() ); 
    165166                } 
    166167#pragma omp critical 
     
    190191        int i; 
    191192 
    192         if (any(val<=0.)) return -inf; 
    193         if (any(beta<=0.)) return -inf; 
    194         for ( i=0; i<dim; i++ ) { 
    195                 res += ( alpha ( i ) - 1 ) *std::log ( val ( i ) ) - beta ( i ) *val ( i ); 
    196         } 
    197         double tmp=res-lognc();; 
    198         it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); 
     193        if ( any ( val <= 0. ) ) return -inf; 
     194        if ( any ( beta <= 0. ) ) return -inf; 
     195        for ( i = 0; i < dim; i++ ) { 
     196                res += ( alpha ( i ) - 1 ) * std::log ( val ( i ) ) - beta ( i ) * val ( i ); 
     197        } 
     198        double tmp = res - lognc();; 
     199        it_assert_debug ( std::isfinite ( tmp ), "Infinite value" ); 
    199200        return tmp; 
    200201} 
     
    204205        int i; 
    205206 
    206         for ( i=0; i<dim; i++ ) { 
    207                 res += lgamma ( alpha ( i ) ) - alpha ( i ) *std::log ( beta ( i ) ) ; 
     207        for ( i = 0; i < dim; i++ ) { 
     208                res += lgamma ( alpha ( i ) ) - alpha ( i ) * std::log ( beta ( i ) ) ; 
    208209        } 
    209210 
     
    211212} 
    212213 
    213 void mgamma::set_parameters(double k0, const vec &beta0) { 
     214void mgamma::set_parameters ( double k0, const vec &beta0 ) { 
    214215        k = k0; 
    215         iepdf->set_parameters(k * ones(beta0.length()), beta0); 
     216        iepdf->set_parameters ( k * ones ( beta0.length() ), beta0 ); 
    216217        dimc = e()->dimension(); 
    217218} 
    218219 
    219 ivec eEmp::resample (RESAMPLING_METHOD method) { 
    220         ivec ind=zeros_i ( n ); 
     220ivec eEmp::resample ( RESAMPLING_METHOD method ) { 
     221        ivec ind = zeros_i ( n ); 
    221222        ivec N_babies = zeros_i ( n ); 
    222223        vec cumDist = cumsum ( w ); 
    223224        vec u ( n ); 
    224         int i,j,parent; 
     225        int i, j, parent; 
    225226        double u0; 
    226227 
    227228        switch ( method ) { 
    228                 case MULTINOMIAL: 
    229                         u ( n - 1 ) = pow ( UniRNG.sample(), 1.0 / n ); 
    230  
    231                         for ( i = n - 2;i >= 0;i-- ) { 
    232                                 u ( i ) = u ( i + 1 ) * pow ( UniRNG.sample(), 1.0 / ( i + 1 ) ); 
    233                         } 
    234  
    235                         break; 
    236  
    237                 case STRATIFIED: 
    238  
    239                         for ( i = 0;i < n;i++ ) { 
    240                                 u ( i ) = ( i + UniRNG.sample() ) / n; 
    241                         } 
    242  
    243                         break; 
    244  
    245                 case SYSTEMATIC: 
    246                         u0 = UniRNG.sample(); 
    247  
    248                         for ( i = 0;i < n;i++ ) { 
    249                                 u ( i ) = ( i + u0 ) / n; 
    250                         } 
    251  
    252                         break; 
    253  
    254                 default: 
    255                         it_error ( "PF::resample(): Unknown resampling method" ); 
     229        case MULTINOMIAL: 
     230                u ( n - 1 ) = pow ( UniRNG.sample(), 1.0 / n ); 
     231 
     232                for ( i = n - 2; i >= 0; i-- ) { 
     233                        u ( i ) = u ( i + 1 ) * pow ( UniRNG.sample(), 1.0 / ( i + 1 ) ); 
     234                } 
     235 
     236                break; 
     237 
     238        case STRATIFIED: 
     239 
     240                for ( i = 0; i < n; i++ ) { 
     241                        u ( i ) = ( i + UniRNG.sample() ) / n; 
     242                } 
     243 
     244                break; 
     245 
     246        case SYSTEMATIC: 
     247                u0 = UniRNG.sample(); 
     248 
     249                for ( i = 0; i < n; i++ ) { 
     250                        u ( i ) = ( i + u0 ) / n; 
     251                } 
     252 
     253                break; 
     254 
     255        default: 
     256                it_error ( "PF::resample(): Unknown resampling method" ); 
    256257        } 
    257258 
     
    259260        j = 0; 
    260261 
    261         for ( i = 0;i < n;i++ ) { 
     262        for ( i = 0; i < n; i++ ) { 
    262263                while ( u ( i ) > cumDist ( j ) ) j++; 
    263264 
     
    270271 
    271272        // find the first parent; 
    272         parent=0; while ( N_babies ( parent ) ==0 ) parent++; 
     273        parent = 0; 
     274        while ( N_babies ( parent ) == 0 ) parent++; 
    273275 
    274276        // Build index 
    275         for ( i = 0;i < n;i++ ) { 
     277        for ( i = 0; i < n; i++ ) { 
    276278                if ( N_babies ( i ) > 0 ) { 
    277279                        ind ( i ) = i; 
    278280                        N_babies ( i ) --; //this index was now replicated; 
    279                 } 
    280                 else { 
     281                } else { 
    281282                        // test if the parent has been fully replicated 
    282283                        // if yes, find the next one 
    283                         while ( ( N_babies ( parent ) ==0 ) || ( N_babies ( parent ) ==1 && parent>i ) ) parent++; 
     284                        while ( ( N_babies ( parent ) == 0 ) || ( N_babies ( parent ) == 1 && parent > i ) ) parent++; 
    284285 
    285286                        // Replicate parent 
     
    292293 
    293294        // copy the internals according to ind 
    294         for ( i=0;i<n;i++ ) { 
    295                 if ( ind ( i ) !=i ) { 
    296                         samples ( i ) =samples ( ind ( i ) ); 
    297                 } 
    298                 w ( i ) = 1.0/n; 
     295        for ( i = 0; i < n; i++ ) { 
     296                if ( ind ( i ) != i ) { 
     297                        samples ( i ) = samples ( ind ( i ) ); 
     298                } 
     299                w ( i ) = 1.0 / n; 
    299300        } 
    300301 
     
    305306        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0"); 
    306307        dim = epdf0->dimension(); 
    307         w=w0; 
    308         w/=sum ( w0 );//renormalize 
    309         n=w.length(); 
     308        w = w0; 
     309        w /= sum ( w0 );//renormalize 
     310        n = w.length(); 
    310311        samples.set_size ( n ); 
    311312        dim = epdf0->dimension(); 
    312313 
    313         for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();} 
     314        for ( int i = 0; i < n; i++ ) { 
     315                samples ( i ) = epdf0->sample(); 
     316        } 
    314317} 
    315318 
    316319void eEmp::set_samples ( const epdf* epdf0 ) { 
    317320        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0"); 
    318         w=1; 
    319         w/=sum ( w );//renormalize 
    320  
    321         for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();} 
    322 } 
    323  
    324 void migamma_ref::from_setting( const Setting &set )  
    325 {                                
     321        w = 1; 
     322        w /= sum ( w );//renormalize 
     323 
     324        for ( int i = 0; i < n; i++ ) { 
     325                samples ( i ) = epdf0->sample(); 
     326        } 
     327} 
     328 
     329void migamma_ref::from_setting ( const Setting &set ) { 
    326330        vec ref; 
    327         UI::get( ref, set, "ref" , UI::compulsory); 
    328         set_parameters(set["k"],ref,set["l"]); 
    329 } 
    330  
    331 void mlognorm::from_setting( const Setting &set )  
    332 {        
    333         vec mu0;         
    334         UI::get( mu0, set, "mu0", UI::compulsory); 
    335         set_parameters(mu0.length(),set["k"]); 
    336         condition(mu0); 
     331        UI::get ( ref, set, "ref" , UI::compulsory ); 
     332        set_parameters ( set["k"], ref, set["l"] ); 
     333} 
     334 
     335void mlognorm::from_setting ( const Setting &set ) { 
     336        vec mu0; 
     337        UI::get ( mu0, set, "mu0", UI::compulsory ); 
     338        set_parameters ( mu0.length(), set["k"] ); 
     339        condition ( mu0 ); 
    337340} 
    338341 
  • library/bdm/stat/merger.cpp

    r461 r477  
    33#include "../estim/arx.h" 
    44 
    5 namespace bdm 
    6 { 
    7  
    8         merger_base::merger_base(const Array<mpdf*> &S, bool own) { 
    9             DBG = false; 
    10             dbg_file = NULL; 
    11             set_sources(S, own); 
    12         } 
    13  
    14         vec merger_base::merge_points ( mat &lW ) { 
    15                 int nu=lW.rows(); 
    16                 vec result; 
    17                 ivec indW; 
    18                 bool infexist; 
    19                 switch ( METHOD ) { 
    20                         case ARITHMETIC: 
    21                                 result= log ( sum ( exp ( lW ) ) ); //ugly! 
    22                                 break; 
    23                         case GEOMETRIC: 
    24                                 result= sum ( lW ) /nu; 
    25                                 break; 
    26                         case LOGNORMAL: 
    27                                 vec sumlW=sum ( lW ) ; 
    28                                 indW=find((sumlW<inf) & (sumlW>-inf)); 
    29                                 infexist=(indW.size()<lW.cols()); 
    30                                 vec mu; 
    31                                 vec lam; 
    32                                 if (infexist){ 
    33                                         mu = sumlW(indW) /nu; //mean of logs 
    34                                         //  
    35                                         mat validlW=lW.get_cols(indW); 
    36                                         lam = sum ( pow ( validlW-outer_product ( ones ( validlW.rows() ),mu ),2 ) ); 
    37                                 } 
    38                                 else { 
    39                                         mu = sum ( lW ) /nu; //mean of logs 
    40                                         lam = sum ( pow ( lW-outer_product ( ones ( lW.rows() ),mu ),2 ) ); 
    41                                 } 
    42                                 // 
    43                                 double coef=0.0; 
    44                                 vec sq2bl=sqrt ( 2*beta*lam ); //this term is everywhere 
    45                                 switch ( nu ) { 
    46                                         case 2: 
    47                                                 coef= ( 1-0.5*sqrt ( ( 4.0*beta-3.0 ) /beta ) ); 
    48                                                 result =coef*sq2bl + mu ; 
    49                                                 break; 
    50                                         // case 4: == can be done similar to case 2 - is it worth it??? 
    51                                         default: // see accompanying document merge_lognorm_derivation.lyx 
    52                                                 coef = sqrt(1-(nu+1)/(2*beta*nu)); 
    53                                                 result =log(besselk((nu-3)/2, sq2bl*coef))-log(besselk((nu-3)/2, sq2bl)) + mu; 
    54                                                 break; 
    55                                 } 
    56                                 break; 
    57                 } 
    58                 if (infexist){ 
    59                         vec tmp =-inf*ones(lW.cols()); 
    60                         set_subvector(tmp, indW, result); 
    61                         return tmp; 
    62                 } 
    63                 else {return result;} 
    64         } 
    65  
    66         void merger_mix::merge ( ) 
    67         { 
    68                 Array<vec> &Smp = eSmp._samples(); //aux 
    69                 vec &w = eSmp._w(); //aux 
    70  
    71                 mat Smp_ex =ones ( dim +1,Npoints ); // Extended samples for the ARX model - the last row is ones 
    72                 for ( int i=0;i<Npoints;i++ ) { set_col_part ( Smp_ex,i,Smp ( i ) );} 
    73  
    74                 if ( DBG )      *dbg_file << Name ( "Smp_0" ) << Smp_ex; 
    75  
    76                 // Stuff for merging 
    77                 vec lw_src ( Npoints );         // weights of the ith source 
    78                 vec lw_mix ( Npoints );         // weights of the approximating mixture 
    79                 vec lw ( Npoints );                     // tmp 
    80                 mat lW=zeros ( Nsources,Npoints ); // array of weights of all sources 
    81                 vec vec0 ( 0 ); 
    82  
    83                 //initialize importance weights 
    84                 lw_mix = 1.0; // assuming uniform grid density -- otherwise  
    85  
    86                 // Initial component in the mixture model 
    87                 mat V0=1e-8*eye ( dim +1 ); 
    88                 ARX A0; A0.set_statistics ( dim, V0 ); //initial guess of Mix: 
    89  
    90                 Mix.init ( &A0, Smp_ex, Ncoms ); 
    91                 //Preserve initial mixture for repetitive estimation via flattening 
    92                 MixEF Mix_init ( Mix ); 
    93  
    94                 // ============= MAIN LOOP ================== 
    95                 bool converged=false; 
    96                 int niter = 0; 
    97                 char dbg_str[100]; 
    98  
    99                 emix* Mpred=Mix.epredictor ( ); 
    100                 vec Mix_pdf ( Npoints ); 
    101                 while ( !converged ) 
    102                 { 
    103                         //Re-estimate Mix 
    104                         //Re-Initialize Mixture model 
    105                         Mix.flatten ( &Mix_init ); 
    106                         Mix.bayesB ( Smp_ex, w*Npoints ); 
    107                         delete Mpred; 
    108                         Mpred = Mix.epredictor ( ); // Allocation => must be deleted at the end!! 
    109                         Mpred->set_rv ( rv ); //the predictor predicts rv of this merger 
    110  
    111                         // This will be active only later in iterations!!! 
    112                         if (  1./sum_sqr ( w ) <effss_coef*Npoints )  
    113                         { 
    114                                 // Generate new samples 
    115                                 eSmp.set_samples ( Mpred ); 
    116                                 for ( int i=0;i<Npoints;i++ ) 
    117                                 { 
    118                                         //////////// !!!!!!!!!!!!! 
    119                                         //if ( Smp ( i ) ( 2 ) <0 ) {Smp ( i ) ( 2 ) = 0.01; } 
    120                                         set_col_part ( Smp_ex,i,Smp ( i ) ); 
    121                                         //Importance of the mixture 
    122                                         //lw_mix ( i ) =Mix.logpred (Smp_ex.get_col(i) ); 
    123                                         lw_mix ( i ) = Mpred->evallog ( Smp ( i ) ); 
    124                                 } 
    125                                 if ( DBG ) 
    126                                 { 
    127                                         cout<<"Resampling =" << 1./sum_sqr ( w ) << endl; 
    128                                         cout << Mix._e()->mean() <<endl; 
    129                                         cout << sum ( Smp_ex,2 ) /Npoints <<endl; 
    130                                         cout << Smp_ex*Smp_ex.T() /Npoints << endl; 
    131                                 } 
    132                         } 
    133                         if ( DBG ) 
    134                         { 
    135                                 sprintf ( dbg_str,"Mpred_mean%d",niter ); 
    136                                 *dbg_file << Name ( dbg_str ) << Mpred->mean(); 
    137                                 sprintf ( dbg_str,"Mpred_var%d",niter ); 
    138                                 *dbg_file << Name ( dbg_str ) << Mpred->variance(); 
    139  
    140  
    141                                 sprintf ( dbg_str,"Mpdf%d",niter ); 
    142                                 for ( int i=0;i<Npoints;i++ ) {Mix_pdf ( i ) = Mix.logpred ( Smp_ex.get_col ( i ) );} 
    143                                 *dbg_file << Name ( dbg_str ) << Mix_pdf; 
    144  
    145                                 sprintf ( dbg_str,"Smp%d",niter ); 
    146                                 *dbg_file << Name ( dbg_str ) << Smp_ex; 
    147  
    148                         } 
    149                         //Importace weighting 
    150                         for ( int i=0;i<mpdfs.length();i++ ) 
    151                         { 
    152                                 lw_src=0.0; 
    153                                 //======== Same RVs =========== 
    154                                 //Split according to dependency in rvs 
    155                                 if ( mpdfs ( i )->dimension() ==dim ) 
    156                                 { 
    157                                         // no need for conditioning or marginalization 
    158                                         lw_src = mpdfs ( i )->e()->evallog_m ( Smp  ); 
    159                                 } 
    160                                 else 
    161                                 { 
    162                                         // compute likelihood of marginal on the conditional variable 
    163                                         if ( mpdfs ( i )->dimensionc() >0 ) 
    164                                         { 
    165                                                 // Make marginal on rvc_i 
    166                                                 epdf* tmp_marg = Mpred->marginal ( mpdfs ( i )->_rvc() ); 
    167                                                 //compute vector of lw_src 
    168                                                 for ( int k=0;k<Npoints;k++ ) 
    169                                                 { 
    170                                                         // Here val of tmp_marg = cond of mpdfs(i) ==> calling dls->get_cond 
    171                                                         lw_src ( k ) += tmp_marg->evallog ( dls ( i )->get_cond ( Smp ( k ) ) ); 
    172                                                 } 
    173                                                 delete tmp_marg; 
     5namespace bdm { 
     6 
     7merger_base::merger_base ( const Array<mpdf*> &S, bool own ) { 
     8        DBG = false; 
     9        dbg_file = NULL; 
     10        set_sources ( S, own ); 
     11} 
     12 
     13vec merger_base::merge_points ( mat &lW ) { 
     14        int nu = lW.rows(); 
     15        vec result; 
     16        ivec indW; 
     17        bool infexist; 
     18        switch ( METHOD ) { 
     19        case ARITHMETIC: 
     20                result = log ( sum ( exp ( lW ) ) ); //ugly! 
     21                break; 
     22        case GEOMETRIC: 
     23                result = sum ( lW ) / nu; 
     24                break; 
     25        case LOGNORMAL: 
     26                vec sumlW = sum ( lW ) ; 
     27                indW = find ( ( sumlW < inf ) & ( sumlW > -inf ) ); 
     28                infexist = ( indW.size() < lW.cols() ); 
     29                vec mu; 
     30                vec lam; 
     31                if ( infexist ) { 
     32                        mu = sumlW ( indW ) / nu; //mean of logs 
     33                        // 
     34                        mat validlW = lW.get_cols ( indW ); 
     35                        lam = sum ( pow ( validlW - outer_product ( ones ( validlW.rows() ), mu ), 2 ) ); 
     36                } else { 
     37                        mu = sum ( lW ) / nu; //mean of logs 
     38                        lam = sum ( pow ( lW - outer_product ( ones ( lW.rows() ), mu ), 2 ) ); 
     39                } 
     40                // 
     41                double coef = 0.0; 
     42                vec sq2bl = sqrt ( 2 * beta * lam ); //this term is everywhere 
     43                switch ( nu ) { 
     44                case 2: 
     45                        coef = ( 1 - 0.5 * sqrt ( ( 4.0 * beta - 3.0 ) / beta ) ); 
     46                        result = coef * sq2bl + mu ; 
     47                        break; 
     48                        // case 4: == can be done similar to case 2 - is it worth it??? 
     49                default: // see accompanying document merge_lognorm_derivation.lyx 
     50                        coef = sqrt ( 1 - ( nu + 1 ) / ( 2 * beta * nu ) ); 
     51                        result = log ( besselk ( ( nu - 3 ) / 2, sq2bl * coef ) ) - log ( besselk ( ( nu - 3 ) / 2, sq2bl ) ) + mu; 
     52                        break; 
     53                } 
     54                break; 
     55        } 
     56        if ( infexist ) { 
     57                vec tmp = -inf * ones ( lW.cols() ); 
     58                set_subvector ( tmp, indW, result ); 
     59                return tmp; 
     60        } else { 
     61                return result; 
     62        } 
     63} 
     64 
     65void merger_mix::merge ( ) { 
     66        Array<vec> &Smp = eSmp._samples(); //aux 
     67        vec &w = eSmp._w(); //aux 
     68 
     69        mat Smp_ex = ones ( dim + 1, Npoints ); // Extended samples for the ARX model - the last row is ones 
     70        for ( int i = 0; i < Npoints; i++ ) { 
     71                set_col_part ( Smp_ex, i, Smp ( i ) ); 
     72        } 
     73 
     74        if ( DBG )      *dbg_file << Name ( "Smp_0" ) << Smp_ex; 
     75 
     76        // Stuff for merging 
     77        vec lw_src ( Npoints );         // weights of the ith source 
     78        vec lw_mix ( Npoints );         // weights of the approximating mixture 
     79        vec lw ( Npoints );                     // tmp 
     80        mat lW = zeros ( Nsources, Npoints ); // array of weights of all sources 
     81        vec vec0 ( 0 ); 
     82 
     83        //initialize importance weights 
     84        lw_mix = 1.0; // assuming uniform grid density -- otherwise 
     85 
     86        // Initial component in the mixture model 
     87        mat V0 = 1e-8 * eye ( dim + 1 ); 
     88        ARX A0; 
     89        A0.set_statistics ( dim, V0 ); //initial guess of Mix: 
     90 
     91        Mix.init ( &A0, Smp_ex, Ncoms ); 
     92        //Preserve initial mixture for repetitive estimation via flattening 
     93        MixEF Mix_init ( Mix ); 
     94 
     95        // ============= MAIN LOOP ================== 
     96        bool converged = false; 
     97        int niter = 0; 
     98        char dbg_str[100]; 
     99 
     100        emix* Mpred = Mix.epredictor ( ); 
     101        vec Mix_pdf ( Npoints ); 
     102        while ( !converged ) { 
     103                //Re-estimate Mix 
     104                //Re-Initialize Mixture model 
     105                Mix.flatten ( &Mix_init ); 
     106                Mix.bayesB ( Smp_ex, w*Npoints ); 
     107                delete Mpred; 
     108                Mpred = Mix.epredictor ( ); // Allocation => must be deleted at the end!! 
     109                Mpred->set_rv ( rv ); //the predictor predicts rv of this merger 
     110 
     111                // This will be active only later in iterations!!! 
     112                if ( 1. / sum_sqr ( w ) < effss_coef*Npoints ) { 
     113                        // Generate new samples 
     114                        eSmp.set_samples ( Mpred ); 
     115                        for ( int i = 0; i < Npoints; i++ ) { 
     116                                //////////// !!!!!!!!!!!!! 
     117                                //if ( Smp ( i ) ( 2 ) <0 ) {Smp ( i ) ( 2 ) = 0.01; } 
     118                                set_col_part ( Smp_ex, i, Smp ( i ) ); 
     119                                //Importance of the mixture 
     120                                //lw_mix ( i ) =Mix.logpred (Smp_ex.get_col(i) ); 
     121                                lw_mix ( i ) = Mpred->evallog ( Smp ( i ) ); 
     122                        } 
     123                        if ( DBG ) { 
     124                                cout << "Resampling =" << 1. / sum_sqr ( w ) << endl; 
     125                                cout << Mix._e()->mean() << endl; 
     126                                cout << sum ( Smp_ex, 2 ) / Npoints << endl; 
     127                                cout << Smp_ex*Smp_ex.T() / Npoints << endl; 
     128                        } 
     129                } 
     130                if ( DBG ) { 
     131                        sprintf ( dbg_str, "Mpred_mean%d", niter ); 
     132                        *dbg_file << Name ( dbg_str ) << Mpred->mean(); 
     133                        sprintf ( dbg_str, "Mpred_var%d", niter ); 
     134                        *dbg_file << Name ( dbg_str ) << Mpred->variance(); 
     135 
     136 
     137                        sprintf ( dbg_str, "Mpdf%d", niter ); 
     138                        for ( int i = 0; i < Npoints; i++ ) { 
     139                                Mix_pdf ( i ) = Mix.logpred ( Smp_ex.get_col ( i ) ); 
     140                        } 
     141                        *dbg_file << Name ( dbg_str ) << Mix_pdf; 
     142 
     143                        sprintf ( dbg_str, "Smp%d", niter ); 
     144                        *dbg_file << Name ( dbg_str ) << Smp_ex; 
     145 
     146                } 
     147                //Importace weighting 
     148                for ( int i = 0; i < mpdfs.length(); i++ ) { 
     149                        lw_src = 0.0; 
     150                        //======== Same RVs =========== 
     151                        //Split according to dependency in rvs 
     152                        if ( mpdfs ( i )->dimension() == dim ) { 
     153                                // no need for conditioning or marginalization 
     154                                lw_src = mpdfs ( i )->e()->evallog_m ( Smp ); 
     155                        } else { 
     156                                // compute likelihood of marginal on the conditional variable 
     157                                if ( mpdfs ( i )->dimensionc() > 0 ) { 
     158                                        // Make marginal on rvc_i 
     159                                        epdf* tmp_marg = Mpred->marginal ( mpdfs ( i )->_rvc() ); 
     160                                        //compute vector of lw_src 
     161                                        for ( int k = 0; k < Npoints; k++ ) { 
     162                                                // Here val of tmp_marg = cond of mpdfs(i) ==> calling dls->get_cond 
     163                                                lw_src ( k ) += tmp_marg->evallog ( dls ( i )->get_cond ( Smp ( k ) ) ); 
     164                                        } 
     165                                        delete tmp_marg; 
    174166 
    175167//                                      sprintf ( str,"marg%d",niter ); 
    176168//                                      *dbg << Name ( str ) << lw_src; 
    177169 
     170                                } 
     171                                // Compute likelihood of the missing variable 
     172                                if ( dim > ( mpdfs ( i )->dimension() + mpdfs ( i )->dimensionc() ) ) { 
     173                                        /////////////// 
     174                                        // There are variales unknown to mpdfs(i) : rvzs 
     175                                        mpdf* tmp_cond = Mpred->condition ( rvzs ( i ) ); 
     176                                        // Compute likelihood 
     177                                        vec lw_dbg = lw_src; 
     178                                        for ( int k = 0; k < Npoints; k++ ) { 
     179                                                lw_src ( k ) += log ( 
     180                                                                    tmp_cond->evallogcond ( 
     181                                                                        zdls ( i )->pushdown ( Smp ( k ) ), 
     182                                                                        zdls ( i )->get_cond ( Smp ( k ) ) ) ); 
     183                                                if ( !std::isfinite ( lw_src ( k ) ) ) { 
     184                                                        lw_src ( k ) = -1e16; 
     185                                                        cout << "!"; 
     186                                                } 
    178187                                        } 
    179                                         // Compute likelihood of the missing variable 
    180                                         if ( dim > ( mpdfs ( i )->dimension() + mpdfs ( i )->dimensionc() ) ) 
    181                                         { 
    182                                                 /////////////// 
    183                                                 // There are variales unknown to mpdfs(i) : rvzs 
    184                                                 mpdf* tmp_cond = Mpred->condition ( rvzs ( i ) ); 
    185                                                 // Compute likelihood 
    186                                                 vec lw_dbg=lw_src; 
    187                                                 for ( int k= 0; k<Npoints; k++ ) 
    188                                                 { 
    189                                                         lw_src ( k ) += log ( 
    190                                                                             tmp_cond->evallogcond ( 
    191                                                                                 zdls ( i )->pushdown ( Smp ( k ) ), 
    192                                                                                 zdls ( i )->get_cond ( Smp ( k ) ) ) ); 
    193                                                         if ( !std::isfinite ( lw_src ( k ) ) ) 
    194                                                         { 
    195                                                                 lw_src ( k ) = -1e16; cout << "!"; 
    196                                                         } 
    197                                                 } 
    198                                                 delete tmp_cond; 
    199                                         } 
    200                                         // Compute likelihood of the partial source 
    201                                         for ( int k= 0; k<Npoints; k++ ) 
    202                                         { 
    203                                                 mpdfs ( i )->condition ( dls ( i )->get_cond ( Smp ( k ) ) ); 
    204                                                 lw_src ( k ) += mpdfs ( i )->e()->evallog ( dls ( i )->pushdown ( Smp ( k ) ) ); 
    205                                         } 
    206  
     188                                        delete tmp_cond; 
    207189                                } 
    208                 //                      it_assert_debug(std::isfinite(sum(lw_src)),"bad"); 
    209                                 lW.set_row ( i, lw_src ); // do not divide by mix 
    210                         } 
    211                         lw = merger_base::merge_points ( lW ); //merge 
    212  
    213                         //Importance weighting 
    214                         lw -=  lw_mix; // hoping that it is not numerically sensitive... 
    215                         w = exp ( lw-max ( lw ) ); 
    216  
    217                         //renormalize 
    218                         double sumw =sum ( w ); 
    219                         if ( std::isfinite ( sumw ) ) 
    220                         { 
    221                                 w = w/sumw; 
    222                         } 
    223                         else 
    224                         { 
    225                                 it_file itf ( "merg_err.it" ); 
    226                                 itf << Name ( "w" ) << w; 
    227                         } 
    228  
    229                         if ( DBG ) 
    230                         { 
    231                                 sprintf ( dbg_str,"lW%d",niter ); 
    232                                 *dbg_file << Name ( dbg_str ) << lW; 
    233                                 sprintf ( dbg_str,"w%d",niter ); 
    234                                 *dbg_file << Name ( dbg_str ) << w; 
    235                                 sprintf ( dbg_str,"lw_m%d",niter ); 
    236                                 *dbg_file << Name ( dbg_str ) << lw_mix; 
    237                         } 
    238                         // ==== stopping rule === 
    239                         niter++; 
    240                         converged = ( niter>stop_niter ); 
    241                 } 
    242                 delete Mpred; 
     190                                // Compute likelihood of the partial source 
     191                                for ( int k = 0; k < Npoints; k++ ) { 
     192                                        mpdfs ( i )->condition ( dls ( i )->get_cond ( Smp ( k ) ) ); 
     193                                        lw_src ( k ) += mpdfs ( i )->e()->evallog ( dls ( i )->pushdown ( Smp ( k ) ) ); 
     194                                } 
     195 
     196                        } 
     197                        //                      it_assert_debug(std::isfinite(sum(lw_src)),"bad"); 
     198                        lW.set_row ( i, lw_src ); // do not divide by mix 
     199                } 
     200                lw = merger_base::merge_points ( lW ); //merge 
     201 
     202                //Importance weighting 
     203                lw -=  lw_mix; // hoping that it is not numerically sensitive... 
     204                w = exp ( lw - max ( lw ) ); 
     205 
     206                //renormalize 
     207                double sumw = sum ( w ); 
     208                if ( std::isfinite ( sumw ) ) { 
     209                        w = w / sumw; 
     210                } else { 
     211                        it_file itf ( "merg_err.it" ); 
     212                        itf << Name ( "w" ) << w; 
     213                } 
     214 
     215                if ( DBG ) { 
     216                        sprintf ( dbg_str, "lW%d", niter ); 
     217                        *dbg_file << Name ( dbg_str ) << lW; 
     218                        sprintf ( dbg_str, "w%d", niter ); 
     219                        *dbg_file << Name ( dbg_str ) << w; 
     220                        sprintf ( dbg_str, "lw_m%d", niter ); 
     221                        *dbg_file << Name ( dbg_str ) << lw_mix; 
     222                } 
     223                // ==== stopping rule === 
     224                niter++; 
     225                converged = ( niter > stop_niter ); 
     226        } 
     227        delete Mpred; 
    243228//              cout << endl; 
    244229 
    245         } 
    246  
    247         // DEFAULTS FOR MERGER_BASE  
    248         const MERGER_METHOD merger_base::DFLT_METHOD=LOGNORMAL; 
    249         const double merger_base::DFLT_beta=1.2; 
    250         // DEFAULTS FOR MERGER_MIX 
    251         const int merger_mix::DFLT_Ncoms=10; 
    252         const double merger_mix::DFLT_effss_coef=0.5; 
    253  
    254 } 
     230} 
     231 
     232// DEFAULTS FOR MERGER_BASE 
     233const MERGER_METHOD merger_base::DFLT_METHOD = LOGNORMAL; 
     234const double merger_base::DFLT_beta = 1.2; 
     235// DEFAULTS FOR MERGER_MIX 
     236const int merger_mix::DFLT_Ncoms = 10; 
     237const double merger_mix::DFLT_effss_coef = 0.5; 
     238 
     239} 
  • library/bdm/stat/merger.h

    r471 r477  
    1717#include "../estim/mixtures.h" 
    1818 
    19 namespace bdm 
    20 { 
     19namespace bdm { 
    2120using std::string; 
    2221 
     
    4342*/ 
    4443 
    45 class merger_base : public compositepdf, public epdf 
    46 { 
    47         protected: 
    48                 //! Data link for each mpdf in mpdfs 
    49                 Array<datalink_m2e*> dls; 
    50                 //! Array of rvs that are not modelled by mpdfs at all, \f$ z_i \f$ 
    51                 Array<RV> rvzs; 
    52                 //! Data Links for extension \f$ f(z_i|x_i,y_i) \f$ 
    53                 Array<datalink_m2e*> zdls; 
    54                 //! number of support points 
    55                 int Npoints; 
    56                 //! number of sources 
    57                 int Nsources; 
    58  
    59                 //! switch of the methoh used for merging 
    60                 MERGER_METHOD METHOD; 
    61                 //! Default for METHOD 
    62                 static const MERGER_METHOD DFLT_METHOD; 
    63                  
    64                 //!Prior on the log-normal merging model 
    65                 double beta; 
    66                 //! default for beta 
    67                 static const double DFLT_beta; 
    68                  
    69                 //! Projection to empirical density (could also be piece-wise linear) 
    70                 eEmp eSmp; 
    71  
    72                 //! debug or not debug 
    73                 bool DBG; 
    74  
    75                 //! debugging file 
    76                 it_file* dbg_file; 
    77         public: 
    78                 //! \name Constructors 
    79                 //! @{ 
    80  
    81                 //!Empty constructor 
    82                 merger_base () : compositepdf() {DBG = false;dbg_file = NULL;} 
    83  
    84                 //!Constructor from sources 
    85                 merger_base (const Array<mpdf*> &S, bool own=false); 
    86  
    87                 //! Function setting the main internal structures 
    88                 void set_sources (const Array<mpdf*> &Sources, bool own) { 
    89                         compositepdf::set_elements (Sources,own); 
    90                         Nsources=mpdfs.length(); 
    91                         //set sizes 
    92                         dls.set_size (Sources.length()); 
    93                         rvzs.set_size (Sources.length()); 
    94                         zdls.set_size (Sources.length()); 
    95  
    96                         rv = getrv (/* checkoverlap = */ false); 
    97                         RV rvc; setrvc (rv, rvc);  // Extend rv by rvc! 
    98                         // join rv and rvc - see descriprion 
    99                         rv.add (rvc); 
    100                         // get dimension 
    101                         dim = rv._dsize(); 
    102  
    103                         // create links between sources and common rv 
    104                         RV xytmp; 
    105                         for (int i = 0;i < mpdfs.length();i++) { 
    106                                 //Establich connection between mpdfs and merger 
    107                                 dls (i) = new datalink_m2e; 
    108                                 dls (i)->set_connection (mpdfs (i)->_rv(), mpdfs (i)->_rvc(), rv); 
    109  
    110                                 // find out what is missing in each mpdf 
    111                                 xytmp = mpdfs (i)->_rv(); 
    112                                 xytmp.add (mpdfs (i)->_rvc()); 
    113                                 // z_i = common_rv-xy 
    114                                 rvzs (i) = rv.subt (xytmp); 
    115                                 //establish connection between extension (z_i|x,y)s and common rv 
    116                                 zdls (i) = new datalink_m2e; zdls (i)->set_connection (rvzs (i), xytmp, rv) ; 
    117                         }; 
    118                 } 
    119                 //! Rectangular support  each vector of XYZ specifies (begining-end) interval for each dimension. Same number of points, \c dimsize, in each dimension.  
    120                 void set_support (const Array<vec> &XYZ, const int dimsize) { 
    121                         set_support(XYZ,dimsize*ones_i(XYZ.length())); 
    122                 } 
    123                 //! Rectangular support  each vector of XYZ specifies (begining-end) interval for each dimension. \c gridsize specifies number of points is each dimension. 
    124                 void set_support (const Array<vec> &XYZ, const ivec &gridsize) { 
    125                         int dim = XYZ.length();  //check with internal dim!! 
    126                         Npoints = prod (gridsize);  
    127                         eSmp.set_parameters (Npoints, false); 
    128                         Array<vec> &samples = eSmp._samples(); 
    129                         eSmp._w() = ones (Npoints) / Npoints; //unifrom size of bins 
    130                         //set samples 
    131                         ivec ind = zeros_i (dim);      //indeces of dimensions in for cycle; 
    132                         vec smpi (dim);            // ith sample 
    133                         vec steps =zeros(dim);            // ith sample 
    134                         // first corner 
    135                         for (int j = 0; j < dim; j++) { 
    136                                 smpi (j) = XYZ (j) (0); /* beginning of the interval*/  
    137                                 it_assert(gridsize(j)!=0.0,"Zeros in gridsize!"); 
    138                                 steps (j) = ( XYZ(j)(1)-smpi(j) )/gridsize(j); 
    139                         } 
    140                         // fill samples 
    141                         for (int i = 0; i < Npoints; i++) { 
    142                                 // copy  
    143                                 samples(i) = smpi;  
    144                                 // go through all dimensions 
    145                                 for (int j = 0;j < dim;j++) { 
    146                                         if (ind (j) == gridsize (j) - 1) { //j-th index is full 
    147                                                 ind (j) = 0; //shift back 
    148                                                 smpi(j) = XYZ(j)(0); 
    149                                                  
    150                                                 if (i<Npoints-1) { 
    151                                                         ind (j + 1) ++; //increase the next dimension; 
    152                                                         smpi(j+1) += steps(j+1); 
    153                                                         break; 
    154                                                 } 
    155                                                  
    156                                         } else { 
    157                                                 ind (j) ++;  
    158                                                 smpi(j) +=steps(j); 
     44class merger_base : public compositepdf, public epdf { 
     45protected: 
     46        //! Data link for each mpdf in mpdfs 
     47        Array<datalink_m2e*> dls; 
     48        //! Array of rvs that are not modelled by mpdfs at all, \f$ z_i \f$ 
     49        Array<RV> rvzs; 
     50        //! Data Links for extension \f$ f(z_i|x_i,y_i) \f$ 
     51        Array<datalink_m2e*> zdls; 
     52        //! number of support points 
     53        int Npoints; 
     54        //! number of sources 
     55        int Nsources; 
     56 
     57        //! switch of the methoh used for merging 
     58        MERGER_METHOD METHOD; 
     59        //! Default for METHOD 
     60        static const MERGER_METHOD DFLT_METHOD; 
     61 
     62        //!Prior on the log-normal merging model 
     63        double beta; 
     64        //! default for beta 
     65        static const double DFLT_beta; 
     66 
     67        //! Projection to empirical density (could also be piece-wise linear) 
     68        eEmp eSmp; 
     69 
     70        //! debug or not debug 
     71        bool DBG; 
     72 
     73        //! debugging file 
     74        it_file* dbg_file; 
     75public: 
     76        //! \name Constructors 
     77        //! @{ 
     78 
     79        //!Empty constructor 
     80        merger_base () : compositepdf() { 
     81                DBG = false; 
     82                dbg_file = NULL; 
     83        } 
     84 
     85        //!Constructor from sources 
     86        merger_base ( const Array<mpdf*> &S, bool own = false ); 
     87 
     88        //! Function setting the main internal structures 
     89        void set_sources ( const Array<mpdf*> &Sources, bool own ) { 
     90                compositepdf::set_elements ( Sources, own ); 
     91                Nsources = mpdfs.length(); 
     92                //set sizes 
     93                dls.set_size ( Sources.length() ); 
     94                rvzs.set_size ( Sources.length() ); 
     95                zdls.set_size ( Sources.length() ); 
     96 
     97                rv = getrv ( /* checkoverlap = */ false ); 
     98                RV rvc; 
     99                setrvc ( rv, rvc );  // Extend rv by rvc! 
     100                // join rv and rvc - see descriprion 
     101                rv.add ( rvc ); 
     102                // get dimension 
     103                dim = rv._dsize(); 
     104 
     105                // create links between sources and common rv 
     106                RV xytmp; 
     107                for ( int i = 0; i < mpdfs.length(); i++ ) { 
     108                        //Establich connection between mpdfs and merger 
     109                        dls ( i ) = new datalink_m2e; 
     110                        dls ( i )->set_connection ( mpdfs ( i )->_rv(), mpdfs ( i )->_rvc(), rv ); 
     111 
     112                        // find out what is missing in each mpdf 
     113                        xytmp = mpdfs ( i )->_rv(); 
     114                        xytmp.add ( mpdfs ( i )->_rvc() ); 
     115                        // z_i = common_rv-xy 
     116                        rvzs ( i ) = rv.subt ( xytmp ); 
     117                        //establish connection between extension (z_i|x,y)s and common rv 
     118                        zdls ( i ) = new datalink_m2e; 
     119                        zdls ( i )->set_connection ( rvzs ( i ), xytmp, rv ) ; 
     120                }; 
     121        } 
     122        //! Rectangular support  each vector of XYZ specifies (begining-end) interval for each dimension. Same number of points, \c dimsize, in each dimension. 
     123        void set_support ( const Array<vec> &XYZ, const int dimsize ) { 
     124                set_support ( XYZ, dimsize*ones_i ( XYZ.length() ) ); 
     125        } 
     126        //! Rectangular support  each vector of XYZ specifies (begining-end) interval for each dimension. \c gridsize specifies number of points is each dimension. 
     127        void set_support ( const Array<vec> &XYZ, const ivec &gridsize ) { 
     128                int dim = XYZ.length();  //check with internal dim!! 
     129                Npoints = prod ( gridsize ); 
     130                eSmp.set_parameters ( Npoints, false ); 
     131                Array<vec> &samples = eSmp._samples(); 
     132                eSmp._w() = ones ( Npoints ) / Npoints; //unifrom size of bins 
     133                //set samples 
     134                ivec ind = zeros_i ( dim );    //indeces of dimensions in for cycle; 
     135                vec smpi ( dim );          // ith sample 
     136                vec steps = zeros ( dim );        // ith sample 
     137                // first corner 
     138                for ( int j = 0; j < dim; j++ ) { 
     139                        smpi ( j ) = XYZ ( j ) ( 0 ); /* beginning of the interval*/ 
     140                        it_assert ( gridsize ( j ) != 0.0, "Zeros in gridsize!" ); 
     141                        steps ( j ) = ( XYZ ( j ) ( 1 ) - smpi ( j ) ) / gridsize ( j ); 
     142                } 
     143                // fill samples 
     144                for ( int i = 0; i < Npoints; i++ ) { 
     145                        // copy 
     146                        samples ( i ) = smpi; 
     147                        // go through all dimensions 
     148                        for ( int j = 0; j < dim; j++ ) { 
     149                                if ( ind ( j ) == gridsize ( j ) - 1 ) { //j-th index is full 
     150                                        ind ( j ) = 0; //shift back 
     151                                        smpi ( j ) = XYZ ( j ) ( 0 ); 
     152 
     153                                        if ( i < Npoints - 1 ) { 
     154                                                ind ( j + 1 ) ++; //increase the next dimension; 
     155                                                smpi ( j + 1 ) += steps ( j + 1 ); 
    159156                                                break; 
    160157                                        } 
     158 
     159                                } else { 
     160                                        ind ( j ) ++; 
     161                                        smpi ( j ) += steps ( j ); 
     162                                        break; 
    161163                                } 
    162164                        } 
    163165                } 
    164                 //! set debug file 
    165                 void set_debug_file (const string fname) { 
    166                         if (DBG) delete dbg_file; 
    167                         dbg_file = new it_file (fname); 
    168                         if (dbg_file) DBG = true; 
    169                 } 
    170                 //! Set internal parameters used in approximation 
    171                 void set_method (MERGER_METHOD MTH=DFLT_METHOD, double beta0 = DFLT_beta) { 
    172                         METHOD = MTH; 
    173                         beta = beta0; 
    174                 } 
    175                 //! Set support points from a pdf by drawing N samples 
    176                 void set_support (const epdf &overall, int N) { 
    177                         eSmp.set_statistics (&overall, N); 
    178                         Npoints = N; 
    179                 } 
    180  
    181                 //! Destructor 
    182                 virtual ~merger_base() { 
    183                         for (int i = 0; i < Nsources; i++) { 
    184                                 delete dls (i); 
    185                                 delete zdls (i); 
    186                         } 
    187                         if (DBG) delete dbg_file; 
    188                 }; 
    189                 //!@} 
    190  
    191                 //! \name Mathematical operations 
    192                 //!@{ 
    193  
    194                 //!Merge given sources in given points 
    195                 virtual void merge () { 
    196                         validate(); 
    197  
    198                         //check if sources overlap: 
    199                         bool OK = true; 
    200                         for (int i = 0;i < mpdfs.length(); i++) { 
    201                                 OK &= (rvzs (i)._dsize() == 0); // z_i is empty 
    202                                 OK &= (mpdfs (i)->_rvc()._dsize() == 0); // y_i is empty 
    203                         } 
    204  
    205                         if (OK) { 
    206                                 mat lW = zeros (mpdfs.length(), eSmp._w().length()); 
    207  
    208                                 vec emptyvec (0); 
    209                                 for (int i = 0; i < mpdfs.length(); i++) { 
    210                                         for (int j = 0; j < eSmp._w().length(); j++) { 
    211                                                 lW (i, j) = mpdfs (i)->evallogcond (eSmp._samples() (j), emptyvec); 
    212                                         } 
    213                                 } 
    214  
    215                                 vec w_nn=merge_points (lW); 
    216                                 vec wtmp = exp (w_nn-max(w_nn)); 
    217                                 //renormalize 
    218                                 eSmp._w() = wtmp / sum (wtmp); 
    219                         } else { 
    220                                 it_error ("Sources are not compatible - use merger_mix"); 
    221                         } 
    222                 }; 
    223  
    224  
    225                 //! Merge log-likelihood values in points using method specified by parameter METHOD 
    226                 vec merge_points (mat &lW); 
    227  
    228  
    229                 //! sample from merged density 
    230 //! weight w is a 
    231                 vec mean() const { 
    232                         const Vec<double> &w = eSmp._w(); 
    233                         const Array<vec> &S = eSmp._samples(); 
    234                         vec tmp = zeros (dim); 
    235                         for (int i = 0; i < Npoints; i++) { 
    236                                 tmp += w (i) * S (i); 
    237                         } 
    238                         return tmp; 
    239                 } 
    240                 mat covariance() const { 
    241                         const vec &w = eSmp._w(); 
    242                         const Array<vec> &S = eSmp._samples(); 
    243  
    244                         vec mea = mean(); 
    245  
    246 //                      cout << sum (w) << "," << w*w << endl; 
    247  
    248                         mat Tmp = zeros (dim, dim); 
    249                         for (int i = 0; i < Npoints; i++) { 
    250                                 Tmp += w (i) * outer_product (S (i), S (i)); 
    251                         } 
    252                         return Tmp -outer_product (mea, mea); 
    253                 } 
    254                 vec variance() const { 
    255                         const vec &w = eSmp._w(); 
    256                         const Array<vec> &S = eSmp._samples(); 
    257  
    258                         vec tmp = zeros (dim); 
    259                         for (int i = 0; i < Nsources; i++) { 
    260                                 tmp += w (i) * pow (S (i), 2); 
    261                         } 
    262                         return tmp -pow (mean(), 2); 
    263                 } 
    264                 //!@} 
    265  
    266                 //! \name Access to attributes 
    267                 //! @{ 
    268  
    269                 //! Access function 
    270                 eEmp& _Smp() {return eSmp;} 
    271  
    272                 //! load from setting 
    273                 void from_setting (const Setting& set) { 
    274                         // get support 
    275                         // find which method to use 
    276                         string meth_str; 
    277                         UI::get<string> (meth_str, set, "method", UI::compulsory); 
    278                         if (!strcmp (meth_str.c_str(), "arithmetic")) 
    279                                 set_method (ARITHMETIC); 
    280                         else { 
    281                                 if (!strcmp (meth_str.c_str(), "geometric")) 
    282                                         set_method (GEOMETRIC); 
    283                                 else if (!strcmp (meth_str.c_str(), "lognormal")) { 
    284                                         set_method (LOGNORMAL); 
    285                                         set.lookupValue( "beta",beta); 
     166        } 
     167        //! set debug file 
     168        void set_debug_file ( const string fname ) { 
     169                if ( DBG ) delete dbg_file; 
     170                dbg_file = new it_file ( fname ); 
     171                if ( dbg_file ) DBG = true; 
     172        } 
     173        //! Set internal parameters used in approximation 
     174        void set_method ( MERGER_METHOD MTH = DFLT_METHOD, double beta0 = DFLT_beta ) { 
     175                METHOD = MTH; 
     176                beta = beta0; 
     177        } 
     178        //! Set support points from a pdf by drawing N samples 
     179        void set_support ( const epdf &overall, int N ) { 
     180                eSmp.set_statistics ( &overall, N ); 
     181                Npoints = N; 
     182        } 
     183 
     184        //! Destructor 
     185        virtual ~merger_base() { 
     186                for ( int i = 0; i < Nsources; i++ ) { 
     187                        delete dls ( i ); 
     188                        delete zdls ( i ); 
     189                } 
     190                if ( DBG ) delete dbg_file; 
     191        }; 
     192        //!@} 
     193 
     194        //! \name Mathematical operations 
     195        //!@{ 
     196 
     197        //!Merge given sources in given points 
     198        virtual void merge () { 
     199                validate(); 
     200 
     201                //check if sources overlap: 
     202                bool OK = true; 
     203                for ( int i = 0; i < mpdfs.length(); i++ ) { 
     204                        OK &= ( rvzs ( i )._dsize() == 0 ); // z_i is empty 
     205                        OK &= ( mpdfs ( i )->_rvc()._dsize() == 0 ); // y_i is empty 
     206                } 
     207 
     208                if ( OK ) { 
     209                        mat lW = zeros ( mpdfs.length(), eSmp._w().length() ); 
     210 
     211                        vec emptyvec ( 0 ); 
     212                        for ( int i = 0; i < mpdfs.length(); i++ ) { 
     213                                for ( int j = 0; j < eSmp._w().length(); j++ ) { 
     214                                        lW ( i, j ) = mpdfs ( i )->evallogcond ( eSmp._samples() ( j ), emptyvec ); 
    286215                                } 
    287216                        } 
    288                         string dbg_file; 
    289                         if (UI::get(dbg_file, set, "dbg_file")) 
    290                                 set_debug_file(dbg_file); 
    291                         //validate() - not used 
    292                 } 
    293  
    294                 void validate() { 
    295                         it_assert (eSmp._w().length() > 0, "Empty support, use set_support()."); 
    296                         it_assert (dim == eSmp._samples() (0).length(), "Support points and rv are not compatible!"); 
    297                         it_assert (isnamed(),"mergers must be named"); 
    298                 } 
    299                 //!@} 
     217 
     218                        vec w_nn = merge_points ( lW ); 
     219                        vec wtmp = exp ( w_nn - max ( w_nn ) ); 
     220                        //renormalize 
     221                        eSmp._w() = wtmp / sum ( wtmp ); 
     222                } else { 
     223                        it_error ( "Sources are not compatible - use merger_mix" ); 
     224                } 
     225        }; 
     226 
     227 
     228        //! Merge log-likelihood values in points using method specified by parameter METHOD 
     229        vec merge_points ( mat &lW ); 
     230 
     231 
     232        //! sample from merged density 
     233//! weight w is a 
     234        vec mean() const { 
     235                const Vec<double> &w = eSmp._w(); 
     236                const Array<vec> &S = eSmp._samples(); 
     237                vec tmp = zeros ( dim ); 
     238                for ( int i = 0; i < Npoints; i++ ) { 
     239                        tmp += w ( i ) * S ( i ); 
     240                } 
     241                return tmp; 
     242        } 
     243        mat covariance() const { 
     244                const vec &w = eSmp._w(); 
     245                const Array<vec> &S = eSmp._samples(); 
     246 
     247                vec mea = mean(); 
     248 
     249//                      cout << sum (w) << "," << w*w << endl; 
     250 
     251                mat Tmp = zeros ( dim, dim ); 
     252                for ( int i = 0; i < Npoints; i++ ) { 
     253                        Tmp += w ( i ) * outer_product ( S ( i ), S ( i ) ); 
     254                } 
     255                return Tmp - outer_product ( mea, mea ); 
     256        } 
     257        vec variance() const { 
     258                const vec &w = eSmp._w(); 
     259                const Array<vec> &S = eSmp._samples(); 
     260 
     261                vec tmp = zeros ( dim ); 
     262                for ( int i = 0; i < Nsources; i++ ) { 
     263                        tmp += w ( i ) * pow ( S ( i ), 2 ); 
     264                } 
     265                return tmp - pow ( mean(), 2 ); 
     266        } 
     267        //!@} 
     268 
     269        //! \name Access to attributes 
     270        //! @{ 
     271 
     272        //! Access function 
     273        eEmp& _Smp() { 
     274                return eSmp; 
     275        } 
     276 
     277        //! load from setting 
     278        void from_setting ( const Setting& set ) { 
     279                // get support 
     280                // find which method to use 
     281                string meth_str; 
     282                UI::get<string> ( meth_str, set, "method", UI::compulsory ); 
     283                if ( !strcmp ( meth_str.c_str(), "arithmetic" ) ) 
     284                        set_method ( ARITHMETIC ); 
     285                else { 
     286                        if ( !strcmp ( meth_str.c_str(), "geometric" ) ) 
     287                                set_method ( GEOMETRIC ); 
     288                        else if ( !strcmp ( meth_str.c_str(), "lognormal" ) ) { 
     289                                set_method ( LOGNORMAL ); 
     290                                set.lookupValue ( "beta", beta ); 
     291                        } 
     292                } 
     293                string dbg_file; 
     294                if ( UI::get ( dbg_file, set, "dbg_file" ) ) 
     295                        set_debug_file ( dbg_file ); 
     296                //validate() - not used 
     297        } 
     298 
     299        void validate() { 
     300                it_assert ( eSmp._w().length() > 0, "Empty support, use set_support()." ); 
     301                it_assert ( dim == eSmp._samples() ( 0 ).length(), "Support points and rv are not compatible!" ); 
     302                it_assert ( isnamed(), "mergers must be named" ); 
     303        } 
     304        //!@} 
    300305}; 
    301 UIREGISTER(merger_base); 
    302  
    303 class merger_mix : public merger_base 
    304 { 
    305         protected: 
    306                 //!Internal mixture of EF models 
    307                 MixEF Mix; 
    308                 //!Number of components in a mixture 
    309                 int Ncoms; 
    310                 //! coefficient of resampling [0,1] 
    311                 double effss_coef; 
    312                 //! stop after niter iterations 
    313                 int stop_niter; 
    314                  
    315                 //! default value for Ncoms 
    316                 static const int DFLT_Ncoms; 
    317                 //! default value for efss_coef; 
    318                 static const double DFLT_effss_coef; 
    319  
    320         public: 
    321                 //!\name Constructors 
    322                 //!@{ 
    323                 merger_mix () {}; 
    324                 merger_mix (const Array<mpdf*> &S,bool own=false) {set_sources (S,own);}; 
    325                 //! Set sources and prepare all internal structures 
    326                 void set_sources (const Array<mpdf*> &S, bool own) { 
    327                         merger_base::set_sources (S,own); 
    328                         Nsources = S.length(); 
    329                 } 
    330                 //! Set internal parameters used in approximation 
    331                 void set_parameters (int Ncoms0 = DFLT_Ncoms, double effss_coef0 = DFLT_effss_coef) { 
    332                         Ncoms = Ncoms0; 
    333                         effss_coef = effss_coef0; 
    334                 } 
    335                 //!@} 
    336  
    337                 //! \name Mathematical operations 
    338                 //!@{ 
    339  
    340                 //!Merge values using mixture approximation 
    341                 void merge (); 
    342  
    343                 //! sample from the approximating mixture 
    344                 vec sample () const { return Mix.posterior().sample();} 
    345                 //! loglikelihood computed on mixture models 
    346                 double evallog (const vec &dt) const { 
    347                         vec dtf = ones (dt.length() + 1); 
    348                         dtf.set_subvector (0, dt); 
    349                         return Mix.logpred (dtf); 
    350                 } 
    351                 //!@} 
    352  
    353                 //!\name Access functions 
    354                 //!@{ 
     306UIREGISTER ( merger_base ); 
     307 
     308class merger_mix : public merger_base { 
     309protected: 
     310        //!Internal mixture of EF models 
     311        MixEF Mix; 
     312        //!Number of components in a mixture 
     313        int Ncoms; 
     314        //! coefficient of resampling [0,1] 
     315        double effss_coef; 
     316        //! stop after niter iterations 
     317        int stop_niter; 
     318 
     319        //! default value for Ncoms 
     320        static const int DFLT_Ncoms; 
     321        //! default value for efss_coef; 
     322        static const double DFLT_effss_coef; 
     323 
     324public: 
     325        //!\name Constructors 
     326        //!@{ 
     327        merger_mix () {}; 
     328        merger_mix ( const Array<mpdf*> &S, bool own = false ) { 
     329                set_sources ( S, own ); 
     330        }; 
     331        //! Set sources and prepare all internal structures 
     332        void set_sources ( const Array<mpdf*> &S, bool own ) { 
     333                merger_base::set_sources ( S, own ); 
     334                Nsources = S.length(); 
     335        } 
     336        //! Set internal parameters used in approximation 
     337        void set_parameters ( int Ncoms0 = DFLT_Ncoms, double effss_coef0 = DFLT_effss_coef ) { 
     338                Ncoms = Ncoms0; 
     339                effss_coef = effss_coef0; 
     340        } 
     341        //!@} 
     342 
     343        //! \name Mathematical operations 
     344        //!@{ 
     345 
     346        //!Merge values using mixture approximation 
     347        void merge (); 
     348 
     349        //! sample from the approximating mixture 
     350        vec sample () const { 
     351                return Mix.posterior().sample(); 
     352        } 
     353        //! loglikelihood computed on mixture models 
     354        double evallog ( const vec &dt ) const { 
     355                vec dtf = ones ( dt.length() + 1 ); 
     356                dtf.set_subvector ( 0, dt ); 
     357                return Mix.logpred ( dtf ); 
     358        } 
     359        //!@} 
     360 
     361        //!\name Access functions 
     362        //!@{ 
    355363//! Access function 
    356                 MixEF& _Mix() {return Mix;} 
    357                 //! Access function 
    358                 emix* proposal() {emix* tmp = Mix.epredictor(); tmp->set_rv (rv); return tmp;} 
    359                 //! from_settings 
    360                 void from_setting(const Setting& set){ 
    361                         merger_base::from_setting(set); 
    362                         set.lookupValue("ncoms",Ncoms); 
    363                         set.lookupValue("effss_coef",effss_coef); 
    364                         set.lookupValue("stop_niter",stop_niter); 
    365                 } 
    366                  
    367                 //! @} 
     364        MixEF& _Mix() { 
     365                return Mix; 
     366        } 
     367        //! Access function 
     368        emix* proposal() { 
     369                emix* tmp = Mix.epredictor(); 
     370                tmp->set_rv ( rv ); 
     371                return tmp; 
     372        } 
     373        //! from_settings 
     374        void from_setting ( const Setting& set ) { 
     375                merger_base::from_setting ( set ); 
     376                set.lookupValue ( "ncoms", Ncoms ); 
     377                set.lookupValue ( "effss_coef", effss_coef ); 
     378                set.lookupValue ( "stop_niter", stop_niter ); 
     379        } 
     380 
     381        //! @} 
    368382 
    369383}; 
    370 UIREGISTER(merger_mix); 
     384UIREGISTER ( merger_mix ); 
    371385 
    372386}