Changeset 180

Show
Ignore:
Timestamp:
05/15/08 01:27:07 (7 months ago)
Author:
edsuom
Message:

Grinding along with C code for new model

Files:

Legend:

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

    r179 r180  
    9090struct parameters 
    9191{ 
    92   PyArrayObject* d;     // Multivariate log-volatility offset 
    93   PyArrayObject* r_zv;  // Cross-correlation matrix, multivariate normal z to 
    94                         // volatility shock v 
    95   PyArrayObject* e;     // VAR(1) coefficient, volatility shock to log-volatility 
    96   PyArrayObject* ri_y;  // Inverted cross-correlation matrix, innovation shocks 
    97   PyArrayObject* g;     // Correlation, multivariate normal z vs. multivariate 
    98                         // normal for innovation shocks 
    99   PyArrayObject* c;     // Scaling constants for multivariate normal pdf 
     92  //--- Model parameters, direct --- 
     93  PyArrayObject* d;  // Multivariate log-volatility offset 
     94  PyArrayObject* e;  // VAR(1) coefficient, volatility shock to log-volatility 
     95  PyArrayObject* g;  // Correlation, multivariate normal z vs. multivariate 
     96                     // normal for innovation shocks 
     97 
     98  //--- Model parameters, derivations --- 
     99  PyArrayObject* rz; // Cross-correlation matrix, multivariate normal z to 
     100                     // volatility shock v 
     101  PyArrayObject* ri; // Inverted cross-correlation matrix, innovation shocks 
     102  PyArrayObject* c;  // Scaling constants for multivariate normal pdf, given g 
    100103}; 
    101104 
    102105 
    103 // A single normal variate and the log-volatility sample derived from it 
     106// A proposal sample 
    104107struct sample 
    105108{ 
    106   double *z;    // Multivariate normal proposal 
    107   double *h;    // Multivariate log-volatility value 
     109  // Log-density of the proposal on z 
     110  double Lz; 
     111  // Log-likelihood of the current innovation, given h 
     112  double Lx; 
     113  // Multivariate normal proposal 
     114  double *z; 
     115  // Multivariate log-volatility value based on the current proposal, or the 
     116  // previous proposal to use this struct if the current proposal hasn't been 
     117  // crunched yet 
     118  double *h; 
     119  // Scratchpad 1-D arrays of the same length as z, h 
     120  double *x0, *x1; 
    108121}; 
    109122 
     
    132145 
    133146 
     147// Log probability density of the unit normal distribution 
     148double normLogDensity(double x) 
     149{ 
     150  static double logC = -log(2 * 3.1415926535897931); 
     151  return -0.5*x*x + logC; 
     152} 
     153 
     154 
    134155// Matrix multiplication x*y -> +z 
    135156// 
     
    153174 
    154175 
    155 // Computes the log-volatility for a sample, given a 1-D array containing a 
    156 // multivariate normal z for the sample, a like-dimensioned array h0 containing 
    157 // a log-volatility value previous to the sample, and the model parameters. 
    158 // 
    159 // The z array is in a supplied sample struct, which the function modifies with 
    160 // the log-volatility value corresponding to the proposal. 
    161 void logVol(struct sample *S, struct parameters *P, double *h0) 
     176// Computes the log-volatility, given a proposal on z, the previously computed 
     177// log-volatility value previous to the sample, and the model parameters. 
     178void logVol(struct sample *S, struct parameters *P) 
    162179{ 
    163180  int k; 
     
    170187 
    171188  // Start with the matrix product for the VAR(1) term... 
    172   matrixMultiply(P->e, h0, S->h); 
     189  matrixMultiply(P->e, S->h, S->x0); 
    173190  // then compute and add the multivariate volatility shock given the proposed 
    174191  // normal variate... 
    175   matrixMultiply(P->r_zv, S->z, S->h); 
     192  matrixMultiply(P->rz, S->z, S->x0); 
    176193  // ...plus the multivariate volatility offset 
    177194  for(k=0; k<N; k++) 
    178     SPA1(S, h, k) += SPP1(P, d, k); 
     195    SPA1(S, x0, k) += SPP1(P, d, k); 
     196  // Now overwrite the previous log-volatility value 
     197  for(k=0; k<N; k++) 
     198    // TODO: Do this more efficiently by swapping pointers? 
     199    SPA1(S, h, k) = SPA1(S, x0, k); 
    179200} 
    180201 
     
    182203// Computes and returns the log-likelihood of a multivariate innovation x given 
    183204// a 1-D array containing a multivariate log-volatility. 
    184 double logLikelihood(struct sample *S, struct parameters *P, double *x) 
     205void logLikelihood(struct sample *S, struct parameters *P, double *x) 
    185206{ 
    186207  int k; 
     
    189210  double L = 0; 
    190211  const int N = (int) P->d->dimensions[0]; 
    191   y = (double *) malloc(2*N * sizeof(double)); 
    192212 
    193213  // Inverse-scale the innovation by the square root of the volatilities in 
    194214  // preparation for decorrelation 
    195215  for(k=0; k<N; k++) 
    196     PA1(y, k) = exp(-0.5 * SPA1(S, h, k)) * PA1(x, k); 
     216    SPA1(S, x0, k) = exp(-0.5 * SPA1(S, h, k)) * PA1(x, k); 
    197217     
    198218  // Now decorrelate the equi-variance innovations in preparation for the 
    199219  // log-likelihood computation for this multivariate log-volatility proposal 
    200   matrixMultiply(P->ri_y, y, y+N); 
     220  matrixMultiply(P->ri, S->x0, S->x1); 
    201221 
    202222  // Now compute log Pr(x[t]|h[t]), the log-likelihood of the decorrelated 
     
    210230    // shocks, times the value of the normal variate value underlying the 
    211231    // volatility shock for this sample 
    212     PA1(y, k) = PA1(y, k+N) - SPP1(P, g, k) * SPA1(S, z, k); 
     232    SPA1(S, x0, k) = SPA1(S, x1, k) - SPP1(P, g, k) * SPA1(S, z, k); 
    213233    // The log-likelihood for this sample is simply the argument of the 
    214234    // exponential of the normal pdf, with the reciprocal scaling of the 
    215235    // exponential being done in log space by subtraction of the log of the 
    216236    // scaling coefficient 
    217     val = PA1(y, k) / SPP2(P, c, k, 0); 
     237    val = SPA1(S, x0, k) / SPP2(P, c, k, 0); 
    218238    L -= 0.5 * val*val + SPP2(P, c, k, 1); // Fast squaring instead of pow() 
    219239    // Since the innovation has been inverse-scaled by the square root of the 
     
    224244 
    225245  // All done 
    226   free(y); 
    227   return L; 
    228 
     246  S.L = L; 
     247
     248 
     249 
     250// Returns with zero only if the proposals are close enough to finish 
     251// likelihood computation 
     252int notCloseEnough(struct sample *sp, int n) 
     253
     254  int k; 
     255  double L; 
     256  double Lmin = +DBL_MAX;   // Anything will be less positive 
     257  double Lmax = -DBL_MAX;   // Anything will be more positive 
     258  for(k=0; k<n; k++) { 
     259    L = PA1(sp, k).Lx; 
     260    if(L < Lmin) 
     261      Lmin = L; 
     262    if(L > Lmax) 
     263      Lmax = L; 
     264  } 
     265  return (Lmax - Lmin > 0.001); 
     266
     267 
    229268 
    230269 
     
    234273// ---------------------------------------------------------------------------- 
    235274 
    236 //--- Supplied arrays --- 
     275//--- Supplied variables --- 
    237276// z    Independent normal variates, [pn] array (updated) 
    238277// h    Simulated last-sample multivariate log-volatility, [p] (overwritten) 
    239278// x    Innovation values, [pn] array 
    240 // ri   Inverse, concurrent cross-correlations between innovation shocks, [pp] 
    241 // c    Constants for multivariate normal PDF 
    242  
    243 //--- Model parameters --- 
     279// w    Wiggle value for +/- proposals (float) 
     280// n    Number of proposals to try per sample (int) 
     281 
     282//--- Model parameters, direct --- 
    244283// d    Volatility offset, [p] vector 
    245284// e    Lag-1 cross-correlations for VAR of volatilities, [pp] array 
    246285// g    Volatility/innovation shock correlations, [p] vector 
    247286 
     287//--- Model parameters, derivations --- 
     288// rz   Concurrent xcorr, innovation-volatility normals, [pp] 
     289// ri   Inverse concurrent xcorr, innovation shocks, [pp] 
     290// c    Constants for multivariate normal PDF 
     291 
    248292//--- Return values (tuple) --- 
    249293// 0    Lx: Log-likelihood of innovations given simulated log-volatilities 
    250294// 1    Lh: Log-likelihood of simulated log-volatilities 
    251295 
    252  
    253 int k0, k1; 
    254 double sum, L; 
    255  
     296const int Nt = Nz[0]; 
     297const int Ns = Nz[1]; 
     298 
     299int k0, k1, k2, k3; 
     300double zp, Lx, Lh; 
     301 
     302struct sample sp[n]; 
     303struct parameters P; 
    256304py::tuple result(2); 
    257305 
     306 
     307// Generate parameter struct 
     308P.d = d_array; P.e = e_array; P.g = g_array; 
     309P.rz = rz_array; P.ri = ri_array; P.c = c_array; 
     310 
     311// Initialize various arrays 
     312x0 = (double *) calloc(sizeof(double), Nt); 
     313for(k0=0; k0<n; k0++) { 
     314  sp[k0].h = (double *) calloc(sizeof(double), Nt); 
     315  sp[k0].x0 = (double *) calloc(sizeof(double), Nt); 
     316  sp[k0].x1 = (double *) calloc(sizeof(double), Nt); 
     317} 
     318 
    258319// For each sample... 
    259 for(k0=0; k0<Nz[1]; k0++) { 
    260  
    261   // TODO 
    262   ; 
     320for(k0=0; k0<Ns; k0++) { 
     321   
     322  // Simulate n sets of h samples from separate proposals on z until a 
     323  // substantially common-valued sample is reached 
     324  k1 = k0; 
     325  do { 
     326    // Generate the next set of sample structs for the proposals... 
     327    for(k2=0; k2<n, k2++) { 
     328      for(k3=0; k3<Nt; k3++) { 
     329        zp = Z2(k3, k1) + uniform(-w, +w); 
     330        SPA1(sp[k2], z, k3) = zp; 
     331        sp[k2].Lz = normLogDensity(zp); 
     332      } 
     333    } 
     334    // ...compute their log-volatilities 
     335    for(k2=0; k2<n, k2++) 
     336      logVol(&sp[k2], &P); 
     337    // ...and the log-likelihood of the innovation for this sample, for each 
     338    // proposal on z and its log-volatility 
     339    for(k2=0; k2<Nt; k2++) 
     340      PA1(x0, k2) = X2(k2, k1); 
     341    for(k2=0; k2<n; k2++) 
     342      logLikelihood(&sp[k2], &P, x0); 
     343 
     344    // TODO 
     345 
     346    // Ready for the next time series sample, if we go that far 
     347    k1++; 
     348 
     349  } while (notCloseEnough(sp, n)); 
     350 
     351  // TODO: Importance sample proposal using total Lz+Lh 
     352 
     353
     354 
     355// Free array memory 
     356free(x0); 
     357for(k0=0; k0<n; k0++) { 
     358  free(sp[k0].h); 
     359  free(sp[k0].x0); 
     360  free(sp[k0].x1); 
    263361} 
    264362 
    265363// All done 
    266 free(P->d); 
    267 free(P->r_zv); 
    268 free(P->e); 
    269 free(P->ri_y); 
    270 free(P->g); 
    271 free(P->c0); 
    272 free(P->c1); 
     364result[0] = Lx; 
     365result[1] = Lh; 
    273366return_val = result;