def test_equal_dense(): np.random.seed(42) for _ in range(3): cov = np.random.rand(5, 5) cov += cov.T cov += 10 * np.eye(5) inv = np.linalg.inv(cov) assert np.allclose(inv.dot(cov), np.eye(5)) x_ = np.random.randn(5) x = tt.vector() x.tag.test_value = x_ pots = [ quadpotential.quad_potential(cov, False, False), quadpotential.quad_potential(inv, True, False), ] if quadpotential.chol_available: pots.append(quadpotential.quad_potential(cov, False, False)) v = np.linalg.solve(cov, x_) e = 0.5 * x_.dot(v) for pot in pots: v_function = theano.function([x], pot.velocity(x)) e_function = theano.function([x], pot.energy(x)) assert np.allclose(v_function(x_), v) assert np.allclose(e_function(x_), e)
def test_elemwise_velocity(): scaling = np.array([1, 2, 3]) x_ = np.ones_like(scaling) x = tt.vector() x.tag.test_value = x_ pot = quadpotential.quad_potential(scaling, True, False) v = theano.function([x], pot.velocity(x)) assert np.allclose(v(x_), scaling) pot = quadpotential.quad_potential(scaling, True, True) v = theano.function([x], pot.velocity(x)) assert np.allclose(v(x_), 1. / scaling)
def test_elemwise_energy(): scaling = np.array([1, 2, 3]) x_ = np.ones_like(scaling) x = tt.vector() x.tag.test_value = x_ pot = quadpotential.quad_potential(scaling, True, False) energy = theano.function([x], pot.energy(x)) assert np.allclose(energy(x_), 0.5 * scaling.sum()) pot = quadpotential.quad_potential(scaling, True, True) energy = theano.function([x], pot.energy(x)) assert np.allclose(energy(x_), 0.5 * (1. / scaling).sum())
def test_elemwise_velocity(): scaling = np.array([1, 2, 3]) x = floatX(np.ones_like(scaling)) pot = quadpotential.quad_potential(scaling, True) v = pot.velocity(x) npt.assert_allclose(v, scaling) assert v.dtype == pot.dtype
def test_random_diag(): d = np.arange(10) + 1 np.random.seed(42) pots = [ quadpotential.quad_potential(d, True), quadpotential.quad_potential(1.0 / d, False), quadpotential.quad_potential(np.diag(d), True), quadpotential.quad_potential(np.diag(1.0 / d), False), ] if quadpotential.chol_available: d_ = scipy.sparse.csc_matrix(np.diag(d)) pot = quadpotential.quad_potential(d_, True) pots.append(pot) for pot in pots: vals = np.array([pot.random() for _ in range(1000)]) npt.assert_allclose(vals.std(0), np.sqrt(1.0 / d), atol=0.1)
def test_random_diag(): d = np.arange(10) + 1 np.random.seed(42) pots = [ quadpotential.quad_potential(d, True), quadpotential.quad_potential(1./d, False), quadpotential.quad_potential(np.diag(d), True), quadpotential.quad_potential(np.diag(1./d), False), ] if quadpotential.chol_available: d_ = scipy.sparse.csc_matrix(np.diag(d)) pot = quadpotential.quad_potential(d_, True) pots.append(pot) for pot in pots: vals = np.array([pot.random() for _ in range(1000)]) npt.assert_allclose(vals.std(0), np.sqrt(1./d), atol=0.1)
def test_equal_diag(): np.random.seed(42) for _ in range(3): diag = np.random.rand(5) x = floatX(np.random.randn(5)) pots = [ quadpotential.quad_potential(diag, False), quadpotential.quad_potential(1.0 / diag, True), quadpotential.quad_potential(np.diag(diag), False), quadpotential.quad_potential(np.diag(1.0 / diag), True), ] if quadpotential.chol_available: diag_ = scipy.sparse.csc_matrix(np.diag(1.0 / diag)) pots.append(quadpotential.quad_potential(diag_, True)) v = np.diag(1.0 / diag).dot(x) e = x.dot(np.diag(1.0 / diag).dot(x)) / 2 for pot in pots: v_ = pot.velocity(x) e_ = pot.energy(x) npt.assert_allclose(v_, v, rtol=1e-6) npt.assert_allclose(e_, e, rtol=1e-6)
def test_equal_diag(): np.random.seed(42) for _ in range(3): diag = np.random.rand(5) x = floatX(np.random.randn(5)) pots = [ quadpotential.quad_potential(diag, False), quadpotential.quad_potential(1. / diag, True), quadpotential.quad_potential(np.diag(diag), False), quadpotential.quad_potential(np.diag(1. / diag), True), ] if quadpotential.chol_available: diag_ = scipy.sparse.csc_matrix(np.diag(1. / diag)) pots.append(quadpotential.quad_potential(diag_, True)) v = np.diag(1. / diag).dot(x) e = x.dot(np.diag(1. / diag).dot(x)) / 2 for pot in pots: v_ = pot.velocity(x) e_ = pot.energy(x) npt.assert_allclose(v_, v) npt.assert_allclose(e_, e)
def test_equal_dense(): np.random.seed(42) for _ in range(3): cov = np.random.rand(5, 5) cov += cov.T cov += 10 * np.eye(5) inv = np.linalg.inv(cov) npt.assert_allclose(inv.dot(cov), np.eye(5), atol=1e-10) x = floatX(np.random.randn(5)) pots = [ quadpotential.quad_potential(cov, False), quadpotential.quad_potential(inv, True), ] if quadpotential.chol_available: pots.append(quadpotential.quad_potential(cov, False)) v = np.linalg.solve(cov, x) e = 0.5 * x.dot(v) for pot in pots: v_ = pot.velocity(x) e_ = pot.energy(x) npt.assert_allclose(v_, v, rtol=1e-4) npt.assert_allclose(e_, e, rtol=1e-4)
def test_equal_diag(): np.random.seed(42) for _ in range(3): diag = np.random.rand(5) x_ = np.random.randn(5) x = tt.vector() x.tag.test_value = x_ pots = [ quadpotential.quad_potential(diag, False, False), quadpotential.quad_potential(1. / diag, True, False), quadpotential.quad_potential(np.diag(diag), False, False), quadpotential.quad_potential(np.diag(1. / diag), True, False), ] if quadpotential.chol_available: diag_ = scipy.sparse.csc_matrix(np.diag(1. / diag)) pots.append(quadpotential.quad_potential(diag_, True, False)) v = np.diag(1. / diag).dot(x_) e = x_.dot(np.diag(1. / diag).dot(x_)) / 2 for pot in pots: v_function = theano.function([x], pot.velocity(x)) e_function = theano.function([x], pot.energy(x)) assert np.allclose(v_function(x_), v) assert np.allclose(e_function(x_), e)
def test_elemwise_posdef2(): scaling = np.array([0, 2, 3]) quadpotential.quad_potential(scaling, True, False)
def test_elemwise_energy(): scaling = np.array([1, 2, 3]) x = floatX(np.ones_like(scaling)) pot = quadpotential.quad_potential(scaling, True) energy = pot.energy(x) npt.assert_allclose(energy, 0.5 * scaling.sum())
def test_elemwise_posdef(): scaling = np.array([0, 2, 3]) with pytest.raises(quadpotential.PositiveDefiniteError): quadpotential.quad_potential(scaling, True)
def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, model=None, blocked=True, potential=None, dtype=None, Emax=1000, target_accept=0.8, gamma=0.05, k=0.75, t0=10, adapt_step_size=True, step_rand=None, **aesara_kwargs): """Set up Hamiltonian samplers with common structures. Parameters ---------- vars: list of aesara variables scaling: array_like, ndim = {1,2} Scaling for momentum distribution. 1d arrays interpreted matrix diagonal. step_scale: float, default=0.25 Size of steps to take, automatically scaled down by 1/n**(1/4) is_cov: bool, default=False Treat scaling as a covariance matrix/vector if True, else treat it as a precision matrix/vector model: pymc3 Model instance blocked: bool, default=True potential: Potential, optional An object that represents the Hamiltonian with methods `velocity`, `energy`, and `random` methods. **aesara_kwargs: passed to aesara functions """ self._model = modelcontext(model) if vars is None: vars = self._model.cont_vars vars = inputvars(vars) super().__init__(vars, blocked=blocked, model=model, dtype=dtype, **aesara_kwargs) self.adapt_step_size = adapt_step_size self.Emax = Emax self.iter_count = 0 size = self._logp_dlogp_func.size self.step_size = step_scale / (size**0.25) self.step_adapt = step_sizes.DualAverageAdaptation( self.step_size, target_accept, gamma, k, t0) self.target_accept = target_accept self.tune = True if scaling is None and potential is None: mean = floatX(np.zeros(size)) var = floatX(np.ones(size)) potential = QuadPotentialDiagAdapt(size, mean, var, 10) if isinstance(scaling, dict): point = Point(scaling, model=model) scaling = guess_scaling(point, model=model, vars=vars) if scaling is not None and potential is not None: raise ValueError("Can not specify both potential and scaling.") if potential is not None: self.potential = potential else: self.potential = quad_potential(scaling, is_cov) self.integrator = integration.CpuLeapfrogIntegrator( self.potential, self._logp_dlogp_func) self._step_rand = step_rand self._warnings = [] self._samples_after_tune = 0 self._num_divs_sample = 0