def __init__(self, grammar, forward_model=None, data=None, ll_params=None, spatial_model=None, initial_tree=None): """ Initializes ShapeGrammarState grammar: Probabilistic context free shape grammar definition. PCFG instance. forward_model: Forward model(s) used in likelihood calculation ll_params: parameters for likelihood calculation spatial_model: Spatial model for the state. Initialized randomly if initial_tree is not provided initial_tree (optional): Parse tree for the state. If not provided, state is initialized randomly. """ self.grammar = grammar self.spatial_model = spatial_model self.forward_model = forward_model if initial_tree is None: self.tree = self._get_random_tree(start=self.grammar.start_symbol, max_depth=self.MAXIMUM_DEPTH) # initialize spatial model self.spatial_model.update(self.tree, self.grammar) else: self.tree = initial_tree # if a subclass does not define moves, we define it here and add subtree move if hasattr(self, 'moves') is False: self.moves = [self.subtree_proposal] # IMPORTANT: we call base class init after we initialize spatial model, # because prior, ll, deriv_prob calculation is done in init and # spatial_model should be available to calculate them PCFGTree.__init__(self, grammar=grammar, data=data, ll_params=ll_params, initial_tree=self.tree)
def _prior(self): """ Prior probability for state Product of probability for tree and spatial layout """ prior = PCFGTree._prior(self) * self.spatial_model.probability() return prior
def subtree_proposal(self): """ Proposes a new state based on current state using subtree move Uses base class PCFGTree's subtree_proposal_propose_tree to generate new tree, then samples positions for new added parts """ pcfg_proposal = PCFGTree.subtree_proposal_propose_tree(self) # get a new spatial model based on proposed tree proposed_spatial_model = self.spatial_model.propose(pcfg_proposal, self.grammar) proposal = self.__class__(forward_model=self.forward_model, data=self.data, ll_params=self.ll_params, spatial_model=proposed_spatial_model, initial_tree=pcfg_proposal) acc_prob = self._subtree_acceptance_probability(proposal) return proposal, acc_prob
def subtree_proposal(self): """ Proposes a new state based on current state using subtree move Uses base class PCFGTree's subtree_proposal_propose_tree to generate new tree, then samples positions for new added parts """ pcfg_proposal = PCFGTree.subtree_proposal_propose_tree(self) # get a new spatial model based on proposed tree proposed_spatial_model = self.spatial_model.propose( pcfg_proposal, self.grammar) proposal = self.__class__(forward_model=self.forward_model, data=self.data, ll_params=self.ll_params, spatial_model=proposed_spatial_model, initial_tree=pcfg_proposal) acc_prob = self._subtree_acceptance_probability(proposal) return proposal, acc_prob
def __str__(self): """ Override in super class for more informative string representations """ return PCFGTree.__str__(self)