def estimate_DiscreteMixture(histo, *args, **kargs):


        """ Estimate a finite  mixture of discrete distributions


        :Parameters:

          * histo (histogram, mixture_data, convolution_data, compound_data),
          * distributions (list) : a list of distribution object
                                   or distribution label(string) : 'B', 'NB', 'U', 'P', ...
          * unknown (string): type of unknown distribution: "Sum" or "Elementary".

        :Keywords:

          * MinInfBound (int): lower bound to the range of possible values (0 -default- or 1). \
                               This optional argument cannot be used in conjunction \
                               with the optional argument InitialDistribution.
          * InfBoundStatus (string): shifting or not of the distribution: "Free" (default value) or "Fixed".
          * DistInfBoundStatus (string): shifting or not of the subsequent components of \
                                         the mixture: "Free" (default value) or "Fixed".
          * NbComponent (string): estimation of the number of components of the mixture: \
                                  "Fixed" (default value) or "Estimated". Le number of estimated \
                                  components is comprised between\
                                  1 and a maximum number which is given by the number of specified \
                                  parametric distributions in the mandatory arguments \
                                  (all of these distributions are assumed to be unknown).
          * Penalty (string): type of Penalty function for model selection: \
                              "AIC" (Akaike Information Criterion), \
                              "AICc" (corrected Akaike Information Criterion) \
                              "BIC" (Bayesian Information Criterion - default value). \
                              "BICc" (corrected Bayesian Information Criterion). \

                              This optional argument can only be used if the optional argument
                              NbComponent is set at "Estimated".

        :Examples:

        .. doctest::
            :options: +SKIP

            >>> estimate_DiscreteMixture(histo, "MIXTURE", "B", dist,...,,
                             MinInfBound=1, InfBoundStatus="Fixed",
                             DistInfBoundStatus="Fixed")
            >>> estimate_DiscreteMixture(histo, "MIXTURE", "B", "NB",...,,
                               MinInfBound=1, InfBoundStatus="Fixed",
                               DistInfBoundStatus="Fixed",
                               NbComponent="Estimated", Penalty="AIC")
            >>> Estimate(histo, "MIXTURE", "B", dist, MinInfBound=1, InfBoundStatus="Fixed",
                    DistInfBoundStatus="Fixed")
            >>> Estimate(histo, "MIXTURE", "B", "NB",
                    MinInfBound=1, InfBoundStatus="Fixed",
                    DistInfBoundStatus="Fixed",
                    NbComponent="Estimated", Penalty="AIC")


        """
        #alias

        #error.CheckArgumentsLength(args, 1, 1)

        # get user arguments
        # list of distributions can be either a list or several arguments
        # e.g.: estimate_DiscreteMixture(["B","B"]) or estimate_DiscreteMixture("B", "B")
        if len(args)==1 and type(args[0])==list:
            distributions = args[0]
        else:
            distributions = list(args)

        InfBoundStatus = kargs.get("InfBoundStatus","Free")
        DistInfBoundStatus = kargs.get("DistInfBoundStatus", "Free")
        NbComponent = kargs.get("NbComponent", "Fixed")


        MinInfBound = kargs.get("MinInfBound", 0)
        Penalty = error.ParseKargs(kargs, "Penalty", "AIC",
                                likelihood_penalty_type)

        #should be before the conversion to booleans
        error.CheckType([MinInfBound, InfBoundStatus, DistInfBoundStatus,
                         NbComponent, Penalty],
                        [int, str, str, str, LikelihoodPenaltyType])


        # transform into boolean when needed
        InfBoundStatus = bool(InfBoundStatus == "Free")
        DistInfBoundStatus = bool(DistInfBoundStatus == "Free")
        NbComponent = bool(NbComponent == "Estimated")


        estimate = [] # list of bool
        pcomponent = [] # list of distribution
        ident = [] # list of distribution identifier

        # Parse list of distribution that could be defined by a distribution,
        # compound, mixture, convolution or simplya string such as "B",
        # "Mixture", ...

        for dist in distributions:

            if isinstance(dist, str):
                dist_authorised = ["BINOMIAL", "B", "POISSON",
                                   "P", "NB", "NEGATIVE_BINOMIAL"]
                if dist not in dist_authorised:
                    raise ValueError("""If distribution is a string, then it
                        must be in %s. You provided %s"""
                        % (dist_authorised, dist))
                #todo: check that poisson is allowed

                pcomponent.append(_DiscreteParametric(0, dist_type[dist]))
                ident.append(dist_type[dist])
                estimate.append(True)
            elif isinstance(dist, _DiscreteParametricModel):
                pcomponent.append(_DiscreteParametric(dist))
                ident.append(None)
                estimate.append(False)
            elif type(dist) in [_DiscreteMixture, _Convolution, _Compound]:
                pcomponent.append(_Distribution(dist))
                ident.append(None)
                estimate.append(False)
            else:
                raise ValueError("""In the case of a MIXTURE estimation,
                argument related to distributions must be either string, or
                Distribution, Mixture, Convolution, Compound. %s provided"""
                % dist)

        # check parameters
        if not NbComponent and Penalty:
            raise TypeError("""
            Penalty can only be used with NbComponent set to 'Estimated'""")

        if not NbComponent: # "FIXED"
            imixt = _DiscreteMixture(pcomponent)
            ret = histo.discrete_mixture_estimation1(imixt, estimate, MinInfBound,
                                            InfBoundStatus, DistInfBoundStatus)

            return ret
        else:  # "ESTIMATED"
            ret = histo.discrete_mixture_estimation2(ident, MinInfBound, InfBoundStatus,
                                            DistInfBoundStatus, Penalty)
            return ret
    def estimate_DiscreteMixture(histo, *args, **kargs):
        """ Estimate a finite  mixture of discrete distributions


        :Parameters:

          * histo (histogram, mixture_data, convolution_data, compound_data),
          * distributions (list) : a list of distribution object
                                   or distribution label(string) : 'B', 'NB', 'U', 'P', ...
          * unknown (string): type of unknown distribution: "Sum" or "Elementary".

        :Keywords:

          * MinInfBound (int): lower bound to the range of possible values (0 -default- or 1). \
                               This optional argument cannot be used in conjunction \
                               with the optional argument InitialDistribution.
          * InfBoundStatus (string): shifting or not of the distribution: "Free" (default value) or "Fixed".
          * DistInfBoundStatus (string): shifting or not of the subsequent components of \
                                         the mixture: "Free" (default value) or "Fixed".
          * NbComponent (string): estimation of the number of components of the mixture: \
                                  "Fixed" (default value) or "Estimated". Le number of estimated \
                                  components is comprised between\
                                  1 and a maximum number which is given by the number of specified \
                                  parametric distributions in the mandatory arguments \
                                  (all of these distributions are assumed to be unknown).
          * Penalty (string): type of Penalty function for model selection: \
                              "AIC" (Akaike Information Criterion), \
                              "AICc" (corrected Akaike Information Criterion) \
                              "BIC" (Bayesian Information Criterion - default value). \
                              "BICc" (corrected Bayesian Information Criterion). \

                              This optional argument can only be used if the optional argument
                              NbComponent is set at "Estimated".

        :Examples:

        .. doctest::
            :options: +SKIP

            >>> estimate_DiscreteMixture(histo, "MIXTURE", "B", dist,...,,
                             MinInfBound=1, InfBoundStatus="Fixed",
                             DistInfBoundStatus="Fixed")
            >>> estimate_DiscreteMixture(histo, "MIXTURE", "B", "NB",...,,
                               MinInfBound=1, InfBoundStatus="Fixed",
                               DistInfBoundStatus="Fixed",
                               NbComponent="Estimated", Penalty="AIC")
            >>> Estimate(histo, "MIXTURE", "B", dist, MinInfBound=1, InfBoundStatus="Fixed",
                    DistInfBoundStatus="Fixed")
            >>> Estimate(histo, "MIXTURE", "B", "NB",
                    MinInfBound=1, InfBoundStatus="Fixed",
                    DistInfBoundStatus="Fixed",
                    NbComponent="Estimated", Penalty="AIC")


        """
        #alias

        #error.CheckArgumentsLength(args, 1, 1)

        # get user arguments
        # list of distributions can be either a list or several arguments
        # e.g.: estimate_DiscreteMixture(["B","B"]) or estimate_DiscreteMixture("B", "B")
        if len(args) == 1 and type(args[0]) == list:
            distributions = args[0]
        else:
            distributions = list(args)

        InfBoundStatus = kargs.get("InfBoundStatus", "Free")
        DistInfBoundStatus = kargs.get("DistInfBoundStatus", "Free")
        NbComponent = kargs.get("NbComponent", "Fixed")

        MinInfBound = kargs.get("MinInfBound", 0)
        Penalty = error.ParseKargs(kargs, "Penalty", "AIC",
                                   likelihood_penalty_type)

        #should be before the conversion to booleans
        error.CheckType([
            MinInfBound, InfBoundStatus, DistInfBoundStatus, NbComponent,
            Penalty
        ], [int, str, str, str, LikelihoodPenaltyType])

        # transform into boolean when needed
        InfBoundStatus = bool(InfBoundStatus == "Free")
        DistInfBoundStatus = bool(DistInfBoundStatus == "Free")
        NbComponent = bool(NbComponent == "Estimated")

        estimate = []  # list of bool
        pcomponent = []  # list of distribution
        ident = []  # list of distribution identifier

        # Parse list of distribution that could be defined by a distribution,
        # compound, mixture, convolution or simplya string such as "B",
        # "Mixture", ...

        for dist in distributions:

            if isinstance(dist, str):
                dist_authorised = [
                    "BINOMIAL", "B", "POISSON", "P", "NB", "NEGATIVE_BINOMIAL"
                ]
                if dist not in dist_authorised:
                    raise ValueError("""If distribution is a string, then it
                        must be in %s. You provided %s""" %
                                     (dist_authorised, dist))
                #todo: check that poisson is allowed

                pcomponent.append(_DiscreteParametric(0, dist_type[dist]))
                ident.append(dist_type[dist])
                estimate.append(True)
            elif isinstance(dist, _DiscreteParametricModel):
                pcomponent.append(_DiscreteParametric(dist))
                ident.append(None)
                estimate.append(False)
            elif type(dist) in [_DiscreteMixture, _Convolution, _Compound]:
                pcomponent.append(_Distribution(dist))
                ident.append(None)
                estimate.append(False)
            else:
                raise ValueError("""In the case of a MIXTURE estimation,
                argument related to distributions must be either string, or
                Distribution, Mixture, Convolution, Compound. %s provided""" %
                                 dist)

        # check parameters
        if not NbComponent and Penalty:
            raise TypeError("""
            Penalty can only be used with NbComponent set to 'Estimated'""")

        if not NbComponent:  # "FIXED"
            imixt = _DiscreteMixture(pcomponent)
            ret = histo.discrete_mixture_estimation1(imixt, estimate,
                                                     MinInfBound,
                                                     InfBoundStatus,
                                                     DistInfBoundStatus)

            return ret
        else:  # "ESTIMATED"
            ret = histo.discrete_mixture_estimation2(ident, MinInfBound,
                                                     InfBoundStatus,
                                                     DistInfBoundStatus,
                                                     Penalty)
            return ret
def Mixture(*args):
    """Construction of a mixture of distributions from elementary distributions
    and associated weights or from an ASCII file.

    A mixture is a parametric model of classification where each elementary
    distribution or component represents a class with its associated weight.

    :Parameters:
      * `weight1`, `weight2`, ... (float) - weights of each component.
         These weights should sum to one (they constitute a discrete
         distribution).
      * `dist1`, `dist2`, ... (`_DiscreteParametricModel`, `_DiscreteMixture`, `_Convolution`,
        `_Compound`) elementary distributions (or components).
      * `filename` (string) -

    :Returns:
        If the construction succeeds, an object of type mixture is returned,
        otherwise no object is returned.

    :Examples:

    .. doctest::
        :options: +SKIP

        >>> Mixture(weight1, dist1, weight2, dist2,...)
        >>> Mixture(filename)

    .. seealso::
        :func:`~openalea.stat_tool.output.Save`,
        :func:`~openalea.stat_tool.estimate.Estimate`,
        :func:`~openalea.stat_tool.simulate.Simulate`.

    """
    error.CheckArgumentsLength(args, 1)

    types = [
        _DiscreteParametricModel, _DiscreteMixture, _Compound, _Convolution
    ]

    # filename
    if (len(args) == 1):
        error.CheckType([args[0]], [str], arg_id=[1])
        result = _DiscreteMixture(args[0])

    # build list of weights and distributions
    else:
        nb_param = len(args)
        if ((nb_param % 2) != 0):
            raise TypeError("Number of parameters must be pair")

        # Extract weights ands distributions
        weights = []
        dists = []
        for i in xrange(nb_param / 2):
            weights.append(args[i * 2])
            error.CheckType([args[i * 2 + 1]], [types], arg_id=[i * 2 + 1])
            error.CheckType([args[i * 2]], [float], arg_id=[i * 2])
            #dists.append(_Distribution(args[i * 2 + 1]))
            dists.append((args[i * 2 + 1]))

        result = _DiscreteMixture(weights, dists)

    return result
def Mixture(*args):
    """Construction of a mixture of distributions from elementary distributions
    and associated weights or from an ASCII file.

    A mixture is a parametric model of classification where each elementary
    distribution or component represents a class with its associated weight.

    :Parameters:
      * `weight1`, `weight2`, ... (float) - weights of each component.
         These weights should sum to one (they constitute a discrete
         distribution).
      * `dist1`, `dist2`, ... (`_DiscreteParametricModel`, `_DiscreteMixture`, `_Convolution`,
        `_Compound`) elementary distributions (or components).
      * `filename` (string) -

    :Returns:
        If the construction succeeds, an object of type mixture is returned,
        otherwise no object is returned.

    :Examples:

    .. doctest::
        :options: +SKIP

        >>> Mixture(weight1, dist1, weight2, dist2,...)
        >>> Mixture(filename)

    .. seealso::
        :func:`~openalea.stat_tool.output.Save`,
        :func:`~openalea.stat_tool.estimate.Estimate`,
        :func:`~openalea.stat_tool.simulate.Simulate`.

    """
    error.CheckArgumentsLength(args, 1)

    types = [_DiscreteParametricModel, _DiscreteMixture, _Compound, _Convolution]

    # filename 
    if (len(args) == 1):
        error.CheckType([args[0]], [str], arg_id=[1])
        result = _DiscreteMixture(args[0])

    # build list of weights and distributions
    else:
        nb_param = len(args)
        if ((nb_param % 2) != 0):
            raise TypeError("Number of parameters must be pair")

        # Extract weights ands distributions
        weights = []
        dists = []
        for i in xrange(nb_param / 2):
            weights.append(args[i * 2])
            error.CheckType([args[i * 2 + 1]], [types], arg_id=[i * 2 + 1])
            error.CheckType([args[i * 2]], [float], arg_id=[i * 2])
            #dists.append(_Distribution(args[i * 2 + 1]))
            dists.append((args[i * 2 + 1]))

        result = _DiscreteMixture(weights, dists)

    return result