class DirichletOutputPSP(RandomPSP): def simulate(self, args): alpha = args.operandValues()[0] return simulateDirichlet(alpha, args.np_prng()) def logDensity(self, val, args): alpha = args.operandValues()[0] return logDensityDirichlet(val, alpha) def description(self, name): return " %s(alphas) samples a simplex point according to the given " \ "Dirichlet distribution." % name registerBuiltinSP("dirichlet", \ typed_nr(DirichletOutputPSP(), [t.HomogeneousArrayType(t.PositiveType())], t.SimplexType())) class SymmetricDirichletOutputPSP(RandomPSP): def simulate(self, args): (alpha, n) = args.operandValues() return simulateDirichlet([float(alpha) for _ in range(int(n))], args.np_prng()) def logDensity(self, val, args): (alpha, n) = args.operandValues() return logDensityDirichlet(val, [float(alpha) for _ in range(int(n))]) def description(self, name): return " %s(alpha, n) samples a simplex point according to the " \
"""(Deterministic) basic programming SPs""" import cPickle as pkl from venture.lite.exception import VentureValueError from venture.lite.sp import SPType from venture.lite.sp_help import binaryPred from venture.lite.sp_help import deterministic_typed from venture.lite.sp_help import type_test from venture.lite.sp_registry import registerBuiltinSP from venture.lite.utils import raise_ import venture.lite.types as t import venture.lite.value as v registerBuiltinSP( "eq", binaryPred(lambda x, y: x.equal(y), descr="eq compares its two arguments for equality")) registerBuiltinSP( "neq", binaryPred(lambda x, y: not x.equal(y), descr="neq checkes whether its arguments are not equal")) registerBuiltinSP("gt", binaryPred(lambda x,y: x.compare(y) > 0, descr="gt returns true if its first argument compares greater " \ "than its second")) registerBuiltinSP("gte", binaryPred(lambda x,y: x.compare(y) >= 0, descr="gte returns true if its first argument compares greater " \ "than or equal to its second"))
@override(DeterministicPSP) def canAbsorb(self, _trace, appNode, parentNode): return parentNode != appNode.operandNodes[2] @override(DeterministicPSP) def description(self,name): return "%s returns its third argument unchanged at runtime, " \ "but tags the subexpression creating the object as being " \ "within the given scope and block." % name def isTagOutputPSP(thing): return isinstance(thing, TagOutputPSP) or \ (isinstance(thing, TypedPSP) and isTagOutputPSP(thing.psp)) registerBuiltinSP("tag", typed_nr(TagOutputPSP(), [t.AnyType("<scope>"), t.AnyType("<block>"), t.AnyType()], t.AnyType())) class TagExcludeOutputPSP(DeterministicPSP): @override(DeterministicPSP) def simulate(self,args): return args.operandValues()[1] @override(DeterministicPSP) def gradientOfSimulate(self, _args, _value, direction): return [0, direction] @override(DeterministicPSP) def canAbsorb(self, _trace, appNode, parentNode): return parentNode != appNode.operandNodes[1]
aux.N += 1 aux.xTotal += x aux.STotal += x * x.T def unincorporate(self, x, args): x = np.mat(x).reshape((self.d, 1)) aux = args.spaux() aux.N -= 1 aux.xTotal -= x aux.STotal -= x * x.T def logDensityOfData(self, aux): (mN, kN, vN, SN) = self.updatedParams(aux) term1 = -(aux.N * self.d * math.log(math.pi)) / 2. term2 = logGenGamma(self.d, vN / 2.) term3 = -logGenGamma(self.d, self.v0 / 2.) term4 = (self.v0 / 2.) * np.linalg.slogdet(self.S0)[1] # first is sign term5 = -(vN / 2.) * np.linalg.slogdet(SN)[1] term6 = (self.d / 2.) * math.log(float(self.k0) / kN) return term1 + term2 + term3 + term4 + term5 + term6 registerBuiltinSP( "make_niw_normal", typed_nr(MakeCMVNOutputPSP(), [ t.HomogeneousArrayType(t.NumberType()), t.NumberType(), t.NumberType(), t.MatrixType() ], SPType([], t.HomogeneousArrayType(t.NumberType()))))
from numbers import Number import numpy as np from venture.lite.exception import VentureValueError from venture.lite.sp_help import deterministic_typed from venture.lite.sp_help import type_test from venture.lite.sp_registry import registerBuiltinSP import venture.lite.value as vv import venture.lite.types as t import venture.lite.utils as u registerBuiltinSP("array", deterministic_typed(lambda *args: np.array(args), [t.AnyType()], t.ArrayType(), variadic=True, sim_grad=lambda args, direction: direction.getArray(), descr="array returns an array initialized with its arguments")) registerBuiltinSP("vector", deterministic_typed(lambda *args: np.array(args), [t.NumberType()], t.ArrayUnboxedType(t.NumberType()), variadic=True, sim_grad=lambda args, direction: direction.getArray(), descr="vector returns an unboxed numeric array initialized with its arguments")) registerBuiltinSP("is_array", type_test(t.ArrayType())) registerBuiltinSP("is_vector", type_test(t.ArrayUnboxedType(t.NumberType()))) registerBuiltinSP("to_array", deterministic_typed(lambda seq: seq.getArray(), [t.HomogeneousSequenceType(t.AnyType())], t.ArrayType(),
# # XXX This implementation will suggest to a multi-site proposal # that there are more distinct possibilities than actually exist, # if more than one table was emptied by recent unincorporations. # This is Github issue #462: # https://github.com/probcomp/Venturecxx/issues/462 if aux.cachedTables: tables += sorted(aux.cachedTables.values()) else: tables.append(aux.nextTable) return tables registerBuiltinSP( 'make_crp', typed_nr(MakeCRPOutputPSP(), [t.NumberType(), t.NumberType()], SPType([], t.AtomType()), min_req_args=1)) def draw_crp_samples(n, alpha, np_rng=None): """Jointly draw n samples from CRP(alpha). This returns an assignment of n objects to clusters, given by a length-n list of cluster ids. """ aux = CRPSPAux() args = MockArgs([], aux, np_rng=np_rng) psp = CRPOutputPSP(alpha, 0) # No dispersion def draw_sample():
def logDensity(self, value, args): n = args.operandValues()[0] xs = args.spaux().xs assert len(xs) > n theta = np.dot(xs[n], self.O) return math.log(theta[value]) def incorporate(self, value, args): n = args.operandValues()[0] os = args.spaux().os if n not in os: os[n] = [] os[n].append(value) def unincorporate(self, value, args): n = args.operandValues()[0] os = args.spaux().os del os[n][os[n].index(value)] if not os[n]: del os[n] class UncollapsedHMMRequestPSP(DeterministicPSP): def simulate(self, args): return Request([], [args.operandValues()[0]]) registerBuiltinSP( "make_lazy_hmm", typed_nr(MakeUncollapsedHMMOutputPSP(), [t.SimplexType(), t.MatrixType(), t.MatrixType()], SPType([t.CountType()], t.IntegerType())))
vvsum(direction)]), deterministic_psp( np.add, sim_grad=lambda args, direction: [vvsum(direction), direction]), deterministic_psp( lambda *args: np.sum(args, axis=0), sim_grad=lambda args, direction: [direction for _ in args], descr="add returns the sum of all its arguments"), deterministic_psp(symbolic_zero_left, sim_grad=lambda args, direction: [0, direction]), deterministic_psp(symbolic_zero_right, sim_grad=lambda args, direction: [direction, 0]), deterministic_psp(lambda a, b: a + b), ]) registerBuiltinSP("add", no_request(generic_add)) generic_sub = dispatching_psp([ SPType([t.NumberType(), t.NumberType()], t.NumberType()), SPType([t.ArrayUnboxedType(t.NumberType()), t.NumberType()], t.ArrayUnboxedType(t.NumberType())), SPType([t.NumberType(), t.ArrayUnboxedType(t.NumberType())], t.ArrayUnboxedType(t.NumberType())), SPType([ t.ArrayUnboxedType(t.NumberType()), t.ArrayUnboxedType(t.NumberType()) ], t.ArrayUnboxedType(t.NumberType())) ], [ deterministic_psp( lambda x, y: x - y, sim_grad=lambda args, direction: [direction, -direction],
class MakeMSPOutputPSP(DeterministicPSP): def simulate(self, args): sharedOperatorNode = args.operandNodes[0] return VentureSPRecord( SP(MSPRequestPSP(sharedOperatorNode), ESRRefOutputPSP())) def description(self, name): return "%s returns the stochastically memoized version of the input SP." % name class MSPRequestPSP(DeterministicPSP): def __init__(self, sharedOperatorNode): self.sharedOperatorNode = sharedOperatorNode def simulate(self, args): vals = args.operandValues() id = str(vals) exp = ["memoizedSP"] + [["quote", val] for val in vals] env = VentureEnvironment(None, ["memoizedSP"], [self.sharedOperatorNode]) return Request([ESR(id, exp, addr.req_frame(id), env)]) registerBuiltinSP( "mem", typed_nr(MakeMSPOutputPSP(), [SPType([t.AnyType("a")], t.AnyType("b"), variadic=True)], SPType([t.AnyType("a")], t.AnyType("b"), variadic=True)))
else: args.append(VentureArray(flat_args[i:i + s])) i += s assert i == len(flat_args) return args class ApplyFunctionOutputPSP(DeterministicPSP): def simulate(self, args): vals = args.operandValues() function = vals[0] arguments = vals[1:] sp_type = function.sp_type unwrapped_args = sp_type.unwrap_arg_list(arguments) #print sp_type.name(), unwrapped_args returned = function.f(*unwrapped_args) wrapped_return = sp_type.wrap_return(returned) return wrapped_return def description(self, _name=None): return "Apply a VentureFunction to arguments." # TODO Add type signature. Look at signature of apply? applyFunctionSP = SP(NullRequestPSP(), ApplyFunctionOutputPSP()) registerBuiltinSP("apply_function", applyFunctionSP)
def simulate(self, args): (operator, operands) = args.operandValues() exp = [operator] + operands env = VentureEnvironment() return Request([ESR(args.node, exp, addr.req_frame(0), env)]) def description(self, name): return "%s(func, vals) returns the result of applying a variadic" \ " function to an array of operands" % name registerBuiltinSP( "apply", esr_output( TypedPSP( ApplyRequestPSP(), SPType([ SPType([t.AnyType("a")], t.AnyType("b"), variadic=True), t.HomogeneousArrayType(t.AnyType("a")) ], t.RequestType("b"))))) class ArrayMapRequestPSP(DeterministicPSP): def simulate(self, args): (operator, operands) = args.operandValues() exps = [[operator, e.quote(operand)] for operand in operands] env = VentureEnvironment() return Request([ ESR((args.node, i), exp, addr.req_frame(i), env) for i, exp in enumerate(exps) ])
else: return [True, False] def description(self, name): return ' {name}(p) returns true with probability p and false otherwise. '\ 'If omitted, p is taken to be 0.5. '\ 'If you are tempted to write ({name} (exp x)),'\ ' write (log_{name} x) instead. '\ 'If you are tempted to write ({name} (logistic x)),'\ ' write (log_odds_{name} x) instead.'\ .format(name=name) registerBuiltinSP( "flip", typed_nr(BernoulliOutputPSP(), [t.ProbabilityType()], t.BoolType(), min_req_args=0)) registerBuiltinSP( "bernoulli", typed_nr(BernoulliOutputPSP(), [t.ProbabilityType()], t.IntegerType(), min_req_args=0)) class LogBernoulliOutputPSP(DiscretePSP): def simulate(self, args): logp = args.operandValues()[0] return math.log(args.py_prng().random()) < logp
# (at your option) any later version. # # Venture is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Venture. If not, see <http://www.gnu.org/licenses/>. import numpy as np from venture.lite.sp import SPType from venture.lite.sp_help import deterministic_psp from venture.lite.sp_help import dispatching_psp from venture.lite.sp_help import no_request from venture.lite.sp_registry import registerBuiltinSP import venture.lite.types as t generic_biplex = dispatching_psp( [SPType([t.BoolType(), t.AnyType(), t.AnyType()], t.AnyType()), SPType([t.ArrayUnboxedType(t.NumberType()), t.ArrayUnboxedType(t.NumberType()), t.ArrayUnboxedType(t.NumberType())], t.ArrayUnboxedType(t.NumberType()))], [deterministic_psp(lambda p, c, a: c if p else a, sim_grad=lambda args, direction: [0, direction, 0] if args[0] else [0, 0, direction], descr="biplex returns either its second or third argument, depending on the first."), deterministic_psp(np.where, # TODO sim_grad descr="vector-wise biplex")]) registerBuiltinSP("biplex", no_request(generic_biplex))
return self._name or '<covariance>' def distribution(self, base, **kwargs): return None def gradient_type(self): return t.ArrayUnboxedType(t.NumericArrayType()) makeGPType = SPType( [GPMeanType('mean function'), GPCovarianceType('covariance kernel')], gpType) makeGPSP = SP(NullRequestPSP(), TypedPSP(MakeGPOutputPSP(), makeGPType)) registerBuiltinSP('make_gp', makeGPSP) xType = t.NumericArrayType('x') oType = t.NumberType('o') def _mean_sp(F, argtypes): def mean_gradientOfSimulate(args, direction): return parameter_nest(F(*args).parameters, direction.getArray()) return deterministic_typed(F, argtypes, GPMeanType(), sim_grad=mean_gradientOfSimulate, descr=F.__doc__)
from venture.lite.psp import DeterministicPSP from venture.lite.psp import TypedPSP from venture.lite.request import ESR from venture.lite.request import Request from venture.lite.sp import SPType from venture.lite.sp_help import esr_output from venture.lite.sp_help import type_test from venture.lite.sp_help import typed_func from venture.lite.sp_help import typed_nr from venture.lite.sp_registry import registerBuiltinSP import venture.lite.address as addr import venture.lite.env as env import venture.lite.types as t registerBuiltinSP("get_current_environment", typed_func(lambda args: args.env, [], env.EnvironmentType(), descr="get_current_environment returns the lexical environment of its invocation site")) registerBuiltinSP("get_empty_environment", typed_func(lambda args: env.VentureEnvironment(), [], env.EnvironmentType(), descr="get_empty_environment returns the empty environment")) registerBuiltinSP("is_environment", type_test(env.EnvironmentType())) class ExtendEnvOutputPSP(DeterministicPSP): def simulate(self,args): (en, sym, _) = args.operandValues() node = args.operandNodes[2] return env.VentureEnvironment(en,[sym],[node]) def description(self,name): return "%s returns an extension of the given environment where the given symbol is bound to the given object" % name
def register_record(name, *fields): (tester, constructor, accessors) = record(name, len(fields)) registerBuiltinSP(name, constructor) registerBuiltinSP("is_" + name, tester) for (f, a) in zip(fields, accessors): registerBuiltinSP(f, a)