def test_log_binom_coeff_many(self):
     for _ in range(100):
         n = randint(1, 10)
         k = randint(0, n)
         self.assertEqual(round(exp(HelperFunctions.log_bin_coeff(n, k))), round(binom(n, k)))
예제 #2
0
    def log_pdf(self, X):
        if not type(X) is numpy.ndarray:
            raise TypeError("X must be a numpy array")
        
        if not len(X.shape) is 2:
            raise TypeError("X must be a 2D numpy array")
        
        # this also enforces correct data ranges
        if X.dtype != numpy.bool8:
            raise ValueError("X must be a bool8 numpy array")
        
        if not X.shape[1] == self.dimension:
            raise ValueError("Dimension of X does not match own dimension")

        num_active_self = sum(self.mu)
        #max_possible_change = min(num_active_self, self.dimension - num_active_self)
        
        # result vector
        log_liks = zeros(len(X))
        
        # compute action dependent log likelihood parts
        for i in range(len(X)):
            x = X[i]
            
            num_active_x = sum(x)
            
            # hamming distances using numpy broadcasting
            # divide by two, integer division is always fine since even number of differences
            num_diff = sum(self.mu != x)
            if num_active_self == num_active_x:
                num_diff / 2
                
            if num_diff > self.N:
                log_liks[i]=-inf
                continue
                
            if num_active_self != num_active_x:
                action = num_active_x < num_active_self
                if not all(x[self.mu==action]==action):
                    log_liks[i]=-inf
                    continue
            else:
                action = 2
            
            #shared-terms
            log_liks[i] = HelperFunctions.log_bin_coeff(self.N - 1, num_diff - 1) \
                            + (num_diff - 1) * log(self.spread) \
                            + (self.N - num_diff) * log(1 - self.spread)
            # if there was a freedom of action, use factor 1/3
            if num_diff <= min(num_active_self,self.dimension-num_active_self):
                log_liks[i] -= log(3)
            # action-specific terms
            if action == 0:
                # add
                log_liks[i] -= HelperFunctions.log_bin_coeff(self.dimension - num_active_self, num_diff)
            elif action == 1:
                # del
                log_liks[i] -= HelperFunctions.log_bin_coeff(num_active_self, num_diff)
            elif action == 2:
                # swap
                log_liks[i] -= HelperFunctions.log_bin_coeff(num_active_self, num_diff) \
                                 - HelperFunctions.log_bin_coeff(self.dimension - num_active_self, num_diff)
            
        return log_liks
 def test_log_binom_coeff_5(self):
     n = 2
     k = 3
     self.assertEqual(round(exp(HelperFunctions.log_bin_coeff(n, k))), binom(n, k))