Changeset 180
- Timestamp:
- 05/15/08 01:27:07 (7 months ago)
- Files:
-
- projects/AsynCluster/trunk/svpmc/model.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
projects/AsynCluster/trunk/svpmc/model.c
r179 r180 90 90 struct parameters 91 91 { 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 100 103 }; 101 104 102 105 103 // A single normal variate and the log-volatility sample derived from it106 // A proposal sample 104 107 struct sample 105 108 { 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; 108 121 }; 109 122 … … 132 145 133 146 147 // Log probability density of the unit normal distribution 148 double normLogDensity(double x) 149 { 150 static double logC = -log(2 * 3.1415926535897931); 151 return -0.5*x*x + logC; 152 } 153 154 134 155 // Matrix multiplication x*y -> +z 135 156 // … … 153 174 154 175 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. 178 void logVol(struct sample *S, struct parameters *P) 162 179 { 163 180 int k; … … 170 187 171 188 // 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); 173 190 // then compute and add the multivariate volatility shock given the proposed 174 191 // normal variate... 175 matrixMultiply(P->r _zv, S->z, S->h);192 matrixMultiply(P->rz, S->z, S->x0); 176 193 // ...plus the multivariate volatility offset 177 194 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); 179 200 } 180 201 … … 182 203 // Computes and returns the log-likelihood of a multivariate innovation x given 183 204 // a 1-D array containing a multivariate log-volatility. 184 doublelogLikelihood(struct sample *S, struct parameters *P, double *x)205 void logLikelihood(struct sample *S, struct parameters *P, double *x) 185 206 { 186 207 int k; … … 189 210 double L = 0; 190 211 const int N = (int) P->d->dimensions[0]; 191 y = (double *) malloc(2*N * sizeof(double));192 212 193 213 // Inverse-scale the innovation by the square root of the volatilities in 194 214 // preparation for decorrelation 195 215 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); 197 217 198 218 // Now decorrelate the equi-variance innovations in preparation for the 199 219 // 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); 201 221 202 222 // Now compute log Pr(x[t]|h[t]), the log-likelihood of the decorrelated … … 210 230 // shocks, times the value of the normal variate value underlying the 211 231 // 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); 213 233 // The log-likelihood for this sample is simply the argument of the 214 234 // exponential of the normal pdf, with the reciprocal scaling of the 215 235 // exponential being done in log space by subtraction of the log of the 216 236 // scaling coefficient 217 val = PA1(y, k) / SPP2(P, c, k, 0);237 val = SPA1(S, x0, k) / SPP2(P, c, k, 0); 218 238 L -= 0.5 * val*val + SPP2(P, c, k, 1); // Fast squaring instead of pow() 219 239 // Since the innovation has been inverse-scaled by the square root of the … … 224 244 225 245 // 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 252 int 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 229 268 230 269 … … 234 273 // ---------------------------------------------------------------------------- 235 274 236 //--- Supplied arrays ---275 //--- Supplied variables --- 237 276 // z Independent normal variates, [pn] array (updated) 238 277 // h Simulated last-sample multivariate log-volatility, [p] (overwritten) 239 278 // x Innovation values, [pn] array 240 // ri Inverse, concurrent cross-correlations between innovation shocks, [pp]241 // c Constants for multivariate normal PDF242 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 --- 244 283 // d Volatility offset, [p] vector 245 284 // e Lag-1 cross-correlations for VAR of volatilities, [pp] array 246 285 // g Volatility/innovation shock correlations, [p] vector 247 286 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 248 292 //--- Return values (tuple) --- 249 293 // 0 Lx: Log-likelihood of innovations given simulated log-volatilities 250 294 // 1 Lh: Log-likelihood of simulated log-volatilities 251 295 252 253 int k0, k1; 254 double sum, L; 255 296 const int Nt = Nz[0]; 297 const int Ns = Nz[1]; 298 299 int k0, k1, k2, k3; 300 double zp, Lx, Lh; 301 302 struct sample sp[n]; 303 struct parameters P; 256 304 py::tuple result(2); 257 305 306 307 // Generate parameter struct 308 P.d = d_array; P.e = e_array; P.g = g_array; 309 P.rz = rz_array; P.ri = ri_array; P.c = c_array; 310 311 // Initialize various arrays 312 x0 = (double *) calloc(sizeof(double), Nt); 313 for(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 258 319 // For each sample... 259 for(k0=0; k0<Nz[1]; k0++) { 260 261 // TODO 262 ; 320 for(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 356 free(x0); 357 for(k0=0; k0<n; k0++) { 358 free(sp[k0].h); 359 free(sp[k0].x0); 360 free(sp[k0].x1); 263 361 } 264 362 265 363 // 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); 364 result[0] = Lx; 365 result[1] = Lh; 273 366 return_val = result;
