Changeset 189
- Timestamp:
- 05/21/08 18:16:16 (7 months ago)
- Files:
-
- projects/AsynCluster/trunk/svpmc/model.c (modified) (15 diffs)
- projects/AsynCluster/trunk/svpmc/model.py (modified) (2 diffs)
- projects/AsynCluster/trunk/svpmc/test/test_model.py (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
projects/AsynCluster/trunk/svpmc/model.c
r188 r189 128 128 { 129 129 int kp; 130 double L h;130 double Lp; 131 131 }; 132 132 … … 250 250 251 251 252 // Returns with zero only if the p ost-first proposals are close enough to253 // finishlikelihood computation254 int notCloseEnough(struct sample sp[] [2], int n)252 // Returns with zero only if the proposals are close enough to finish 253 // likelihood computation 254 int notCloseEnough(struct sample sp[], int n) 255 255 { 256 256 int k; … … 259 259 double Lmax = -HUGE_VAL; // Anything will be more positive 260 260 for(k=0; k<n; k++) { 261 L = sp[k] [1].L_diff;261 L = sp[k].L_diff; 262 262 if(L < Lmin) 263 263 Lmin = L; … … 276 276 // the log-probability of the proposal's having been selected. 277 277 struct selection \ 278 importanceSample(struct sample sp[] [2], double Lz[], int n)279 { 280 int k , kpMax;278 importanceSample(struct sample sp[], double Lz[], int n) 279 { 280 int k; 281 281 double val; 282 282 double Lp[n], Dp[n]; 283 double L_min = +HUGE_VAL; // Anything will be more negative 284 double pMax = -HUGE_VAL; // Anything will be more positive 283 double L_max = -HUGE_VAL; // Anything will be more positive 285 284 struct selection result; 286 285 287 286 // Normalize log-densities to prevent overflow 288 287 for(k=0; k<n; k++) { 289 val = sp[k] [1].Lx + Lz[k];290 if(val < L_min)291 L_m in= val;288 val = sp[k].Lx + Lz[k]; 289 if(val > L_max) 290 L_max = val; 292 291 Lp[k] = val; 293 292 } 294 293 295 // Compute linear probability density for each proposal and their maximum 296 for(k=0; k<n; k++) { 297 val = exp(Lp[k] - L_min); 298 Dp[k] = val; 299 if(val > pMax) { 300 pMax = val; 301 kpMax = k; 302 } 303 } 294 // Compute linear probability density for each proposal, relative to the 295 // maximum one 296 for(k=0; k<n; k++) 297 Dp[k] = exp(Lp[k] - L_max); 304 298 305 299 // Accept-reject sampling with uniform random proposal selection … … 309 303 // ...until the selected proposal is accepted, with probability 310 304 // proportional to its relative weight 311 } while( result.kp != kpMax && uniform(0, pMax) > Dp[result.kp]);305 } while(uniform(0, 1.0) > Dp[result.kp]); 312 306 313 307 // The probability density of the selected log-volatility proposal is just 314 308 // the linear, unnormalized weight of the selected sample 315 result.L h= Lp[result.kp];309 result.Lp = Lp[result.kp]; 316 310 return result; 317 311 } … … 329 323 // h Simulated last-sample multivariate log-volatility, [p] (overwritten) 330 324 // w Wiggle value for +/- proposals (float) 331 // n Number of proposals to try per time-series sample (int) 325 // np Number of proposals to try per log-volatility simulation (int) 326 // ne Max number of time-series samples to evaluate per proposal (int) 332 327 333 328 //--- Model parameters, direct --- … … 351 346 const int Ns = Nz[1]; 352 347 353 int notFirst;354 348 int k0, k1, k2, k3; 355 349 double val, L_diff; … … 359 353 // Multivariate innovation for one current time-series sample 360 354 double *xk; 361 // Log probability density of each proposal on z 362 double Lz[n]; 355 // The value of z and h for each proposal, at the first time-series sample of 356 // the evaluation interval 357 double zp[np], hp[np][Nt]; 358 // Log probability density of the value of z for each proposal 359 double Lz[np]; 360 // Log-likelihood of the innovation for the first time-series sample in 361 // proposal evalutions, for each proposal 362 double Lxk[np]; 363 363 364 364 // A struct for the result of the importance-sampling function 365 365 struct selection spSelection; 366 // Two sets of proposal sample structs, one for the first time-series sample in 367 // each log-volatility computation (from which the innovation's log-volatility 368 // is computed) and another for all time-series samples thereafter. 369 struct sample sp[n][2]; 366 // A set of proposal sample structs 367 struct sample sp[np]; 370 368 // A struct for the model parameters 371 369 struct parameters P; … … 378 376 P.rz = rz_array; P.ri = ri_array; P.sc = sc_array; 379 377 380 // Initialize various stuff 381 xk = (double *) calloc(sizeof(double), Nt); 382 for(k0=0; k0<n; k0++) { 383 for(k1=0; k1<2; k1++) { 384 sp[k0][k1].Lx = 0; 385 sp[k0][k1].z = (double *) malloc(sizeof(double) * Nt); 386 sp[k0][k1].h = (double *) malloc(sizeof(double) * Nt); 387 sp[k0][k1].x0 = (double *) malloc(sizeof(double) * Nt); 388 sp[k0][k1].x1 = (double *) malloc(sizeof(double) * Nt); 389 } 378 // Initialize various arrays 379 xk = (double *) malloc(sizeof(double) * Nt); 380 for(k0=0; k0<np; k0++) { 381 sp[k0].z = (double *) malloc(sizeof(double) * Nt); 382 sp[k0].h = (double *) malloc(sizeof(double) * Nt); 383 sp[k0].x0 = (double *) malloc(sizeof(double) * Nt); 384 sp[k0].x1 = (double *) malloc(sizeof(double) * Nt); 390 385 // The "previous" log-volatility of the first time-series sample is set to 391 386 // the log-volatility offset. … … 393 388 // TODO: Treat it as another latent parameter and simulate its value 394 389 for(k1=0; k1<Nt; k1++) 395 PA1(sp[k0] [0].h, k1) = D1(k1);390 PA1(sp[k0].h, k1) = D1(k1); 396 391 } 397 392 … … 399 394 for(k0=0; k0<Ns; k0++) { 400 395 401 // Simulate n sets of h samples from separate proposals on z until a 402 // substantially common-valued sample is reached 396 // Simulate np sets of h samples from separate proposals on z from the 397 // current time-series sample to some subsequent time-series sample at which 398 // the log-likelihood of the innovation for that sample becomes substantially 399 // the same for all proposals. 403 400 404 401 k1 = k0; 405 notFirst = 0; 402 403 // Clear the log-likelihood accumulator of each proposal struct for the next 404 // proposal evalution 405 for(k2=0; k2<np; k2++) 406 sp[k2].Lx = 0; 406 407 407 408 do { … … 411 412 PA1(xk, k2) = X2(k2, k1); 412 413 413 // Set z for the set of sample structs... 414 for(k2=0; k2<n; k2++) { 414 // For each proposal... 415 for(k2=0; k2<np; k2++) { 416 417 // Set z... 415 418 for(k3=0; k3<Nt; k3++) { 416 419 val = Z2(k3, k1); 417 if( !notFirst) {420 if(k1==k0) { 418 421 // First time-series sample, use a proposal on z instead of z itself 419 422 val += uniform(-w, +w); 423 zp[k2] = val; 420 424 Lz[k2] = normLogDensity(val); 421 425 } 422 PA1(sp[k2] [notFirst].z, k3) = val;426 PA1(sp[k2].z, k3) = val; 423 427 } 424 } 425 // ...compute their log-volatilities 426 for(k2=0; k2<n; k2++) 427 logVol(&sp[k2][notFirst], &P); 428 // ...and the log-likelihood of the innovation for this time-series sample, 429 // for each proposal on z and its log-volatility 430 val = 0; 431 for(k2=0; k2<n; k2++) { 432 logLikelihood(&sp[k2][notFirst], &P, xk); 433 } 434 435 if(k1==k0) { 436 // Next will be the second time-series sample... 437 notFirst = 1; 438 // ...and will be starting with copy of h arrays from proposal structs 439 // for the just-completed first time-series sample 440 for(k2=0; k2<n; k2++) { 428 // ...compute the multivariate log-volatility 429 logVol(&sp[k2], &P); 430 // ...and the log-likelihood of the innovation for this time-series 431 // sample, given the log-volatility 432 logLikelihood(&sp[k2], &P, xk); 433 434 // Save the first log-volatility and the log-likelihood based on it (and 435 // it alone, at this point) as the log-likelihood of the innovation given 436 // the log-volatility of the proposal 437 if(k1==k0) { 441 438 for(k3=0; k3<Nt; k3++) 442 PA1(sp[k2][1].h, k3) = PA1(sp[k2][0].h, k3); 439 hp[k2][k3] = PA1(sp[k2].h, k3); 440 Lxk[k2] = sp[k2].Lx; 443 441 } 444 442 } … … 447 445 k1++; 448 446 449 } while (k1<Ns && (k1==k0+1 || notCloseEnough(sp, n)));447 } while (k1<Ns && k1<k0+ne); 450 448 451 449 // Importance sample proposal using pProb=exp(Lz+Lx) for each... 452 spSelection = importanceSample(sp, Lz, n); 450 spSelection = importanceSample(sp, Lz, np); 451 // ...add the log-likelihood of the innovation given the selected 452 // log-volatility proposal to what will be the total log-likelihood of the 453 // innovations given the entire simulated h... 454 Lx += Lxk[spSelection.kp]; 453 455 // ...add the log-density of the selected log-volatility proposal to what 454 456 // will be the total log-density of the entire simulated h... 455 Lh += spSelection.L h;456 // ...and update the normal variate underlying the cur ent time-series sample457 Lh += spSelection.Lp; 458 // ...and update the normal variate underlying the current time-series sample 457 459 // to that on which the selected log-volatility proposal was based. 458 460 for(k1=0; k1<Nt; k1++) 459 Z2(k1, k0) = PA1(sp[spSelection.kp][0].z, k1);460 461 Z2(k1, k0) = zp[spSelection.kp]; 462 461 463 //--- DEBUG ----------------------------------------------------------------- 462 printf("\n%d %d\n---------------------------\n",k0, spSelection.kp);463 for(k1=0; k1<n; k1++)464 printf("%d %f %f\n", k1, sp[k1][1].Lx, Lz[k1]);464 //printf("\n%d %d\n---------------------------\n",k0, spSelection.kp); 465 //for(k1=0; k1<n; k1++) 466 // printf("%d %f %f\n", k1, Lxk[k1], sp[k1].Lx); 465 467 //--------------------------------------------------------------------------- 466 468 … … 469 471 // sample. 470 472 for(k1=0; k1<Nt; k1++) { 471 val = PA1(sp[spSelection.kp][1].h, k1); 472 for(k2=0; k2<n; k2++) 473 PA1(sp[k2][0].h, k1) = val; 474 } 475 476 // Add the log-likelihood of this time-series sample's innovation to the 477 // running total and clear the Lx accumulators for the next time-series 478 // sample 479 for(k1=0; k1<Nt; k1++) { 480 Lx += sp[k1][0].Lx; 481 sp[k1][0].Lx = 0; 482 sp[k1][1].Lx = 0; 473 val = hp[spSelection.kp][k1]; 474 for(k2=0; k2<np; k2++) 475 PA1(sp[k2].h, k1) = val; 483 476 } 484 477 … … 489 482 // sample 490 483 for(k0=0; k0<Nt; k0++) 491 H1(k0) = PA1(sp[spSelection.kp] [1].h, k0);484 H1(k0) = PA1(sp[spSelection.kp].h, k0); 492 485 493 486 // Free array memory 494 487 free(xk); 495 for(k0=0; k0<n; k0++) { 496 for(k1=0; k1<2; k1++) { 497 free(sp[k0][k1].z); 498 free(sp[k0][k1].h); 499 free(sp[k0][k1].x0); 500 free(sp[k0][k1].x1); 501 } 488 for(k0=0; k0<np; k0++) { 489 free(sp[k0].z); 490 free(sp[k0].h); 491 free(sp[k0].x0); 492 free(sp[k0].x1); 502 493 } 503 494 projects/AsynCluster/trunk/svpmc/model.py
r188 r189 294 294 # ...scaling constants for multivariate normal pdf 295 295 sc = s.empty((self.p, 2)) 296 sc[:,0] = s.sqrt(1 - self.g**2)296 sc[:,0] = s.sqrt(1.0 - self.g**2) 297 297 sc[:,1] = s.log(s.sqrt(2*s.pi) * sc[:,0]) 298 298 … … 301 301 Lx = 0 302 302 Lh = 0 303 for name in ('z', 'h', 'x', 304 'w', 'np', 'ne', 305 'd', 'e', 'g', 'rz', 'ri', 'sc'): 306 print name, locals().get(name, getattr(self, name, "-")) 307 303 308 for k in xrange(self.N2): 304 309 result = self.inline( 305 'z', 'h', 'x', 'w', 'n', 'd', 'e', 'g', 'rz', 'ri', 'sc', 306 w=self.wiggle, n=self.N1) 307 print k, result 310 'z', 'h', 'x', 311 'w', 'np', 'ne', 312 'd', 'e', 'g', 'rz', 'ri', 'sc', 313 w=self.wiggle, np=self.N1, ne=2) 308 314 Lx += result[0] 309 315 Lh += result[1] projects/AsynCluster/trunk/svpmc/test/test_model.py
r188 r189 510 510 int k; 511 511 const int n = NX[0]; 512 struct sample sp[n] [2];512 struct sample sp[n]; 513 513 for(k=0; k<n; k++) { 514 sp[k] [1].L_diff = X1(k);515 sp[k] [1].Lx = X1(k);514 sp[k].L_diff = X1(k); 515 sp[k].Lx = X1(k); 516 516 } 517 517 """ … … 529 529 spSelection = importanceSample(sp, Lz, n); 530 530 result[0] = spSelection.kp; 531 result[1] = spSelection.L h;531 result[1] = spSelection.Lp; 532 532 return_val = result; 533 533 """ … … 578 578 corr = 0.0 579 579 params = { 580 'a': [0 ],581 'b': [[0 ]],580 'a': [0.0], 581 'b': [[0.0]], 582 582 'cr': [], 583 'd': [0 ],584 'e': [[0 ]],583 'd': [0.0], 584 'e': [[0.0]], 585 585 'fs': [1.0], 586 586 'fr': [], … … 588 588 } 589 589 590 def _z_to_h(self, z, eValue, fsValue ):590 def _z_to_h(self, z, eValue, fsValue=1.0): 591 591 """ 592 592 Runs the volatility shocks through a VAR(1) to get simulated … … 595 595 return signal.lfilter([1], [1.0, -eValue], fsValue*z) 596 596 597 def _x_to_y(self, x, aValue , bValue):597 def _x_to_y(self, x, aValue=0.0, bValue=1.0): 598 598 """ 599 599 Runs the innovations through a VAR(1) to get simulated 600 600 observations. 601 601 """ 602 return signal.lfilter([1], [1.0, -bValue], x) + aValue * s.ones_like(x) 602 return s.row_stack([ 603 signal.lfilter([1], [1.0, -bValue], x) + aValue * s.ones_like(x)]) 603 604 604 605 def _simData(self, Ns, eValue, gValue=0, fsValue=1): … … 626 627 s.array(kw.get(name, self.params[name]), dtype='d')) 627 628 # Return the parameter container along with a model to be tested 628 modelObj = model.Model( N1=N1, N2=N2)629 modelObj = model.Model() 629 630 modelObj.paramNames = util.PARAM_NAMES 630 modelObj.y = s.row_stack([y]) 631 modelObj.N1=N1 632 modelObj.N2=N2 631 633 return pc, modelObj 632 634 633 def _check(self, x, zReal, zSim, eValue, fsValue=1.0): 634 # Reconstruct simulated h from z 635 hSim = self._z_to_h(zSim, e, fs) 636 hReal = self._z_to_h(zReal, e, fs) 637 if VERBOSE: 638 fig = self.fig 639 vectors = (x, (zReal, zSim), (hReal, hSim)) 640 for k, vector in enumerate(vectors): 641 spNumber = 100*len(vectors) + k + 11 642 sp = fig.add_subplot(spNumber) 643 if not isinstance(vector, (tuple, list)): 644 vector = [vector] 645 for v in vector: 646 sp.plot(v) 647 self._check_corr(hReal, hSim) 648 649 def _likelihood(self, x, eValue, wiggle, N1, N2): 635 def _plot(self, *vectors): 636 fig = self.fig 637 for k, vector in enumerate(vectors): 638 spNumber = 100*len(vectors) + k + 11 639 sp = fig.add_subplot(spNumber) 640 if not isinstance(vector, (tuple, list)): 641 vector = [vector] 642 for v in vector: 643 sp.plot(v) 644 sp.grid(True) 645 646 def _likelihood(self, eValue, wiggle, Ns, Nr, N1, N2, Ne): 650 647 """ 651 648 Runs C code for L{model.Model.likelihood} independent of the method 652 649 itself. 653 650 """ 654 z = s.zeros((1, len(x))) 655 zAll = s.empty((N2, len(x))) 651 z = s.zeros((1, Ns)) 656 652 kw = { 657 653 'h':s.empty(1), 658 654 'sc':s.array([1, s.log(s.sqrt(2*s.pi))]), 659 655 'z':z, 660 'x':s.row_stack([x]),661 656 'w':wiggle, 662 'n':N1, 657 'np':N1, 658 'ne':Ne, 663 659 'd':s.array([0.0]), 664 660 'e':s.array([[float(eValue)]]), … … 668 664 } 669 665 modelObj = model.Model() 670 Lx = s.empty(N2) 671 Lh = s.empty(N2) 672 for k in xrange(N2): 673 result = modelObj.inlineDirect(modelObj.code['likelihood'], **kw) 674 Lx[k] = result[0] 675 Lh[k] = result[1] 676 zAll[k,:] = z.copy() 677 return Lx, Lh, zAll 666 for j in xrange(Nr): 667 iv, hReal, x = self._simData(Ns, eValue) 668 kw['x'] = s.row_stack([x]) 669 for k in xrange(N2): 670 modelObj.inlineDirect(modelObj.code['likelihood'], **kw) 671 hSim = self._z_to_h(z[0,:], eValue, 1.0) 672 yield hReal, hSim 678 673 679 674 def test_basic(self): 680 675 wiggle = 0.1 681 676 eValue = 0.90 682 Ns, N1, N2 = 3, 5, 10683 x = 2 .0*s.ones(Ns)677 Ns, N1, N2 = 10, 5, 20 678 x = 2*s.ones(Ns) 684 679 Lx, Lh, zSim = self._likelihood(x, eValue, wiggle, N1, N2) 685 #fig = self.fig686 #fig.add_subplot(211).plot(Lx)687 #fig.add_subplot(212).plot(Lh)688 680 print "\nk Lx Lh Simulated Volatility Shocks" 689 681 print "-"*100 690 682 for k, z in enumerate(zSim): 691 683 zLine = " ".join(["%+4.2f" % xx for xx in z]) 692 print "%d: %+5.1f %+6.1f%s%s" % (k, Lx[k], Lh[k], " "*5, zLine) 693 684 print "%3d: %+5.1f %+6.1f%s%s" % (k, Lx[k], Lh[k], " "*5, zLine) 685 686 def test_highCorrelation_h(self): 687 Ne = 2 688 wiggle = 3.0 689 eValue = 0.99 690 Ns, N1, N2 = 200, 20, 1 691 for hReal, hSim in self._likelihood(eValue, wiggle, Ns, 1, N1, N2, Ne): 692 self._plot((hReal, hSim)) 693 694 def test_highCorrelation_correlation(self): 695 # Empirically, it looks like Ne=2 is best (possibly Ne=3, but why?) 696 Ne = 2 697 Nr = 10000 698 wiggle = 3.0 699 eValue = 0.99 700 Ns, N1, N2 = 200, 20, 1 701 correlations = [] 702 for hReal, hSim in self._likelihood(eValue, wiggle, Ns, Nr, N1, N2, Ne): 703 corrInfo = stats.spearmanr(hReal, hSim) 704 if VERBOSE: 705 print corrInfo[0] 706 correlations.append(corrInfo[0]) 707 #self.failUnless(corrInfo[0] > 0.8) 708 sp = self.fig.add_subplot(111) 709 sp.hist(s.array(correlations)) 710 sp.set_title("Ne=%d" % Ne) 711 #self._check(x, iv[1,:], zSim[-1,:], eValue) 712 694 713 def test_highCorrelation_model(self): 695 wiggle = 0.1714 wiggle = 3.0 696 715 eValue = 0.95 697 Ns, N1, N2 = 1000, 10, 100716 Ns, N1, N2 = 300, 20, 1 698 717 iv, h, x = self._simData(Ns, eValue) 699 pc, modelObj = self._modelAndParamFactory(wiggle, Ns, N1, N2, e=[[0.95]]) 718 pc, modelObj = self._modelAndParamFactory( 719 wiggle, Ns, N1, N2, e=[[eValue]]) 720 pc.z = s.zeros((1, Ns)) 700 721 modelObj.y = self._x_to_y(x) 701 722 Lx, Lh, z, hn = modelObj.likelihood(pc) 702 self._check(x, iv[1,:], z[0,:], eValue) 703 704 def test_hybridGibbs_lowCorrelation(self): 705 self._setupModel(e=[[0.4]]) 706 self._runHG(20, 0.5) 707 708 def test_hybridGibbs_noCorrelation(self): 709 self._setupModel(e=[[0.0]]) 710 self._runHG(20, 0.5) 711 712 def test_hybridGibbs_highSigma(self): 713 self._setupModel(e=[[0.5]], fs=[[2.0]]) 714 self._runHG(20, 0.5) 723 self._plot(x, (iv[1,:], z[0,:]), (h, self._z_to_h(z[0,:], eValue)))
