| 85 | | // Model.likelihood |
|---|
| | 85 | // Model.zProposal |
|---|
| | 86 | // |
|---|
| | 87 | // Supplied variables |
|---|
| | 88 | // ---------------------------------------------------------------------------- |
|---|
| | 89 | // z Independent normal variates, [pn] array (updated) |
|---|
| | 90 | // M Number of uniform-proposal MCMC iterations per IID normal draw |
|---|
| | 91 | // wiggle = Width of random-walk uniform proposal |
|---|
| | 92 | |
|---|
| | 93 | |
|---|
| | 94 | int k0, k1, k2; |
|---|
| | 95 | double norm, normp, L, Lp; |
|---|
| | 96 | |
|---|
| | 97 | |
|---|
| | 98 | // for each multivariate sample... |
|---|
| | 99 | for(k0=0; k0<Nz[1]; k0++) { |
|---|
| | 100 | |
|---|
| | 101 | // Do a random walk from this column of independent random-walk normal |
|---|
| | 102 | // variates to produce a multivariate iid normal proposal. It is this on |
|---|
| | 103 | // which we build a multivariate log-volatility proposal for this |
|---|
| | 104 | // multivariate sample. |
|---|
| | 105 | |
|---|
| | 106 | // For each time series... |
|---|
| | 107 | for(k1=0; k1<Nz[0]; k1++) { |
|---|
| | 108 | // Initialize the current normal value with the current proposal value and |
|---|
| | 109 | // compute its log-likelihood |
|---|
| | 110 | norm = Z2(k1, k0); |
|---|
| | 111 | L = -0.5 * pow(norm, 2); |
|---|
| | 112 | // For each oversampling iteration... |
|---|
| | 113 | for(k2=0; k2<M; k2++) { |
|---|
| | 114 | // Generate a uniform, symmetric, random walk proposal |
|---|
| | 115 | normp = norm + wiggle * (drand48() - 0.5); |
|---|
| | 116 | // Do the ratio in log space |
|---|
| | 117 | Lp = -0.5 * pow(normp, 2); |
|---|
| | 118 | dL = Lp - L; |
|---|
| | 119 | // The uniform random variate thus needs to be in logspace as well, but |
|---|
| | 120 | // it's not always even needed. Thus the log operation is done just |
|---|
| | 121 | // once, and only some of the time. |
|---|
| | 122 | if(dL > 0 || log(drand48()) < dL) { |
|---|
| | 123 | // Update current value and its log probability when proposal |
|---|
| | 124 | // accepted |
|---|
| | 125 | norm = normp; |
|---|
| | 126 | L = Lp; |
|---|
| | 127 | } |
|---|
| | 128 | } |
|---|
| | 129 | // Update this element of the IID normal array in place |
|---|
| | 130 | Z2(k1, k0) = norm; |
|---|
| | 131 | } |
|---|
| | 132 | } |
|---|
| | 133 | |
|---|
| | 134 | |
|---|
| | 135 | |
|---|
| | 136 | // Model.logVolatilities |
|---|
| 115 | | // 2 Independent normal variate random-walk proposals |
|---|
| 116 | | // 3 Correlated volatility shocks |
|---|
| 117 | | // 4 Innovation values after inverse-scaling by log-volatility |
|---|
| 118 | | // 5 Inverse-scaled innovation values after decorrelation |
|---|
| 119 | | // 6 - |
|---|
| 120 | | // 7 - |
|---|
| 121 | | |
|---|
| 122 | | |
|---|
| 123 | | // THIS CODE IS WHERE THE VAST MAJORITY OF THE TOTAL CPU TIME IS EXPENDED! |
|---|
| 124 | | |
|---|
| 125 | | |
|---|
| 126 | | int km, kh; |
|---|
| 127 | | int k0, k1, k2, k3, nd; |
|---|
| 128 | | double sum, norm, normp, dL, L0, L1, L; |
|---|
| 129 | | |
|---|
| 130 | | double wiggle = sigma * pow(n3, -0.5); |
|---|
| 131 | | |
|---|
| 132 | | |
|---|
| 133 | | // Initialize constants for bivariate normal probability density function |
|---|
| 134 | | for(k2=0; k2<Nz[0]; k2++) { |
|---|
| 135 | | Y2(k2, 0) = 2*(1 - pow(G1(k2), 2)); |
|---|
| 136 | | Y2(k2, 1) = 0.5 * log(3.1415926535897931 * Y2(k2, 0)); |
|---|
| 137 | | } |
|---|
| 138 | | |
|---|
| 139 | | |
|---|
| 140 | | // Initialize volatility shocks by correlating the current (supplied) set of |
|---|
| 141 | | // iid random-walk variates |
|---|
| 142 | | |
|---|
| 143 | | // for each multivariate sample... |
|---|
| 144 | | for(k1=0; k1<Nz[1]; k1++) { |
|---|
| 145 | | |
|---|
| 146 | | // For each time series... |
|---|
| 147 | | for(k2=0; k2<Nz[0]; k2++) { |
|---|
| 148 | | // The matrix product of the cross-correlations and the independent |
|---|
| 149 | | // variates for this sample... |
|---|
| | 159 | // 2 Innovation values after inverse-scaling by log-volatility |
|---|
| | 160 | // 3 Inverse-scaled innovation values after decorrelation |
|---|
| | 161 | |
|---|
| | 162 | |
|---|
| | 163 | int k0, k1, km; |
|---|
| | 164 | double sum; |
|---|
| | 165 | double L = 0; |
|---|
| | 166 | |
|---|
| | 167 | |
|---|
| | 168 | // For each sample... |
|---|
| | 169 | for(k0=0; k0<Nz[1]; k0++) { |
|---|
| | 170 | |
|---|
| | 171 | // Run the VAR(1) process to get the current multivariate log-volatility |
|---|
| | 172 | // value |
|---|
| | 173 | |
|---|
| | 174 | // For each time series... |
|---|
| | 175 | for(k1=0; k1<Nz[0]; k1++) { |
|---|
| | 176 | // The volatility offset plus the shock... |
|---|
| | 177 | sum = D1(k1) + V2(k2, k1); |
|---|
| | 178 | // ...plus the dot product for the VAR(1) term... |
|---|
| | 179 | for(km=0; km<Nz[0]; km++) |
|---|
| | 180 | sum += E2(k1, km) * H2(k1, k0); |
|---|
| | 181 | // ...is the current log-volatility value |
|---|
| | 182 | H2(k1, k0+1) = sum; |
|---|
| | 183 | } |
|---|
| | 184 | |
|---|
| | 185 | // Now inverse-scale the innovations for this sample by the square root of |
|---|
| | 186 | // the volatilities in preparation for decorrelating the innovations |
|---|
| | 187 | for(k1=0; k1<Nz[0]; k1++) |
|---|
| | 188 | Y2(k1, 2) = exp(-0.5 * H2(k1, k0+1)) * X2(k1, k0); |
|---|
| | 189 | |
|---|
| | 190 | // Now decorrelate the equi-variance innovations in preparation for the |
|---|
| | 191 | // log-likelihood computation for this multivariate log-volatility proposal |
|---|
| | 192 | |
|---|
| | 193 | // For each time series... |
|---|
| | 194 | for(k1=0; k1<Nz[0]; k1++) { |
|---|
| | 195 | // The product of the inverted cross-correlation matrix and the correlated |
|---|
| | 196 | // variates... |
|---|
| 152 | | sum += RV2(k2, km) * Y2(k2, 2); |
|---|
| 153 | | // ...is the correlated volatility shock for this time series and sample |
|---|
| 154 | | V2(k2, k1) = sum; |
|---|
| 155 | | } |
|---|
| 156 | | } |
|---|
| 157 | | |
|---|
| 158 | | |
|---|
| 159 | | // Hybrid Gibbs sampler with Metropolis-Hastings accept/reject step for each |
|---|
| 160 | | // conditional density draw. |
|---|
| 161 | | |
|---|
| 162 | | // For each overall iteration... |
|---|
| 163 | | for(k0=0; k0<n0; k0++) { |
|---|
| 164 | | |
|---|
| 165 | | // for each multivariate sample... |
|---|
| 166 | | for(k1=0; k1<Nz[1]; k1++) { |
|---|
| 167 | | |
|---|
| 168 | | // Do a random walk from this column of independent random-walk normal |
|---|
| 169 | | // variates to produce a multivariate iid normal proposal. It is this on |
|---|
| 170 | | // which we build a multivariate log-volatility proposal for this |
|---|
| 171 | | // multivariate sample. |
|---|
| 172 | | |
|---|
| 173 | | // For each time series... |
|---|
| 174 | | for(k2=0; k2<Nz[0]; k2++) { |
|---|
| 175 | | // Initialize the scratchpad with the current proposal value and compute |
|---|
| 176 | | // its log-likelihood |
|---|
| 177 | | Y2(k2, 2) = Z2(k2, k1); |
|---|
| 178 | | L0 = -0.5 * pow(Y2(k2, 2), 2); |
|---|
| 179 | | // For each oversampling iteration... |
|---|
| 180 | | for(k3=0; k3<n3; k3++) { |
|---|
| 181 | | // Generate a uniform, symmetric, random walk proposal |
|---|
| 182 | | normp = Y2(k2, 2) + wiggle * (drand48() - 0.5); |
|---|
| 183 | | // Do the ratio in log space |
|---|
| 184 | | L1 = -0.5 * pow(normp, 2); |
|---|
| 185 | | dL = L1 - L0; |
|---|
| 186 | | // The uniform random variate thus needs to be in logspace as well, but |
|---|
| 187 | | // it's not always even needed. Thus the log operation is done just |
|---|
| 188 | | // once, and only some of the time. |
|---|
| 189 | | if(dL > 0 || log(drand48()) < dL) { |
|---|
| 190 | | // Update current value and its log probability when proposal |
|---|
| 191 | | // accepted |
|---|
| 192 | | Y2(k2, 2) = normp; |
|---|
| 193 | | L0 = L1; |
|---|
| 194 | | } |
|---|
| 195 | | } |
|---|
| 196 | | } |
|---|
| 197 | | |
|---|
| 198 | | // Now correlate the iid proposal to form a proposed column of volatility |
|---|
| 199 | | // shocks |
|---|
| 200 | | |
|---|
| 201 | | // For each time series... |
|---|
| 202 | | for(k2=0; k2<Nz[0]; k2++) { |
|---|
| 203 | | // The matrix product of the cross-correlations and the proposed |
|---|
| 204 | | // independent variates... |
|---|
| 205 | | sum = 0; |
|---|
| 206 | | for(km=0; km<Nz[0]; km++) |
|---|
| 207 | | sum += RV2(k2, km) * Y2(k2, 2); |
|---|
| 208 | | // ...is the correlated volatility shock proposal for this time series |
|---|
| 209 | | Y2(k2, 3) = sum; |
|---|
| 210 | | } |
|---|
| 211 | | |
|---|
| 212 | | // Now do the VAR(1) starting with this proposed volatility shock and |
|---|
| 213 | | // proceeding through the other shocks subsequent to it to compute |
|---|
| 214 | | // Pr(hp[t]|x,h[:t],h[t+1:]). |
|---|
| 215 | | L = 0; |
|---|
| 216 | | if(k3+nv >= Nz[1]) { |
|---|
| 217 | | nd = Nz[1]; |
|---|
| 218 | | } else { |
|---|
| 219 | | nd = k3+nv; |
|---|
| 220 | | } |
|---|
| 221 | | |
|---|
| 222 | | // For the current sample and some samples subsequent to it... |
|---|
| 223 | | for(k3=k1; k3<nd; k3++) { |
|---|
| 224 | | // We alternate between the two columns of the log-volatility scratchpad |
|---|
| 225 | | // for current & previous multivariate log-volatility values |
|---|
| 226 | | kh = k3 % 2; |
|---|
| 227 | | // For each time series... |
|---|
| 228 | | for(k2=0; k2<Nz[0]; k2++) { |
|---|
| 229 | | if(k1 == 0) { |
|---|
| 230 | | // The log-volatility value of the first multivariate sample is just |
|---|
| 231 | | // the offset scaled by its VAR gain, plus the proposed shock |
|---|
| 232 | | H2(k2, 0) = D1(k2) / (1 - E2(k2, k2)) + Y2(k2, 3); |
|---|
| 233 | | } else { |
|---|
| 234 | | // For all other samples, the offset plus the proposed shock... |
|---|
| 235 | | sum = D1(k2) + Y2(k2, 3); |
|---|
| 236 | | // ...plus the dot product for the VAR(1) term... |
|---|
| 237 | | for(km=0; km<Nz[0]; km++) |
|---|
| 238 | | sum += E2(k2, km) * H2(k2, 1-kh); |
|---|
| 239 | | // ...is the proposed log-volatility value |
|---|
| 240 | | H2(k2, kh) = sum; |
|---|
| 241 | | } |
|---|
| 242 | | } |
|---|
| 243 | | |
|---|
| 244 | | // Now inverse-scale the innovations for this sample by the square root |
|---|
| 245 | | // of the volatilities in preparation for decorrelating the innovations |
|---|
| 246 | | for(k2=0; k2<Nz[0]; k2++) |
|---|
| 247 | | Y2(k2, 4) = exp(-0.5 * H2(k2, kh)) * X2(k2, k3); |
|---|
| 248 | | |
|---|
| 249 | | // Now decorrelate the equi-variance innovations in preparation for the |
|---|
| 250 | | // log-likelihood computation for this multivariate log-volatility |
|---|
| 251 | | // proposal |
|---|
| 252 | | |
|---|
| 253 | | // For each time series... |
|---|
| 254 | | for(k2=0; k2<Nz[0]; k2++) { |
|---|
| 255 | | // The product of the inverted cross-correlation matrix and the |
|---|
| 256 | | // correlated variates... |
|---|
| 257 | | sum = 0; |
|---|
| 258 | | for(km=0; km<Nz[0]; km++) |
|---|
| 259 | | sum += RI2(k2, km) * Y2(k2, 4); |
|---|
| 260 | | // ...is the decorrelated multivariate innovation for this sample, |
|---|
| 261 | | // given its proposed log-volatility |
|---|
| 262 | | Y2(k2, 5) = sum; |
|---|
| 263 | | } |
|---|
| 264 | | |
|---|
| 265 | | // Now compute log Pr(x[t]|hp[t],h[t+1:]), the log-likelihood of the |
|---|
| 266 | | // decorrelated multivariate innovation, conditional on the proposed |
|---|
| 267 | | // log-volatility hp[t] and the log-volatilities of all subsequent |
|---|
| 268 | | // samples. The proposed log-volatility hp[t] is itself generated |
|---|
| 269 | | // conditional on the log-volatilities of earlier samples, so no further |
|---|
| 270 | | // account of such samples needs be made. |
|---|
| | 199 | sum += RI2(k1, km) * Y2(k1, 2); |
|---|
| | 200 | // ...is the decorrelated multivariate innovation for this sample, given |
|---|
| | 201 | // its log-volatility |
|---|
| | 202 | Y2(k1, 3) = sum; |
|---|
| | 203 | } |
|---|
| | 204 | |
|---|
| | 205 | // Now compute log Pr(x[t]|h[t]), the log-likelihood of the decorrelated |
|---|
| | 206 | // multivariate innovation for this sample, conditional on the just-computed |
|---|
| | 207 | // log-volatility h[t]. |
|---|
| 272 | | // For each time series... |
|---|
| 273 | | for(k2=0; k2<Nz[0]; k2++) { |
|---|
| 274 | | // Offset the decorrelated innovation by the mean, which is the |
|---|
| 275 | | // correlation between the normal variates for innovation and proposed |
|---|
| 276 | | // volatility shocks, times the value of the normal variate value for |
|---|
| 277 | | // the proposed volatility shock for this sample (or the current normal |
|---|
| 278 | | // variate value, for subsequent samples) |
|---|
| 279 | | if(k3 == k1) { |
|---|
| 280 | | norm = V2(k2, 2); |
|---|
| 281 | | } else { |
|---|
| 282 | | norm = Z2(k2, k3); |
|---|
| 283 | | } |
|---|
| 284 | | Y2(k2, 5) = Y2(k2, 5) - G1(k2) * H2(k2, kh); |
|---|
| 285 | | // The log-likelihood for this sample is simply the argument of the |
|---|
| 286 | | // exponential of the normal pdf, with the reciprocal scaling of the |
|---|
| 287 | | // exponential being done in log space by subtraction. |
|---|
| 288 | | L -= pow(Y2(k2, 5) / Y2(k2, 0), 2) + Y2(k2, 1); |
|---|
| 289 | | // Since the innovation has been inverse-scaled by the square root of |
|---|
| 290 | | // the proposed volatility, the probability density needs to be scaled |
|---|
| 291 | | // as well. In log space, this is a subtraction of half the proposed |
|---|
| 292 | | // log-volatility. |
|---|
| 293 | | L -= 0.5 * H2(k2, kh); |
|---|
| 294 | | } |
|---|
| 295 | | } |
|---|
| 296 | | |
|---|
| 297 | | // TODO |
|---|
| 298 | | // Need to record L for this sample to compare in next MH iteration |
|---|
| 299 | | |
|---|
| 300 | | |
|---|
| 301 | | |
|---|
| 302 | | // Do a Metropolis-Hastings accept/reject based on the log-likelihood for |
|---|
| 303 | | // the proposal versus the log-likelihood for the previously accepted |
|---|
| 304 | | // normal value for this sample. |
|---|
| 305 | | |
|---|
| 306 | | // If this is the first, initialization iteration, we always accept the |
|---|
| 307 | | // null "proposal," which was only obtained to (re)compute the |
|---|
| 308 | | // log-likelihood given the current normal variates. |
|---|
| 309 | | if(k0 == 0) { |
|---|
| 310 | | P2(0, k1) = L0; |
|---|
| 311 | | P2(1, k1) = L1; |
|---|
| 312 | | } else { |
|---|
| 313 | | // Do the ratio of likelihoods for hp[t] vs current h[t] in log space |
|---|
| 314 | | dL = L1 - P2(0, k1); |
|---|
| 315 | | // The uniform random variate thus needs to be in logspace as well, but |
|---|
| 316 | | // it's not always even needed. Thus the log operation is done just once, |
|---|
| 317 | | // and only some of the time. |
|---|
| 318 | | if(dL > 0 || log(drand48()) < dL) { |
|---|
| 319 | | P2(0, k1) = L0; |
|---|
| 320 | | P2(1, k1) = L1; |
|---|
| 321 | | // For each time series... |
|---|
| 322 | | for(k2=0; k2<Nz[0]; k2++) |
|---|
| 323 | | Z2(k2, k1) = Y2(k2, 2); |
|---|
| 324 | | } |
|---|
| 325 | | } |
|---|
| 326 | | |
|---|
| 327 | | // End of Metropolis-Hastings step for this multivariate sample |
|---|
| 328 | | } |
|---|
| 329 | | |
|---|
| 330 | | // End of this iteration |
|---|
| 331 | | } |
|---|
| 332 | | |
|---|
| 333 | | // End of MCMC run. The array Z2 has been overwritten with updated iid normal |
|---|
| 334 | | // variates underlying an updated set of log-volatilities, and the vector P1 |
|---|
| 335 | | // has been overwritten with the log-likelihood of each multivariate innovation |
|---|
| 336 | | // sample given those log-volatilities. |
|---|
| 337 | | |
|---|
| 338 | | |
|---|
| | 209 | // For each time series... |
|---|
| | 210 | for(k1=0; k1<Nz[0]; k1++) { |
|---|
| | 211 | // Offset the decorrelated innovation by the mean, which is the correlation |
|---|
| | 212 | // between the normal variates for innovation and proposed volatility |
|---|
| | 213 | // shocks, times the value of the normal variate value underlying the |
|---|
| | 214 | // volatility shock for this sample |
|---|
| | 215 | Y2(k1, 3) = Y2(k1, 3) - G1(k1) * Z2(k1, k0); |
|---|
| | 216 | // The log-likelihood for this sample is simply the argument of the |
|---|
| | 217 | // exponential of the normal pdf, with the reciprocal scaling of the |
|---|
| | 218 | // exponential being done in log space by subtraction. |
|---|
| | 219 | L -= pow(Y2(k1, 3) / Y2(k1, 0), 2) + Y2(k1, 1); |
|---|
| | 220 | // Since the innovation has been inverse-scaled by the square root of the |
|---|
| | 221 | // proposed volatility, the probability density needs to be scaled as |
|---|
| | 222 | // well. In log space, this is a subtraction of half the log-volatility. |
|---|
| | 223 | L -= 0.5 * H2(k1, k0+1); |
|---|
| | 224 | } |
|---|
| | 225 | } |
|---|
| | 226 | |
|---|
| | 227 | // The return value is the total log-volatility |
|---|
| | 228 | return_val = L; |
|---|