Changeset 1025

Show
Ignore:
Timestamp:
05/31/10 15:55:10 (14 years ago)
Author:
dedecius
Message:

Class implementing partial forgetting in ARX in a way similar to ARXfrg. The ARXpartforg::bayes() method (sh|c)ould be divided into smaller functions in the future(?)

Location:
library/bdm/estim
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • library/bdm/estim/arx.cpp

    r1013 r1025  
    291291        } 
    292292} 
    293 } 
    294  
     293 
     294void ARXpartialforg::bayes ( const vec &val, const vec &cond ) { 
     295    #define LOG2  0.69314718055995 
     296    vec frg = cond.right(cond.length() - rgrlen); 
     297    vec cond_rgr = cond.left(rgrlen);       // regression vector 
     298 
     299    int dimV = est._V().cols(); 
     300    int nparams = dimV - 1;                 // number of parameters 
     301    int nalternatives = pow(2, nparams);    // number of alternatives 
     302     
     303    // Permutation matrix 
     304    mat perm_matrix = ones(nalternatives, nparams); 
     305    int i, j, period, idx_from, idx_to, start, end; 
     306    for(i = 0; i < nparams; i++) { 
     307        idx_from = pow(2, i); 
     308        idx_to = 2 * pow(2, i) - 1; 
     309        period = pow(2, i+1); 
     310        j = 0; 
     311        start = idx_from; 
     312        end = idx_to; 
     313        while(start < pow(2, nparams)) { 
     314            perm_matrix.set_submatrix(start, end, i, i, 0); 
     315            j++; 
     316            start = idx_from + period * j; 
     317            end = idx_to + period * j; 
     318        } 
     319    } 
     320 
     321    // Array of egiws for approximation 
     322    Array<egiw*> egiw_array(nalternatives + 1); 
     323    // No. of conditioning rows in LD 
     324    int nalternatives_cond, position; 
     325 
     326    for(int i = 0; i < nalternatives; i++) { 
     327        // vector defining alternatives 
     328        vec vec_alt = perm_matrix.get_row(i); 
     329 
     330        // full alternative or filtered 
     331        if( sum(vec_alt) == vec_alt.length() )  { 
     332            egiw_array(i) = &alter_est; 
     333            continue; 
     334        } else if( sum(vec_alt) == 0 ) { 
     335            egiw_array(i) = &est; 
     336            continue; 
     337        } 
     338 
     339        nalternatives_cond = sum(vec_alt) + 1; 
     340        ivec vec_perm(0);                   // permutation vector 
     341 
     342        for(int j = 0; j < nparams; j++) { 
     343            position = dimV - j - 2; 
     344            if ( vec_alt(position) == 0 ) { 
     345                vec_perm.ins(j, position + 1); 
     346            } 
     347            else { 
     348                vec_perm.ins(0, position + 1); 
     349            } 
     350        } 
     351        vec_perm.ins(0, 0); 
     352 
     353        ldmat filt (est._V(), vec_perm); 
     354        ldmat alt (alter_est._V(), vec_perm); 
     355 
     356        mat tmpL(dimV, dimV); 
     357        tmpL.set_rows( 0, alt._L().get_rows(0, nalternatives_cond - 1) ); 
     358        tmpL.set_rows( nalternatives_cond, filt._L().get_rows(nalternatives_cond, nparams) ); 
     359 
     360        vec tmpD(dimV); 
     361        tmpD.set_subvector( 0, alt._D()(0, nalternatives_cond - 1) ); 
     362        tmpD.set_subvector( nalternatives_cond, filt._D()(nalternatives_cond, nparams) ); 
     363 
     364        ldmat tmpLD (tmpL, tmpD); 
     365 
     366        vec_perm = sort_index(vec_perm); 
     367        ldmat newLD (tmpLD, vec_perm); 
     368 
     369        egiw_array(i) = new egiw(1, newLD, alter_est._nu()); 
     370    } 
     371 
     372    // Approximation 
     373    double sumVecCommon;                // frequently used term 
     374    vec vecNu(nalternatives);           // vector of nus of components 
     375    vec vecD(nalternatives);            // vector of LS reminders  
     376    vec vecCommon(nalternatives);       // vector of common parts 
     377    mat matVecsTheta;                           // matrix whose rows are theta vects. 
     378 
     379    for (i = 0; i < nalternatives; i++) { 
     380        vecNu.shift_left( egiw_array(i)->_nu() ); 
     381        vecD.shift_left( egiw_array(i)->_V()._D()(0) ); 
     382        matVecsTheta.append_row( egiw_array(i)->est_theta()  ); 
     383    } 
     384 
     385    vecCommon = elem_mult ( frg, elem_div(vecNu, vecD) ); 
     386    sumVecCommon = sum(vecCommon); 
     387 
     388    // approximation of est. regr. coefficients 
     389    vec aprEstTheta(nparams);  aprEstTheta.zeros(); 
     390    for (i = 0; i < nalternatives; i++) { 
     391        aprEstTheta +=  matVecsTheta.get_row(i) * vecCommon(i); 
     392    } 
     393    aprEstTheta /= sumVecCommon; 
     394     
     395    // approximation of degr. of freedom 
     396    double aprNu; 
     397    double A = log( sumVecCommon );             // Term 'A' in equation 
     398    for ( int i = 0; i < nalternatives; i++ ) { 
     399        A += frg(i) * ( log( vecD(i) ) - psi( 0.5 * vecNu(i) ) ); 
     400    } 
     401    aprNu = ( 1 + sqrt(1 + 4 * (A - LOG2)/3 ) ) / ( 2 * (A - LOG2) ); 
     402 
     403    // approximation of LS reminder D(0,0) 
     404    double aprD = aprNu / sumVecCommon; 
     405 
     406    // Aproximation of covariance of LS est. 
     407    mat aprC = zeros(nparams, nparams); 
     408    for ( int i = 0; i < nalternatives; i++ ) { 
     409        aprC += egiw_array(i)->est_theta_cov().to_mat() * frg(i);  
     410        vec tmp = ( matVecsTheta.get_row(i) - aprEstTheta ); 
     411        aprC += vecCommon(i) * outer_product( tmp, tmp); 
     412    } 
     413 
     414    // Construct GiW pdf 
     415    ldmat aprCinv ( inv(aprC) ); 
     416    vec D = concat( aprD, aprCinv._D() ); 
     417    mat L = eye(dimV); 
     418    L.set_submatrix(1, 0, aprCinv._L() * aprEstTheta); 
     419    L.set_submatrix(1, 1, aprCinv._L()); 
     420    ldmat aprLD (L, D); 
     421    est = egiw(1, aprLD, aprNu); 
     422 
     423    // update 
     424    ARX::bayes ( val, cond_rgr ); 
     425} 
     426 
     427} 
     428 
  • library/bdm/estim/arx.h

    r1013 r1025  
    229229 
    230230 
     231/*! 
     232* \brief ARX with partial forgetting 
     233 
     234Implements partial forgetting when <tt>bayes(const vec &yt, const vec &cond=empty_vec)</tt> is called, where \c cond is a vector <em>(regressor', forg.factor')</em>. 
     235 
     236Note, that the weights have the same order as hypotheses, following this scheme: 
     237\li 0 means that the parameter doesn't change, 
     238\li 1 means that the parameter varies. 
     239 
     240The combinations of parameters are described binary: 
     241\f[ 
     242  0, 0, 0\ldots \\ 
     243  1, 0, 0\ldots \\ 
     244  0, 1, 0\ldots \\ 
     245  1, 1, 0\ldots \\ 
     246  \ldots 
     247\f] 
     248where each n-th column has altering 1's and 0's in n-tuples, n = 0,...,number of params. Hence, the first forg. factor relates to the situation when no parameter changes, the second one when the first parameter changes etc. 
     249 
     250See ARX class for more information about ARX. 
     251*/ 
     252class ARXpartialforg : public ARX { 
     253public: 
     254        ARXpartialforg() : ARX(1.0) {}; 
     255        //! copy constructor 
     256        ARXpartialforg ( const ARXpartialforg &A0 ) : ARX ( A0 ) {}; 
     257        virtual ARXpartialforg* _copy() const { 
     258                ARXpartialforg *A = new ARXpartialforg ( *this ); 
     259                return A; 
     260        } 
     261 
     262    void bayes ( const vec &val, const vec &cond );  
     263        void validate() { 
     264                ARX::validate(); 
     265                int philen = pow(2, est._V().cols() - 1); 
     266                rvc.add ( RV ( "{phi }", vec_1(philen) ) ); // pocet 2^parametru 
     267                dimc += philen; 
     268        } 
     269}; 
     270UIREGISTER ( ARXpartialforg ); 
     271 
    231272 
    232273////////////////////