コード例 #1
0
 def test_normal_variable(self):
     # to avoid static method warnings in tests,
     # that by construction of the unittest package have to be expressed in such way
     self.dummy_variable = "dummy_value"
     mu = 53
     sigma = 4
     tol = 0.15
     norm = Normal(mu=mu, sigma=sigma)
     values = norm.get_values(no_values=400)
     rand = RandomVariable()
     rand.calculate_parameters(values)
     if not rand.get_distribution_type() == "NORMAL":
         raise Exception("Excepted a normal!")
     mu_r = rand.random_variable.mu
     sigma_r = rand.random_variable.sigma
     diff_value_mu = abs(mu - mu_r) / (max(abs(mu), abs(mu_r)))
     diff_value_sigma = abs(sigma - sigma_r) / (max(abs(sigma), abs(sigma_r)))
     if diff_value_mu > tol or diff_value_sigma > tol:
         raise Exception("parameters found outside tolerance")
    def read_from_string(self, distribution_type, distribution_parameters):
        """
        Read the random variable from string

        Parameters
        -----------
        distribution_type
            Distribution type
        distribution_parameters
            Distribution parameters splitted by ;
        """
        if distribution_type == "NORMAL":
            self.random_variable = Normal()
            self.random_variable.read_from_string(distribution_parameters)
        elif distribution_type == "UNIFORM":
            self.random_variable = Uniform()
            self.random_variable.read_from_string(distribution_parameters)
        elif distribution_type == "EXPONENTIAL":
            self.random_variable = Exponential()
            self.random_variable.read_from_string(distribution_parameters)
        elif distribution_type == "IMMEDIATE":
            self.random_variable = Constant0()
    def calculate_parameters(self,
                             values,
                             parameters=None,
                             force_distribution=None):
        """
        Calculate parameters of the current distribution

        Parameters
        -----------
        values
            Empirical values to work on
        parameters
            Possible parameters of the algorithm
        force_distribution
            If provided, distribution to force usage (e.g. EXPONENTIAL)

        """

        if parameters is None:
            parameters = {}

        debug_mode = parameters["debug"] if "debug" in parameters else False

        if self.random_variable is not None:
            self.random_variable.calculate_parameters(values)
        else:
            norm = Normal()
            unif = Uniform()
            expon = Exponential()
            constant = Constant0()

            if not force_distribution or not force_distribution == "EXPONENTIAL":
                likelihoods = list()
                likelihoods.append(
                    [constant,
                     constant.calculate_loglikelihood(values)])
                if force_distribution == "NORMAL" or force_distribution is None:
                    norm.calculate_parameters(values)
                    likelihoods.append(
                        [norm, norm.calculate_loglikelihood(values)])
                if force_distribution == "UNIFORM" or force_distribution is None:
                    unif.calculate_parameters(values)
                    likelihoods.append(
                        [unif, unif.calculate_loglikelihood(values)])
                if force_distribution == "EXPONENTIAL" or force_distribution is None:
                    expon.calculate_parameters(values)
                    likelihoods.append(
                        [expon, expon.calculate_loglikelihood(values)])
                likelihoods = [x for x in likelihoods if str(x[1]) != 'nan']
                likelihoods = sorted(likelihoods,
                                     key=lambda x: x[1],
                                     reverse=True)

                if debug_mode:
                    print("likelihoods = ", likelihoods)

                self.random_variable = likelihoods[0][0]
            else:
                avg_values = np.average(values)
                if values and avg_values > 0.00000:
                    expon.scale = avg_values
                    self.random_variable = expon
                else:
                    self.random_variable = constant