def or_d(x, y): out = defaultdict(lambdaMinusInfinity) out[True] = logplusexp( x.get(True, -Infinity) + y.get(False, -Infinity), x.get(False, -Infinity) + y.get(True, -Infinity)) out[False] = log1mexp(out[True]) return out
def cons_d(x, y): out = defaultdict(lambdaMinusInfinity) for a, av in list(x.items()): for b, bv in list(y.items()): out[a + b] = logplusexp(out[a + b], av + bv) return out
def if_d(prb, x, y): out = defaultdict(lambdaMinusInfinity) pt = prb[True] pf = prb[False] for a, av in list(x.items()): out[a] = av + pt for b, bv in list(y.items()): out[b] = logplusexp(out[b], bv + pf) return out
def compute_outcomes(f, *args, **kwargs): """ Return a dictionary of outcomes using our RandomContext tools, giving each possible trace (up to the given depth) and its probability. f here is a function of context, as in f(context, *args) kwargs['Cfirst'] constrols whether C is the first or last argument to f. It cannot be anything else In kwargs you can pass "catchandpass" as a tuple of exceptions to catch and do nothing with """ out = defaultdict(lambdaMinusInfinity) # dict from strings to lps that we accumulate cs = ContextSet() # this is the "open" set of contexts we need to explore cs.add(RandomContext(cs)) # add a single context with no history i = 0 while len(cs) > 0: context = cs.pop() # pop an element from Context set. # print "CTX", context.lp, context#, " \t", cs.Q try: # figure out the ordering of where C is passed to the lambda if kwargs.get('Cfirst', True):# does C go at the beginning or the end? v = f(context, *args) # when we call context.flip, we may update cs with new paths to explore else: newargs = args + (context,) v = f(*newargs) # print ">>>", v # add up the lp for this outcomem out[v] = logplusexp(out[v], context.lp) except kwargs.get('catchandpass', None) as e: pass except ContextSizeException: # prune that path pass if i >= kwargs.get('maxit', 1000): return out ## TODO: Hmm can either return the partial answer here or raise an exception if len(cs) > kwargs.get('maxcontext', 1000): # sometimes we can generate way too many contexts, so let's avoid that raise TooManyContextsException i += 1 return out
def equal_d(x, y): peq = -Infinity for a, v in list(x.items()): peq = logplusexp(peq, v + y.get(a, -Infinity)) # P(x=a,y=a) return {True: peq, False: log1mexp(peq)}
def car_d(x): out = defaultdict(lambdaMinusInfinity) for a, av in list(x.items()): v = a[1] if len(a) > 1 else '' out[v] = logplusexp(out[v], av) return out