コード例 #1
0
def test_assoccomm():
    from symbolic_pymc.relations import buildo

    x, a, b, c = tt.dvectors('xabc')
    test_expr = x + 1
    q = var('q')

    res = run(1, q, buildo(tt.add, test_expr.owner.inputs, test_expr))
    assert q == res[0]

    res = run(1, q, buildo(q, test_expr.owner.inputs, test_expr))
    assert tt.add == res[0].reify()

    res = run(1, q, buildo(tt.add, q, test_expr))
    assert mt(tuple(test_expr.owner.inputs)) == res[0]

    res = run(0, var('x'), eq_comm(mt.mul(a, b), mt.mul(b, var('x'))))
    assert (mt(a), ) == res

    res = run(0, var('x'), eq_comm(mt.add(a, b), mt.add(b, var('x'))))
    assert (mt(a), ) == res

    res = run(0, var('x'), (eq_assoc, mt.add(a, b, c), mt.add(a, var('x'))))

    # TODO: `res[0]` should return `etuple`s.  Since `eq_assoc` effectively
    # picks apart the results of `arguments(...)`, I don't know if we can
    # keep the `etuple`s around.  We might be able to convert the results
    # to `etuple`s automatically by wrapping `eq_assoc`, though.
    res_obj = etuple(*res[0]).eval_obj
    assert res_obj == mt(b + c)

    res = run(0, var('x'), (eq_assoc, mt.mul(a, b, c), mt.mul(a, var('x'))))
    res_obj = etuple(*res[0]).eval_obj
    assert res_obj == mt(b * c)
コード例 #2
0
def test_assoccomm():
    x, a, b, c = tt.dvectors("xabc")
    test_expr = x + 1
    q = var()

    res = run(1, q, applyo(tt.add, etuple(*test_expr.owner.inputs), test_expr))
    assert q == res[0]

    res = run(1, q, applyo(q, etuple(*test_expr.owner.inputs), test_expr))
    assert tt.add == res[0].reify()

    res = run(1, q, applyo(tt.add, q, test_expr))
    assert mt(tuple(test_expr.owner.inputs)) == res[0]

    x = var()
    res = run(0, x, eq_comm(mt.mul(a, b), mt.mul(b, x)))
    assert (mt(a), ) == res

    res = run(0, x, eq_comm(mt.add(a, b), mt.add(b, x)))
    assert (mt(a), ) == res

    (res, ) = run(0, x, eq_assoc(mt.add(a, b, c), mt.add(a, x)))
    assert res == mt(b + c)

    (res, ) = run(0, x, eq_assoc(mt.mul(a, b, c), mt.mul(a, x)))
    assert res == mt(b * c)
コード例 #3
0
def test_distributions():
    res = run(0, var('q'), eq(var('q'), mt(1)),
              constant_neq(var('q'), np.array(1.)))

    assert not res

    res = run(0, var('q'), eq(var('q'), mt(2)),
              constant_neq(var('q'), np.array(1.)))

    assert res
コード例 #4
0
def test_meta_helpers():
    zeros_mt = mt.zeros(2)
    assert np.array_equal(zeros_mt.reify().eval(), np.r_[0., 0.])

    zeros_mt = mt.zeros(2, dtype=int)
    assert np.array_equal(zeros_mt.reify().eval(), np.r_[0, 0])

    mat_mt = mt(np.eye(2))
    diag_mt = mt.diag(mat_mt)
    assert np.array_equal(diag_mt.reify().eval(), np.r_[1., 1.])

    diag_mt = mt.diag(mt(np.r_[1, 2, 3]))
    assert np.array_equal(diag_mt.reify().eval(), np.diag(np.r_[1, 2, 3]))
コード例 #5
0
def test_pymc_broadcastable():
    """Test PyMC3 to Theano conversion amid array broadcasting."""
    tt.config.compute_test_value = 'ignore'

    mu_X = tt.vector('mu_X')
    sd_X = tt.vector('sd_X')
    mu_Y = tt.vector('mu_Y')
    sd_Y = tt.vector('sd_Y')
    mu_X.tag.test_value = np.array([0.], dtype=tt.config.floatX)
    sd_X.tag.test_value = np.array([1.], dtype=tt.config.floatX)
    mu_Y.tag.test_value = np.array([1.], dtype=tt.config.floatX)
    sd_Y.tag.test_value = np.array([0.5], dtype=tt.config.floatX)

    with pm.Model() as model:
        X_rv = pm.Normal('X_rv', mu_X, sd=sd_X, shape=(1, ))
        Y_rv = pm.Normal('Y_rv', mu_Y, sd=sd_Y, shape=(1, ))
        Z_rv = pm.Normal('Z_rv',
                         X_rv + Y_rv,
                         sd=sd_X + sd_Y,
                         shape=(1, ),
                         observed=[10.])

    with pytest.warns(UserWarning):
        fgraph = model_graph(model)

    Z_rv_tt = canonicalize(fgraph, return_graph=False)

    # This will break comparison if we don't reuse it
    rng = Z_rv_tt.owner.inputs[1].owner.inputs[-1]

    mu_X_ = mt.vector('mu_X')
    sd_X_ = mt.vector('sd_X')
    mu_Y_ = mt.vector('mu_Y')
    sd_Y_ = mt.vector('sd_Y')
    tt.config.compute_test_value = 'ignore'
    X_rv_ = mt.NormalRV(mu_X_, sd_X_, (1, ), rng, name='X_rv')
    X_rv_ = mt.addbroadcast(X_rv_, 0)
    Y_rv_ = mt.NormalRV(mu_Y_, sd_Y_, (1, ), rng, name='Y_rv')
    Y_rv_ = mt.addbroadcast(Y_rv_, 0)
    Z_rv_ = mt.NormalRV(mt.add(X_rv_, Y_rv_),
                        mt.add(sd_X_, sd_Y_), (1, ),
                        rng,
                        name='Z_rv')
    obs_ = mt(Z_rv.observations)
    Z_rv_obs_ = mt.observed(obs_, Z_rv_)
    Z_rv_meta = canonicalize(Z_rv_obs_.reify(), return_graph=False)

    assert mt(Z_rv_tt) == mt(Z_rv_meta)
コード例 #6
0
def test_constant_neq():
    q_lv = var()

    res = run(0, q_lv, eq(q_lv, mt(1)), constant_neq(q_lv, np.array(1.0)))
    assert not res

    # TODO: If `constant_neq` was a true constraint, this would work.
    # res = run(0, q_lv, constant_neq(q_lv, np.array(1.0)), eq(q_lv, mt(1)))
    # assert not res

    # TODO: If `constant_neq` was a true constraint, this would work.
    # res = run(0, q_lv, constant_neq(q_lv, np.array(1.0)), eq(q_lv, mt(2)))
    # assert res == (mt(2),)

    res = run(0, q_lv, eq(q_lv, mt(2)), constant_neq(q_lv, np.array(1.0)))
    assert res == (mt(2), )
コード例 #7
0
def test_terms():
    x, a, b = tt.dvectors("xab")
    test_expr = x + a * b

    assert mt(test_expr.owner.op) == operator(test_expr)
    assert mt(tuple(test_expr.owner.inputs)) == tuple(arguments(test_expr))

    assert tuple(arguments(test_expr)) == mt(tuple(test_expr.owner.inputs))

    # Implicit `etuple` conversion should retain the original object
    # (within the implicitly introduced meta object, of course).
    assert test_expr == arguments(test_expr)._parent._eval_obj.obj

    assert graph_equal(test_expr,
                       term(operator(test_expr), arguments(test_expr)))
    assert mt(test_expr) == term(operator(test_expr), arguments(test_expr))

    # Same here: should retain the original object.
    assert test_expr == term(operator(test_expr), arguments(test_expr)).reify()
コード例 #8
0
ファイル: test_meta.py プロジェクト: volcacius/symbolic-pymc
def test_scan_op():
    def f_pow2(x_tm1):
        return 2 * x_tm1

    state = theano.tensor.scalar("state")
    n_steps = theano.tensor.iscalar("nsteps")
    output, updates = theano.scan(
        f_pow2, [], state, [], n_steps=n_steps, truncate_gradient=-1, go_backwards=False
    )

    output_mt = mt(output)

    assert isinstance(output_mt.owner.inputs[0].owner.op, mt.Scan)

    assert output is output_mt.reify()
コード例 #9
0
def test_unify_ops():
    def f_pow2(x_tm1):
        return 2 * x_tm1

    state = theano.tensor.scalar("state")
    n_steps = theano.tensor.iscalar("nsteps")
    output, updates = theano.scan(f_pow2, [],
                                  state, [],
                                  n_steps=n_steps,
                                  truncate_gradient=-1,
                                  go_backwards=False)

    assert np.array_equal(output.eval({
        state: 1.0,
        n_steps: 4
    }), np.r_[2.0, 4.0, 8.0, 16.0])

    scan_tt = output.owner.inputs[0].owner.op

    inputs_lv, outputs_lv, info_lv = var(), var(), var()
    scan_lv = mt.Scan(inputs_lv, outputs_lv, info_lv)

    s = unify(scan_lv, scan_tt, {})

    assert s is not False
    assert s[inputs_lv] is scan_tt.inputs

    s_new = s.copy()
    s_new[outputs_lv] = [5 * s_new[inputs_lv][0]]

    new_scan_mt = reify(scan_lv, s_new)

    output_mt = mt(output)
    output_mt.owner.inputs[0].owner.op = new_scan_mt
    output_mt.owner.inputs[0].reset()
    output_mt.owner.outputs[0].reset()
    output_mt.owner.reset()
    output_mt.reset()
    assert output_mt.obj is not output

    output_new = output_mt.reify()

    assert output_new != output

    assert np.array_equal(output_new.eval({
        state: 1.0,
        n_steps: 4
    }), np.r_[5.0, 25.0, 125.0, 625.0])
コード例 #10
0
def test_etuple_term():
    """Test `etuplize` and `etuple` interaction with `term`
    """
    # Take apart an already constructed/evaluated meta
    # object.
    e2 = mt.add(mt.vector(), mt.vector())

    e2_et = etuplize(e2)

    assert isinstance(e2_et, ExpressionTuple)

    # e2_et_expect = etuple(
    #     mt.add,
    #     etuple(mt.TensorVariable,
    #            etuple(mt.TensorType,
    #                   'float64', (False,), None),
    #            None, None, None),
    #     etuple(mt.TensorVariable,
    #            etuple(mt.TensorType,
    #                   'float64', (False,), None),
    #            None, None, None),
    # )
    e2_et_expect = etuple(mt.add, e2.base_arguments[0], e2.base_arguments[1])
    assert e2_et == e2_et_expect
    assert e2_et.eval_obj is e2

    # Make sure expression expansion works from Theano objects, too.
    # First, do it manually.
    tt_expr = tt.vector() + tt.vector()

    mt_expr = mt(tt_expr)
    assert mt_expr.obj is tt_expr
    assert mt_expr.reify() is tt_expr
    e3 = etuplize(mt_expr)
    assert e3 == e2_et
    assert e3.eval_obj is mt_expr
    assert e3.eval_obj.reify() is tt_expr

    # Now, through `etuplize`
    e2_et_2 = etuplize(tt_expr)
    assert e2_et_2 == e3 == e2_et
    assert isinstance(e2_et_2, ExpressionTuple)
    assert e2_et_2.eval_obj == tt_expr
コード例 #11
0
def test_meta_classes():
    vec_tt = tt.vector('vec')
    vec_m = metatize(vec_tt)
    assert vec_m.obj == vec_tt
    assert type(vec_m) == TheanoMetaTensorVariable

    # This should invalidate the underlying base object.
    vec_m.index = 0
    assert vec_m.obj is None
    assert vec_m.reify().type == vec_tt.type
    assert vec_m.reify().name == vec_tt.name

    vec_type_m = vec_m.type
    assert type(vec_type_m) == TheanoMetaTensorType
    assert vec_type_m.dtype == vec_tt.dtype
    assert vec_type_m.broadcastable == vec_tt.type.broadcastable
    assert vec_type_m.name == vec_tt.type.name

    assert graph_equal(tt.add(1, 2), mt.add(1, 2).reify())

    meta_var = mt.add(1, var()).reify()
    assert isinstance(meta_var, TheanoMetaTensorVariable)
    assert isinstance(meta_var.owner.op.obj, theano.Op)
    assert isinstance(meta_var.owner.inputs[0].obj, tt.TensorConstant)

    test_vals = [1, 2.4]
    meta_vars = metatize(test_vals)
    assert meta_vars == [metatize(x) for x in test_vals]
    # TODO: Do we really want meta variables to be equal to their
    # reified base objects?
    # assert meta_vars == [tt.as_tensor_variable(x) for x in test_vals]

    name_mt = var()
    add_tt = tt.add(0, 1)
    add_mt = mt.add(0, 1, name=name_mt)

    assert add_mt.name is name_mt
    assert add_tt.type == add_mt.type.reify()
    assert mt(add_tt.owner) == add_mt.owner
    # assert isvar(add_mt._obj)

    # Let's confirm that we can dynamically create a new meta `Op` type
    test_mat = np.c_[[2, 3], [4, 5]]

    svd_tt = tt.nlinalg.SVD()(test_mat)
    # First, can we create one from a new base `Op` instance?
    svd_op_mt = mt(tt.nlinalg.SVD())
    svd_mt = svd_op_mt(test_mat)

    assert svd_mt[0].owner.nin == 1
    assert svd_mt[0].owner.nout == 3

    svd_outputs = svd_mt[0].owner.outputs
    assert svd_outputs[0] == svd_mt[0]
    assert svd_outputs[1] == svd_mt[1]
    assert svd_outputs[2] == svd_mt[2]

    assert mt(svd_tt) == svd_mt

    # Next, can we create one from a base `Op` type/class?
    svd_op_type_mt = mt.nlinalg.SVD
    assert isinstance(svd_op_type_mt, type)
    assert issubclass(svd_op_type_mt, TheanoMetaOp)

    # svd_op_inst_mt = svd_op_type_mt(tt.nlinalg.SVD())
    # svd_op_inst_mt(test_mat) == svd_mt

    # Apply node with logic variable as outputs
    svd_apply_mt = TheanoMetaApply(svd_op_mt, [test_mat], outputs=var('out'))
    assert isinstance(svd_apply_mt.inputs, tuple)
    assert isinstance(svd_apply_mt.inputs[0], MetaSymbol)
    assert isvar(svd_apply_mt.outputs)
    assert svd_apply_mt.nin == 1
    assert svd_apply_mt.nout is None

    # Apply node with logic variable as inputs
    svd_apply_mt = TheanoMetaApply(svd_op_mt, var('in'), outputs=var('out'))
    assert svd_apply_mt.nin is None

    # A meta variable with None index
    var_mt = TheanoMetaVariable(svd_mt[0].type, svd_mt[0].owner, None, None)
    assert var_mt.index is None
    reified_var_mt = var_mt.reify()

    assert isinstance(reified_var_mt, TheanoMetaTensorVariable)
    assert reified_var_mt.index == 0
    assert var_mt.index == 0
    assert reified_var_mt == svd_mt[0]

    # A meta variable with logic variable index
    var_mt = TheanoMetaVariable(svd_mt[0].type, svd_mt[0].owner, var('index'), None)
    assert isvar(var_mt.index)
    reified_var_mt = var_mt.reify()
    assert isvar(var_mt.index)
    assert reified_var_mt.index == 0

    const_mt = mt(1)
    assert isinstance(const_mt, TheanoMetaTensorConstant)
    assert const_mt != mt(2)
コード例 #12
0
def test_normal_normal_regression():
    tt.config.compute_test_value = "ignore"
    theano.config.cxx = ""
    np.random.seed(9283)

    N = 10
    M = 3
    a_tt = tt.vector("a")
    R_tt = tt.vector("R")
    X_tt = tt.matrix("X")
    V_tt = tt.vector("V")

    a_tt.tag.test_value = np.random.normal(size=M)
    R_tt.tag.test_value = np.abs(np.random.normal(size=M))
    X = np.random.normal(10, 1, size=N)
    X = np.c_[np.ones(10), X, X * X]
    X_tt.tag.test_value = X
    V_tt.tag.test_value = np.ones(N)

    beta_rv = NormalRV(a_tt, R_tt, name="\\beta")

    E_y_rv = X_tt.dot(beta_rv)
    E_y_rv.name = "E_y"
    Y_rv = NormalRV(E_y_rv, V_tt, name="Y")

    y_tt = tt.as_tensor_variable(Y_rv.tag.test_value)
    y_tt.name = "y"
    y_obs_rv = observed(y_tt, Y_rv)
    y_obs_rv.name = "y_obs"

    #
    # Use the relation with identify/match `Y`, `X` and `beta`.
    #
    y_args_tail_lv, b_args_tail_lv = var(), var()
    beta_lv = var()

    y_args_lv, y_lv, Y_lv, X_lv = var(), var(), var(), var()
    (res, ) = run(
        1,
        (beta_lv, y_args_tail_lv, b_args_tail_lv),
        applyo(mt.observed, y_args_lv, y_obs_rv),
        eq(y_args_lv, (y_lv, Y_lv)),
        normal_normal_regression(Y_lv, X_lv, beta_lv, y_args_tail_lv,
                                 b_args_tail_lv),
    )

    # TODO FIXME: This would work if non-op parameters (e.g. names) were covered by
    # `operator`/`car`.  See `TheanoMetaOperator`.
    assert res[0].eval_obj.obj == beta_rv
    assert res[0] == etuplize(beta_rv)
    assert res[1] == etuplize(Y_rv)[2:]
    assert res[2] == etuplize(beta_rv)[1:]

    #
    # Use the relation with to produce `Y` from given `X` and `beta`.
    #
    X_new_mt = mt(tt.eye(N, M))
    beta_new_mt = mt(NormalRV(0, 1, size=M))
    Y_args_cdr_mt = etuplize(Y_rv)[2:]
    Y_lv = var()
    (res, ) = run(
        1, Y_lv,
        normal_normal_regression(Y_lv, X_new_mt, beta_new_mt, Y_args_cdr_mt))
    Y_out_mt = res.eval_obj

    Y_new_mt = etuple(mt.NormalRV, mt.dot(X_new_mt,
                                          beta_new_mt)) + Y_args_cdr_mt
    Y_new_mt = Y_new_mt.eval_obj

    assert Y_out_mt == Y_new_mt
コード例 #13
0
def test_pymc_normal_model():
    """Conduct a more in-depth test of PyMC3/Theano conversions for a specific model."""
    tt.config.compute_test_value = 'ignore'

    mu_X = tt.dscalar('mu_X')
    sd_X = tt.dscalar('sd_X')
    mu_Y = tt.dscalar('mu_Y')
    mu_X.tag.test_value = np.array(0., dtype=tt.config.floatX)
    sd_X.tag.test_value = np.array(1., dtype=tt.config.floatX)
    mu_Y.tag.test_value = np.array(1., dtype=tt.config.floatX)

    # We need something that uses transforms...
    with pm.Model() as model:
        X_rv = pm.Normal('X_rv', mu_X, sd=sd_X)
        S_rv = pm.HalfCauchy('S_rv',
                             beta=np.array(0.5, dtype=tt.config.floatX))
        Y_rv = pm.Normal('Y_rv', X_rv * S_rv, sd=S_rv)
        Z_rv = pm.Normal('Z_rv', X_rv + Y_rv, sd=sd_X, observed=10.)

    fgraph = model_graph(model, output_vars=[Z_rv])

    Z_rv_tt = canonicalize(fgraph, return_graph=False)

    # This will break comparison if we don't reuse it
    rng = Z_rv_tt.owner.inputs[1].owner.inputs[-1]

    mu_X_ = mt.dscalar('mu_X')
    sd_X_ = mt.dscalar('sd_X')
    tt.config.compute_test_value = 'ignore'
    X_rv_ = mt.NormalRV(mu_X_, sd_X_, None, rng, name='X_rv')
    S_rv_ = mt.HalfCauchyRV(np.array(0., dtype=tt.config.floatX),
                            np.array(0.5, dtype=tt.config.floatX),
                            None,
                            rng,
                            name='S_rv')
    Y_rv_ = mt.NormalRV(mt.mul(X_rv_, S_rv_), S_rv_, None, rng, name='Y_rv')
    Z_rv_ = mt.NormalRV(mt.add(X_rv_, Y_rv_), sd_X, None, rng, name='Z_rv')
    obs_ = mt(Z_rv.observations)
    Z_rv_obs_ = mt.observed(obs_, Z_rv_)

    Z_rv_meta = mt(canonicalize(Z_rv_obs_.reify(), return_graph=False))

    assert mt(Z_rv_tt) == Z_rv_meta

    # Now, let's try that with multiple outputs.
    fgraph.disown()
    fgraph = model_graph(model, output_vars=[Y_rv, Z_rv])

    assert len(fgraph.variables) == 25

    Y_new_rv = walk(Y_rv, fgraph.memo)
    S_new_rv = walk(S_rv, fgraph.memo)
    X_new_rv = walk(X_rv, fgraph.memo)
    Z_new_rv = walk(Z_rv, fgraph.memo)

    # Make sure our new vars are actually in the graph and where
    # they should be.
    assert Y_new_rv == fgraph.outputs[0]
    assert Z_new_rv == fgraph.outputs[1]
    assert X_new_rv in fgraph.variables
    assert S_new_rv in fgraph.variables
    assert isinstance(Z_new_rv.owner.op, Observed)

    # Let's only look at the variables involved in the `Z_rv` subgraph.
    Z_vars = theano.gof.graph.variables(theano.gof.graph.inputs([Z_new_rv]),
                                        [Z_new_rv])

    # Let's filter for only the `RandomVariables` with names.
    Z_vars_count = Counter([
        n.name for n in Z_vars
        if n.name and n.owner and isinstance(n.owner.op, RandomVariable)
    ])

    # Each new RV should be present and only occur once.
    assert Y_new_rv.name in Z_vars_count.keys()
    assert X_new_rv.name in Z_vars_count.keys()
    assert Z_new_rv.owner.inputs[1].name in Z_vars_count.keys()
    assert all(v == 1 for v in Z_vars_count.values())
コード例 #14
0
def test_pymc_normals():
    tt.config.compute_test_value = 'ignore'

    rand_state = theano.shared(np.random.RandomState())
    mu_a = NormalRV(0., 100**2, name='mu_a', rng=rand_state)
    sigma_a = HalfCauchyRV(5, name='sigma_a', rng=rand_state)
    mu_b = NormalRV(0., 100**2, name='mu_b', rng=rand_state)
    sigma_b = HalfCauchyRV(5, name='sigma_b', rng=rand_state)
    county_idx = np.r_[1, 1, 2, 3]
    # We want the following for a, b:
    # N(m, S) -> m + N(0, 1) * S
    a = NormalRV(mu_a,
                 sigma_a,
                 size=(len(county_idx), ),
                 name='a',
                 rng=rand_state)
    b = NormalRV(mu_b,
                 sigma_b,
                 size=(len(county_idx), ),
                 name='b',
                 rng=rand_state)
    radon_est = a[county_idx] + b[county_idx] * 7
    eps = HalfCauchyRV(5, name='eps', rng=rand_state)
    radon_like = NormalRV(radon_est, eps, name='radon_like', rng=rand_state)
    radon_like_rv = observed(tt.as_tensor_variable(np.r_[1., 2., 3., 4.]),
                             radon_like)

    graph_mt = mt(radon_like_rv)
    expr_graph, = run(
        1, var('q'),
        non_obs_fixedp_graph_applyo(scale_loc_transform, graph_mt, var('q')))

    radon_like_rv_opt = expr_graph.reify()

    assert radon_like_rv_opt.owner.op == observed

    radon_like_opt = radon_like_rv_opt.owner.inputs[1]
    radon_est_opt = radon_like_opt.owner.inputs[0]

    # These should now be `tt.add(mu_*, ...)` outputs.
    a_opt = radon_est_opt.owner.inputs[0].owner.inputs[0]
    b_opt = radon_est_opt.owner.inputs[1].owner.inputs[0].owner.inputs[0]
    # Make sure NormalRV gets replaced with an addition
    assert a_opt.owner.op == tt.add
    assert b_opt.owner.op == tt.add

    # Make sure the first term in the addition is the old NormalRV mean
    mu_a_opt = a_opt.owner.inputs[0].owner.inputs[0]
    assert 'mu_a' == mu_a_opt.name == mu_a.name
    mu_b_opt = b_opt.owner.inputs[0].owner.inputs[0]
    assert 'mu_b' == mu_b_opt.name == mu_b.name

    # Make sure the second term in the addition is the standard NormalRV times
    # the old std. dev.
    assert a_opt.owner.inputs[1].owner.op == tt.mul
    assert b_opt.owner.inputs[1].owner.op == tt.mul

    sigma_a_opt = a_opt.owner.inputs[1].owner.inputs[0].owner.inputs[0]
    assert sigma_a_opt.owner.op == sigma_a.owner.op
    sigma_b_opt = b_opt.owner.inputs[1].owner.inputs[0].owner.inputs[0]
    assert sigma_b_opt.owner.op == sigma_b.owner.op

    a_std_norm_opt = a_opt.owner.inputs[1].owner.inputs[1]
    assert a_std_norm_opt.owner.op == NormalRV
    assert a_std_norm_opt.owner.inputs[0].data == 0.0
    assert a_std_norm_opt.owner.inputs[1].data == 1.0
    b_std_norm_opt = b_opt.owner.inputs[1].owner.inputs[1]
    assert b_std_norm_opt.owner.op == NormalRV
    assert b_std_norm_opt.owner.inputs[0].data == 0.0
    assert b_std_norm_opt.owner.inputs[1].data == 1.0
コード例 #15
0
def test_etuple_term():
    """Test `etuplize` and `etuple` interaction with `term`."""
    # Take apart an already constructed/evaluated meta
    # object.
    e2 = mt.add(mt.vector(), mt.vector())

    e2_et = etuplize(e2)

    assert isinstance(e2_et, ExpressionTuple)

    # e2_et_expect = etuple(
    #     mt.add,
    #     etuple(mt.TensorVariable,
    #            etuple(mt.TensorType,
    #                   'float64', (False,), None),
    #            None, None, None),
    #     etuple(mt.TensorVariable,
    #            etuple(mt.TensorType,
    #                   'float64', (False,), None),
    #            None, None, None),
    # )
    e2_et_expect = etuple(mt.add, e2.base_arguments[0], e2.base_arguments[1])
    assert e2_et == e2_et_expect
    assert e2_et.eval_obj is e2

    # Make sure expression expansion works from Theano objects, too.
    # First, do it manually.
    tt_expr = tt.vector() + tt.vector()

    mt_expr = mt(tt_expr)
    assert mt_expr.obj is tt_expr
    assert mt_expr.reify() is tt_expr
    e3 = etuplize(mt_expr)
    assert e3 == e2_et
    assert e3.eval_obj is mt_expr
    assert e3.eval_obj.reify() is tt_expr

    # Now, through `etuplize`
    e2_et_2 = etuplize(tt_expr)
    assert e2_et_2 == e3 == e2_et
    assert isinstance(e2_et_2, ExpressionTuple)
    assert e2_et_2.eval_obj == tt_expr

    test_expr = mt(tt.vector("z") * 7)
    assert rator(test_expr) == mt.mul
    assert rands(test_expr)[0] == mt(tt.vector("z"))

    dim_shuffle_op = rator(rands(test_expr)[1])

    assert isinstance(dim_shuffle_op, mt.DimShuffle)
    assert rands(rands(test_expr)[1]) == etuple(mt(7))

    with pytest.raises(ConsError):
        rator(dim_shuffle_op)
    # assert rator(dim_shuffle_op) == mt.DimShuffle
    # assert rands(dim_shuffle_op) == etuple((), ("x",), True)

    const_tensor = rands(rands(test_expr)[1])[0]
    with pytest.raises(ConsError):
        rator(const_tensor)
    with pytest.raises(ConsError):
        rands(const_tensor)

    et_expr = etuplize(test_expr)
    exp_res = etuple(mt.mul, mt(tt.vector("z")),
                     etuple(mt.DimShuffle((), ("x", ), True), mt(7))
                     # etuple(etuple(mt.DimShuffle, (), ("x",), True), mt(7))
                     )

    assert et_expr == exp_res
    assert exp_res.eval_obj == test_expr