def test_error_linspace(): with pytest.raises(AssertionError): # Switch cases do not sum to one. command = Sequence( Sample(Y, beta(a=2, b=3)), Switch(Y, linspace(0, .5, 5), lambda i: Sample(X, bernoulli(p=i)))) command.interpret()
def test_error_range(): with pytest.raises(AssertionError): # Switch cases do not sum to one. command = Sequence( Sample(Y, randint(low=0, high=4)), Switch(Y, range(0, 3), lambda i: Sample(X, bernoulli(p=1 / (i + 1))))) command.interpret()
def make_model_for(n=2): command = Sequence( Sample(Y, choice({'0': .2, '1': .2, '2': .2, '3': .2, '4': .2})), For(0, n, lambda i: Sequence( Sample(Z[i], bernoulli(p=.5)), IfElse( (Y << {str(i)}) | (Z[i] << {0}), Sample(X[i], bernoulli(p=.1)), Otherwise, Sample(X[i], bernoulli(p=.5)))))) return command.interpret()
def test_condition_prob_zero(): with pytest.raises(Exception): Sequence(Sample(Y, { 'a': .1, 'b': .1, 'c': .8 }), Condition(Y << {'d'})).interpret() with pytest.raises(Exception): Sequence(Sample(Y, beta(a=1, b=1)), Condition(Y > 1)).interpret()
def test_simple_model_enumerate(): command_switch = Sequence( Sample(Y, randint(low=0, high=4)), Switch(Y, enumerate(range(0, 4)), lambda i, j: Sample(X, bernoulli(p=1 / (i + j + 1))))) model = command_switch.interpret() assert allclose(model.prob(Y << {0} & (X << {1})), .25 * 1 / (0 + 0 + 1)) assert allclose(model.prob(Y << {1} & (X << {1})), .25 * 1 / (1 + 1 + 1)) assert allclose(model.prob(Y << {2} & (X << {1})), .25 * 1 / (2 + 2 + 1)) assert allclose(model.prob(Y << {3} & (X << {1})), .25 * 1 / (3 + 3 + 1))
def test_complex_model(): # Slow for larger number of repetitions # https://github.com/probcomp/sum-product-dsl/issues/43 command = Sequence( Sample(Y, choice({'0': .2, '1': .2, '2': .2, '3': .2, '4': .2})), For(0, 3, lambda i: Sequence( Sample(Z[i], bernoulli(p=0.1)), IfElse( Y << {str(i)} | Z[i] << {0}, Sample(X[i], bernoulli(p=1/(i+1))), Otherwise, Sample(X[i], bernoulli(p=0.1)))))) model = command.interpret() assert allclose(model.prob(Y << {'0'}), 0.2)
def test_complex_model_reorder(): command = Sequence( Sample(Y, choice({'0': .2, '1': .2, '2': .2, '3': .2, '4': .2})), For(0, 3, lambda i: Sample(Z[i], bernoulli(p=0.1))), For(0, 3, lambda i: IfElse( Y << {str(i)}, Sample(X[i], bernoulli(p=1/(i+1))), Z[i] << {0}, Sample(X[i], bernoulli(p=1/(i+1))), Otherwise, Sample(X[i], bernoulli(p=0.1))))) model = command.interpret() assert(allclose(model.prob(Y << {'0'}), 0.2))
def get_command_randint(): return Sequence( Sample(simAll, randint(low=0, high=ns)), For( 0, 5, lambda k: Switch( simAll, range(0, ns), lambda i: Sequence( Sample(sim[k], bernoulli(p=i / nd)), Sample(p1[k], randint(low=0, high=ns)), IfElse( sim[k] << {1}, Sequence( Transform(p2[k], p1[k]), Switch( p1[k], range(ns), lambda j: Sequence( Sample(clickA[k], bernoulli(p=i / nd)), Sample(clickB[k], bernoulli(p=i / nd))))), True, Sequence( Sample(p2[k], randint(low=0, high=ns)), Switch( p1[k], range(ns), lambda j: Sample( clickA[k], bernoulli(p=j / nd))), Switch( p2[k], range(ns), lambda j: Sample( clickB[k], bernoulli(p=j / nd)))))))))
def get_command_beta(): return Sequence( Sample(simAll, beta(a=2, b=3)), For( 0, 5, lambda k: Switch( simAll, binspace(0, 1, ns), lambda i: Sequence( Sample(sim[k], bernoulli(p=i.right)), Sample(p1[k], uniform()), IfElse( sim[k] << {1}, Sequence( Transform(p2[k], p1[k]), Switch( p1[k], binspace(0, 1, ns), lambda j: Sequence( Sample(clickA[k], bernoulli(p=i.right)), Sample(clickB[k], bernoulli(p=i.right))))), True, Sequence( Sample(p2[k], uniform()), Switch( p1[k], binspace(0, 1, ns), lambda j: Sample( clickA[k], bernoulli(p=j.right))), Switch( p2[k], binspace(0, 1, ns), lambda j: Sample( clickB[k], bernoulli(p=j.right)))))))))
def test_simple_model_lte(): command_switch = Sequence( Sample(Y, beta(a=2, b=3)), Switch(Y, binspace(0, 1, 5), lambda i: Sample(X, bernoulli(p=i.right)))) model_switch = command_switch.interpret() command_ifelse = Sequence( Sample(Y, beta(a=2, b=3)), IfElse( Y <= 0, Sample(X, bernoulli(p=0)), Y <= 0.25, Sample(X, bernoulli(p=.25)), Y <= 0.50, Sample(X, bernoulli(p=.50)), Y <= 0.75, Sample(X, bernoulli(p=.75)), Y <= 1, Sample(X, bernoulli(p=1)), )) model_ifelse = command_ifelse.interpret() grid = [float(x) for x in linspace(0, 1, 5)] for model in [model_switch, model_ifelse]: symbols = model.get_symbols() assert symbols == {X, Y} assert allclose( model.logprob(X << {1}), logsumexp([ model.logprob((il < Y) <= ih) + log(ih) for il, ih in zip(grid[:-1], grid[1:]) ]))
def get_model(): Y = Id('Y') X = Id('X') Z = Id('Z') command = Sequence( Sample(Y, choice({ '0': .2, '1': .2, '2': .2, '3': .2, '4': .2 })), Sample(Z, bernoulli(p=0.1)), IfElse(Y << {str(0)} | Z << {0}, Sample(X, bernoulli(p=1 / (0 + 1))), Otherwise, Transform(X, Z**2 + Z))) return command.interpret()
def model_perfect_nested(): Nationality = Id('Nationality') Perfect = Id('Perfect') GPA = Id('GPA') command = Sequence( Sample(Nationality, choice({ 'India': 0.5, 'USA': 0.5 })), IfElse( Nationality << {'India'}, Sequence( Sample(Perfect, choice({ 'True': 0.01, 'False': 0.99 })), IfElse(Perfect << {'True'}, Sample(GPA, atomic(loc=10)), True, Sample(GPA, uniform(scale=10)))), Nationality << {'USA'}, Sequence( Sample(Perfect, choice({ 'True': 0.01, 'False': 0.99 })), IfElse( Perfect << {'True'}, Sample(GPA, atomic(loc=4)), True, Sample(GPA, uniform(scale=4)), )))) return command.interpret()
def test_simple_model_eq(): command_switch = Sequence( Sample(Y, randint(low=0, high=4)), Switch(Y, range(0, 4), lambda i: Sample(X, bernoulli(p=1 / (i + 1))))) model_switch = command_switch.interpret() command_ifelse = Sequence( Sample(Y, randint(low=0, high=4)), IfElse( Y << {0}, Sample(X, bernoulli(p=1 / (0 + 1))), Y << {1}, Sample(X, bernoulli(p=1 / (1 + 1))), Y << {2}, Sample(X, bernoulli(p=1 / (2 + 1))), Y << {3}, Sample(X, bernoulli(p=1 / (3 + 1))), )) model_ifelse = command_ifelse.interpret() for model in [model_switch, model_ifelse]: symbols = model.get_symbols() assert symbols == {X, Y} assert allclose(model.logprob(X << {1}), logsumexp([-log(4) - log(i + 1) for i in range(4)]))
def test_condition_nominal(): command = Sequence(Sample(Y, choice({ 'a': .1, 'b': .1, 'c': .8 })), Condition(Y << {'a', 'b'})) model = command.interpret() assert allclose(model.prob(Y << {'a'}), .5) assert allclose(model.prob(Y << {'b'}), .5) assert allclose(model.prob(Y << {'c'}), 0)
def test_if_else_transform(): model = Sequence( Sample(X, norm(loc=0, scale=1)), IfElse(X > 0, Transform(Z, X**2), Otherwise, Transform(Z, X))).interpret() assert model.children[0].env == {X: X, Z: X**2} assert model.children[1].env == {X: X, Z: X} assert allclose(model.children[0].logprob(Z > 0), 0) assert allclose(model.children[1].logprob(Z > 0), -float('inf')) assert allclose(model.logprob(Z > 0), -log(2))
def test_simple_model(): command = Sequence( Sample(Y, bernoulli(p=0.5)), For(0, 5, lambda i: Sample(X[i], bernoulli(p=1/(i+1))))) model = command.interpret() symbols = model.get_symbols() assert len(symbols) == 6 assert Y in symbols assert X[0] in symbols assert X[1] in symbols assert X[2] in symbols assert X[3] in symbols assert X[4] in symbols assert model.logprob(X[0] << {1}) == log(1/1) assert model.logprob(X[1] << {1}) == log(1/2) assert model.logprob(X[2] << {1}) == log(1/3) assert model.logprob(X[3] << {1}) == log(1/4) assert model.logprob(X[4] << {1}) == log(1/5)
def test_ifelse_zero_conditions(): command = Sequence( Sample(Y, randint(low=0, high=3)), IfElse( Y << {-1}, Transform(X, Y**(-1)), Y << {0}, Sample(X, bernoulli(p=1)), Y << {1}, Transform(X, Y), Y << {2}, Transform(X, Y**2), Y << {3}, Transform(X, Y**3), )) model = command.interpret() assert len(model.children) == 3 assert len(model.weights) == 3 assert allclose(model.weights[0], model.logprob(Y << {0})) assert allclose(model.weights[1], model.logprob(Y << {1})) assert allclose(model.weights[2], model.logprob(Y << {2}))
def model_ifelse_exhuastive(): command = Sequence( Sample(Nationality, choice({ 'India': 0.5, 'USA': 0.5 })), Sample(Perfect, choice({ 'True': 0.01, 'False': 0.99 })), IfElse((Nationality << {'India'}) & (Perfect << {'False'}), Sample(GPA, uniform(loc=0, scale=10)), (Nationality << {'India'}) & (Perfect << {'True'}), Sample(GPA, atomic(loc=10)), (Nationality << {'USA'}) & (Perfect << {'False'}), Sample(GPA, uniform(loc=0, scale=4)), (Nationality << {'USA'}) & (Perfect << {'True'}), Sample(GPA, atomic(loc=4)))) return command.interpret()
from sppl.compilers.ast_to_spe import Id from sppl.compilers.ast_to_spe import IfElse from sppl.compilers.ast_to_spe import Otherwise from sppl.compilers.ast_to_spe import Sample from sppl.compilers.ast_to_spe import Sequence from sppl.distributions import bernoulli Burglary = Id('Burglary') Earthquake = Id('Earthquake') Alarm = Id('Alarm') JohnCalls = Id('JohnCalls') MaryCalls = Id('MaryCalls') program = Sequence( Sample(Burglary, bernoulli(p=0.001)), Sample(Earthquake, bernoulli(p=0.002)), IfElse( Burglary << {1}, IfElse( Earthquake << {1}, Sample(Alarm, bernoulli(p=0.95)), Otherwise, Sample(Alarm, bernoulli(p=0.94))), Otherwise, IfElse( Earthquake << {1}, Sample(Alarm, bernoulli(p=0.29)), Otherwise, Sample(Alarm, bernoulli(p=0.001)))), IfElse( Alarm << {1}, Sequence( Sample(JohnCalls, bernoulli(p=0.90)), Sample(MaryCalls, bernoulli(p=0.70))), Otherwise, Sequence(
def test_condition_real_continuous(): command = Sequence(Sample(Y, beta(a=1, b=1)), Condition(Y < .5)) model = command.interpret() assert allclose(model.prob(Y < .5), 1) assert allclose(model.prob(Y > .5), 0)
def test_condition_real_discrete_no_range(): command = Sequence(Sample(Y, randint(low=0, high=4)), Condition(Y << {0, 2})) model = command.interpret() assert allclose(model.prob(Y << {0}), .5) assert allclose(model.prob(Y << {1}), .5)
def test_if_else_transform_reverse(): command = Sequence( Sample(X, norm(loc=0, scale=1)), Sample(Y, bernoulli(p=0.5)), IfElse(Y << {0}, Transform(Z, X**2), Otherwise, Transform(Z, X))) model = command.interpret() assert allclose(model.logprob(Z > 0), log(3) - log(4))
def test_simple_transform(): command = Sequence(Sample(X, norm(loc=0, scale=1)), Transform(Z, X**2)) model = command.interpret() assert model.get_symbols() == {Z, X} assert model.env == {Z: X**2, X: X} assert (model.logprob(Z > 0)) == 0
def make_model_handcode(): command = Sequence( Sample(Y, choice({'0': .2, '1': .2, '2': .2, '3': .2, '4': .2})), Sample(Z[0], bernoulli(p=.5)), Sample(Z[1], bernoulli(p=.5)), IfElse( Y << {str(0)}, Sequence( Sample(X[0], bernoulli(p=.1)), IfElse( Z[1] << {0}, Sample(X[1], bernoulli(p=.1)), Otherwise, Sample(X[1], bernoulli(p=.5)))), Y << {str(1)}, Sequence( Sample(X[1], bernoulli(p=.1)), IfElse( Z[0] << {0}, Sample(X[0], bernoulli(p=.1)), Otherwise, Sample(X[0], bernoulli(p=.5)))), Otherwise, Sequence( IfElse( Z[0] << {0}, Sample(X[0], bernoulli(p=.1)), Otherwise, Sample(X[0], bernoulli(p=.5))), IfElse( Z[1] << {0}, Sample(X[1], bernoulli(p=.1)), Otherwise, Sample(X[1], bernoulli(p=.5)))))) return command.interpret()