Changeset 151
- Timestamp:
- 04/19/08 20:26:56 (8 months ago)
- Files:
-
- projects/AsynCluster/tags/20080419 (copied) (copied from projects/AsynCluster/trunk)
- projects/AsynCluster/tags/20080419/svpmc/model.py (modified) (11 diffs)
- projects/AsynCluster/tags/20080419/svpmc/params.py (modified) (4 diffs)
- projects/AsynCluster/tags/20080419/svpmc/pmc.py (modified) (3 diffs)
- projects/AsynCluster/tags/20080419/svpmc/sample.py (modified) (2 diffs)
- projects/AsynCluster/tags/20080419/svpmc/test/test_model.py (modified) (4 diffs)
- projects/AsynCluster/tags/20080419/svpmc/test/test_params.py (added)
- projects/AsynCluster/tags/20080419/svpmc/test/test_sample.py (modified) (1 diff)
- projects/AsynCluster/trunk/svpmc/model.py (modified) (11 diffs)
- projects/AsynCluster/trunk/svpmc/params.py (modified) (4 diffs)
- projects/AsynCluster/trunk/svpmc/pmc.py (modified) (3 diffs)
- projects/AsynCluster/trunk/svpmc/sample.py (modified) (2 diffs)
- projects/AsynCluster/trunk/svpmc/test/test_model.py (modified) (4 diffs)
- projects/AsynCluster/trunk/svpmc/test/test_params.py (added)
- projects/AsynCluster/trunk/svpmc/test/test_sample.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
projects/AsynCluster/tags/20080419/svpmc/model.py
r150 r151 70 70 71 71 def likelihood(paramContainer, wiggle): 72 v, L= M.likelihood(paramContainer, wiggle)73 return Packer( v, L)()72 L, v = M.likelihood(paramContainer, wiggle) 73 return Packer(L, v)() 74 74 75 75 ########################################################################### … … 112 112 def likelihood(self, paramContainer, wiggle, remote=False, local=False): 113 113 """ 114 Returns the log-likelihood of the parameters in the supplied114 Computes the log-likelihood of the parameters in the supplied 115 115 I{paramContainer} for my model. 116 116 117 Updates in-place the container's sole latent parameter, an array of 118 volatility shocks after some MCMC involved with the likelihood 119 compution. 117 Updates the container in-place with the log-likelihood and an array of 118 volatility shocks on which the likelihood computation is based, after 119 undergoing some nested MCMC. 120 121 Returns a deferred that fires (with C{None}) when the likelihood 122 computation is done and the paramContainer has been updated. 120 123 """ 121 124 def gotPackedLikelihood(result): … … 123 126 # An error from the remote likelihood method call is treated as 124 127 # infinitely low likelihood 125 return-s.inf128 paramContainer.pLogLikelihood = -s.inf 126 129 up = pack.Unpacker(result) 127 paramContainer. v= up()128 returnup()130 paramContainer.pLogLikelihood = up() 131 paramContainer.latent = up() 129 132 130 133 def gotLikelihood(result): 131 paramContainer. v= result[0]132 returnresult[1]134 paramContainer.pLogLikelihood = result[0] 135 paramContainer.latent = result[1] 133 136 134 137 if (remote or self.remoteMode) and not local: … … 210 213 def _get_var(self): 211 214 if 'var' not in self.cache: 212 self.cache['var'] = VAR(self. tsList)215 self.cache['var'] = VAR(self.y) 213 216 return self.cache['var'] 214 217 var = property(_get_var) … … 254 257 if hs != xs: 255 258 raise ValueError("Need one log-volatility per innovation") 256 x *= s.exp(-0.5*h)259 x = s.exp(-0.5*h) * x.copy() 257 260 if 'decorrelate' not in self.cache: 258 261 self.cache['decorrelate'] = linalg.inv( … … 268 271 The result will be the total log-likelihood of the innovations, given 269 272 my volatility/innovation shock correlations C{g} and the volatility 270 shocks currently in my random walker C{nw}. A constant term in the 271 log-likelihood is disregarded, C{sqrt(2*pi)}. 272 """ 273 mu = self.g * self.nw() 273 shocks currently in my random walker C{nw}. 274 """ 275 mu = +self.g * self.nw() 274 276 sigma2 = 1 - self.g**2 275 logProbs = -(y - mu)**2 / (2*sigma2) - 0.5 * s.log(sigma2)277 logProbs = -(y - mu)**2 / (2*sigma2) - 0.5 * s.log(2*s.pi*sigma2) 276 278 return logProbs.sum() 277 279 278 def logUniform(self , N):280 def logUniform(self): 279 281 """ 280 282 Returns a log-uniform variate taken from a large array that is … … 284 286 """ 285 287 logU = getattr(self, '_logU_array', []) 286 if self._logU_index >= len(logU) :288 if self._logU_index >= len(logU)-1: 287 289 self._logU_index = -1 288 290 # The efficient array operation … … 296 298 def likelihood(self, paramContainer, wiggle): 297 299 """ 298 Call this method with a parameter object that defines (1) a set of 299 values for my parameters and (2) an array of volatility shocks to be 300 used as a starting point for another simulation draw of volatilities. 300 Call this method with a parameter object that defines: 301 302 1. a set of values for my parameters, and 303 304 2. a latent parameter consisting of an array of volatility shocks 305 to be used as a starting point for another simulation draw of 306 volatilities, and 307 308 3. a 1-D array of log-likelihoods for each observation time given 309 the volatility shocks. 301 310 302 311 A new 2-D array of log-volatilities will be drawn from a relatively … … 309 318 310 319 The value of that log-likelihood at the end of the log-volatility 311 simulation is returned in a tuple, preceded by the volatility shocks320 simulation is returned in a tuple, followed by the volatility shocks 312 321 underlying the log-volatilities drawn at that point. 313 322 … … 318 327 what, making any call to this method with it a waste of computing time. 319 328 """ 320 if paramContainer.v:321 self.nw(paramContainer. v)329 if len(paramContainer.latent): 330 self.nw(paramContainer.latent) 322 331 self.setParamSequence(paramContainer.paramSequence()) 323 332 # Obtain innovations as residuals of the reversed VAR(1) … … 330 339 # Compute the total log-likelihood conditional on the proposed 331 340 # log-volatilities 341 #Lp = self.likelihoodOfInnovations(s.exp(-0.5*h)*x) 332 342 Lp = self.likelihoodOfInnovations(self.decorrelate(x, h)) 333 343 # Metropolis-Hastings accept/reject of the proposal 334 344 if Lp > L or (Lp-L) > self.logUniform(): 345 if j > 0: 346 print "\n%d -> %d" % (L, Lp) 335 347 L = Lp 336 348 vShocks = self.nw() 337 return vShocks, L 349 else: 350 print ".", 351 print "\n" 352 return L, vShocks projects/AsynCluster/tags/20080419/svpmc/params.py
r150 r151 27 27 28 28 29 SHAPE_MISMATCH = ValueError( 30 "shape mismatch: objects cannot be broadcast to a single shape") 31 32 29 33 PARAM_NAMES = [ 30 34 # Approximately p*(3+2.5) parameters total, e.g., 125 for p=5 … … 50 54 51 55 56 class FlexArray(object): 57 """ 58 I am an array of arbitrary objects, accessible in much the same manner as the 59 elements of a SciPy array object. Initially, all my objects are C{None}. 60 61 Call an instance of me with a hash array and you'll get a new instance with 62 just the subset of objects referenced by the array. 63 64 Call the instance with a single object ID and you'll get that object, just 65 like you'd get a numeric scalar by addressing a single element of a SciPy 66 array. 67 68 B{Caveat}: Unlike the behavior of SciPy arrays, Setting elements of a 69 subset or raveled version of an instance of me does I{not} set the 70 corresponding element of the original instance. 71 72 """ 73 def __init__(self, *shape): 74 self.shape = shape 75 self.N = 1 76 for dim in shape: 77 self.N *= dim 78 # Object list 79 self.O = [None] * self.N 80 # Index array 81 self.I = s.arange(self.N).reshape(*shape) 82 83 def __call__(self, I): 84 if isinstance(I, int): 85 return self.O[I] 86 newVersion = self.__class__(*I.shape) 87 for j, k in enumerate(I.ravel()): 88 newVersion.O[j] = self.O[k] 89 return newVersion 90 91 def __len__(self): 92 return self.N 93 94 def __iter__(self): 95 self.k = -1 96 return self 97 98 def next(self): 99 self.k += 1 100 if self.k < self.N: 101 return self(self.I[self.k]) 102 raise StopIteration 103 104 def __getitem__(self, key): 105 return self(self.I[key]) 106 107 def __setitem__(self, key, value): 108 I = self.I[key] 109 if isinstance(I, int): 110 self.O[I] = value 111 elif I.shape == s.shape(value): 112 if not isinstance(value, (list, tuple)): 113 value = value.ravel() 114 for j, k in enumerate(I.ravel()): 115 self.O[k] = value[j] 116 else: 117 raise SHAPE_MISMATCH 118 119 def ravel(self): 120 return self(self.I.ravel()) 121 122 def reshape(self, *shape): 123 return self(self.I.reshape(*shape)) 124 125 def __add__(self, other): 126 if other.shape != self.shape: 127 raise SHAPE_MISMATCH 128 newVersion = self(self.I) 129 for k, thisObj in enumerate(newVersion.O): 130 thisObj += other.O[k] 131 return newVersion 132 133 def call(self, methodName, *args, **kw): 134 """ 135 For each of my objects, call the method specified by I{methodName} with 136 any further args and keywords supplied. 137 138 Returns the result (must be a numeric scalar) of each call in an array 139 of the same shape as my object array. 140 """ 141 x = s.empty(self.shape) 142 for k in self.I.ravel(): 143 thisValue = getattr(self.O[k], methodName)(*args, **kw) 144 if not isinstance(thisValue, (int, long, float)): 145 raise ValueError( 146 "Called method must return a numeric scalar value") 147 x.ravel()[k] = thisValue 148 return x 149 52 150 53 151 class PriorContainer(object): … … 61 159 self.spec = fh.read() 62 160 fh.close() 63 64 65 161 66 162 … … 140 236 141 237 142 class ParamArray(object):143 """144 My items can be accessed in the same manner as those of a SciPy array145 object.146 """147 def __init__(self, iterable):148 self.pcList = list(iterable)149 150 def _get_indices(self):151 return s.arange(len(self.pcList))152 I = property(_get_indices)153 154 def __len__(self):155 return len(self.pcList)156 157 def __getitem__(self, key):158 I = self.I[key]159 if isinstance(I, int):160 return self.pcList[I]161 return self.__class__([self.pcList[x] for x in I])162 163 def __getslice__(self, i, j):164 return self.__class__(self.pcList[i:j])165 166 def append(self, pc):167 self.pcList.append(pc)168 169 170 171 238 class ParameterContainer(Parameterized): 172 239 """ 173 240 """ 174 keyAttrs = {' v':[]}241 keyAttrs = {'latent':[], 'pLogLikelihood':None, 'pLogProposal':None} 175 242 paramNames = PARAM_NAMES 176 243 177 244 def __add__(self, other): 178 newVersion = self.__class__( v=self.v)245 newVersion = self.__class__(latent=self.latent) 179 246 newVersion.setParamSequence([ 180 247 getattr(self, name) + getattr(other, name) projects/AsynCluster/tags/20080419/svpmc/pmc.py
r150 r151 33 33 from asyncluster.master import jobs 34 34 35 import model 35 import model, params 36 36 from sample import resample 37 37 … … 194 194 """ 195 195 k = 0 196 XP, W = params.ParamArray, []196 XP, W = [], [] 197 197 wfd = defer.waitForDeferred( 198 198 self.queue.call(self.proposals, X, v, series='proposals')) … … 214 214 W.append(L[If] + XPJ[1][Ic][If] - XPJ[2][Ic][If]) 215 215 if XP: 216 yield s.row_stack(XP), s.concatenate(W) 216 arrayXP = params.FlexArray(len(XP)) 217 for k, thisXP in enumerate(XP): 218 arrayXP[k] = thisXP 219 yield arrayXP, s.concatenate(W) 217 220 else: 218 221 yield [], [] projects/AsynCluster/tags/20080419/svpmc/sample.py
r150 r151 87 87 if x is None: 88 88 return self.x.copy() 89 if s.shape(x) != self.x.shape: 89 s1, s0 = s.shape(x), self.x.shape 90 if len(s1) == 1 or (len(s1) == 2 and s1[1] == 1): 91 # Resize doesn't seem to work in all cases, so just build another 92 # single-row array 93 x = s.row_stack([x]) 94 s1 = (1, s1[0]) 95 if s1 != s0: 90 96 raise ValueError( 91 97 "You can only update me with an equivalent-dimensioned array") … … 134 140 vector supplied will be re-used. 135 141 """ 136 if correlations: 137 # Generate the correlation matrix and save in case not supplied 138 # next time 139 self.r = linalg.cholesky( 140 self.covarMatrix(correlations), lower=True) 142 if correlations is not None: 141 143 self.y = s.empty_like(self.x) 144 if correlations: 145 # Generate the correlation matrix and save in case not supplied 146 # next time 147 self.r = linalg.cholesky( 148 self.covarMatrix(correlations), lower=True) 149 else: 150 self.r = None 151 142 152 n = self.x.shape[0] 143 if s.shape(getattr(self, 'r', None)) != (n, n): 153 if n == 1: 154 return self.x.copy() 155 if not hasattr(self, 'r') or s.shape(self.r) != (n, n): 144 156 raise ValueError( 145 157 "Must have a [%d x %d] cross-correlation matrix defined" \ projects/AsynCluster/tags/20080419/svpmc/test/test_model.py
r149 r151 22 22 import scipy as s 23 23 from scipy import stats, random 24 from scipy.signal import signaltools 24 25 25 26 from twisted.internet import reactor, defer … … 28 29 from twisted_goodies.pybywire import pack, params 29 30 30 import model 31 import model, tseries 31 32 import util 32 33 … … 150 151 "'Uncorrelated' hypothesis fails with p=%f" % corrInfo[1]) 151 152 153 def _check_corr(self, x, y, plot=True): 154 corrInfo = stats.spearmanr(x, y) 155 failed = abs(corrInfo[0]) < 0.5 and corrInfo[1] > 0.05 156 regressInfo = stats.linregress(x, y) 157 if (plot and VERBOSE) or failed: 158 m, b = regressInfo[:2] 159 sp = self.fig.add_subplot(111) 160 sp.plot(x, y, '.', x, m*x+b, '-') 161 sp.grid(True) 162 sp.set_title("r=%f, p=%f" % corrInfo) 163 if failed: 164 self.fail( 165 "Correlation is %f; " % corrInfo[0] +\ 166 "'Uncorrelated' hypothesis not disproved, p=%f" % corrInfo[1]) 167 152 168 def _check_xcorr(self, dPeak): 153 169 n = self.model.n … … 354 370 355 371 class Test_Model_other(Multivariate_BaseCase): 372 N = 100 373 corr = 0.0 374 params = { 375 'a': [0], 376 'b': [[0]], 377 'c': [], 378 'd': [0.01], 379 'e': [[0.8]], 380 'f': [], 381 'g': [corr], 382 } 383 for key, value in params.iteritems(): 384 params[key] = s.array(value) 385 386 class Mock_ParameterContainer(object): 387 latent = [] 388 def paramSequence(self): 389 return [self.params[x] for x in "abcdefg"] 390 391 @classmethod 392 def pcFactory(cls): 393 pc = cls.Mock_ParameterContainer() 394 pc.params = cls.params 395 return pc 396 356 397 def setUp(self): 357 self.model = model.Model() 358 398 # Parameters 399 # Simulate a single time series of data per the parameters 400 self.iv = random.multivariate_normal( 401 [0, 0], [[1.0, self.corr], [self.corr, 1.0]], self.N).transpose() 402 h = signaltools.lfilter( 403 [1], [1.0, self.params['e'][0][0]], self.iv[1,:]) 404 self.x = s.exp(0.5*h) * self.iv[1,:] 405 # Instantiate a model to be tested and set its parameters 406 self.model = model.Model(tsList=[tseries.TimeSeries( 407 'test', data=s.column_stack([s.arange(self.N), self.x]))]) 408 for name, value in self.params.iteritems(): 409 setattr(self.model, name, value) 410 359 411 def test_likelihoodOfInnovations(self): 360 self.fail("TODO") 412 self.model.nw(self.iv[1,:]) 413 pLog = self.model.likelihoodOfInnovations(self.iv[0,:]) 414 self.failUnlessAlmostEqual( 415 4.0 * s.exp(pLog/self.N) * s.sqrt(1-self.corr**2), 1.0, 0) 416 # <+> <-+--------------> <-+---------------------------> 417 # | | | 418 # | | +- Divide by scaling term of 419 # | | joint density 420 # | | 421 # | +- Linear density, averaged 422 # | 423 # +--- Unscale by 1/2 total probability for each, squared 361 424 362 425 def test_logUniform(self): 363 self.fail("TODO") 426 N = 35000 427 import timeit 428 tObserved = timeit.Timer( 429 "M.logUniform()", 430 "import model\nM = model.Model()").timeit(N) 431 tBaseline = timeit.Timer( 432 "s.log(s.rand())", 433 "import scipy as s").timeit(N) 434 percent = 100 * tObserved/tBaseline 435 if VERBOSE: 436 print "The efficient method took %2d%% as long as the stupid way" \ 437 % percent 438 self.failUnless(percent < 40) 364 439 365 440 def test_likelihood(self): 366 self.fail("TODO") 441 N_plot = 100 442 wiggle = 0.001 443 self.model.M = 10000 444 paramContainer = self.pcFactory() 445 # DEBUG 446 paramContainer.latent = 0.5*self.iv[1,:] + 0.5*s.randn(self.N) 447 L, vShocks = self.model.likelihood(paramContainer, wiggle) 448 #import pdb; pdb.set_trace() 449 if VERBOSE: 450 fig = self.fig 451 sp = fig.add_subplot(211) 452 sp.plot(self.iv[1,:N_plot]) 453 sp = fig.add_subplot(212) 454 sp.plot(vShocks[0][:N_plot]) 455 self._check_corr(self.iv[1,:], vShocks[0]) 456 projects/AsynCluster/tags/20080419/svpmc/test/test_sample.py
r148 r151 89 89 if k % M == 0: 90 90 yield x 91 92 def test_call(self): 93 walker = sample.NormalWalk(1, 100) 94 walker(s.ones(100)) 95 walker(s.ones((1,100))) 96 walker(s.ones((100,1))) 91 97 92 98 def test_univariate_bigJumps(self): projects/AsynCluster/trunk/svpmc/model.py
r150 r151 70 70 71 71 def likelihood(paramContainer, wiggle): 72 v, L= M.likelihood(paramContainer, wiggle)73 return Packer( v, L)()72 L, v = M.likelihood(paramContainer, wiggle) 73 return Packer(L, v)() 74 74 75 75 ########################################################################### … … 112 112 def likelihood(self, paramContainer, wiggle, remote=False, local=False): 113 113 """ 114 Returns the log-likelihood of the parameters in the supplied114 Computes the log-likelihood of the parameters in the supplied 115 115 I{paramContainer} for my model. 116 116 117 Updates in-place the container's sole latent parameter, an array of 118 volatility shocks after some MCMC involved with the likelihood 119 compution. 117 Updates the container in-place with the log-likelihood and an array of 118 volatility shocks on which the likelihood computation is based, after 119 undergoing some nested MCMC. 120 121 Returns a deferred that fires (with C{None}) when the likelihood 122 computation is done and the paramContainer has been updated. 120 123 """ 121 124 def gotPackedLikelihood(result): … … 123 126 # An error from the remote likelihood method call is treated as 124 127 # infinitely low likelihood 125 return-s.inf128 paramContainer.pLogLikelihood = -s.inf 126 129 up = pack.Unpacker(result) 127 paramContainer. v= up()128 returnup()130 paramContainer.pLogLikelihood = up() 131 paramContainer.latent = up() 129 132 130 133 def gotLikelihood(result): 131 paramContainer. v= result[0]132 returnresult[1]134 paramContainer.pLogLikelihood = result[0] 135 paramContainer.latent = result[1] 133 136 134 137 if (remote or self.remoteMode) and not local: … … 210 213 def _get_var(self): 211 214 if 'var' not in self.cache: 212 self.cache['var'] = VAR(self. tsList)215 self.cache['var'] = VAR(self.y) 213 216 return self.cache['var'] 214 217 var = property(_get_var) … … 254 257 if hs != xs: 255 258 raise ValueError("Need one log-volatility per innovation") 256 x *= s.exp(-0.5*h)259 x = s.exp(-0.5*h) * x.copy() 257 260 if 'decorrelate' not in self.cache: 258 261 self.cache['decorrelate'] = linalg.inv( … … 268 271 The result will be the total log-likelihood of the innovations, given 269 272 my volatility/innovation shock correlations C{g} and the volatility 270 shocks currently in my random walker C{nw}. A constant term in the 271 log-likelihood is disregarded, C{sqrt(2*pi)}. 272 """ 273 mu = self.g * self.nw() 273 shocks currently in my random walker C{nw}. 274 """ 275 mu = +self.g * self.nw() 274 276 sigma2 = 1 - self.g**2 275 logProbs = -(y - mu)**2 / (2*sigma2) - 0.5 * s.log(sigma2)277 logProbs = -(y - mu)**2 / (2*sigma2) - 0.5 * s.log(2*s.pi*sigma2) 276 278 return logProbs.sum() 277 279 278 def logUniform(self , N):280 def logUniform(self): 279 281 """ 280 282 Returns a log-uniform variate taken from a large array that is … … 284 286 """ 285 287 logU = getattr(self, '_logU_array', []) 286 if self._logU_index >= len(logU) :288 if self._logU_index >= len(logU)-1: 287 289 self._logU_index = -1 288 290 # The efficient array operation … … 296 298 def likelihood(self, paramContainer, wiggle): 297 299 """ 298 Call this method with a parameter object that defines (1) a set of 299 values for my parameters and (2) an array of volatility shocks to be 300 used as a starting point for another simulation draw of volatilities. 300 Call this method with a parameter object that defines: 301 302 1. a set of values for my parameters, and 303 304 2. a latent parameter consisting of an array of volatility shocks 305 to be used as a starting point for another simulation draw of 306 volatilities, and 307 308 3. a 1-D array of log-likelihoods for each observation time given 309 the volatility shocks. 301 310 302 311 A new 2-D array of log-volatilities will be drawn from a relatively … … 309 318 310 319 The value of that log-likelihood at the end of the log-volatility 311 simulation is returned in a tuple, preceded by the volatility shocks320 simulation is returned in a tuple, followed by the volatility shocks 312 321 underlying the log-volatilities drawn at that point. 313 322 … … 318 327 what, making any call to this method with it a waste of computing time. 319 328 """ 320 if paramContainer.v:321 self.nw(paramContainer. v)329 if len(paramContainer.latent): 330 self.nw(paramContainer.latent) 322 331 self.setParamSequence(paramContainer.paramSequence()) 323 332 # Obtain innovations as residuals of the reversed VAR(1) … … 330 339 # Compute the total log-likelihood conditional on the proposed 331 340 # log-volatilities 341 #Lp = self.likelihoodOfInnovations(s.exp(-0.5*h)*x) 332 342 Lp = self.likelihoodOfInnovations(self.decorrelate(x, h)) 333 343 # Metropolis-Hastings accept/reject of the proposal 334 344 if Lp > L or (Lp-L) > self.logUniform(): 345 if j > 0: 346 print "\n%d -> %d" % (L, Lp) 335 347 L = Lp 336 348 vShocks = self.nw() 337 return vShocks, L 349 else: 350 print ".", 351 print "\n" 352 return L, vShocks projects/AsynCluster/trunk/svpmc/params.py
r150 r151 27 27 28 28 29 SHAPE_MISMATCH = ValueError( 30 "shape mismatch: objects cannot be broadcast to a single shape") 31 32 29 33 PARAM_NAMES = [ 30 34 # Approximately p*(3+2.5) parameters total, e.g., 125 for p=5 … … 50 54 51 55 56 class FlexArray(object): 57 """ 58 I am an array of arbitrary objects, accessible in much the same manner as the 59 elements of a SciPy array object. Initially, all my objects are C{None}. 60 61 Call an instance of me with a hash array and you'll get a new instance with 62 just the subset of objects referenced by the array. 63 64 Call the instance with a single object ID and you'll get that object, just 65 like you'd get a numeric scalar by addressing a single element of a SciPy 66 array. 67 68 B{Caveat}: Unlike the behavior of SciPy arrays, Setting elements of a 69 subset or raveled version of an instance of me does I{not} set the 70 corresponding element of the original instance. 71 72 """ 73 def __init__(self, *shape): 74 self.shape = shape 75 self.N = 1 76 for dim in shape: 77 self.N *= dim 78 # Object list 79 self.O = [None] * self.N 80 # Index array 81 self.I = s.arange(self.N).reshape(*shape) 82 83 def __call__(self, I): 84 if isinstance(I, int): 85 return self.O[I] 86 newVersion = self.__class__(*I.shape) 87 for j, k in enumerate(I.ravel()): 88 newVersion.O[j] = self.O[k] 89 return newVersion 90 91 def __len__(self): 92 return self.N 93 94 def __iter__(self): 95 self.k = -1 96 return self 97 98 def next(self): 99 self.k += 1 100 if self.k < self.N: 101 return self(self.I[self.k]) 102 raise StopIteration 103 104 def __getitem__(self, key): 105 return self(self.I[key]) 106 107 def __setitem__(self, key, value): 108 I = self.I[key] 109 if isinstance(I, int): 110 self.O[I] = value 111 elif I.shape == s.shape(value): 112 if not isinstance(value, (list, tuple)): 113 value = value.ravel() 114 for j, k in enumerate(I.ravel()): 115 self.O[k] = value[j] 116 else: 117 raise SHAPE_MISMATCH 118 119 def ravel(self): 120 return self(self.I.ravel()) 121 122 def reshape(self, *shape): 123 return self(self.I.reshape(*shape)) 124 125 def __add__(self, other): 126 if other.shape != self.shape: 127 raise SHAPE_MISMATCH 128 newVersion = self(self.I) 129 for k, thisObj in enumerate(newVersion.O): 130 thisObj += other.O[k] 131 return newVersion 132 133 def call(self, methodName, *args, **kw): 134 """ 135 For each of my objects, call the method specified by I{methodName} with 136 any further args and keywords supplied. 137 138 Returns the result (must be a numeric scalar) of each call in an array 139 of the same shape as my object array. 140 """ 141 x = s.empty(self.shape) 142 for k in self.I.ravel(): 143 thisValue = getattr(self.O[k], methodName)(*args, **kw) 144 if not isinstance(thisValue, (int, long, float)): 145 raise ValueError( 146 "Called method must return a numeric scalar value") 147 x.ravel()[k] = thisValue 148 return x 149 52 150 53 151 class PriorContainer(object): … … 61 159 self.spec = fh.read() 62 160 fh.close() 63 64 65 161 66 162 … … 140 236 141 237 142 class ParamArray(object):143 """144 My items can be accessed in the same manner as those of a SciPy array145 object.146 """147 def __init__(self, iterable):148 self.pcList = list(iterable)149 150 def _get_indices(self):151 return s.arange(len(self.pcList))152 I = property(_get_indices)153 154 def __len__(self):155 return len(self.pcList)156 157 def __getitem__(self, key):158 I = self.I[key]159 if isinstance(I, int):160 return self.pcList[I]161 return self.__class__([self.pcList[x] for x in I])162 163 def __getslice__(self, i, j):164 return self.__class__(self.pcList[i:j])165 166 def append(self, pc):167 self.pcList.append(pc)168 169 170 171 238 class ParameterContainer(Parameterized): 172 239 """ 173 240 """ 174 keyAttrs = {' v':[]}241 keyAttrs = {'latent':[], 'pLogLikelihood':None, 'pLogProposal':None} 175 242 paramNames = PARAM_NAMES 176 243 177 244 def __add__(self, other): 178 newVersion = self.__class__( v=self.v)245 newVersion = self.__class__(latent=self.latent) 179 246 newVersion.setParamSequence([ 180 247 getattr(self, name) + getattr(other, name) projects/AsynCluster/trunk/svpmc/pmc.py
r150 r151 33 33 from asyncluster.master import jobs 34 34 35 import model 35 import model, params 36 36 from sample import resample 37 37 … … 194 194 """ 195 195 k = 0 196 XP, W = params.ParamArray, []196 XP, W = [], [] 197 197 wfd = defer.waitForDeferred( 198 198 self.queue.call(self.proposals, X, v, series='proposals')) … … 214 214 W.append(L[If] + XPJ[1][Ic][If] - XPJ[2][Ic][If]) 215 215 if XP: 216 yield s.row_stack(XP), s.concatenate(W) 216 arrayXP = params.FlexArray(len(XP)) 217 for k, thisXP in enumerate(XP): 218 arrayXP[k] = thisXP 219 yield arrayXP, s.concatenate(W) 217 220 else: 218 221 yield [], [] projects/AsynCluster/trunk/svpmc/sample.py
r150 r151 87 87 if x is None: 88 88 return self.x.copy() 89 if s.shape(x) != self.x.shape: 89 s1, s0 = s.shape(x), self.x.shape 90 if len(s1) == 1 or (len(s1) == 2 and s1[1] == 1): 91 # Resize doesn't seem to work in all cases, so just build another 92 # single-row array 93 x = s.row_stack([x]) 94 s1 = (1, s1[0]) 95 if s1 != s0: 90 96 raise ValueError( 91 97 "You can only update me with an equivalent-dimensioned array") … … 134 140 vector supplied will be re-used. 135 141 """ 136 if correlations: 137 # Generate the correlation matrix and save in case not supplied 138 # next time 139 self.r = linalg.cholesky( 140 self.covarMatrix(correlations), lower=True) 142 if correlations is not None: 141 143 self.y = s.empty_like(self.x) 144 if correlations: 145 # Generate the correlation matrix and save in case not supplied 146 # next time 147 self.r = linalg.cholesky( 148 self.covarMatrix(correlations), lower=True) 149 else: 150 self.r = None 151 142 152 n = self.x.shape[0] 143 if s.shape(getattr(self, 'r', None)) != (n, n): 153 if n == 1: 154 return self.x.copy() 155 if not hasattr(self, 'r') or s.shape(self.r) != (n, n): 144 156 raise ValueError( 145 157 "Must have a [%d x %d] cross-correlation matrix defined" \ projects/AsynCluster/trunk/svpmc/test/test_model.py
r149 r151 22 22 import scipy as s 23 23 from scipy import stats, random 24 from scipy.signal import signaltools 24 25 25 26 from twisted.internet import reactor, defer … … 28 29 from twisted_goodies.pybywire import pack, params 29 30 30 import model 31 import model, tseries 31 32 import util 32 33 … … 150 151 "'Uncorrelated' hypothesis fails with p=%f" % corrInfo[1]) 151 152 153 def _check_corr(self, x, y, plot=True): 154 corrInfo = stats.spearmanr(x, y) 155 failed = abs(corrInfo[0]) < 0.5 and corrInfo[1] > 0.05 156 regressInfo = stats.linregress(x, y) 157 if (plot and VERBOSE) or failed: 158 m, b = regressInfo[:2] 159 sp = self.fig.add_subplot(111) 160 sp.plot(x, y, '.', x, m*x+b, '-') 161 sp.grid(True) 162 &nbs
