示例#1
0
    def estimate_convolution(histo, *args, **kargs):
        """ Estimate a convolution

        :Usage:

        .. doctest::
            :options: +SKIP

            >>> Estimate(histo, "CONVOLUTION", dist,
                    MinInfBound=1, Parametric=False)
                    Estimate(histo, "CONVOLUTION", dist,
                    InitialDistribution=initial_dist, Parametric=False)

        """

        if len(args) == 0:
            raise ValueError("expect at least two argument")
        known_distribution = args[0]
        Weight = kargs.get("Weight", -1)
        NbIteration = kargs.get("NbIteration", -1)
        InitialDistribution = kargs.get("InitialDistribution", None)
        MinInfBound = kargs.get("MinInfBound", 0)

        Estimator = error.ParseKargs(kargs, "Estimator", "Likelihood",
                                     estimator_type)
        Penalty = error.ParseKargs(kargs, "Penalty", "SecondDifference",
                                   smoothing_penalty_type)
        Outside = error.ParseKargs(kargs, "Outside", "Zero", outside_type)

        if isinstance(known_distribution, _DiscreteParametricModel):
            known_distribution = _DiscreteParametric(known_distribution)
        elif type(known_distribution) in [
                _DiscreteMixture, _Convolution, _Compound
        ]:
            known_distribution = _Distribution(known_distribution)
        else:
            raise TypeError("""
            argument "known_distribution" must be of type _DiscreteMixture, _COnvolution,
            _Compound or _DiscreteParametricModel""")

        if InitialDistribution:
            return histo.convolution_estimation1(known_distribution,
                                                 InitialDistribution,
                                                 Estimator, NbIteration,
                                                 Weight, Penalty, Outside)

        else:
            return histo.convolution_estimation2(known_distribution,
                                                 MinInfBound, Estimator,
                                                 NbIteration, Weight, Penalty,
                                                 Outside)
    def estimate_convolution(histo, *args, **kargs):
        """ Estimate a convolution

        :Usage:

        .. doctest::
            :options: +SKIP

            >>> Estimate(histo, "CONVOLUTION", dist,
                    MinInfBound=1, Parametric=False)
                    Estimate(histo, "CONVOLUTION", dist,
                    InitialDistribution=initial_dist, Parametric=False)

        """

        if len(args)==0:
            raise ValueError("expect at least two argument")
        known_distribution = args[0]
        Weight = kargs.get("Weight", -1)
        NbIteration = kargs.get("NbIteration", -1)
        InitialDistribution = kargs.get("InitialDistribution", None)
        MinInfBound = kargs.get("MinInfBound", 0)

        Estimator = error.ParseKargs(kargs, "Estimator", "Likelihood",
                                estimator_type)
        Penalty = error.ParseKargs(kargs, "Penalty", "SecondDifference",
                                smoothing_penalty_type)
        Outside = error.ParseKargs(kargs, "Outside", "Zero", outside_type)

        if isinstance(known_distribution, _DiscreteParametricModel):
            known_distribution = _DiscreteParametric(known_distribution)
        elif type(known_distribution) in [_DiscreteMixture, _Convolution, _Compound]:
            known_distribution = _Distribution(known_distribution)
        else:
            raise TypeError("""
            argument "known_distribution" must be of type _DiscreteMixture, _COnvolution,
            _Compound or _DiscreteParametricModel""")

        if InitialDistribution:
            return histo.convolution_estimation1(known_distribution,
                                                InitialDistribution, Estimator,
                                                NbIteration, Weight, Penalty,
                                                Outside)

        else :
            return histo.convolution_estimation2(known_distribution,
                                                 MinInfBound,
                                                 Estimator, NbIteration, Weight,
                                                 Penalty, Outside)
    def estimate_compound(histo, *args, **kargs):
        """estimate a compound


        :Usage:

        .. doctest::
            :options: +SKIP

            >>> Estimate(histo, "COMPOUND", dist, unknown,
                    Parametric=False, MinInfBound=0)
                    Estimate(histo, "COMPOUND", dist, unknown,
                    InitialDistribution=initial_dist, Parametric=False)
        """

        if len(args)<2:
            raise ValueError("expect at least three arguments")

        known_distribution = args[0]
        ##if isinstance(known_distribution, _DiscreteParametricModel):
        #    known_distribution = _DiscreteParametric(known_distribution)
        #elif type(known_distribution) in [_DiscreteMixture, _Convolution, _Compound]:
        #    known_distribution = _Distribution(known_distribution)
        #else:
        #    raise TypeError("""
        #    argument "known_distribution" must be of type _DiscreteMixture,
        #     _COnvolution, _Compound or _DiscreteParametricModel""")

        Type = args[1]
        error.CheckType([Type], [str])

        Weight = kargs.get("Weight", -1)
        NbIteration = kargs.get("NbIteration", -1)
        InitialDistribution = kargs.get("InitialDistribution", None)
        MinInfBound = kargs.get("MinInfBound", 0)

        Estimator = error.ParseKargs(kargs, "Estimator", "Likelihood",
                                estimator_type)
        Penalty = error.ParseKargs(kargs, "Penalty", "SecondDifference",
                                smoothing_penalty_type)
        Outside = error.ParseKargs(kargs, "Outside", "Zero", outside_type)

        if MinInfBound and InitialDistribution:
            raise ValueError("""MinInfBound and InitialDistribution cannot be
                             used together.""")
        #if Estimator != _stat_tool.PENALIZED_LIKELIHOOD:
        #    if Penalty or Weight or Outside:
        #        raise ValueError("""Estimator cannot be used with O
        #            utside or Weight or Penalty option""")

	    #The second argument is either a string (e.g.,"Sum") or an unknown
        #distribution.
        try:
            if Type:
                Type = compound_type[Type]
        except KeyError:
            raise AttributeError("Bad type. Possible types are %s"
                                 % (str(compound_type.keys())))

        #The second argument is either a string (e.g.,"Sum") or an unknown
        #distribution.
        unknown_distribution = None

        if InitialDistribution:
            unknown_distribution = InitialDistribution
            if isinstance(unknown_distribution, _Distribution):
                unknown_distribution = _DiscreteParametric(unknown_distribution)
            elif type(unknown_distribution) in \
                [_DiscreteMixture, _Convolution, _Compound]:
                unknown_distribution = _Distribution(unknown_distribution)
            else:
                raise TypeError("""
                    argument "known_distribution" must be of type
                     _DiscreteMixture, _COnvolution, _Compound or _DiscreteParametricModel""")
            if Type == 's':

                return histo.compound_estimation1(
                    unknown_distribution, known_distribution, Type,
                    Estimator, NbIteration, Weight, Penalty, Outside)
            elif Type == 'e':

                return histo.compound_estimation1(
                           known_distribution, unknown_distribution, Type,
                           Estimator, NbIteration, Weight, Penalty, Outside)
            else:
                raise KeyError("should not enter here.")	
        else:
            return histo.compound_estimation2(
                            known_distribution, Type, MinInfBound,  Estimator,
                            NbIteration, Weight, Penalty, Outside)
    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
示例#5
0
def _estimate_renewal_interval_data(obj, **kargs):
    """
    Estimate switch renewal_count_data

    .. todo:: to be completed and validated with tests

    see stat_func4 in aml
    """
    #only LIKELIHOOD and PENALIZED_LIKELIHOOD
    Estimator = error.ParseKargs(kargs, "Estimator",
                                 'Likelihood', estimator_type)


    NbIteration = kargs.get("NbIteration", I_DEFAULT)
    error.CheckType([NbIteration], [int])

    # distribution
    InitialInterEvent = kargs.get("InitialInterEvent", None)
    error.CheckType([InitialInterEvent], [[type(None), _DiscreteParametricModel,
                                           _DiscreteMixture, _Convolution, _Compound]])
    if isinstance(InitialInterEvent, _DiscreteParametricModel):
        InitialInterEvent = _DiscreteParametric(InitialInterEvent)
    else:
        InitialInterEvent = _Distribution(InitialInterEvent)
    #cast initialInterEvent to parametric ?
    Penalty = error.ParseKargs(kargs, "Penalty", "SecondDifference",
                               smoothing_penalty_type)
    Weight = kargs.get("Weight", D_DEFAULT)
    error.CheckType([Weight], [[int, float]])
    Outside = error.ParseKargs(kargs, "Outside", "Zero", outside_type)
    error.CheckType([Weight], [[int, float]])

    InterEventMean = error.ParseKargs(kargs, "InterEventMean",
                            'Computed', mean_computation_map)


    if Estimator == estimator_type['PenalizedLikelihood']:
        if kargs.get("InterEventMean") is None:
            InterEventMean = ONE_STEP_LATE
        elif InterEventMean == COMPUTED:
            raise ValueError("""
                Incompatible options Estimator and InterEventMean""")
    else:
        if kargs.get("Penalty"):
            raise ValueError("""Incompatible options Penalty with type o""")
        if kargs.get("Weight"):
            raise ValueError("""Incompatible options Weight with type o""")
        if kargs.get("Outside"):
            raise ValueError("""Incompatible options Outside with type o""")

    if isinstance(obj, _FrequencyDistribution):
        if InitialInterEvent:
            renew = obj.estimation_inter_event(InitialInterEvent,
                                           Estimator, NbIteration,
                                           InterEventMean, Weight,
                                           Penalty, Outside)
        else:
            renew = obj.estimation(Estimator, NbIteration,
                                   InterEventMean ,
                                   Weight, Penalty, Outside)
    else:
        if InitialInterEvent:
            renew = obj.estimation_inter_event(InitialInterEvent,
                                           Estimator, NbIteration,
                                           InterEventMean, Weight,
                                           Penalty, Outside)
        else:
            renew = obj.estimation(Estimator, NbIteration,
                                   InterEventMean ,
                                   Weight, Penalty, Outside)

    return renew
示例#6
0
def _estimate_renewal_count_data(obj, itype, **kargs):
    """
    Estimate switch renewal_count_data
    """
    Type = 'v'
    error.CheckType([obj, itype], [[_TimeEvents, _RenewalData], str])
    if isinstance(itype, str):
        if itype == "Ordinary":
            Type = 'o'
        elif itype == "Equilibrium":
            Type = 'e'
        else:
            raise AttributeError("type must be Ordinary or Equilibrium")
    else:
        raise AttributeError("type must be Ordinary or Equilibrium")


    Estimator = error.ParseKargs(kargs, "Estimator",
                                 'Likelihood', estimator_type)

    NbIteration = kargs.get("NbIteration", I_DEFAULT)
    error.CheckType([NbIteration], [int])

    InitialInterEvent = kargs.get("InitialInterEvent", None)
    error.CheckType([InitialInterEvent], [[type(None), _DiscreteParametricModel,
                                           _DiscreteMixture, _Convolution, _Compound]])

    EquilibriumEstimator = error.ParseKargs(kargs, "EquilibriumEstimator",
                            'CompleteLikelihood', estimator_semi_markov_type)

    InterEventMean = error.ParseKargs(kargs, "InterEventMean",
                            'Computed', mean_computation_map)

    Penalty = error.ParseKargs(kargs, "Penalty", "SecondDifference",
                               smoothing_penalty_type)

    Outside = error.ParseKargs(kargs, "Outside", "Zero", outside_type)
    Weight = kargs.get("Weight", -1.)
    error.CheckType([Weight], [[int, float]])

    if Type != 'e':
        if kargs.get("EquilibriumEstimator"):
            raise Exception("EquilibriumEstimator cannot be used with type='e'")
        if kargs.get("InterEventMean"):
            raise Exception("InterEventMean be used with type='e'")

    if Estimator == estimator_type['PenalizedLikelihood']:
        if kargs.get("InterEventMean") is None:
            InterEventMean = ONE_STEP_LATE
        elif InterEventMean == COMPUTED:
            raise ValueError("""
                Incompatible options Estimator and InterEventMean""")
    else:
        if kargs.get("Penalty"):
            raise ValueError("""Incompatible options Penalty with type o""")
        if kargs.get("Weight"):
            raise ValueError("""Incompatible options Weight with type o""")
        if kargs.get("Outside"):
            raise ValueError("""Incompatible options Outside with type o""")

    if InitialInterEvent:
        #cast from InitialInterEvent to Mixture, Compound should be done

        if isinstance(InitialInterEvent, _DiscreteParametricModel):
            InitialInterEvent = _DiscreteParametric(InitialInterEvent)
        else:
            InitialInterEvent = _Distribution(InitialInterEvent)
        renew = obj.estimation_inter_event_type(Type, InitialInterEvent,
                                           Estimator, NbIteration,
                                           EquilibriumEstimator,
                                           InterEventMean, Weight,
                                           Penalty, Outside)
    else:
        renew = obj.estimation_type(Type, Estimator, NbIteration,
                               EquilibriumEstimator, InterEventMean ,
                               Weight, Penalty, Outside)

    return renew
示例#7
0
    def estimate_compound(histo, *args, **kargs):
        """estimate a compound


        :Usage:

        .. doctest::
            :options: +SKIP

            >>> Estimate(histo, "COMPOUND", dist, unknown,
                    Parametric=False, MinInfBound=0)
                    Estimate(histo, "COMPOUND", dist, unknown,
                    InitialDistribution=initial_dist, Parametric=False)
        """

        if len(args) < 2:
            raise ValueError("expect at least three arguments")

        known_distribution = args[0]
        ##if isinstance(known_distribution, _DiscreteParametricModel):
        #    known_distribution = _DiscreteParametric(known_distribution)
        #elif type(known_distribution) in [_DiscreteMixture, _Convolution, _Compound]:
        #    known_distribution = _Distribution(known_distribution)
        #else:
        #    raise TypeError("""
        #    argument "known_distribution" must be of type _DiscreteMixture,
        #     _COnvolution, _Compound or _DiscreteParametricModel""")

        Type = args[1]
        error.CheckType([Type], [str])

        Weight = kargs.get("Weight", -1)
        NbIteration = kargs.get("NbIteration", -1)
        InitialDistribution = kargs.get("InitialDistribution", None)
        MinInfBound = kargs.get("MinInfBound", 0)

        Estimator = error.ParseKargs(kargs, "Estimator", "Likelihood",
                                     estimator_type)
        Penalty = error.ParseKargs(kargs, "Penalty", "SecondDifference",
                                   smoothing_penalty_type)
        Outside = error.ParseKargs(kargs, "Outside", "Zero", outside_type)

        if MinInfBound and InitialDistribution:
            raise ValueError("""MinInfBound and InitialDistribution cannot be
                             used together.""")
        #if Estimator != _stat_tool.PENALIZED_LIKELIHOOD:
        #    if Penalty or Weight or Outside:
        #        raise ValueError("""Estimator cannot be used with O
        #            utside or Weight or Penalty option""")

#The second argument is either a string (e.g.,"Sum") or an unknown
#distribution.
        try:
            if Type:
                Type = compound_type[Type]
        except KeyError:
            raise AttributeError("Bad type. Possible types are %s" %
                                 (str(compound_type.keys())))

        #The second argument is either a string (e.g.,"Sum") or an unknown
        #distribution.
        unknown_distribution = None

        if InitialDistribution:
            unknown_distribution = InitialDistribution
            if isinstance(unknown_distribution, _Distribution):
                unknown_distribution = _DiscreteParametric(
                    unknown_distribution)
            elif type(unknown_distribution) in \
                [_DiscreteMixture, _Convolution, _Compound]:
                unknown_distribution = _Distribution(unknown_distribution)
            else:
                raise TypeError("""
                    argument "known_distribution" must be of type
                     _DiscreteMixture, _COnvolution, _Compound or _DiscreteParametricModel"""
                                )
            if Type == 's':

                return histo.compound_estimation1(unknown_distribution,
                                                  known_distribution, Type,
                                                  Estimator, NbIteration,
                                                  Weight, Penalty, Outside)
            elif Type == 'e':

                return histo.compound_estimation1(known_distribution,
                                                  unknown_distribution, Type,
                                                  Estimator, NbIteration,
                                                  Weight, Penalty, Outside)
            else:
                raise KeyError("should not enter here.")
        else:
            return histo.compound_estimation2(known_distribution, Type,
                                              MinInfBound, Estimator,
                                              NbIteration, Weight, Penalty,
                                              Outside)
示例#8
0
    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