Show
Ignore:
Timestamp:
09/18/09 00:17:11 (15 years ago)
Author:
smidl
Message:

egiw.variance works for multidimensional + cleanup in tests

Files:
1 modified

Legend:

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

    r565 r629  
    1717        this->bayes ( dt, 1.0 ); 
    1818}; 
     19 
     20void egiw::set_parameters (int dimx0, ldmat V0, double nu0) { 
     21        dimx = dimx0; 
     22        nPsi = V0.rows() - dimx; 
     23        dim = dimx * (dimx + nPsi); // size(R) + size(Theta) 
     24         
     25        V = V0; 
     26        if (nu0 < 0) { 
     27                nu = 0.1 + nPsi + 2 * dimx + 2; // +2 assures finite expected value of R 
     28                // terms before that are sufficient for finite normalization 
     29        } else { 
     30                nu = nu0; 
     31        } 
     32} 
    1933 
    2034vec egiw::sample() const { 
     
    119133                mat R; 
    120134                mean_mat ( M, R ); 
    121                 return cvectorize ( concat_vertical ( M, R ) ); 
     135                return concat( cvectorize (  M),cvectorize( R ) ); 
    122136        } 
    123137 
     
    125139 
    126140vec egiw::variance() const { 
    127  
     141        int l = V.rows(); 
     142        // cut out rest of lower-right part of V 
     143        const ldmat tmp ( V, linspace ( dimx, l - 1 ) ); 
     144        // invert it 
     145        ldmat itmp ( l ); 
     146        tmp.inv ( itmp ); 
     147         
     148        // following Wikipedia notation 
     149        // m=nu-nPsi-dimx-1, p=dimx  
     150        double mp1p=nu-nPsi-2*dimx; // m-p+1 
     151        double mp1m=mp1p-2;         // m-p-1 
     152         
    128153        if ( dimx == 1 ) { 
    129                 int l = V.rows(); 
    130                 const ldmat tmp ( V, linspace ( 1, l - 1 ) ); 
    131                 ldmat itmp ( l ); 
    132                 tmp.inv ( itmp ); 
    133                 double cove = V._D() ( 0 ) / ( nu - nPsi - 2 * dimx - 2 ); 
     154                double cove = V._D() ( 0 ) / mp1m ; 
    134155 
    135156                vec var ( l ); 
    136157                var.set_subvector ( 0, diag ( itmp.to_mat() ) *cove ); 
    137                 var ( l - 1 ) = cove * cove / ( nu - nPsi - 2 * dimx - 2 ); 
     158                var ( l - 1 ) = cove * cove / (mp1m-2); 
    138159                return var; 
    139160        } else { 
    140                 bdm_error ( "not implemented" ); 
    141                 return vec(); 
     161                ldmat Vll( V, linspace(0,dimx-1)); // top-left part of V 
     162                mat Y=Vll.to_mat(); 
     163                mat varY(Y.rows(), Y.cols());  
     164                 
     165                double denom = (mp1p-1)*mp1m*mp1m*(mp1m-2);         // (m-p)(m-p-1)^2(m-p-3) 
     166                 
     167                int i,j; 
     168                for ( i=0; i<Y.rows(); i++){ 
     169                        for ( j=0; j<Y.cols(); j++){ 
     170                                varY(i,j) = (mp1p*Y(i,j)*Y(i,j) + mp1m * Y(i,i)* Y(j,j)) /denom; 
     171                        } 
     172                } 
     173                vec mean_dR = diag(Y)/mp1m; // corresponds to cove 
     174                vec var_th=diag ( itmp.to_mat() ); 
     175                vec var_Th ( mean_dR.length()*var_th.length() ); 
     176                // diagonal of diag(mean_dR) \kron diag(var_th) 
     177                for (int i=0; i<mean_dR.length(); i++){ 
     178                        var_Th.set_subvector(i*var_th.length(), var_th*mean_dR(i));   
     179                } 
     180                 
     181                return concat(var_Th, cvectorize(varY)); 
    142182        } 
    143183}