Changeset 156

Show
Ignore:
Timestamp:
04/23/08 15:34:26 (8 months ago)
Author:
edsuom
Message:

Working on Model.logLikelihood: VAR process tested

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • projects/AsynCluster/trunk/svpmc/model.c

    r155 r156  
    165165double L = 0; 
    166166 
     167py::tuple result(2); 
     168 
    167169 
    168170// For each sample... 
     
    175177  for(k1=0; k1<Nz[0]; k1++) { 
    176178    // The volatility offset plus the shock... 
    177     sum = D1(k1) + V2(k2, k1); 
     179    sum = D1(k1) + V2(k1, k0); 
    178180    // ...plus the dot product for the VAR(1) term... 
    179181    for(km=0; km<Nz[0]; km++) 
    180       sum += E2(k1, km) * H2(k1, k0); 
     182      sum += E2(k1, km) * H2(km, k0); 
    181183    // ...is the current log-volatility value 
    182184    H2(k1, k0+1) = sum; 
    183185  } 
    184      
     186   
    185187  // Now inverse-scale the innovations for this sample by the square root of 
    186188  // the volatilities in preparation for decorrelating the innovations 
     
    197199    sum = 0; 
    198200    for(km=0; km<Nz[0]; km++) 
    199       sum += RI2(k1, km) * Y2(k1, 2); 
     201      sum += RI2(k1, km) * Y2(km, 2); 
    200202    // ...is the decorrelated multivariate innovation for this sample, given 
    201203    // its log-volatility 
     
    206208  // multivariate innovation for this sample, conditional on the just-computed 
    207209  // log-volatility h[t]. 
    208        
     210   
    209211  // For each time series... 
    210212  for(k1=0; k1<Nz[0]; k1++) { 
     
    223225    L -= 0.5 * H2(k1, k0+1); 
    224226  } 
    225 
    226  
    227 // The return value is the total log-volatility 
    228 return_val = L; 
     227 
     228  // The probability density, on its own, of the first log-volatility sample is 
     229  // proportional to the probability density of the innovation for that sample 
     230  // given the log-volatility. So we'll be returning that value, too. 
     231  if(k0 == 0) 
     232    result[0] = L; 
     233
     234 
     235// Return the first log-likelihood along with the total of the log-likelihoods 
     236result[1] = L; 
     237return_val = result; 
  • projects/AsynCluster/trunk/svpmc/model.py

    r155 r156  
    191191    _logU_index = -1 
    192192 
    193     keyAttrs = {'tsList':None, 'n0':500, 'n3':10} 
     193    keyAttrs = {'tsList':None, 'Mv':100, 'Mz':10} 
    194194    paramNames = params.PARAM_NAMES 
    195195 
     
    242242        return cv 
    243243 
    244     def decaySamples(self, tol): 
    245         """ 
    246         """ 
    247  
     244    def decaySamples(self, x, tol): 
     245        """ 
     246        Returns the number of samples needed for the effect of an impulse to 
     247        the VAR(1) process having the supplied lag-1 correlation matrix I{x} to 
     248        decay below I{tol}. 
     249        """ 
     250        return s.ceil(s.log(tol) / s.log(x.diagonal())).max() 
     251     
    248252    def logUniform(self): 
    249253        """ 
     
    261265        return logU[self._logU_index] 
    262266 
     267    def zProposal(self, z, sigma): 
     268        """ 
     269        Does a random walk from the supplied 2-D array I{z} of normal random 
     270        variates, using a symmetric normal proposal distribution with standard 
     271        deviation I{sigma}. 
     272        """ 
     273        z = z.copy() 
     274        self.inline( 
     275            'z', 'M', 'wiggle', M=self.Mz, wiggle=sigma/s.sqrt(self.Mz)) 
     276        return z 
     277     
    263278    def logVolatilities(self, z, v, x, h0): 
    264279        """ 
     
    277292        The method returns a tuple with the total log-likelihood value and the 
    278293        computed log-volatility array I{h}. 
     294 
     295        CALLS TO THIS METHOD IS WHERE MOST OF THE CPU TIME IS SPENT! 
    279296        """ 
    280297        # Mostly empty log-volatility array 
     
    293310            self.cache['lv_work'] = y, ri 
    294311        # Run the C code where the heavy lifting is done 
    295         L = self.inline( 
    296             'z', 'v', 'x', 'h', 
    297             'ri', 'y', 'd', 'e', 'g') 
    298         return L, h[:,1:] 
    299  
    300     def zProposal(self, z, sigma): 
    301         """ 
    302         """ 
    303         z = z.copy() 
    304         self.inline( 
    305             'z', 'M', 'wiggle', M=self.Mz, wiggle=sigma/s.sqrt(self.Mz)) 
    306         return z 
    307      
     312        L0, L = self.inline('z', 'v', 'x', 'h', 'ri', 'y', 'd', 'e', 'g') 
     313        return L0, L, h[:,1:] 
     314 
    308315    def hybridGibbs(self, z, x, sigma): 
    309316        """ 
     
    316323        L_total = 0 
    317324        if 'hg_work' in self.cache: 
    318             rv, Nv = self.cache['hg_work'] 
     325            rv, N = self.cache['hg_work'] 
    319326        else: 
    320327            # Concurrent cross-correlations between volatility shocks 
    321328            rv = s.matrix( 
    322329                linalg.cholesky(self.covarMatrix(self.f), lower=True)) 
    323             Nv = 100 # TODO: Use decaySamples() 
    324             self.cache['hg_work'] = rv, Nv 
     330            N = 100 # TODO: Use decaySamples() 
     331            self.cache['hg_work'] = rv, N 
    325332        # Initialize volatility shocks from cross-correlation of the IID 
    326333        # variates... 
     
    328335        # ...and initial log-volatilites, from the offset alone... 
    329336        h0 = self.d.copy() 
    330         # ...and the log-likelihood of the first sample given the current IID 
    331         # variates... 
    332         L = self.logVolatilities(z[:,:N], v[:,:N], x[:,:N], h0)[0] 
    333337        # ...and a set of random-walk proposals for the IID variates, along 
    334338        # with their volatility shocks 
     
    337341        # Do conditional draws of each sample in turn 
    338342        for k in xrange(self.n): 
     343            # We need to compare the current and proposed log-volatilities for 
     344            # this sample, given the previous log-volatility sample 
     345 
     346            # Current 
     347            LV = self.logVolatilities(z[:,k:k+N], v[:,k:k+N], x[:,k:k+N], h0) 
     348            # Proposal 
    339349            zpk = s.column_stack([zp[:,k], z[:,k+1:k+N]]) 
    340350            vpk = s.column_stack([vp[:,k], v[:,k+1:k+N]]) 
    341             Lp, h = self.logVolatilities(zpk, vpk, x[:,k:k+N], h0) 
     351            LVp = self.logVolatilities(zpk, vpk, x[:,k:k+N], h0) 
    342352            # Metropolis-Hastings accept/reject of the proposal 
    343             if Lp > L or (Lp-L) > self.logUniform(): 
     353            if LVp[1] > LV[1] or LVp[1] - LV[1] > self.logUniform(): 
     354                LV = LVp 
    344355                z[k] = zp[k] 
    345356                v[k] = vp[k] 
    346                 h0 = h[0] 
    347             # Add the log-likelihood of the drawn log-volatility sample to the 
    348             # overall tally 
    349             L_total += L 
     357            # Update stuff for the next sample 
     358            h0 = LV[2][0] 
     359            L_total += LV[0] 
    350360        return L_total 
    351361     
  • projects/AsynCluster/trunk/svpmc/test/test_model.py

    r153 r156  
    2121 
    2222import scipy as s 
    23 from scipy import stats, random 
     23from scipy import stats, random, linalg 
    2424from scipy.signal import signaltools 
    2525 
     
    166166                "'Uncorrelated' hypothesis not disproved, p=%f" % corrInfo[1]) 
    167167     
    168     def _check_xcorr(self, dPeak): 
    169         n = self.model.n 
    170         for j in xrange(20): 
    171             h = self.model.draw_h(0.5) 
    172         # Correlation 
    173         nd = 6 
    174         d = s.arange(-nd, nd+1) 
    175         r = s.array( 
    176             [s.correlate(h[0,nd+lag:n-nd+lag], h[1,nd:n-nd])[0] for lag in d]) 
    177         lagMetric = r[nd+dPeak] / \ 
    178                     max(s.concatenate([r[:nd+dPeak], r[nd+dPeak:]])) 
    179         self.failUnless(lagMetric < 10) 
    180         if VERBOSE: 
    181             sp = self.fig.add_subplot(111) 
    182             sp.plot(d, r, 'o-') 
    183             sp.grid(True) 
    184      
    185168 
    186169class Test_VAR(Multivariate_BaseCase): 
     
    263246 
    264247 
    265 class Test_Model_draw_h(Multivariate_BaseCase): 
     248class Test_Model_logVolatilities_VAR(Multivariate_BaseCase): 
    266249    def setUp(self): 
    267250        self.model = model.Model(tsList=util.TS_LIST) 
    268251 
     252    def _draw_h(self): 
     253        self.model.c = s.array([0.0]) 
     254        self.model.g = s.array([0.0]) 
     255        z = s.randn(self.model.p, self.model.n) 
     256        rv = s.matrix( 
     257            linalg.cholesky(self.model.covarMatrix(self.model.f), lower=True)) 
     258        v = s.array(rv * z) 
     259        return self.model.logVolatilities( 
     260            z, v, s.zeros_like(z), self.model.d.copy())[2] 
     261     
    269262    def test_indep_offset(self): 
    270263        n = self.model.n 
    271264        self.model.d = s.array([1.0, 1.0]) 
    272         self.model.f = [0.0] 
     265        self.model.f = s.array([0.0]) 
    273266        for j in xrange(10): 
    274267            e1, e2 = 0.8*s.rand(2) + 0.1 
    275268            self.model.e = s.array([[e1, 0.0], [0.0, e2]]) 
    276269            for k in xrange(20): 
    277                 h = self.model.draw_h(0.5
     270                h = self._draw_h(
    278271            for m, em in enumerate((e1, e2)): 
    279272                ratio = h[m,n/2:].mean() /  ( 1.0/(1-em) ) 
     
    286279        self.model.e = s.array([[e1, 0.0], [0.0, e2]]) 
    287280        self.model.f = [0.0] 
    288         for j in xrange(20): 
    289             h = self.model.draw_h(0.5) 
     281        h = self._draw_h() 
    290282        # Uncorrelated 
    291283        self._check_uncorr(h[0,:], h[1,:]) 
     
    301293            sp.plot(h[k,:]) 
    302294 
     295    def _check_xcorr(self, dPeak): 
     296        n = self.model.n 
     297        h = self._draw_h() 
     298        # Correlation 
     299        nd = 6 
     300        d = s.arange(-nd, nd+1) 
     301        r = s.array( 
     302            [s.correlate(h[0,nd+lag:n-nd+lag], h[1,nd:n-nd])[0] for lag in d]) 
     303        lagMetric = r[nd+dPeak] / \ 
     304                    max(s.concatenate([r[:nd+dPeak], r[nd+dPeak:]])) 
     305        self.failUnless(lagMetric < 10) 
     306        if VERBOSE: 
     307            sp = self.fig.add_subplot(111) 
     308            sp.plot(d, r, 'o-') 
     309            sp.grid(True) 
     310 
    303311    def test_xcorr_var(self): 
    304312        self.model.d = s.array([0.0, 0.0]) 
    305         self.model.e = s.array([[0.0, 0.5], [0.0, 0.0]]) 
     313        self.model.e = s.array([[0.0, 0.9], [0.0, 0.0]]) 
    306314        self.model.f = [0.0] 
    307315        self._check_xcorr(1)