def testPoissonCDF(self): with self.test_session(): batch_size = 6 lam = constant_op.constant([3.0] * batch_size) lam_v = 3.0 x = [2.2, 3.1, 4., 5.5, 6., 7.] poisson = poisson_lib.Poisson(rate=lam) log_cdf = poisson.log_cdf(x) self.assertEqual(log_cdf.get_shape(), (6, )) self.assertAllClose(log_cdf.eval(), stats.poisson.logcdf(x, lam_v)) cdf = poisson.cdf(x) self.assertEqual(cdf.get_shape(), (6, )) self.assertAllClose(cdf.eval(), stats.poisson.cdf(x, lam_v))
def testPoissonLogPmfMultidimensional(self): with self.test_session(): batch_size = 6 lam = constant_op.constant([[2.0, 4.0, 5.0]] * batch_size) lam_v = [2.0, 4.0, 5.0] x = np.array([[2., 3., 4., 5., 6., 7.]], dtype=np.float32).T poisson = poisson_lib.Poisson(rate=lam) log_pmf = poisson.log_prob(x) self.assertEqual(log_pmf.get_shape(), (6, 3)) self.assertAllClose(log_pmf.eval(), stats.poisson.logpmf(x, lam_v)) pmf = poisson.prob(x) self.assertEqual(pmf.get_shape(), (6, 3)) self.assertAllClose(pmf.eval(), stats.poisson.pmf(x, lam_v))
def testPoissonSampleMultidimensionalMean(self): with self.test_session(): lam_v = np.array([np.arange(1, 51, dtype=np.float32)]) # 1 x 50 poisson = poisson_lib.Poisson(rate=lam_v) # Choosing `n >= (k/rtol)**2, roughly ensures our sample mean should be # within `k` std. deviations of actual up to rtol precision. n = int(100e3) samples = poisson.sample(n, seed=123456) sample_values = samples.eval() self.assertEqual(samples.get_shape(), (n, 1, 50)) self.assertEqual(sample_values.shape, (n, 1, 50)) self.assertAllClose(sample_values.mean(axis=0), stats.poisson.mean(lam_v), rtol=.01, atol=0)
def testPoissonCdfMultidimensional(self): with self.test_session(): batch_size = 6 lam = constant_op.constant([[2.0, 4.0, 5.0]] * batch_size) lam_v = [2.0, 4.0, 5.0] x = np.array([[2.2, 3.1, 4., 5.5, 6., 7.]], dtype=np.float32).T poisson = poisson_lib.Poisson(rate=lam) log_cdf = poisson.log_cdf(x) self.assertEqual(log_cdf.get_shape(), (6, 3)) self.assertAllClose(log_cdf.eval(), stats.poisson.logcdf(x, lam_v)) cdf = poisson.cdf(x) self.assertEqual(cdf.get_shape(), (6, 3)) self.assertAllClose(cdf.eval(), stats.poisson.cdf(x, lam_v))
def testPoissonSampleMultidimensionalVariance(self): with self.test_session(): lam_v = np.array([np.arange(5, 15, dtype=np.float32)]) # 1 x 10 poisson = poisson_lib.Poisson(rate=lam_v) # Choosing `n >= 2 * lam * (k/rtol)**2, roughly ensures our sample # variance should be within `k` std. deviations of actual up to rtol # precision. n = int(300e3) samples = poisson.sample(n, seed=123456) sample_values = samples.eval() self.assertEqual(samples.get_shape(), (n, 1, 10)) self.assertEqual(sample_values.shape, (n, 1, 10)) self.assertAllClose(sample_values.var(axis=0), stats.poisson.var(lam_v), rtol=.03, atol=0)
def testPoissonSample(self): with self.test_session(): lam_v = 4.0 lam = constant_op.constant(lam_v) # Choosing `n >= (k/rtol)**2, roughly ensures our sample mean should be # within `k` std. deviations of actual up to rtol precision. n = int(100e3) poisson = poisson_lib.Poisson(rate=lam) samples = poisson.sample(n, seed=123456) sample_values = samples.eval() self.assertEqual(samples.get_shape(), (n, )) self.assertEqual(sample_values.shape, (n, )) self.assertAllClose(sample_values.mean(), stats.poisson.mean(lam_v), rtol=.01) self.assertAllClose(sample_values.var(), stats.poisson.var(lam_v), rtol=.01)
def testPoissonMode(self): with self.test_session(): lam_v = [1.0, 3.0, 2.5, 3.2, 1.1, 0.05] poisson = poisson_lib.Poisson(lam=lam_v) self.assertEqual(poisson.mode().get_shape(), (6, )) self.assertAllClose(poisson.mode().eval(), np.floor(lam_v))
def __init__(self, loc, scale, quadrature_size=8, quadrature_fn=quadrature_scheme_lognormal_quantiles, validate_args=False, allow_nan_stats=True, name="PoissonLogNormalQuadratureCompound"): """Constructs the PoissonLogNormalQuadratureCompound`. Note: `probs` returned by (optional) `quadrature_fn` are presumed to be either a length-`quadrature_size` vector or a batch of vectors in 1-to-1 correspondence with the returned `grid`. (I.e., broadcasting is only partially supported.) Args: loc: `float`-like (batch of) scalar `Tensor`; the location parameter of the LogNormal prior. scale: `float`-like (batch of) scalar `Tensor`; the scale parameter of the LogNormal prior. quadrature_size: Python `int` scalar representing the number of quadrature points. quadrature_fn: Python callable taking `loc`, `scale`, `quadrature_size`, `validate_args` and returning `tuple(grid, probs)` representing the LogNormal grid and corresponding normalized weight. normalized) weight. Default value: `quadrature_scheme_lognormal_quantiles`. validate_args: Python `bool`, default `False`. When `True` distribution parameters are checked for validity despite possibly degrading runtime performance. When `False` invalid inputs may silently render incorrect outputs. allow_nan_stats: Python `bool`, default `True`. When `True`, statistics (e.g., mean, mode, variance) use the value "`NaN`" to indicate the result is undefined. When `False`, an exception is raised if one or more of the statistic's batch members are undefined. name: Python `str` name prefixed to Ops created by this class. Raises: TypeError: if `quadrature_grid` and `quadrature_probs` have different base `dtype`. """ parameters = dict(locals()) with ops.name_scope(name, values=[loc, scale]) as name: if loc is not None: loc = ops.convert_to_tensor(loc, name="loc") if scale is not None: scale = ops.convert_to_tensor( scale, dtype=None if loc is None else loc.dtype, name="scale") self._quadrature_grid, self._quadrature_probs = tuple( quadrature_fn(loc, scale, quadrature_size, validate_args)) dt = self._quadrature_grid.dtype if dt.base_dtype != self._quadrature_probs.dtype.base_dtype: raise TypeError( "Quadrature grid dtype ({}) does not match quadrature " "probs dtype ({}).".format( dt.name, self._quadrature_probs.dtype.name)) self._distribution = poisson_lib.Poisson( log_rate=self._quadrature_grid, validate_args=validate_args, allow_nan_stats=allow_nan_stats) self._mixture_distribution = categorical_lib.Categorical( logits=math_ops.log(self._quadrature_probs), validate_args=validate_args, allow_nan_stats=allow_nan_stats) self._loc = loc self._scale = scale self._quadrature_size = quadrature_size super(PoissonLogNormalQuadratureCompound, self).__init__( dtype=dt, reparameterization_type=distribution_lib.NOT_REPARAMETERIZED, validate_args=validate_args, allow_nan_stats=allow_nan_stats, parameters=parameters, graph_parents=[loc, scale], name=name)
def __init__(self, loc, scale, quadrature_grid_and_probs=None, validate_args=False, allow_nan_stats=True, name="PoissonLogNormalQuadratureCompound"): """Constructs the PoissonLogNormalQuadratureCompound on `R**k`. Args: loc: `float`-like (batch of) scalar `Tensor`; the location parameter of the LogNormal prior. scale: `float`-like (batch of) scalar `Tensor`; the scale parameter of the LogNormal prior. quadrature_grid_and_probs: Python pair of `float`-like `Tensor`s representing the sample points and the corresponding (possibly normalized) weight. When `None`, defaults to: `np.polynomial.hermite.hermgauss(deg=8)`. validate_args: Python `bool`, default `False`. When `True` distribution parameters are checked for validity despite possibly degrading runtime performance. When `False` invalid inputs may silently render incorrect outputs. allow_nan_stats: Python `bool`, default `True`. When `True`, statistics (e.g., mean, mode, variance) use the value "`NaN`" to indicate the result is undefined. When `False`, an exception is raised if one or more of the statistic's batch members are undefined. name: Python `str` name prefixed to Ops created by this class. Raises: TypeError: if `loc.dtype != scale[0].dtype`. """ parameters = locals() with ops.name_scope(name, values=[loc, scale]): loc = ops.convert_to_tensor(loc, name="loc") self._loc = loc scale = ops.convert_to_tensor(scale, name="scale") self._scale = scale dtype = loc.dtype.base_dtype if dtype != scale.dtype.base_dtype: raise TypeError( "loc.dtype(\"{}\") does not match scale.dtype(\"{}\")". format(loc.dtype.name, scale.dtype.name)) grid, probs = distribution_util.process_quadrature_grid_and_probs( quadrature_grid_and_probs, dtype, validate_args) self._quadrature_grid = grid self._quadrature_probs = probs self._quadrature_size = distribution_util.dimension_size(probs, axis=0) self._mixture_distribution = categorical_lib.Categorical( logits=math_ops.log(self._quadrature_probs), validate_args=validate_args, allow_nan_stats=allow_nan_stats) # The following maps the broadcast of `loc` and `scale` to each grid # point, i.e., we are creating several log-rates that correspond to the # different Gauss-Hermite quadrature points and (possible) batches of # `loc` and `scale`. self._log_rate = ( loc[..., array_ops.newaxis] + np.sqrt(2.) * scale[..., array_ops.newaxis] * grid) self._distribution = poisson_lib.Poisson( log_rate=self._log_rate, validate_args=validate_args, allow_nan_stats=allow_nan_stats) super(PoissonLogNormalQuadratureCompound, self).__init__( dtype=dtype, reparameterization_type=distribution_lib.NOT_REPARAMETERIZED, validate_args=validate_args, allow_nan_stats=allow_nan_stats, parameters=parameters, graph_parents=[loc, scale], name=name)
def _make_poisson(self, rate, validate_args=False): return poisson_lib.Poisson(rate=rate, validate_args=validate_args)
def _make_poisson(self, rate, validate_args=False): return poisson_lib.Poisson( log_rate=math_ops.log(rate), validate_args=validate_args)