def __init__(self,
               cat,
               components,
               validate_args=False,
               allow_nan_stats=True,
               use_static_graph=False,
               name="Mixture"):
    """Initialize a Mixture distribution.

    A `Mixture` is defined by a `Categorical` (`cat`, representing the
    mixture probabilities) and a list of `Distribution` objects
    all having matching dtype, batch shape, event shape, and continuity
    properties (the components).

    The `num_classes` of `cat` must be possible to infer at graph construction
    time and match `len(components)`.

    Args:
      cat: A `Categorical` distribution instance, representing the probabilities
          of `distributions`.
      components: A list or tuple of `Distribution` instances.
        Each instance must have the same type, be defined on the same domain,
        and have matching `event_shape` and `batch_shape`.
      validate_args: Python `bool`, default `False`. If `True`, raise a runtime
        error if batch or event ranks are inconsistent between cat and any of
        the distributions. This is only checked if the ranks cannot be
        determined statically at graph construction time.
      allow_nan_stats: Boolean, default `True`. If `False`, raise an
       exception if a statistic (e.g. mean/mode/etc...) is undefined for any
        batch member. If `True`, batch members with valid parameters leading to
        undefined statistics will return NaN for this statistic.
      use_static_graph: Calls to `sample` will not rely on dynamic tensor
        indexing, allowing for some static graph compilation optimizations, but
        at the expense of sampling all underlying distributions in the mixture.
        (Possibly useful when running on TPUs).
        Default value: `False` (i.e., use dynamic indexing).
      name: A name for this distribution (optional).

    Raises:
      TypeError: If cat is not a `Categorical`, or `components` is not
        a list or tuple, or the elements of `components` are not
        instances of `Distribution`, or do not have matching `dtype`.
      ValueError: If `components` is an empty list or tuple, or its
        elements do not have a statically known event rank.
        If `cat.num_classes` cannot be inferred at graph creation time,
        or the constant value of `cat.num_classes` is not equal to
        `len(components)`, or all `components` and `cat` do not have
        matching static batch shapes, or all components do not
        have matching static event shapes.
    """
    parameters = dict(locals())
    if not isinstance(cat, categorical.Categorical):
      raise TypeError("cat must be a Categorical distribution, but saw: %s" %
                      cat)
    if not components:
      raise ValueError("components must be a non-empty list or tuple")
    if not isinstance(components, (list, tuple)):
      raise TypeError("components must be a list or tuple, but saw: %s" %
                      components)
    if not all(isinstance(c, distribution.Distribution) for c in components):
      raise TypeError(
          "all entries in components must be Distribution instances"
          " but saw: %s" % components)

    dtype = components[0].dtype
    if not all(d.dtype == dtype for d in components):
      raise TypeError("All components must have the same dtype, but saw "
                      "dtypes: %s" % [(d.name, d.dtype) for d in components])
    static_event_shape = components[0].event_shape
    static_batch_shape = cat.batch_shape
    for di, d in enumerate(components):
      if not tensorshape_util.is_compatible_with(static_batch_shape,
                                                 d.batch_shape):
        raise ValueError(
            "components[{}] batch shape must be compatible with cat "
            "shape and other component batch shapes".format(di))
      static_event_shape = tensorshape_util.merge_with(
          static_event_shape, d.event_shape)
      static_batch_shape = tensorshape_util.merge_with(
          static_batch_shape, d.batch_shape)
    if tensorshape_util.rank(static_event_shape) is None:
      raise ValueError(
          "Expected to know rank(event_shape) from components, but "
          "none of the components provide a static number of ndims")

    # Ensure that all batch and event ndims are consistent.
    with tf.name_scope(name) as name:
      num_components = cat.event_size
      static_num_components = tf.get_static_value(num_components)
      if static_num_components is None:
        raise ValueError(
            "Could not infer number of classes from cat and unable "
            "to compare this value to the number of components passed in.")
      # Possibly convert from numpy 0-D array.
      static_num_components = int(static_num_components)
      if static_num_components != len(components):
        raise ValueError("cat.num_classes != len(components): %d vs. %d" %
                         (static_num_components, len(components)))

      cat_batch_shape = cat.batch_shape_tensor()
      cat_batch_rank = tf.size(input=cat_batch_shape)
      if validate_args:
        batch_shapes = [d.batch_shape_tensor() for d in components]
        batch_ranks = [tf.size(input=bs) for bs in batch_shapes]
        check_message = ("components[%d] batch shape must match cat "
                         "batch shape")
        self._assertions = [
            assert_util.assert_equal(
                cat_batch_rank, batch_ranks[di], message=check_message % di)
            for di in range(len(components))
        ]
        self._assertions += [
            assert_util.assert_equal(
                cat_batch_shape, batch_shapes[di], message=check_message % di)
            for di in range(len(components))
        ]
      else:
        self._assertions = []

      self._cat = cat
      self._components = list(components)
      self._num_components = static_num_components
      self._static_event_shape = static_event_shape
      self._static_batch_shape = static_batch_shape

      self._use_static_graph = use_static_graph
      if use_static_graph and static_num_components is None:
        raise ValueError("Number of categories must be known statically when "
                         "`static_sample=True`.")
    # We let the Mixture distribution access _graph_parents since its arguably
    # more like a baseclass.
    graph_parents = self._cat._graph_parents  # pylint: disable=protected-access
    for c in self._components:
      graph_parents += c._graph_parents  # pylint: disable=protected-access

    super(Mixture, self).__init__(
        dtype=dtype,
        reparameterization_type=reparameterization.NOT_REPARAMETERIZED,
        validate_args=validate_args,
        allow_nan_stats=allow_nan_stats,
        parameters=parameters,
        graph_parents=graph_parents,
        name=name)
def __init__ ( self , cat , components , validate_args = False , allow_nan_stats = True , use_static_graph = False , name = "Mixture" ) : parameters = dict ( locals ( ) ) if not isinstance ( cat , categorical . Categorical ) : raise TypeError ( "cat must be a Categorical distribution, but saw: %s" % cat ) if not components : raise ValueError ( "components must be a non-empty list or tuple" ) if not isinstance ( components , ( list , tuple ) ) : raise TypeError ( "components must be a list or tuple, but saw: %s" % components ) if not all ( isinstance ( c , distribution . Distribution ) for c in components ) : raise TypeError ( "all entries in components must be Distribution instances" " but saw: %s" % components ) dtype = components [ 0 ] . dtype if not all ( d . dtype == dtype for d in components ) : raise TypeError ( "All components must have the same dtype, but saw " "dtypes: %s" % [ ( d . name , d . dtype ) for d in components ] ) static_event_shape = components [ 0 ] . event_shape static_batch_shape = cat . batch_shape for di , d in enumerate ( components ) : if not tensorshape_util . is_compatible_with ( static_batch_shape , d . batch_shape ) : raise ValueError ( "components[{}] batch shape must be compatible with cat " "shape and other component batch shapes" . format ( di ) ) static_event_shape = tensorshape_util . merge_with ( static_event_shape , d . event_shape ) static_batch_shape = tensorshape_util . merge_with ( static_batch_shape , d . batch_shape ) if tensorshape_util . rank ( static_event_shape ) is None : raise ValueError ( "Expected to know rank(event_shape) from components, but " "none of the components provide a static number of ndims" ) with tf . name_scope ( name ) as name : num_components = cat . event_size static_num_components = tf . get_static_value ( num_components ) if static_num_components is None : raise ValueError ( "Could not infer number of classes from cat and unable " "to compare this value to the number of components passed in." ) static_num_components = int ( static_num_components ) if static_num_components != len ( components ) : raise ValueError ( "cat.num_classes != len(components): %d vs. %d" % ( static_num_components , len ( components ) ) ) cat_batch_shape = cat . batch_shape_tensor ( ) cat_batch_rank = tf . size ( input = cat_batch_shape ) if validate_args : batch_shapes = [ d . batch_shape_tensor ( ) for d in components ] batch_ranks = [ tf . size ( input = bs ) for bs in batch_shapes ] check_message = ( "components[%d] batch shape must match cat " "batch shape" ) self . _assertions = [ assert_util . assert_equal ( cat_batch_rank , batch_ranks [ di ] , message = check_message % di ) for di in range ( len ( components ) ) ] self . _assertions += [ assert_util . assert_equal ( cat_batch_shape , batch_shapes [ di ] , message = check_message % di ) for di in range ( len ( components ) ) ] else : self . _assertions = [ ] self . _cat = cat self . _components = list ( components ) self . _num_components = static_num_components self . _static_event_shape = static_event_shape self . _static_batch_shape = static_batch_shape self . _use_static_graph = use_static_graph if use_static_graph and static_num_components is None : raise ValueError ( "Number of categories must be known statically when " "`static_sample=True`." ) graph_parents = self . _cat . _graph_parents for c in self . _components : graph_parents += c . _graph_parents super ( Mixture , self ) . __init__ ( dtype = dtype , reparameterization_type = reparameterization . NOT_REPARAMETERIZED , validate_args = validate_args , allow_nan_stats = allow_nan_stats , parameters = parameters , graph_parents = graph_parents , name = name )
Initialize a Mixture distribution.

    A `Mixture` is defined by a `Categorical` (`cat`, representing the
    mixture probabilities) and a list of `Distribution` objects
    all having matching dtype, batch shape, event shape, and continuity
    properties (the components).

    The `num_classes` of `cat` must be possible to infer at graph construction
    time and match `len(components)`.

    Args:
      cat: A `Categorical` distribution instance, representing the probabilities
          of `distributions`.
      components: A list or tuple of `Distribution` instances.
        Each instance must have the same type, be defined on the same domain,
        and have matching `event_shape` and `batch_shape`.
      validate_args: Python `bool`, default `False`. If `True`, raise a runtime
        error if batch or event ranks are inconsistent between cat and any of
        the distributions. This is only checked if the ranks cannot be
        determined statically at graph construction time.
      allow_nan_stats: Boolean, default `True`. If `False`, raise an
       exception if a statistic (e.g. mean/mode/etc...) is undefined for any
        batch member. If `True`, batch members with valid parameters leading to
        undefined statistics will return NaN for this statistic.
      use_static_graph: Calls to `sample` will not rely on dynamic tensor
        indexing, allowing for some static graph compilation optimizations, but
        at the expense of sampling all underlying distributions in the mixture.
        (Possibly useful when running on TPUs).
        Default value: `False` (i.e., use dynamic indexing).
      name: A name for this distribution (optional).

    Raises:
      TypeError: If cat is not a `Categorical`, or `components` is not
        a list or tuple, or the elements of `components` are not
        instances of `Distribution`, or do not have matching `dtype`.
      ValueError: If `components` is an empty list or tuple, or its
        elements do not have a statically known event rank.
        If `cat.num_classes` cannot be inferred at graph creation time,
        or the constant value of `cat.num_classes` is not equal to
        `len(components)`, or all `components` and `cat` do not have
        matching static batch shapes, or all components do not
        have matching static event shapes.