(self, v, normalized=False, method = 'MLE')
return I
Calculates the betweenness preferences of a
        node v based on the mutual information of path 
        statistics of length two.

        @nornalized: whether or not to normalize betweenness preference values

        @method: which method to use for the entropy calculation. The default 'MLE' uses 
            the standard Maximum-Likelihood estimation of entropy. Setting method to 
            'Miller' additionally applies a Miller-correction. see e.g. 
            Liam Paninski: Estimation of Entropy and Mutual Information, Neural Computation 5, 2003 or 
            http://www.nowozin.net/sebastian/blog/estimating-discrete-entropy-part-2.html
Calculates the betweenness preferences of a
        node v based on the mutual information of path 
        statistics of length two.
Calculates the betweenness preferences of a node v based on the mutual information of path statistics of length two .
def BetweennessPreference(self, v, normalized=False, method = 'MLE'):
        """
        Calculates the betweenness preferences of a
        node v based on the mutual information of path 
        statistics of length two.

        @nornalized: whether or not to normalize betweenness preference values

        @method: which method to use for the entropy calculation. The default 'MLE' uses 
            the standard Maximum-Likelihood estimation of entropy. Setting method to 
            'Miller' additionally applies a Miller-correction. see e.g. 
            Liam Paninski: Estimation of Entropy and Mutual Information, Neural Computation 5, 2003 or 
            http://www.nowozin.net/sebastian/blog/estimating-discrete-entropy-part-2.html
        """
        
        assert method == 'MLE' or method =='Miller'    

        # If the network is empty, just return zero
        if len(self.getNodes()) == 0:
            return 0.0

        # First create the betweenness preference matrix (equation (2) of the paper)
        B_v = self.BWPrefMatrix(v)

        if B_v.shape[0] == 0 or B_v.shape[1] == 0:
            return None

        # Normalize matrix (equation (3) of the paper)
        # NOTE: P_v has the same shape as B_v
        P_v = _np.zeros(shape=B_v.shape)
        S = _np.sum(B_v)

        if S>0:
            P_v = B_v / S

        # Compute marginal probabilities
        # Marginal probabilities P^v_d = \sum_s'{P_{s'd}}
        marginal_d = _np.sum(P_v, axis=0)

        # Marginal probabilities P^v_s = \sum_d'{P_{sd'}}
        marginal_s = _np.sum(P_v, axis=1)        

        if method=='Miller':    

            # total number of samples, i.e. observed two-paths
            N = _np.sum(B_v)

            #print('N = ', N)        
            #print('B = ', B_v)
            #print('marginal_s = ', marginal_s)
            #print('marginal_d = ', marginal_d)

            # marginal entropy H(S)
            H_s = Paths.__Entropy(marginal_s, len(marginal_s), N, method='Miller')

            # print('H(S) = ', H_s)
            # marginal entropy H(D)

            H_d = Paths.__Entropy(marginal_d, len(marginal_d), N, method='Miller')

            #print('H(D) = ', H_d)
            # we need the conditional entropy H(D|S)

            H_ds = 0
            for s in range(len(marginal_s)):

                # number of two paths s -> v -> * observed in the data
                N_s = _np.sum(B_v[s,:])

                #print('N(s=' + str(s) + ') = ' +  str(N_s))

                # probabilities of all destinations, given the particular source s
                p_ds = B_v[s,:]/_np.sum(B_v[s,:])

                #print('P(D|S=' + str(s) + ') = '+ str(p_ds))

                # number of possible destinations d
                K_s = len(p_ds)

                #print('K(s=' + str(s) + ') = ' +  str(K_s))

                # marginal_s[s] is the overall probability of source s
                p_s = marginal_s[s]

                # add to conditional entropy
                H_ds += p_s * Paths.__Entropy(p_ds, K_s, N_s, method='Miller')

            #print('H(D|S) = ', H_ds)

        else: 
            # use MLE estimation
            H_s = Paths.__Entropy(marginal_s)
            H_d = Paths.__Entropy(marginal_d)
            H_ds = 0

            for s in range(len(marginal_s)):
                p_ds = P_v[s,:]/_np.sum(P_v[s,:])
                H_ds += marginal_s[s] * Paths.__Entropy(p_ds)

            # Alternative calculation (without explicit entropies)
            # build mask for non-zero elements
            # row, col = np.nonzero(P_v)
            # pv = P_v[(row,col)]
            # marginal = np.outer(marginal_s, marginal_d)
            # log_argument = np.divide( pv, marginal[(row,col)] )    
            # I = np.dot( pv, np.log2(log_argument) )    

        I = H_d - H_ds

        if normalized:
            I =  I/_np.min([H_s, H_d])

        return I
def BetweennessPreference ( self , v , normalized = False , method = 'MLE' ) : assert method == 'MLE' or method == 'Miller' # If the network is empty, just return zero if len ( self . getNodes ( ) ) == 0 : return 0.0 # First create the betweenness preference matrix (equation (2) of the paper) B_v = self . BWPrefMatrix ( v ) if B_v . shape [ 0 ] == 0 or B_v . shape [ 1 ] == 0 : return None # Normalize matrix (equation (3) of the paper) # NOTE: P_v has the same shape as B_v P_v = _np . zeros ( shape = B_v . shape ) S = _np . sum ( B_v ) if S > 0 : P_v = B_v / S # Compute marginal probabilities # Marginal probabilities P^v_d = \sum_s'{P_{s'd}} marginal_d = _np . sum ( P_v , axis = 0 ) # Marginal probabilities P^v_s = \sum_d'{P_{sd'}} marginal_s = _np . sum ( P_v , axis = 1 ) if method == 'Miller' : # total number of samples, i.e. observed two-paths N = _np . sum ( B_v ) #print('N = ', N)         #print('B = ', B_v) #print('marginal_s = ', marginal_s) #print('marginal_d = ', marginal_d) # marginal entropy H(S) H_s = Paths . __Entropy ( marginal_s , len ( marginal_s ) , N , method = 'Miller' ) # print('H(S) = ', H_s) # marginal entropy H(D) H_d = Paths . __Entropy ( marginal_d , len ( marginal_d ) , N , method = 'Miller' ) #print('H(D) = ', H_d) # we need the conditional entropy H(D|S) H_ds = 0 for s in range ( len ( marginal_s ) ) : # number of two paths s -> v -> * observed in the data N_s = _np . sum ( B_v [ s , : ] ) #print('N(s=' + str(s) + ') = ' +  str(N_s)) # probabilities of all destinations, given the particular source s p_ds = B_v [ s , : ] / _np . sum ( B_v [ s , : ] ) #print('P(D|S=' + str(s) + ') = '+ str(p_ds)) # number of possible destinations d K_s = len ( p_ds ) #print('K(s=' + str(s) + ') = ' +  str(K_s)) # marginal_s[s] is the overall probability of source s p_s = marginal_s [ s ] # add to conditional entropy H_ds += p_s * Paths . __Entropy ( p_ds , K_s , N_s , method = 'Miller' ) #print('H(D|S) = ', H_ds) else : # use MLE estimation H_s = Paths . __Entropy ( marginal_s ) H_d = Paths . __Entropy ( marginal_d ) H_ds = 0 for s in range ( len ( marginal_s ) ) : p_ds = P_v [ s , : ] / _np . sum ( P_v [ s , : ] ) H_ds += marginal_s [ s ] * Paths . __Entropy ( p_ds ) # Alternative calculation (without explicit entropies) # build mask for non-zero elements # row, col = np.nonzero(P_v) # pv = P_v[(row,col)] # marginal = np.outer(marginal_s, marginal_d) # log_argument = np.divide( pv, marginal[(row,col)] )     # I = np.dot( pv, np.log2(log_argument) )     I = H_d - H_ds if normalized : I = I / _np . min ( [ H_s , H_d ] ) return I