Changeset 207

Show
Ignore:
Timestamp:
06/02/08 19:04:49 (7 months ago)
Author:
edsuom
Message:

Got Rao-Blackwellized version working locally & remotely, with better but still disappointing degeneracy

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • projects/AsynCluster/trunk/asyncluster/ndm/worker.py

    r125 r207  
    9191    Manager() 
    9292 
     93 
     94def runForeground(debug=False): 
     95    """ 
     96    Runs a child worker L{Manager} in the foreground. Useful for debugging, 
     97    because you can see stdout & stderr. 
     98    """ 
     99    if debug: 
     100        import pdb 
     101        try: 
     102            Manager() 
     103        except: 
     104            pdb.pm() 
     105    else: 
     106        Manager() 
  • projects/AsynCluster/trunk/svpmc/model.c

    r205 r207  
    182182  double c, cp; 
    183183  const double diff = b-a; 
    184   const double scaleUp = 1.06; // Increase scale value to account for EXP error 
    185184  // Compute the scale value c as the maximum possible pdf (regular normal 
    186185  // distribution) within the truncated range 
    187186  if(a < 0) { 
    188187    if(b > 0) { 
    189       // Center is within the range, so use its pdf 
    190       c = scaleUp; 
     188      // Center is within the range, so use the maximum pdf at center 
     189      c = 1.02; // Higher than 1.0 due to max EXP +error of 1.02 
    191190    } else { 
    192       // Range is below center, so use pdf at its right edge 
    193       c = scaleUp * EXP(-0.5*b*b); 
     191      // Range is below center, so use maximum pdf at its right edge 
     192      c = 1.0625 * EXP(-0.5*b*b); // Scaled up by 1.02 / 0.96 
    194193    } 
    195194  } else { 
    196195    // Range is above center, so use pdf at its left edge 
    197     c = scaleUp * EXP(-0.5*a*a); 
     196    c = 1.0625 * EXP(-0.5*a*a); // Scaled up by 1.02 / 0.96 
    198197  } 
    199198  // Accept-reject sampling for the truncated normal distribution 
     
    315314// z    Independent normal variates, [pn] array (updated) 
    316315// x    Innovation values, [pn] array 
    317 // h    Simulated last-sample multivariate log-volatility, [p] (overwritten) 
    318316// w    Wiggle value for +/- proposals (float) 
    319317// ni   Number of hybrid-Gibbs iterations (int) 
     
    469467} 
    470468 
    471 // Save the multivariate log-volatility simulated for the last time-series 
    472 // sample in the last iteration 
    473 for(k0=0; k0<Nt; k0++) 
    474   H1(k0) = PA1(se[ke].h, k0); 
    475  
    476469// Free array memory 
    477470free(xk); 
  • projects/AsynCluster/trunk/svpmc/model.py

    r206 r207  
    8989            self._z[member,:,:] = z 
    9090        if len(self.failures) + len(self.successes) == self.m: 
    91             zPacked = pack.Packer(self.z)() 
     91            zInt = (INT_SCALE * self.z).astype('h') 
     92            zPacked = pack.Packer(zInt)() 
    9293            k = 0 
    9394            N = len(zPacked) 
     
    125126        global MODEL 
    126127        MODEL = modelObj 
     128        MODEL.z = None 
    127129 
    128130    def newZ(zPacked, k, N): 
     
    130132        if k == 0: 
    131133            CHUNKS = [] 
     134            MODEL.z = None 
    132135        CHUNKS.append(zPacked) 
    133         if k == N-1: 
    134             MODEL.z = %f * pack.Unpacker(''.join(CHUNKS)).astype('d') 
     136        if k == N-1 and len(CHUNKS) == N: 
     137            zInt = pack.Unpacker(''.join(CHUNKS))() 
     138            MODEL.z = %f * zInt.astype('d') 
    135139     
    136140    def hybridGibbs(paramContainer): 
    137         return pack.Packer(*MODEL.hybridGibbs(paramContainer)) 
     141        if MODEL is None: 
     142            raise RuntimeError('No model available') 
     143        return pack.Packer(MODEL.hybridGibbs(paramContainer))() 
    138144     
    139145    def likelihood(paramContainer): 
     146        if MODEL is None: 
     147            raise RuntimeError('No model available') 
     148        if MODEL.z is None: 
     149            raise RuntimeError( 
     150                'Model not initialized with simulated log-volatility data') 
    140151        return MODEL.likelihood(paramContainer) 
    141152 
     
    220231        def unpackResult(packedResult): 
    221232            if packedResult: 
    222                 return list(pack.Unpacker(packedResult)
    223  
     233                return pack.Unpacker(packedResult)(
     234         
    224235        def simulationDone(result): 
    225236            if result is None: 
    226237                update() 
    227238                return False 
    228             update(result[0]) 
    229             paramContainer.h = result[1] 
     239            update(result) 
    230240            return True 
    231241         
     
    257267            return paramContainer 
    258268 
     269        # DEBUG 
    259270        if (remote or self.remoteMode) and not local: 
    260271            d = self.client.run( 
     
    332343    #--- Support -------------------------------------------------------------- 
    333344 
    334     def covarMatrix(self, cs, cr): 
    335         """ 
    336         Returns a covariance matrix from the vector or sequence of I{cs} 
    337         standard deviations and I{cr} cross-correlations. 
    338  
    339         The I{cs} argument is in the form s0, s1,..., sp. It must have C{p} 
    340         elements. 
    341  
    342         The I{cr} argument must have C{0.5*(p**2 + p)} elements and is in the 
    343         form r00, r01, r02,..., r0p, r11, r12,..., r1p,..., rpp 
    344         """ 
    345         i = 0 
    346         p = self.p 
    347         cv = s.zeros((p, p)) 
    348         for j in xrange(p): 
    349             cv[j,j] = cs[j]**2 
    350             for k in xrange(j+1, p): 
    351                 cv[j, k] = cv[k, j] = cr[i] * cs[j] * cs[k] 
    352                 i += 1 
    353         return cv 
    354  
    355345    def setParams(self, paramContainer): 
    356346        """ 
    357         """ 
    358         # Set my parameters 
     347        Sets up array variables for an inline call made by the caller, 
     348        including innovations as residuals of my observations run through the 
     349        reversed VAR(1). 
     350        """ 
    359351        self.setParamSequence(paramContainer.paramSequence()) 
    360  
    361         # Set up array variables for the inline call, including innovations as 
    362         # residuals of my observations run through the reversed VAR(1)... 
    363352        self.x = self.var.reverse(self.a, self.b) 
    364         # ...concurrent cross-correlations between volatility shocks and 
    365         # inverse of concurrent cross-correlations between innovation shocks 
    366         # (we'll bail out with no result if either is invalid), and... 
    367         try: 
    368             self.rz = linalg.cholesky( 
    369                 self.covarMatrix(self.fs, self.fr), lower=True).astype('d') 
    370             self.ri = linalg.inv(linalg.cholesky(self.covarMatrix( 
    371                 s.ones(self.p), self.cr), lower=True)).astype('d') 
    372         except linalg.LinAlgError: 
    373             return 
    374         # ...scaling constants for multivariate normal pdf 
    375         self.sc = s.empty((self.p, 2)) 
    376         self.sc[:,0] = 1.0 / s.sqrt(1.0 - self.g**2) 
    377         self.sc[:,1] = s.log(s.sqrt(2*s.pi) / self.sc[:,0]) 
    378      
     353 
    379354     
    380355    #--- The API -------------------------------------------------------------- 
     
    396371        If a L{linalg.LinAlgError} is raised due to an invalid correlation 
    397372        matrix parameter, the method returns with no result. Otherwise, it 
    398         returns a tuple containing the following: 
    399          
    400             1. The IID normal variates underlying the simulated 
    401                log-volatilities after the last simulation round. 
    402  
    403             2. The multivariate log-volatility value for the last time-series 
    404                sample after the last simulation round. (Useful for 
    405                extrapolating from the fitted model.) 
     373        returns the IID normal variates underlying the simulated 
     374        log-volatilities after the last simulation round. 
    406375 
    407376        """ 
     
    410379        # every log-volatility simulation 
    411380        z = s.zeros_like(self.x) 
    412         # This will contain the simulated log-volatility of the last 
    413         # time-series sample 
    414         h = s.empty(self.p) 
    415381        self.inline( 
    416             'z', 'h', 'x', 'w', 'ni', 
     382            'z', 'x', 'w', 'ni', 
    417383            'd', 'e', 'g', 'rz', 'ri', 'sc', 
    418384            w=self.wiggle, ni=self.Ni) 
    419         return z, h 
     385        return z 
    420386 
    421387    def likelihood(self, paramContainer): 
  • projects/AsynCluster/trunk/svpmc/params.py

    r206 r207  
    2222import os.path 
    2323import scipy as s 
     24from scipy import linalg 
    2425from scipy.stats import distributions 
    2526 
     
    248249        - A scalar I{Lj} with the log-probability density of the proposal jump 
    249250          resulting in my parameters. 
    250  
    251         - A 1-D array I{h} containing the last multivariate log-volatility 
    252           value of any log-volatility simulation yet done on me. 
    253      
    254     """ 
    255     keyAttrs = {'Lx':None, 'Lp':None, 'Lj':None, 'h':None} 
     251     
     252    """ 
     253    keyAttrs = {'Lx':None, 'Lp':None, 'Lj':None} 
    256254 
    257255 
     
    268266 
    269267    """ 
    270     keyAttrs = {'V':None} 
    271268    paramNames = ['dname', 'loc', 'scale', 'a', 'b'] 
    272269    N_draw = 1000 
    273     N_attempts = 200 
    274270 
    275271    class Constant(object): 
     
    318314 
    319315    def _newDraw(self): 
    320         D = len(self.V) 
    321316        rJumps = self.rdsObj.rvs(self.N_draw) 
    322317        pJumps = self.rdsObj.pdf(rJumps) 
     
    348343        return self.distObj.rvs(1)[0] 
    349344 
    350     def rJump(self, startValue, vIndex): 
    351         """ 
    352         Call this method with a I{startValue} and the index I{vIndex} that 
    353         points to the value in my array I{V} for the jump deviation to use for 
    354         the jump. 
     345    def rJump(self, startValue, v, N_attempts=200): 
     346        """ 
     347        Call this method with a I{startValue} and the jump deviation I{v} to 
     348        use for the jump. 
    355349 
    356350        Draws a jump value from a normal distribution with a standard deviation 
     
    375369        each possible jump deviation in the I{p} array of the result. 
    376370        """ 
    377         v = self.V[vIndex] 
    378371        vInverse = 1.0 / v 
    379         for k in xrange(self.N_attempts): 
     372        for k in xrange(N_attempts): 
    380373            rJump, pJump = self._rJumpDraw() 
    381374            rJump *= v 
     
    404397    @ivar p: The number of time series. 
    405398 
    406     @ivar paramNames: A list of the parameter names in sequence. 
     399    @ivar primaryParamNames: A list of the primary parameter names in sequence. 
     400 
     401    @ivar derivedParamNames: A list of the derived parameter names in sequence. 
    407402     
    408403    """ 
    409404    typeChecking = True 
     405    N_attempts = 200 
    410406     
    411407    def __init__(self, p, n): 
     
    420416        return array 
    421417 
     418    def covarMatrix(self, cs, cr): 
     419        """ 
     420        Returns a covariance matrix from the vector or sequence of I{cs} 
     421        standard deviations and I{cr} cross-correlations. 
     422 
     423        The I{cs} argument is in the form s0, s1,..., sp. It must have C{p} 
     424        elements. 
     425 
     426        The I{cr} argument must have C{0.5*(p**2 + p)} elements and is in the 
     427        form r00, r01, r02,..., r0p, r11, r12,..., r1p,..., rpp 
     428        """ 
     429        i = 0 
     430        p = len(cs) 
     431        cv = s.zeros((p, p)) 
     432        for j in xrange(p): 
     433            cv[j,j] = cs[j]**2 
     434            for k in xrange(j+1, p): 
     435                cv[j, k] = cv[k, j] = cr[i] * cs[j] * cs[k] 
     436                i += 1 
     437        return cv 
     438     
     439    def derivedParams(self, paramContainer): 
     440        """ 
     441        Sets derived parameters in the supplied I{paramContainer} based on its 
     442        primary parameters, unless there is an error in generating the derived 
     443        parameters. 
     444 
     445        Returns C{True} if everything went OK, C{False} if not. 
     446        """ 
     447        # Concurrent cross-correlations between volatility shocks and inverse 
     448        # of concurrent cross-correlations between innovation shocks 
     449        try: 
     450            rz = linalg.cholesky(self.covarMatrix( 
     451                paramContainer.fs, paramContainer.fr), lower=True) 
     452            ri = linalg.inv(linalg.cholesky(self.covarMatrix( 
     453                s.ones(self.p), paramContainer.cr), lower=True)) 
     454        except linalg.LinAlgError: 
     455            return False 
     456        paramContainer.rz = rz 
     457        paramContainer.ri = ri 
     458        # Scaling constants for multivariate normal pdf 
     459        sc = s.empty((self.p, 2)) 
     460        sc[:,0] = 1.0 / s.sqrt(1.0 - paramContainer.g**2) 
     461        sc[:,1] = s.log(s.sqrt(2*s.pi) / sc[:,0]) 
     462        paramContainer.sc = sc 
     463        return True 
     464 
    422465    def new(self): 
    423466        """ 
    424467        Returns a new parameter container with values intialized from a random 
    425468        draw of my priors. 
    426         """ 
    427         Lp = 0 
    428         paramContainer = ParameterContainer(paramNames=self.paramNames) 
    429         for name in self.paramNames: 
    430             priorFlexArray = getattr(self, name) 
    431             paramArray = priorFlexArray.call('rvs') 
    432             Lp += s.log(priorFlexArray.call('pdf', paramArray)).sum() 
    433             setattr(paramContainer, name, paramArray) 
     469 
     470        The method will generate derived parameters based on the primary 
     471        parameter values, repeating as needed to get primary values that 
     472        work. The derived values are included in the returned parameter 
     473        container. 
     474        """ 
     475        paramContainer = ParameterContainer( 
     476            paramNames=self.primaryParamNames+self.derivedParamNames) 
     477        for k in xrange(self.N_attempts): 
     478            Lp = 0 
     479            for name in self.primaryParamNames: 
     480                priorFlexArray = getattr(self, name) 
     481                paramArray = priorFlexArray.call('rvs') 
     482                setattr(paramContainer, name, paramArray) 
     483                Lp += s.log(priorFlexArray.call('pdf', paramArray)).sum() 
     484            if self.derivedParams(paramContainer): 
     485                break 
     486        else: 
     487            raise ValueError( 
     488                "Couldn't generate a valid set of derived parameters") 
    434489        paramContainer.Lp = Lp 
    435490        paramContainer.Lj = 0 # There was no jump 
    436491        return paramContainer 
    437492 
    438     def proposal(self, paramContainer, vIndex, vWeights): 
     493    def proposal(self, paramContainer, v): 
    439494        """ 
    440495        Returns a new instance of L{ParameterContainer} with a random-walk 
    441         proposal based on the supplied I{paramContainer}, my priors, the jump 
    442         deviation defined at the I{vIndex} position of my 1-D array of jump 
    443         deviations, and a 1-D array I{vWeights} of mixture weights for the jump 
    444         deviations in the jump distribution. 
     496        proposal based on the supplied I{paramContainer}, my priors, and the 
     497        supplied jump deviation I{v}. 
    445498 
    446499        The returned parameter container object will have new values of I{Lp} 
    447500        and I{Lj} corresponding to the proposal. 
    448501 
    449         The value of I{Lj} is computed for each parameter element from a jump 
    450         distribution that is a mixture of normal distributions. Each of the 
    451         normals has a standard deviation defined by one element of my jump 
    452         deviation array with a corresponding mixture weight in the supplied 
    453         I{vWeights} array. 
     502        The value of I{Lj} is computed for each parameter element from a normal 
     503        jump distribution whose width is proportional to the jump deviation 
     504        I{v} and the width of the parameter's prior distribution. 
     505 
     506        The method will generate derived parameters based on the primary 
     507        parameter values of the proposal, repeating as needed to get primary 
     508        values that work. The derived values are included in the returned 
     509        parameter container. 
    454510        """ 
    455511        if self.typeChecking and \ 
     
    458514                "You must supply a ParameterContainer as the first "+\ 
    459515                "argument, not a '%s'" % type(paramContainer)) 
    460         newVersion = ParameterContainer(paramNames=self.paramNames) 
    461         Lp, Lj = 0, 0 
    462         # Define a 1-D array holding the probability density for each jump, 
    463         # joint across all parameters. Since the densities will be scaled by 
    464         # the weight for each jump deviation, just start the array with the 
    465         # weights. 
    466         for name in self.paramNames: 
    467             priorsFA = getattr(self, name) 
    468             startValues = getattr(paramContainer, name) 
    469             jumpsFA = priorsFA.call('rJump', startValues, vIndex) 
    470             setattr(newVersion, name, jumpsFA.x) 
    471             Lp += s.log(jumpsFA.px).sum() 
    472             Lj += s.log(jumpsFA.pJump).sum() 
     516        newVersion = ParameterContainer( 
     517            paramNames=self.primaryParamNames + self.derivedParamNames) 
     518        for k in xrange(self.N_attempts): 
     519            Lp, Lj = 0, 0 
     520            # Define a 1-D array holding the probability density for each jump, 
     521            # joint across all parameters. Since the densities will be scaled 
     522            # by the weight for each jump deviation, just start the array with 
     523            # the weights. 
     524            for name in self.primaryParamNames: 
     525                priorsFA = getattr(self, name) 
     526                startValues = getattr(paramContainer, name) 
     527                jumpsFA = priorsFA.call( 
     528                    'rJump', startValues, v, N_attempts=self.N_attempts) 
     529                setattr(newVersion, name, jumpsFA.x) 
     530                Lp += s.log(jumpsFA.px).sum() 
     531                Lj += s.log(jumpsFA.pJump).sum() 
     532            if self.derivedParams(newVersion): 
     533                break 
     534        else: 
     535            raise ValueError( 
     536                "Couldn't generate a valid set of derived parameters") 
    473537        newVersion.Lp = Lp 
    474538        newVersion.Lj = Lj 
  • projects/AsynCluster/trunk/svpmc/pmc.py

    r206 r207  
    157157        self.pm = projectManager 
    158158        self.mm = projectManager.mgr 
     159        self.V = projectManager.V 
    159160        self.queue = projectManager.queue 
    160161        self.resampler = Resampler(logWeights=True)             
     
    171172    def proposals(self, *args): 
    172173        """ 
    173         Call this method with a 1-D FlexArray of parameter containers and an 
    174         integer index of a particular jump deviation, and it will generate 
    175         proposals from the existing parameters. 
     174        Call this method with a 1-D FlexArray of parameter containers and a 
     175        jump deviation, and it will generate proposals from the existing 
     176        parameters. 
    176177 
    177178        Call it with just an integer number of proposals, and it will generate 
    178179        new ones directly from the priors. 
    179180 
    180         Runs a log-volatility simulation for each proposal via the model 
    181         manager, which constructs a 3-D array of the normal variates underlying 
    182         the entire set of simulations. 
    183  
    184         Returns a deferred that fires when all the log-volatility simulations 
    185         are done. The deferred fires with a 1-D FlexArray of the proposals 
    186         along with an equal-length 1-D bool array of True/False values 
    187         indicating which of them resulted in valid log-volatility simulations. 
    188         """ 
    189         def simulationDone(success): 
    190             if success: 
    191                 print vIndex, 
    192             else: 
    193                 print ".", 
    194             I.append(success) 
    195  
    196         def allDone(null): 
    197             return XP, s.array(I) 
    198          
    199         dList = [] 
    200         I = [] 
     181        Returns a 1-D FlexArray of parameter containers embodying the 
     182        proposals. 
     183        """ 
    201184        if len(args) == 2: 
    202185            new = False 
    203             X, vIndex = args 
     186            X, v = args 
    204187            N = len(X) 
    205188        else: 
    206189            new = True 
    207190            N = args[0] 
    208             vIndex = "+" 
    209191        XP = params.FlexArray(N) 
    210192        for k in xrange(N): 
     
    212194                proposalPC = self.pm.priors.new() 
    213195            else: 
    214                 proposalPC = self.pm.priors.proposal( 
    215                     X[k], vIndex, self.allocator.W) 
     196                proposalPC = self.pm.priors.proposal(X[k], v) 
    216197            XP[k] = proposalPC 
    217             d = self.mm.zSimulation(proposalPC, k) 
     198        return XP 
     199     
     200    def simulations(self, X): 
     201        """ 
     202        Runs a log-volatility simulation for each parameter container supplied 
     203        in the 1-D FlexArray I{X}. The simulations are run via the model 
     204        manager, which constructs a 3-D array of the normal variates underlying 
     205        the entire set of simulations. 
     206 
     207        Returns a deferred that fires when all the log-volatility simulations 
     208        are done. 
     209        """ 
     210        def simulationDone(success): 
     211            if success: 
     212                print "+", 
     213            else: 
     214                print ".", 
     215 
     216        dList = [] 
     217        for k, Xk in enumerate(X): 
     218            d = self.mm.zSimulation(Xk, k) 
    218219            d.addCallback(simulationDone) 
    219220            d.addErrback(self._oops, k=k) 
    220221            dList.append(d) 
    221         return defer.DeferredList(dList).addCallback(allDone) 
    222      
    223     def weights(self, XP, vIndex): 
     222        d = defer.DeferredList(dList) 
     223        d.addCallback(lambda _: self.mm.nextIteration()) 
     224        d.addErrback(self._oops) 
     225        return d 
     226     
     227    def weights(self, XP, v): 
    224228        """ 
    225229        Returns a deferred that fires with a 1-D array of log importance 
    226         weights for the proposals supplied in the 1-D FlexArray I{XP}. 
     230        weights for the parameter proposals in the 1-D FlexArray I{XP}. 
    227231         
    228232        The importance weights are to be combined with those from other calls 
     
    241245                    for x in ('Lx', 'Lp', 'Lj')]) 
    242246            else: 
    243                 info = "" 
    244247                L = -s.inf 
    245             print "%6.4f\t%+12.2f\t%s" % (self.pm.V[vIndex], L, info) 
     248            if L < 0: 
     249                print "%6.4f" % v 
     250            else: 
     251                print "%6.4f\t%+12.2f\t%s" % (v, L, info) 
    246252            return L 
    247253         
     
    250256        dList = [self.mm.likelihood(XPk).addCallback(weight) for XPk in XP] 
    251257        return defer.gatherResults(dList).addCallback(lambda W: s.array(W)) 
    252  
     258     
    253259    @defer.deferredGenerator 
    254260    def run(self, N_iter): 
     
    266272 
    267273        """ 
    268         def gotTheseWeights(Wv, I, Iv): 
    269             """ 
    270             Returns a 1-D weights array of the same length as this allocation's 
    271             length, with infinitely negative values except for the valid 
    272             weights supplied in I{Wv}. 
    273             """ 
    274             W = -s.inf * s.ones(len(I)) 
    275             W[Iv] = Wv 
    276             return W 
    277  
    278274        X = None 
    279275        if self.socket: 
     
    286282        for i in xrange(N_iter): 
    287283            print "\n%03d\n%s" % (i+1, "-"*100) 
    288             self.mm.nextIteration() 
    289284            if X is None: 
    290                 print "Generating %d proposals from priors:" % N_members 
    291285                # No existing members, generate proposals directly from the 
    292                 # priors 
    293                 wfd = defer.waitForDeferred(self.proposals(N_members)) 
     286                # priors and simulate log-volatilities for them 
     287                print "Generating %d proposals from priors " % N_members +\ 
     288                      "and simulating log-volatilities for them" 
     289                wfd = defer.waitForDeferred( 
     290                    self.queue.call(self.proposals, N_members)) 
    294291                yield wfd 
    295                 XP, validXP = wfd.getResult() 
    296             else: 
    297                 print "Generating %d proposals from previous population:" \ 
    298                       % N_members 
    299                 # Regular iteration, use proposals generated from the last 
    300                 # iteration's members 
    301                 dList, resultList = [], [] 
     292                XP = wfd.getResult() 
     293                wfd = defer.waitForDeferred(self.simulations(XP)) 
     294                yield wfd 
     295                wfd.getResult() 
     296            else: 
     297                # Regular iteration, simulate log-volatilities for the last 
     298                # iteration's members and use proposals generated from those 
     299                # members 
     300                print "\nSimulating log-volatilities for the previous "+\ 
     301                      "population and generating %d proposals " % N_members +\ 
     302                      "from the population:" 
     303                resultList = [] 
     304                dList = [self.simulations(X)] 
    302305                for vIndex, I, d in self.allocator.assembler(resultList): 
    303                     d.addCallback(lambda _: self.proposals(X[I], vIndex)) 
    304                 dList.append(d) 
     306                    d.addCallback( 
     307                        lambda _: 
     308                        self.queue.call(self.proposals, X[I], self.V[vIndex])) 
     309                    d.addErrback(self._oops, vIndex=vIndex) 
     310                    dList.append(d) 
     311                # Record the previous iteration's members while the nodes work on 
     312                # generating the proposals and simulations for the current iteration... 
     313                if i > 0: 
     314                    self.pm.writeParams(X) 
    305315                wfd = defer.waitForDeferred(defer.DeferredList(dList)) 
    306316                yield wfd 
    307317                wfd.getResult() 
    308                 XP, validXP = resultList 
     318                XP = resultList[0] 
    309319            print "\n" 
    310320            # Evaluate the proposals 
    311321            dList, resultList = [], [] 
    312322            for vIndex, I, d in self.allocator.assembler(resultList): 
    313                 Iv = validXP[I].nonzero()[0] 
    314                 d.addCallback(lambda _: self.weights(XP[I][Iv], vIndex)) 
    315                 d.addCallback(gotTheseWeights, I, Iv) 
     323                d.addCallback(lambda _: self.weights(XP[I], self.V[vIndex])) 
    316324                d.addErrback(self._oops, vIndex=vIndex) 
    317325                dList.append(d) 
    318             # Record the previous iteration's members while the nodes work on 
    319             # evaluating the valid proposals for the current iteration... 
    320             if X is not None: 
    321                 self.pm.writeParams(X) 
    322             # "Wait" here for all the proposals to be evaluated 
    323326            wfd = defer.waitForDeferred(defer.DeferredList(dList)) 
    324327            yield wfd 
     
    332335                self.allocator.updateAllocations(I0[I1]) 
    333336            else: 
     337                # No valid parameters, start over 
     338                X = None 
    334339                self.allocator.updateAllocations() 
    335340        wfd = defer.waitForDeferred(self.pm.done()) 
  • projects/AsynCluster/trunk/svpmc/project.py

    r206 r207  
    7070      iteration. 
    7171 
    72     @ivar paramNames: A list of the names of parameter arrays in the parameter 
    73       sequences used in the project
     72    @ivar paramNames: A list of the names of arrays in the parameter containers 
     73      used in the project for both primary and secondary parameters
    7474 
    7575    @ivar D: The number of jump deviations used by the D-kernel PMC 
     
    9191        'm':        'member',     
    9292        } 
    93      
    9493    def __init__(self, specFile, ncFile="svpmc.nc", m=1000, readOnly=False): 
    9594        self.m = m 
     
    224223                        pa[j,k] = params.Prior(**kw) 
    225224         
    226         self.paramNames = [] 
     225        self.primaryParamNames = [] 
    227226        titles, dimensions = [], [] 
    228227        self.paramInfo = {} 
     
    236235                constructPriors(priorSpec, shape) 
    237236            titles.append(title) 
    238             self.paramNames.append(name) 
    239         self.priors.paramNames = self.paramNames 
     237            self.primaryParamNames.append(name) 
     238        self.priors.primaryParamNames = self.primaryParamNames 
     239        self.derivedParamNames = [] 
     240        for name, sourceParams, description in self.tables['derivation']: 
     241            self.derivedParamNames.append(name) 
     242        self.priors.derivedParamNames = self.derivedParamNames 
     243        self.paramNames = self.primaryParamNames + self.derivedParamNames 
    240244        return titles, dimensions 
    241245 
     
    254258        obs.long_name = "Observations, %d time series " % self.p +\ 
    255259                        "with %d samples each" % self.n 
    256         # Last-Sample Log-Volatility 
    257         logVol = cdf.createVariable( 
    258             "log_volatility", 'f', ('iteration', 'member', 'series')) 
    259         logVol.long_name = "Last Sample of Simulated Log-Volatilities" 
    260260        # Parameters 
    261         for k, name in enumerate(self.paramNames): 
     261        for k, name in enumerate(self.primaryParamNames): 
    262262            pDim = ['iteration', 'member'] + pDims[k] 
    263263            param = cdf.createVariable(name, 'f', tuple(pDim)) 
    264264            param.long_name = pTitles[k] 
    265         # Log-Likelihood 
    266         L = cdf.createVariable("log_likelihood", 'f', ('iteration', 'member')) 
     265        # Log-Likelihood, log-density of priors and jumps 
     266        L = cdf.createVariable("Lx", 'f', ('iteration', 'member')) 
    267267        L.long_name = "Log-Likelihood of Observations Given Parameters" 
     268        L = cdf.createVariable("Lp", 'f', ('iteration', 'member')) 
     269        L.long_name = "Log-Density of Parameters from Prior Distributions" 
     270        L = cdf.createVariable("Lj", 'f', ('iteration', 'member')) 
     271        L.long_name = "Log-Density of Proposal Jumps" 
    268272        # Done setting up, save what we've got thus far 
    269273        cdf.sync() 
     
    279283                "Each iteration record must have %d parameters" % self.m) 
    280284        # Write the parameters to their variables 
    281         for name in self.paramNames: 
     285        for name in self.primaryParamNames: 
    282286            var = self.cdf.variables[name] 
    283287            # Iterate over a 1-D FlexArray of the population's parameter arrays 
    284288            for member, paramArray in enumerate(getattr(parameters, name)): 
    285289                var[self.iteration, member, :] = paramArray.astype('f') 
    286         # Write the last sample's multivariate log-volatility value for each 
     290        # Write the log-volatility, prior and jump log-density values for each 
    287291        # population member 
    288         var = self.cdf.variables['log_volatility'] 
    289         for member, h in enumerate(parameters.h): 
    290             var[self.iteration, member, :] = h.astype('f') 
    291         # Write the log-volatility value for each population member 
    292         var = self.cdf.variables['log_likelihood'] 
    293         var[self.iteration, :] = parameters.Lx.astype('f') 
     292        for name in ('Lx', 'Lp', 'Lj'): 
     293            var = self.cdf.variables[name] 
     294            var[self.iteration, :] = getattr(parameters, name).astype('f') 
    294295        # Done writing this iteration of the CDF record 
    295296        self.cdf.sync() 
  • projects/AsynCluster/trunk/svpmc/test/test_model.py

    r205 r207  
    346346 
    347347class Test_Model_misc(BaseCase): 
    348     def test_covarMatrix(self): 
    349         def tryCoeffs(cs, cr, x): 
    350             x = s.array(x) 
    351             modelObj.y = s.empty((x.shape[0], 100)) 
    352             y = modelObj.covarMatrix(cs, cr) 
    353             self.failUnlessEqual(y.shape, x.shape) 
    354             self.failUnless( 
    355                 s.absolute(y-x).max() < 1E-8, 
    356                 "Generated array \n%s\n != \n%s" % (y, x)) 
    357  
    358         modelObj = model.Model() 
    359         tryCoeffs([1.0], [], [[1.0]]) 
    360         tryCoeffs([1.0, 1.0], [0.2], [[1.0, 0.2], [0.2, 1.0]]) 
    361         tryCoeffs([2, 3], [0], [[4.0, 0.0], [0.0, 9.0]]) 
    362         tryCoeffs([3, 4], [0.5], [[9.0, 6.0], [6.0, 16.0]]) 
    363         tryCoeffs( 
    364             [3, 4, 5], [0.1, 0.2, 0.3], 
    365             [[9.0, 1.2, 3.0], [1.2, 16.0, 6.0], [3.0, 6.0, 25.0]]) 
    366  
    367348    def test_support_uniform(self): 
    368349        code = """ 
     
    384365          X1(k) = truncnorm(a, b); 
    385366        """ 
    386         Ns = 100 
     367        Ns = 10000 
    387368        ranges = ((-1, +1), (-0.5, +1.5), (1.0, 2.0), (3.0, 5.0)) 
    388369        fig = self.fig 
     
    752733            ('g', -0.9, +0.9)] 
    753734        fig = self.fig 
    754         spNumberBase = 100*len(paramInfoList) + 1
     735        spNumberBase = 100*len(paramInfoList) + 2
    755736        for j, paramInfo in enumerate(paramInfoList): 
    756737            paramName = paramInfo[0] 
     
    761742                Lx[k] = modelObj.inlineDirect( 
    762743                    modelObj.code['likelihood'], **inlineVars) 
    763             sp = fig.add_subplot(spNumberBase+j) 
     744            sp = fig.add_subplot(spNumberBase+2*j) 
    764745            sp.plot(values, Lx, '.') 
    765746            sp.set_title("Parameter '%s'" % paramName) 
     747            sp = fig.add_subplot(spNumberBase+2*j+1) 
     748            Lx_max = Lx.max() 
     749            sp.plot(values, s.exp(Lx-Lx_max)) 
     750            sp.set_title("Parameter '%s'" % paramName) 
    766751            inlineVars[paramName] = originalParamValue 
     752 
     753    def test_Lx_vs_z(self): 
     754        wiggle = 1.0 
     755        eValue = 0.90 
     756        Ns, Ni, Nr = 1000, 40, 200 
     757 
     758        Lx = s.empty(Nr) 
     759        modelObj = model.Model() 
     760 
     761        inlineVars = self._inlineVars(wiggle, eValue, Ni) 
     762        for zReal, zSim, hReal, hSim in self._hybridGibbs(Ns, 1, inlineVars): 
     763            pass 
     764 
     765        fig = self.fig 
     766        zErrorList = [0.0005, 0.001, 0.01] 
     767        spNumberBase = 100*len(zErrorList) + 11 
     768        for j, zError in enumerate(zErrorList): 
     769            for k in xrange(Nr): 
     770                inlineVars['z'] = ( 
     771                    zSim + zError*2*(s.rand(1, Ns) - 0.5)).reshape((1, 1, Ns)) 
     772                Lx[k] = modelObj.inlineDirect( 
     773                    modelObj.code['likelihood'], **inlineVars) 
     774            sp = fig.add_subplot(spNumberBase+j) 
     775            sp.hist(Lx) 
     776            sp.set_title("Range (+/-) of zError: %f" % zError) 
    767777     
    768778    def test_optimize_Ni(self): 
  • projects/AsynCluster/trunk/svpmc/test/test_params.py

    <
    r196 r207  
    222222class Test_Prior(util.TestCase): 
    223223    def setUp(self): 
    224         self.V = s.array([1.0, 0.1, 0.01]) 
    225         self.p = params.Prior(dname='norm', loc=1, scale=1, D=3, Df=0.1) 
     224        self.p = params.Prior(dname='norm', loc=1, scale=1) 
    226225        self.p.N_draw = 10 
    227226        self.pdf = self.p.rdsObj.pdf 
     
    235234        self.failUnless(s.equal(s.array([p.pdf(x) for x in X]), 0.5).all()) 
    236235 
    237     def _checkDraw(self, rv, pV): 
     236    def _checkDraw(self, rJump, pJump): 
    238237        pdf = self.p.rdsObj.pdf 
    239         for k, v in enumerate(self.V): 
    240             self.failUnlessAlmostEqual(pdf(rv/v)/v, pV[k], 5) 
     238        self.failUnlessAlmostEqual(pdf(rJump), pJump, 5) 
    241239 
    242240    def test_newDraw(self): 
     
    249247    def test_rJumpDraw(self): 
    250248        for k in xrange(103): 
    251             rv, pV = self.p._rJumpDraw() 
    252             self._checkDraw(rv, pV
     249            rJump, pJump = self.p._rJumpDraw() 
     250            self._checkDraw(rJump, pJump
    253251 
    254252    def test_rJump(self): 
    255253        for startValue in s.linspace(-1, +3, 10): 
    256             for vIndex, v in enumerate(self.V): 
    257                 jumpObj = self.p.rJump(startValue, vIndex) 
    258                 print "\n", vIndex, v 
     254            for v in (0.1, 0.001, 0.0001): 
     255                jumpObj = self.p.rJump(startValue, v) 
    259256                jumpValue = jumpObj.x - startValue 
    260257                rv = jumpValue / v 
    261                 print jumpValue, rv, jumpObj.pV[vIndex] 
    262                 self.failUnlessAlmostEqual(self.pdf(rv)/v, jumpObj.pV[vIndex]) 
    263                 print "OK" 
    264                  
    265  
    266 class Test_PriorContainer(util.TestCase): 
     258                self.failUnlessAlmostEqual(self.pdf(rv)/v, jumpObj.pJump) 
     259 
     260 
     261class Test_PriorContainer_misc(util.TestCase): 
    267262    MPC = util.Mock_ParameterContainer 
    268     V = s.array([1.0, 0.1, 0.01]) 
    269263     
    270264    def setUp(self): 
    271265        self.priorContainer = params.PriorContainer( 
    272             self.MPC.p, self.MPC.N, self.V
     266            self.MPC.p, self.MPC.N
    273267        self.priorContainer.typeChecking = False 
    274         self.priorContainer.paramNames = self.MPC.paramNames 
    275         kw = {'dname':'norm', 'loc':0, 'V':self.V} 
    276         for i, name in enumerate(self.priorContainer.paramNames): 
     268        self.priorContainer.primaryParamNames = util.PRIMARY_PARAM_NAMES 
     269        self.priorContainer.derivedParamNames = util.DERIVED_PARAM_NAMES