class_docstr: Blockwise distribution.
  
  This distribution converts a distribution or list of distributions into a
  vector-variate distribution by doing a sequence of reshapes and concatenating
  the results. This is particularly useful for converting `JointDistribution`
  instances to vector-variate for downstream uses which can only handle
  single-`Tensor` distributions.
  
  #### Examples
  
  Flattening a sequence of distrbutions:
  
  ```python
  tfd = tfp.distributions
  
  d = tfd.Blockwise(
      [
          tfd.Independent(
              tfd.Normal(
                  loc=tf.zeros(4, dtype=tf.float64),
                  scale=1),
              reinterpreted_batch_ndims=1),
          tfd.MultivariateNormalTriL(
              scale_tril=tf.eye(2, dtype=tf.float32)),
      ],
      dtype_override=tf.float32,
  )
  x = d.sample([2, 1])
  y = d.log_prob(x)
  x.shape  # ==> (2, 1, 4 + 2)
  x.dtype  # ==> tf.float32
  y.shape  # ==> (2, 1)
  y.dtype  # ==> tf.float32
  
  d.mean()  # ==> np.zeros((4 + 2,))
  ```
  
  Flattening a joint distribution:
  
  ```python
  tfd = tfp.distributions
  
  Root = tfd.JointDistributionCoroutine.Root  # Convenient alias.
  def model():
    e = yield Root(tfd.Independent(tfd.Exponential(rate=[100, 120]), 1))
    g = yield tfd.Gamma(concentration=e[..., 0], rate=e[..., 1])
    n = yield Root(tfd.Normal(loc=0, scale=2.))
    yield tfd.Normal(loc=n, scale=g)
  
  joint = tfd.JointDistributionCoroutine(model)
  d = tfd.Blockwise(joint)
  
  x = d.sample([2, 1])
  y = d.log_prob(x)
  x.shape  # ==> (2, 1, 2 + 1 + 1 + 1)
  x.dtype  # ==> tf.float32
  y.shape  # ==> (2, 1)
  y.dtype  # ==> tf.float32
  ```
class_docstr_tok: ["Blockwise","distribution",".","This","distribution","converts","a","distribution","or","list","of","distributions","into","a","vector-variate","distribution","by","doing","a","sequence","of","reshapes","and","concatenating","the","results",".","This","is","particularly","useful","for","converting","`","JointDistribution","`","instances","to","vector-variate","for","downstream","uses","which","can","only","handle","single-","`","Tensor","`","distributions",".","#","#","#","#","Examples","Flattening","a","sequence","of","distrbutions",":","``","`","python","tfd","=","tfp.distributions","d","=","tfd.Blockwise","(","[","tfd.Independent","(","tfd.Normal","(","loc=tf.zeros","(","4",",","dtype=tf.float64",")",",","scale=1",")",",","reinterpreted_batch_ndims=1",")",",","tfd.MultivariateNormalTriL","(","scale_tril=tf.eye","(","2",",","dtype=tf.float32",")",")",",","]",",","dtype_override=tf.float32",",",")","x","=","d.sample","(","[","2",",","1","]",")","y","=","d.log_prob","(","x",")","x.shape","#","==",">","(","2",",","1",",","4","+","2",")","x.dtype","#","==",">","tf.float32","y.shape","#","==",">","(","2",",","1",")","y.dtype","#","==",">","tf.float32","d.mean","(",")","#","==",">","np.zeros","(","(","4","+","2",",",")",")","``","`","Flattening","a","joint","distribution",":","``","`","python","tfd","=","tfp.distributions","Root","=","tfd.JointDistributionCoroutine.Root","#","Convenient","alias",".","def","model","(",")",":","e","=","yield","Root","(","tfd.Independent","(","tfd.Exponential","(","rate=","[","100",",","120","]",")",",","1",")",")","g","=","yield","tfd.Gamma","(","concentration=e","[","...",",","0","]",",","rate=e","[","...",",","1","]",")","n","=","yield","Root","(","tfd.Normal","(","loc=0",",","scale=2",".",")",")","yield","tfd.Normal","(","loc=n",",","scale=g",")","joint","=","tfd.JointDistributionCoroutine","(","model",")","d","=","tfd.Blockwise","(","joint",")","x","=","d.sample","(","[","2",",","1","]",")","y","=","d.log_prob","(","x",")","x.shape","#","==",">","(","2",",","1",",","2","+","1","+","1","+","1",")","x.dtype","#","==",">","tf.float32","y.shape","#","==",">","(","2",",","1",")","y.dtype","#","==",">","tf.float32","``","`"]
docstr: Construct the `Blockwise` distribution.
  
  Args:
    distributions: Python `list` of `tfp.distributions.Distribution`
      instances or a single `tfp.distributions.JointDistribution` instance.
      If `list`, all distribution instances must have the same `batch_shape`
      and all must have `event_ndims==1`, i.e., be vector-variate
      distributions.
    dtype_override: samples of `distributions` will be cast to this `dtype`.
      If unspecified, all `distributions` must have the same `dtype`.
      Default value: `None` (i.e., do not cast).
    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.
code: def __init__(
      self,
      distributions,
      dtype_override=None,
      validate_args=False,
      allow_nan_stats=False,
      name="Blockwise",
  ):
      """Construct the `Blockwise` distribution.
  
      Args:
        distributions: Python `list` of `tfp.distributions.Distribution`
          instances or a single `tfp.distributions.JointDistribution` instance.
          If `list`, all distribution instances must have the same `batch_shape`
          and all must have `event_ndims==1`, i.e., be vector-variate
          distributions.
        dtype_override: samples of `distributions` will be cast to this `dtype`.
          If unspecified, all `distributions` must have the same `dtype`.
          Default value: `None` (i.e., do not cast).
        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.
      """
      parameters = dict(locals())
      with tf.name_scope(name) as name:
          self._distributions = distributions
          if dtype_override is not None:
              distributions = tf.nest.map_structure(
                  lambda d: _Cast(d, dtype_override), distributions
              )
          if _is_iterable(distributions):
              self._distribution = joint_distribution_sequential.JointDistributionSequential(
                  list(distributions)
              )
          else:
              self._distribution = distributions
  
          # Need to cache these for JointDistributions as the batch shape of that
          # distribution can change after `_sample` calls.
          self._cached_batch_shape_tensor = (
              self._distribution.batch_shape_tensor()
          )
          self._cached_batch_shape = self._distribution.batch_shape
  
          if dtype_override is not None:
              dtype = dtype_override
          else:
              dtype = set(
                  dtype_util.base_dtype(dtype)
                  for dtype in tf.nest.flatten(self._distribution.dtype)
                  if dtype is not None
              )
              if (
                  len(dtype) == 0
              ):  # pylint: disable=g-explicit-length-test
                  dtype = tf.float32
              elif len(dtype) == 1:
                  dtype = dtype.pop()
              else:
                  raise TypeError(
                      "Distributions must have same dtype; found: {}.".format(
                          self._distribution.dtype
                      )
                  )
  
          reparameterization_type = set(
              tf.nest.flatten(
                  self._distribution.reparameterization_type
              )
          )
          reparameterization_type = (
              reparameterization_type.pop()
              if len(reparameterization_type) == 1
              else reparameterization.NOT_REPARAMETERIZED
          )
  
          super(_Blockwise, self).__init__(
              dtype=dtype,
              validate_args=validate_args,
              allow_nan_stats=allow_nan_stats,
              reparameterization_type=reparameterization_type,
              parameters=parameters,
              name=name,
          )
  
imports: import functools
  import tensorflow.compat.v2
  from tensorflow_probability.python.distributions import distribution
  from tensorflow_probability.python.distributions import joint_distribution_sequential
  from tensorflow_probability.python.distributions import kullback_leibler
  from tensorflow_probability.python.internal import assert_util
  from tensorflow_probability.python.internal import auto_composite_tensor
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import parameter_properties
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import reparameterization
  from tensorflow_probability.python.internal import tensorshape_util
label_desc: Use image node_id 1 to create a new _Blockwise object from inherited base classes: distribution_lib with example: obj = _Blockwise(distributions, dtype_override, validate_args, allow_nan_stats, name)