Changeset 179
- Timestamp:
- 05/14/08 17:30:57 (7 months ago)
- Files:
-
- projects/AsynCluster/trunk/svpmc/model.c (modified) (3 diffs)
- projects/AsynCluster/trunk/svpmc/model.py (modified) (6 diffs)
- projects/AsynCluster/trunk/svpmc/test/test_model.py (modified) (3 diffs)
- projects/AsynCluster/trunk/svpmc/test/test_weave.py (modified) (4 diffs)
- projects/AsynCluster/trunk/svpmc/weave.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
projects/AsynCluster/trunk/svpmc/model.c
r178 r179 86 86 // ---------------------------------------------------------------------------- 87 87 88 // Normal (zero mean, unit variance) probability density 89 double npdf(double x) 90 { 91 // 1/sqrt(2*pi) = 0.39894228... 92 return 0.398942280401 * exp(-0.5 * pow(x, 2)); 93 } 94 95 96 // Normal (zero mean, unit variance) cumulative density 97 double ncdf(double x) 98 { 99 double ax, t, tp, sum; 100 // The cdf is computed from the absolute value of x and corrected at the end 101 // if necessary 102 ax = fabs(x); 103 // Compute t, the variable used in the series summation 104 t = 1.0 / (1.0 + 0.2316419*ax); 105 // Efficiently compute the series summation 106 tp = t; 107 sum = tp * 0.31938; // t 108 tp *= t; 109 sum -= tp * 0.35656; // t^2 110 tp *= t; 111 sum += tp * 1.78148; // t^3 112 tp *= t; 113 sum -= tp * 1.82125; // t^4 114 tp *= t; 115 sum += tp * 1.33027; // t^5 116 // Compute the cdf, assuming x to be positive 117 sum *= npdf(ax); 118 // Correct if x < 0 119 if(x > 0) 120 sum = 1 - sum; 88 89 // Model parameters 90 struct parameters 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 100 }; 101 102 103 // A single normal variate and the log-volatility sample derived from it 104 struct sample 105 { 106 double *z; // Multivariate normal proposal 107 double *h; // Multivariate log-volatility value 108 }; 109 110 111 // Uniformly distributed random variate in (a,b) 112 double uniform(double a, double b) 113 { 114 // Seed the PRNG on the first run only 115 static int seeded = 0; 116 if (!seeded) { 117 int i; 118 int j = 0; 119 unsigned short seed[3]; 120 for(i=0;i<3;i++) { 121 do { 122 j++; 123 } while (j < (i+1)*10000); 124 seed[i] = clock()*clock() % 65537; 125 } 126 seed48(seed); 127 seeded = 1; 128 } 129 // Compute and return a variate from U(a,b) 130 return (b - a) * drand48() + a; 131 } 132 133 134 // Matrix multiplication x*y -> +z 135 // 136 // The square matrix 'x' is a PyArrayObject and 'y' and 'z' are 1-D arrays. The 137 // result is added to what's already in 'z'. 138 void matrixMultiply(PyArrayObject* x, double *y, double *z) 139 { 140 int kr, km; 141 double val, sum; 142 const int rows = (int) x->dimensions[0]; 143 // Compute the dot product for each row of x 144 for(kr=0; kr<rows; kr++) { 145 // For this row of y and z... 146 sum = 0; 147 // Matrix multiplication dot product 148 for(km=0; km<rows; km++) 149 sum += PP2(x, kr, km) * PA1(y, km); 150 PA1(z, kr) += sum; 151 } 152 } 153 154 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) 162 { 163 int k; 164 const int N = (int) P->d->dimensions[0]; 165 for(k=0; k<N; k++) 166 SPA1(S, h, k) = 0; 167 168 // Run the VAR(1) process to get the current multivariate log-volatility 169 // value 170 171 // Start with the matrix product for the VAR(1) term... 172 matrixMultiply(P->e, h0, S->h); 173 // then compute and add the multivariate volatility shock given the proposed 174 // normal variate... 175 matrixMultiply(P->r_zv, S->z, S->h); 176 // ...plus the multivariate volatility offset 177 for(k=0; k<N; k++) 178 SPA1(S, h, k) += SPP1(P, d, k); 179 } 180 181 182 // Computes and returns the log-likelihood of a multivariate innovation x given 183 // a 1-D array containing a multivariate log-volatility. 184 double logLikelihood(struct sample *S, struct parameters *P, double *x) 185 { 186 int k; 187 double *y; 188 double val; 189 double L = 0; 190 const int N = (int) P->d->dimensions[0]; 191 y = (double *) malloc(2*N * sizeof(double)); 192 193 // Inverse-scale the innovation by the square root of the volatilities in 194 // preparation for decorrelation 195 for(k=0; k<N; k++) 196 PA1(y, k) = exp(-0.5 * SPA1(S, h, k)) * PA1(x, k); 197 198 // Now decorrelate the equi-variance innovations in preparation for the 199 // log-likelihood computation for this multivariate log-volatility proposal 200 matrixMultiply(P->ri_y, y, y+N); 201 202 // Now compute log Pr(x[t]|h[t]), the log-likelihood of the decorrelated 203 // multivariate innovation for this sample, conditional on the sample's 204 // log-volatility. 205 206 // Now the log-likelihoood. For each time series... 207 for(k=0; k<N; k++) { 208 // Offset the decorrelated innovation by the mean, which is the correlation 209 // between the normal variates for innovation and proposed volatility 210 // shocks, times the value of the normal variate value underlying the 211 // volatility shock for this sample 212 PA1(y, k) = PA1(y, k+N) - SPP1(P, g, k) * SPA1(S, z, k); 213 // The log-likelihood for this sample is simply the argument of the 214 // exponential of the normal pdf, with the reciprocal scaling of the 215 // exponential being done in log space by subtraction of the log of the 216 // scaling coefficient 217 val = PA1(y, k) / SPP2(P, c, k, 0); 218 L -= 0.5 * val*val + SPP2(P, c, k, 1); // Fast squaring instead of pow() 219 // Since the innovation has been inverse-scaled by the square root of the 220 // proposed volatility, the probability density needs to be scaled as 221 // well. In log space, this is a subtraction of half the log-volatility. 222 L -= 0.5 * SPA1(S, h, k); 223 } 224 121 225 // All done 122 return sum; 123 } 124 125 126 // Truncated normal (zero mean, unit variance) probability density 127 double tnpdf(double x, double a, double b) 128 { 129 double y; 130 if(x < a || x > b) { 131 y = 0; 132 } else { 133 y = npdf(x) / (ncdf(b) - ncdf(a)); 134 } 135 return y; 136 } 137 138 139 140 // Model.zProposal 141 // 142 // Supplied variables 143 // ---------------------------------------------------------------------------- 144 // z Independent normal variates, [pn] array (updated) 145 // wiggle = half-width of independent uniform proposal 146 147 #define w (double)wiggle 148 149 int k0, k1; 150 double x, zk, c, cp, L; 151 152 // Seed the PRNG on the first run only 153 static int seeded = 0; 154 if (!seeded) { 155 int i; 156 int j = 0; 157 unsigned short seed[3]; 158 for(i=0;i<3;i++) { 159 do { 160 j++; 161 } while (j < (i+1)*10000); 162 seed[i] = clock()*clock() % 65537; 163 } 164 seed48(seed); 165 seeded = 1; 166 } 167 168 // The joint log-density of all the jumps 169 L = 0; 170 // for each multivariate sample... 171 for(k0=0; k0<Nz[1]; k0++) { 172 173 // Do a random walk (a single uniformly distributed step) from this column of 174 // independent random-walk normal variates to produce a multivariate iid 175 // normal proposal. It is this on which we build a multivariate 176 // log-volatility proposal for this multivariate sample. 177 178 // For each time series... 179 for(k1=0; k1<Nz[0]; k1++) { 180 // Compute the scale value c as a bit more* than the maximum pdf (regular 181 // normal distribution) at the endpoints and middle of the truncated range 182 c = 0; 183 zk = Z2(k1, k0); 184 for(x = -w; x < w; x += w) { 185 cp = 1.12 * npdf(zk + x); // *Scaling by 1.12 works for w <= 1.0 186 if(cp > c) 187 c = cp; 188 } 189 // Accept-reject sampling for the truncated normal distribution 190 do { 191 // Generate a proposal within the truncated range 192 x = zk + 2*w*(drand48() - 0.5); 193 // Compute the pdf of the proposal, using the regular normal distribution 194 cp = npdf(x); 195 // Accept (and exit the loop) when the scaled uniform variate is less 196 // than the proposal's pdf 197 } while(c*drand48() > cp); 198 // Update this element of the IID normal array in place with the accepted 199 // proposal 200 Z2(k1, k0) = x; 201 // Add the log-density of the accepted proposal 202 L += log(tnpdf(x, zk-w, zk+w)); 203 } 204 } 205 206 return_val = L; 207 208 209 210 // Model.logVolatilities 226 free(y); 227 return L; 228 } 229 230 231 // Model.hybridGibbs 211 232 // 212 233 // Supplied variables … … 214 235 215 236 //--- Supplied arrays --- 216 // z Independent normal variates for log-volatilities, [pn] array217 // v Log-volatility shocks, [pn]237 // z Independent normal variates, [pn] array (updated) 238 // h Simulated last-sample multivariate log-volatility, [p] (overwritten) 218 239 // x Innovation values, [pn] array 219 // h Log-volatility values, [p(n+1)] array (last n samples overwritten)220 240 // ri Inverse, concurrent cross-correlations between innovation shocks, [pp] 221 // y Miscellaneous multivariate scratchpad, [p8] array (overwritten)241 // c Constants for multivariate normal PDF 222 242 223 243 //--- Model parameters --- … … 226 246 // g Volatility/innovation shock correlations, [p] vector 227 247 228 229 // The multivariate scratchpad y is used as follows, by column: 230 // ---------------------------------------------------------------------------- 231 // 0 Bivariate norm PDF: sqrt(1-sigma**2) 232 // 1 Bivariate norm PDF, log-scaling: log(sqrt(2*pi)*sqrt(1-sigma**2)) 233 // 2 Innovation values after inverse-scaling by log-volatility 234 // 3 Inverse-scaled innovation values after decorrelation 235 236 237 int k0, k1, km; 238 double sum; 239 double L = 0; 248 //--- Return values (tuple) --- 249 // 0 Lx: Log-likelihood of innovations given simulated log-volatilities 250 // 1 Lh: Log-likelihood of simulated log-volatilities 251 252 253 int k0, k1; 254 double sum, L; 240 255 241 256 py::tuple result(2); 242 243 257 244 258 // For each sample... 245 259 for(k0=0; k0<Nz[1]; k0++) { 246 260 247 // Run the VAR(1) process to get the current multivariate log-volatility 248 // value 249 250 // For each time series... 251 for(k1=0; k1<Nz[0]; k1++) { 252 // The volatility offset plus the shock... 253 sum = D1(k1) + V2(k1, k0); 254 // ...plus the dot product for the VAR(1) term... 255 for(km=0; km<Nz[0]; km++) 256 sum += E2(k1, km) * H2(km, k0); 257 // ...is the current log-volatility value 258 H2(k1, k0+1) = sum; 259 } 260 261 // Now inverse-scale the innovations for this sample by the square root of 262 // the volatilities in preparation for decorrelating the innovations 263 for(k1=0; k1<Nz[0]; k1++) 264 Y2(k1, 2) = exp(-0.5 * H2(k1, k0+1)) * X2(k1, k0); 265 266 // Now decorrelate the equi-variance innovations in preparation for the 267 // log-likelihood computation for this multivariate log-volatility proposal 268 269 // For each time series... 270 for(k1=0; k1<Nz[0]; k1++) { 271 // The product of the inverted cross-correlation matrix and the correlated 272 // variates... 273 sum = 0; 274 for(km=0; km<Nz[0]; km++) 275 sum += RI2(k1, km) * Y2(km, 2); 276 // ...is the decorrelated multivariate innovation for this sample, given 277 // its log-volatility 278 Y2(k1, 3) = sum; 279 } 280 281 // Now compute log Pr(x[t]|h[t]), the log-likelihood of the decorrelated 282 // multivariate innovation for this sample, conditional on the just-computed 283 // log-volatility h[t]. 284 285 // For each time series... 286 for(k1=0; k1<Nz[0]; k1++) { 287 // Offset the decorrelated innovation by the mean, which is the correlation 288 // between the normal variates for innovation and proposed volatility 289 // shocks, times the value of the normal variate value underlying the 290 // volatility shock for this sample 291 Y2(k1, 3) = Y2(k1, 3) - G1(k1) * Z2(k1, k0); 292 // The log-likelihood for this sample is simply the argument of the 293 // exponential of the normal pdf, with the reciprocal scaling of the 294 // exponential being done in log space by subtraction of the log of the 295 // scaling coefficient 296 L -= 0.5 * pow(Y2(k1, 3) / Y2(k1, 0), 2) + Y2(k1, 1); 297 // Since the innovation has been inverse-scaled by the square root of the 298 // proposed volatility, the probability density needs to be scaled as 299 // well. In log space, this is a subtraction of half the log-volatility. 300 L -= 0.5 * H2(k1, k0+1); 301 } 302 303 // The probability density, on its own, of the first log-volatility sample is 304 // proportional to the probability density of the innovation for that sample 305 // given the log-volatility. So we'll be returning that value, too. 306 if(k0 == 0) 307 result[0] = L; 308 } 309 310 // Return the first log-likelihood along with the total of the log-likelihoods 311 result[1] = L; 261 // TODO 262 ; 263 } 264 265 // 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); 312 273 return_val = result; projects/AsynCluster/trunk/svpmc/model.py
r178 r179 180 180 181 181 """ 182 _logU_index = -1183 184 182 keyAttrs = {'y':None, 'Mv':1} 185 183 … … 224 222 return cv 225 223 226 def decaySamples(self, tol):227 """228 Returns as an int the number of samples needed for the effect of an229 impulse to the log-volatility VAR(1) process to decay below I{tol}.230 """231 if 'ds' not in self.cache:232 p = self.e.shape[0]233 # The impulse234 x = s.column_stack([s.ones(p), s.zeros((p, self.n))])235 # Simulate the impulse response with a VAR object236 self.cache['ds'] = VAR(x).forward(x, s.zeros(p), self.e).max(0)237 I = s.less(self.cache['ds'], tol).nonzero()[0]238 if len(I):239 return I.min()240 return self.n241 242 def logUniform(self):243 """244 Returns a log-uniform variate taken from a large array that is245 generated and refreshed periodically. Generating the uniform variates246 and taking their log in a single large array operation is more247 efficient than doing so one value at a time.248 """249 logU = getattr(self, '_logU_array', [])250 if self._logU_index >= len(logU)-1:251 self._logU_index = -1252 # The efficient array operation253 logU = self._logU_array = s.log(s.rand(10000))254 self._logU_index += 1255 return logU[self._logU_index]256 257 def zProposal(self, z, wiggle):258 """259 Does a random walk step from the supplied 2-D array I{z} of zero-mean,260 unit-variance normal random variates with a jump from a uniform261 distribution having width +/- I{wiggle}.262 263 Returns a copy of the array with all elements changed from the original264 values, independently, along with the total log-density of the jumps.265 """266 z = z.copy()267 L = self.inline('z', 'wiggle')268 return z, L269 270 224 def logVolatilities(self, z, v, x, h0): 271 225 """ … … 313 267 Updates the IID normal variates in place. Returns the likelihood of the 314 268 innovations in I{x}, given the simulated log-volatilities, along with 315 the last sample's multivariate log-volatility value, the 316 log-probability of the simulated result, and the fractional acceptance 317 rate of the MCMC steps. 269 the last sample's multivariate log-volatility value, and the 270 log-probability of the simulated result. 318 271 319 272 The method will account for the effect of log-volatility proposals on … … 323 276 """ 324 277 L_total = 0 325 acceptances = 0326 278 N = self.decaySamples(tol) 327 279 # Initialize volatility shocks from cross-correlation of the IID … … 364 316 z[:,k] = zp[:,k] 365 317 v[:,k] = vp[:,k] 366 acceptances += 1367 318 # Update stuff for the next sample 368 319 h0 = LV[2][:,0] … … 372 323 if L_total < -1E6: 373 324 return -s.inf, s.zeros_like(h0), 0.0, 0.0 374 return L_total, h0, L_result , float(acceptances)/self.n325 return L_total, h0, L_result 375 326 376 327 projects/AsynCluster/trunk/svpmc/test/test_model.py
r178 r179 20 20 """ 21 21 22 import os.path 22 import os.path, textwrap 23 23 import scipy as s 24 24 from scipy import stats, random, linalg, signal … … 161 161 return model.Model(**kw) 162 162 163 def inline(self, code, **kw): 164 """ 165 Do an inline call with the model's Weaver API and support code. 166 """ 167 return self.modelFactory().inlineDirect(textwrap.dedent(code), **kw) 168 163 169 def _covarMatrix(self, cs, cr): 164 170 i = 0 … … 316 322 [[9.0, 1.2, 3.0], [1.2, 16.0, 6.0], [3.0, 6.0, 25.0]]) 317 323 318 def test_logUniform(self): 319 N = 35000 320 import timeit 321 tObserved = timeit.Timer( 322 "M.logUniform()", 323 "import model\nM = model.Model()").timeit(N) 324 tBaseline = timeit.Timer( 325 "s.log(s.rand())", 326 "import scipy as s").timeit(N) 327 percent = 100 * tObserved/tBaseline 328 if VERBOSE: 329 print "The efficient method took %2d%% as long as the stupid way" \ 330 % percent 331 self.failUnless(percent < 40) 332 333 def test_zProposal_dist(self): 334 N = 10000 335 z = s.zeros((2,3)) 336 modelObj = self.modelFactory() 337 z1 = s.empty(N) 338 z2 = s.empty(N) 339 for k in xrange(N): 340 z, L_result = modelObj.zProposal(z, 0.8) 341 z1[k] = z[0,0] 342 z2[k] = z[1,1] 343 self.failUnlessNormal(z1) 344 self.failUnlessNormal(z2) 345 self._check_uncorr(z1, z2) 346 347 def test_zProposal_L(self): 348 N = 1000 349 z0 = s.ones((1,1)) 350 modelObj = self.modelFactory() 351 z = s.empty(N) 352 L = s.empty(N) 353 for k in xrange(N): 354 zk, L_result = modelObj.zProposal(z0, 0.8) 355 z[k] = zk[0,0] 356 L[k] = L_result 357 fig = self.fig 358 sp = fig.add_subplot(211) 359 sp.hist(z) 360 sp = fig.add_subplot(212) 361 sp.plot(z, s.exp(L), '.') 362 363 def test_decaySamples(self): 364 x = s.zeros((5, 1000)) 365 x[2,0] = 1.0 # The impulse 366 var = model.VAR(x) 367 a = s.zeros(5) 368 modelObj = self.modelFactory() 369 for j in xrange(20): 370 # Keep all coefficients small enough to ensure stability 371 b = modelObj.e = 0.3*s.rand(5,5) 372 y = var.forward(x, a, b) 373 for tol in s.logspace(-5, -1, 10): 374 N = modelObj.decaySamples(tol) 375 print tol, N 376 failed = abs(y[:,N].max()) > tol 377 if (N > 100 or failed) and VERBOSE: 378 N_plot = min([3*N, 30]) 379 sp = self.fig.add_subplot(111) 380 sp.semilogy(y[:,:N_plot].transpose()) 381 sp.axvline(N) 382 sp.axhline(tol) 383 self.failIf( 384 failed, 385 "Estimate of %d samples " % N +\ 386 "to decay within %f tolerance was insufficient" % tol) 387 324 def test_support_uniform(self): 325 code = """ 326 return_val = uniform((double) a, (double) b); 327 """ 328 N = 100 329 for x, y in ((1, 2), (-1, +3)): 330 z = s.array([self.inline(code, a=x, b=y) for k in xrange(N)]) 331 self.failUnless(len(z), N) 332 self.failUnless(z.min() > x) 333 self.failUnless(z.max() < y) 334 self.failUnlessEqual(len(s.unique(z)), N) 335 336 def test_support_matrixMultiply(self): 337 code = """ 338 int k; 339 double b[8]; 340 double c[8]; 341 for(k=0; k<8; k++) { 342 b[k] = 1.5*k; 343 c[k] = 0; 344 } 345 matrixMultiply(a_array, b, c); 346 for(k=0; k<8; k++) 347 R1(k) = c[k]; 348 """ 349 a = s.arange(64, dtype='d').reshape(8,8) 350 b = 1.5 * s.arange(8).reshape((8,1)) 351 r = s.empty(8) 352 self.inline(code, a=a, r=r) 353 self.failUnlessElementsEqual(r, s.matrix(a)*b) 354 388 355 389 356 class Test_Model_logVolatilities_VAR(BaseCase): projects/AsynCluster/trunk/svpmc/test/test_weave.py
r175 r179 34 34 35 35 //---------------------------------------- 36 // TestableWeaver.support 37 38 struct vectorPackage 39 { 40 PyArrayObject* x; 41 PyArrayObject* y; 42 double result; 43 }; 44 45 void dotProduct(struct vectorPackage *vp) 46 { 47 int k; 48 int N = (int) vp->x->dimensions[0]; 49 vp->result = 0; 50 for(k=0; k<N; k++) 51 vp->result += SPP1(vp, x, k) * SPP1(vp, y, k); 52 } 53 54 //---------------------------------------- 36 55 // TestableWeaver.foo 37 56 … … 43 62 X1(0) += 100; 44 63 //---------------------------------------- 64 45 65 46 66 // Bogus.something … … 64 84 return x[0] 65 85 86 def dotProduct(self, x, y): 87 code = "\n".join([ 88 line.strip() for line in [ 89 "struct vectorPackage vectors;", 90 "vectors.x = x_array;", 91 "vectors.y = y_array;", 92 "dotProduct(&vectors);", 93 "return_val = vectors.result;"]]) 94 return self.inlineDirect(code, x=x, y=y) 95 66 96 67 97 class Test_Weaver(util.TestCase): … … 69 99 self.weaver = TestableWeaver() 70 100 71 def test_inline_alone(self): 72 self.weaver._code = {'support':None, 'foo':CODE} 73 self.failUnlessEqual(self.weaver.foo(s.array([1])), 1164) 74 101 def test_support(self): 102 x = s.randn(100) 103 y = s.randn(100) 104 self.weaver._code = self.weaver._parseCode(CODE) 105 self.failUnlessEqual(self.weaver.dotProduct(x, y), s.dot(x, y)) 106 75 107 def test_parseCode(self): 76 108 code = self.weaver._parseCode(CODE) projects/AsynCluster/trunk/svpmc/weave.py
r175 r179 26 26 from pkg_resources import resource_string 27 27 from scipy.weave import * 28 from scipy.weave.base_info import custom_info 29 30 31 class my_info(custom_info): 32 _extra_compile_args = ['-w'] 33 __macros = [ 34 # Access an element i of a 1-D array whose pointer is pa 35 'PA1(pa,i)', 36 "*(pa + i)", 37 38 # Access an element i of a 1-D array whose pointer is pa in a structure 39 # whose pointer is s 40 'SPA1(s,pa,i)', 41 "*(s->pa + i)", 42 43 # Access an element i, j of a 2-D Numpy array object whose pointer is 44 # ppa 45 'PP2(ppa,i,j)', 46 "(*((double*)(ppa->data + (i)*ppa->strides[0] + (j)*ppa->strides[1])))", 47 48 # Access an element i of a 1-D Numpy array object whose pointer is ppa 49 # in a structure whose pointer is s 50 'SPP1(s,ppa,i)', 51 "(*((double*)(s->ppa->data + (i)*s->ppa->strides[0])))", 52 53 # Access an element i, j of a 2-D Numpy array object whose pointer is 54 # ppa in a structure whose pointer is s 55 'SPP2(s,ppa,i,j)', 56 "(*((double*)(s->ppa->data + "+\ 57 "(i)*s->ppa->strides[0] + (j)*s->ppa->strides[1])))", 58 ] 59 60 def __init__(self): 61 k = 0 62 macros = ["'%s'" % (x,) for x in self.__macros] 63 while(k < len(macros)): 64 name, value = macros[k:k+2] 65 self.add_define_macro((name, value)) 66 self.add_undefine_macro(name) 67 k += 2 28 68 29 69 … … 45 85 line. 46 86 """ 87 infoObj = my_info() 88 47 89 def _parseCode(self, text): 48 90 re_delimiter = re.compile( … … 111 153 return inline( 112 154 self.code[methodName], args, local_dict, 113 extra_compile_args=['-w'], support_code=self.code['support'])155 customize=self.infoObj, support_code=self.code['support']) 114 156 115 116 157 def inlineDirect(self, code, **kw): 158 """ 159 Call this method with a string of C I{code} and keywords defining the 160 names and values of variables to be passed to the code function. 161 162 Using this method entails less CPU overhead (but also less convenience 163 and flexibility) than using L{inline}. 164 """ 165 return inline( 166 code, kw.keys(), kw, 167 customize=self.infoObj, support_code=self.code['support'])
