Changeset 156
- Timestamp:
- 04/23/08 15:34:26 (9 months ago)
- Files:
-
- projects/AsynCluster/trunk/svpmc/model.c (modified) (5 diffs)
- projects/AsynCluster/trunk/svpmc/model.py (modified) (8 diffs)
- projects/AsynCluster/trunk/svpmc/test/test_model.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
projects/AsynCluster/trunk/svpmc/model.c
r155 r156 165 165 double L = 0; 166 166 167 py::tuple result(2); 168 167 169 168 170 // For each sample... … … 175 177 for(k1=0; k1<Nz[0]; k1++) { 176 178 // The volatility offset plus the shock... 177 sum = D1(k1) + V2(k 2, k1);179 sum = D1(k1) + V2(k1, k0); 178 180 // ...plus the dot product for the VAR(1) term... 179 181 for(km=0; km<Nz[0]; km++) 180 sum += E2(k1, km) * H2(k 1, k0);182 sum += E2(k1, km) * H2(km, k0); 181 183 // ...is the current log-volatility value 182 184 H2(k1, k0+1) = sum; 183 185 } 184 186 185 187 // Now inverse-scale the innovations for this sample by the square root of 186 188 // the volatilities in preparation for decorrelating the innovations … … 197 199 sum = 0; 198 200 for(km=0; km<Nz[0]; km++) 199 sum += RI2(k1, km) * Y2(k 1, 2);201 sum += RI2(k1, km) * Y2(km, 2); 200 202 // ...is the decorrelated multivariate innovation for this sample, given 201 203 // its log-volatility … … 206 208 // multivariate innovation for this sample, conditional on the just-computed 207 209 // log-volatility h[t]. 208 210 209 211 // For each time series... 210 212 for(k1=0; k1<Nz[0]; k1++) { … … 223 225 L -= 0.5 * H2(k1, k0+1); 224 226 } 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 236 result[1] = L; 237 return_val = result; projects/AsynCluster/trunk/svpmc/model.py
r155 r156 191 191 _logU_index = -1 192 192 193 keyAttrs = {'tsList':None, ' n0':500, 'n3':10}193 keyAttrs = {'tsList':None, 'Mv':100, 'Mz':10} 194 194 paramNames = params.PARAM_NAMES 195 195 … … 242 242 return cv 243 243 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 248 252 def logUniform(self): 249 253 """ … … 261 265 return logU[self._logU_index] 262 266 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 263 278 def logVolatilities(self, z, v, x, h0): 264 279 """ … … 277 292 The method returns a tuple with the total log-likelihood value and the 278 293 computed log-volatility array I{h}. 294 295 CALLS TO THIS METHOD IS WHERE MOST OF THE CPU TIME IS SPENT! 279 296 """ 280 297 # Mostly empty log-volatility array … … 293 310 self.cache['lv_work'] = y, ri 294 311 # 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 308 315 def hybridGibbs(self, z, x, sigma): 309 316 """ … … 316 323 L_total = 0 317 324 if 'hg_work' in self.cache: 318 rv, N v= self.cache['hg_work']325 rv, N = self.cache['hg_work'] 319 326 else: 320 327 # Concurrent cross-correlations between volatility shocks 321 328 rv = s.matrix( 322 329 linalg.cholesky(self.covarMatrix(self.f), lower=True)) 323 N v= 100 # TODO: Use decaySamples()324 self.cache['hg_work'] = rv, N v330 N = 100 # TODO: Use decaySamples() 331 self.cache['hg_work'] = rv, N 325 332 # Initialize volatility shocks from cross-correlation of the IID 326 333 # variates... … … 328 335 # ...and initial log-volatilites, from the offset alone... 329 336 h0 = self.d.copy() 330 # ...and the log-likelihood of the first sample given the current IID331 # variates...332 L = self.logVolatilities(z[:,:N], v[:,:N], x[:,:N], h0)[0]333 337 # ...and a set of random-walk proposals for the IID variates, along 334 338 # with their volatility shocks … … 337 341 # Do conditional draws of each sample in turn 338 342 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 339 349 zpk = s.column_stack([zp[:,k], z[:,k+1:k+N]]) 340 350 vpk = s.column_stack([vp[:,k], v[:,k+1:k+N]]) 341 L p, h= self.logVolatilities(zpk, vpk, x[:,k:k+N], h0)351 LVp = self.logVolatilities(zpk, vpk, x[:,k:k+N], h0) 342 352 # 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 344 355 z[k] = zp[k] 345 356 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] 350 360 return L_total 351 361 projects/AsynCluster/trunk/svpmc/test/test_model.py
r153 r156 21 21 22 22 import scipy as s 23 from scipy import stats, random 23 from scipy import stats, random, linalg 24 24 from scipy.signal import signaltools 25 25 … … 166 166 "'Uncorrelated' hypothesis not disproved, p=%f" % corrInfo[1]) 167 167 168 def _check_xcorr(self, dPeak):169 n = self.model.n170 for j in xrange(20):171 h = self.model.draw_h(0.5)172 # Correlation173 nd = 6174 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 185 168 186 169 class Test_VAR(Multivariate_BaseCase): … … 263 246 264 247 265 class Test_Model_ draw_h(Multivariate_BaseCase):248 class Test_Model_logVolatilities_VAR(Multivariate_BaseCase): 266 249 def setUp(self): 267 250 self.model = model.Model(tsList=util.TS_LIST) 268 251 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 269 262 def test_indep_offset(self): 270 263 n = self.model.n 271 264 self.model.d = s.array([1.0, 1.0]) 272 self.model.f = [0.0]265 self.model.f = s.array([0.0]) 273 266 for j in xrange(10): 274 267 e1, e2 = 0.8*s.rand(2) + 0.1 275 268 self.model.e = s.array([[e1, 0.0], [0.0, e2]]) 276 269 for k in xrange(20): 277 h = self. model.draw_h(0.5)270 h = self._draw_h() 278 271 for m, em in enumerate((e1, e2)): 279 272 ratio = h[m,n/2:].mean() / ( 1.0/(1-em) ) … … 286 279 self.model.e = s.array([[e1, 0.0], [0.0, e2]]) 287 280 self.model.f = [0.0] 288 for j in xrange(20): 289 h = self.model.draw_h(0.5) 281 h = self._draw_h() 290 282 # Uncorrelated 291 283 self._check_uncorr(h[0,:], h[1,:]) … … 301 293 sp.plot(h[k,:]) 302 294 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 303 311 def test_xcorr_var(self): 304 312 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]]) 306 314 self.model.f = [0.0] 307 315 self._check_xcorr(1)
