Ejemplo n.º 1
0
 def makeConsistent(self):
     weight = 0
     for node, val in self.unpropagatedObservations.iteritems():
         appNode = self.getConstrainableNode(node)
         #      print "PROPAGATE", node, appNode
         scaffold = constructScaffold(self, [OrderedSet([appNode])])
         rhoWeight, _ = detachAndExtract(self, scaffold)
         scaffold.lkernels[appNode] = DeterministicLKernel(
             self.pspAt(appNode), val)
         xiWeight = regenAndAttach(self, scaffold, False, OmegaDB(),
                                   OrderedDict())
         # If xiWeight is -inf, we are in an impossible state, but that might be ok.
         # Finish constraining, to avoid downstream invariant violations.
         node.observe(val)
         constrain(self, appNode, node.observedValue)
         weight += xiWeight
         weight -= rhoWeight
     self.unpropagatedObservations.clear()
     if not math.isnan(weight):
         # Note: +inf weight is possible at spikes in density against
         # Lebesgue measure.
         return weight
     else:
         # How could we get a NaN here?
         # If one observation made the state inconsistent, the rhoWeight
         # of another might conceivably be infinite, possibly leading to
         # a nan weight.  I want to normalize these to indicating that
         # the resulting state is impossible.
         return float("-inf")
Ejemplo n.º 2
0
 def regen_with_proposal(self, scaffold, values):
     pnodes = scaffold.getPrincipalNodes()
     assert len(values) == len(
         pnodes
     ), "Tried to propose %d values, but subproblem accepts %d values" % (
         len(values), len(pnodes))
     infer.registerDeterministicLKernels(self, scaffold, pnodes, values)
     xiWeight = regenAndAttach(self, scaffold, False, OmegaDB(),
                               OrderedDict())
     # de-mutate the scaffold in case it is used for subsequent operations
     infer.unregisterDeterministicLKernels(self, scaffold, pnodes)
     return xiWeight
Ejemplo n.º 3
0
def detachAndExtractAtBorder(trace, border, scaffold, compute_gradient=False):
    """Returns the weight and an OmegaDB.  The OmegaDB contains
  sufficient information to restore the trace, and, if
  compute_gradient is True, to determine the partial derivative of
  the weight with respect to the value at each node.  The latter is
  computed by one level of reverse-mode AD, with the underlying trace
  serving as tape."""
    weight = 0
    omegaDB = OmegaDB()
    for node in reversed(border):
        if scaffold.isAbsorbing(node):
            weight += detach(trace, node, scaffold, omegaDB, compute_gradient)
        else:
            if node.isObservation: weight += getAndUnconstrain(trace, node)
            weight += extract(trace, node, scaffold, omegaDB, compute_gradient)
    return weight, omegaDB
Ejemplo n.º 4
0
 def freeze(self, id):
     assert id in self.families
     node = self.families[id]
     if isConstantNode(node):
         # All set
         pass
     else:
         assert isOutputNode(node)
         value = self.valueAt(node)
         unevalFamily(self, node, Scaffold(), OmegaDB())
         # XXX It looks like we kinda want to replace the identity of this
         # node by a constant node, but we don't have a nice way to do that
         # so we fake it by dropping the components and marking it frozen.
         node.isFrozen = True
         self.setValueAt(node, value)
         node.requestNode = None
         node.operandNodes = None
         node.operatorNode = None
Ejemplo n.º 5
0
    def __call__(self, trace, scaffolder):
        # CONSDIER how to unify this code with EnumerativeGibbsOperator.
        # Problems:
        # - a torus cannot be copied by copy_trace
        # - a particle cannot be copied by copy_trace either
        # - copy_trace undoes incorporation (on Lite traces)

        scaffold = scaffolder.sampleIndex(trace)
        assertTrace(trace, scaffold)

        pnodes = scaffold.getPrincipalNodes()
        allSetsOfValues = \
            getCartesianProductOfEnumeratedValuesWithAddresses(trace, pnodes)

        xiWeights = []
        xiParticles = []

        for newValuesWithAddresses in allSetsOfValues:
            xiParticle = self.copy_trace(trace)
            # CONSIDER what to do with the weight from this
            xiParticle.makeConsistent()
            # Impossible original state is probably fine
            # ASSUME the scaffolder is deterministic. Have to make the
            # scaffold again b/c detach mutates it, and b/c it may not work
            # across copies of the trace.
            scaffold = scaffolder.sampleIndex(xiParticle)
            (rhoWeight, _) = detachAndExtract(xiParticle, scaffold)
            assertTorus(scaffold)
            registerDeterministicLKernelsByAddress(xiParticle, scaffold,
                                                   newValuesWithAddresses)
            xiWeight = regenAndAttach(xiParticle, scaffold, False, OmegaDB(),
                                      OrderedDict())
            xiParticles.append(xiParticle)
            # CONSIDER What to do with the rhoWeight.  Subtract off the
            # likelihood?  Subtract off the prior and the likelihood?  Do
            # nothing?  Subtracting off the likelihood makes
            # hmm-approx-filter.vnt from ppaml-cps/cp4/p3_hmm be
            # deterministic (except roundoff effects), but that may be an
            # artifact of the way that program is written.
            xiWeights.append(xiWeight - rhoWeight)
        return (xiParticles, xiWeights)
Ejemplo n.º 6
0
    def compute_particles(self, trace, scaffold):
        assertTrace(trace, scaffold)

        pnodes = scaffold.getPrincipalNodes()
        currentValues = getCurrentValues(trace, pnodes)

        registerDeterministicLKernels(trace, scaffold, pnodes, currentValues)

        rhoWeight, self.rhoDB = detachAndExtract(trace, scaffold)
        xiWeights = []
        xiParticles = []

        allSetsOfValues = getCartesianProductOfEnumeratedValues(trace, pnodes)

        for newValues in allSetsOfValues:
            if newValues == currentValues:
                # If there are random choices downstream, keep their current values.
                # This follows the auxiliary variable method in Neal 2000,
                # "Markov Chain Sampling Methods for Dirichlet Process Models"
                # (Algorithm 8 with m = 1).
                # Otherwise, we may target the wrong stationary distribution.
                # See testEnumerativeGibbsBrushRandomness in
                # test/inference_language/test_enumerative_gibbs.py for an
                # example.
                shouldRestore = True
                omegaDB = self.rhoDB
            else:
                shouldRestore = False
                omegaDB = OmegaDB()
            xiParticle = self.copy_trace(trace)
            assertTorus(scaffold)
            registerDeterministicLKernels(trace, scaffold, pnodes, newValues)
            xiParticles.append(xiParticle)
            xiWeights.append(
                regenAndAttach(xiParticle, scaffold, shouldRestore, omegaDB,
                               OrderedDict()))
            # if shouldRestore:
            #   assert_almost_equal(xiWeights[-1], rhoWeight)
        return (xiParticles, xiWeights)
Ejemplo n.º 7
0
 def just_regen(self, scaffold):
     return regenAndAttach(self, scaffold, False, OmegaDB(), OrderedDict())
Ejemplo n.º 8
0
 def uneval(self, id):
     assert id in self.families
     unevalFamily(self, self.families[id], Scaffold(), OmegaDB())
     del self.families[id]
Ejemplo n.º 9
0
 def eval(self, id, exp):
     assert id not in self.families
     (_, self.families[id]) = evalFamily(self, addr.directive_address(id),
                                         self.unboxExpression(exp),
                                         self.globalEnv, Scaffold(), False,
                                         OmegaDB(), OrderedDict())
Ejemplo n.º 10
0
def update(trace, node):
    scaffold = Scaffold()
    omegaDB = OmegaDB()
    unapplyPSP(trace, node, scaffold, omegaDB)
    applyPSP(trace, node, scaffold, False, omegaDB, OrderedDict())