Advertisement
Guest User

Untitled

a guest
Dec 8th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.44 KB | None | 0 0
  1. import numpy as np
  2. from matplotlib import pyplot as plt
  3. import time
  4. from scipy.optimize import curve_fit
  5. from scipy import stats
  6.  
  7.  
  8. def histo(d_out):
  9.     '''Création de l'histogramme (degree distribution) à partir d'une liste de degrés.
  10.    
  11.    d_out : liste de degrés.
  12.    indice : abscisse de l'histogramme.
  13.    hist : ordonnée de l'histogramme (ie nombre de fois où la valeur d'absisse apparait dans d_out.'''
  14.  
  15.     hist = {key:0 for key in set(d_out)}
  16.     for d in d_out:
  17.         hist[d] += 1
  18.     return list(hist.keys()), list(hist.values())
  19.  
  20.  
  21.  
  22. ########################
  23. ### Logarithmic binning
  24.  
  25.  
  26. def log_binning(x,y,a=1.5):
  27.     '''Retourne le binning de l'histogramme en entrée.
  28.    Typiquement, x est indice et y hist.
  29.    a > 1 determine le pas de l'intervalle : quand a augmente, les intervalles
  30.    sont moins nombreux mais plus précis.
  31.    En sortie, on a deux liste contenant les abscisses et ordonnées des points
  32.    obtenus par le log binning.'''
  33.     if a<=1:
  34.         raise Exception('a must be > 1 to have correct intervals.')
  35.     #
  36.     # print("x[-1] = %f" % (x[-1]))
  37.     # print("a = %f" % (a))
  38.     # print("np.log(x[-1]) = %f" % (np.log(x[-1])))
  39.     # print("np.log(x[a]) = %f" % (np.log(x[a])))
  40.     n = range(int(np.log(x[-1]) / np.log(a))+2)
  41.     power_x = [a**i for i in n]
  42.     y_bin = stats.binned_statistic(x, y, 'sum', bins=power_x)[0]
  43.     x_bin = [(a**(i+1) + a**i -1)/2 for i in n]
  44.  
  45.     diff_x = np.array(power_x[1:])-np.array(power_x[:-1])
  46.     y_bin = np.array(y_bin) / diff_x
  47. #    x_plot = [(a**(i+1) + a**i -1)/2 for i in n]
  48.  
  49.     y_bin_end = []
  50.     x_bin_end = []
  51.     for i in range(len(y_bin)):
  52.         if y_bin[i]>0:
  53.             y_bin_end.append(y_bin[i])
  54.             x_bin_end.append(x_bin[i])
  55.  
  56.     return x_bin[:-1], y_bin
  57.  
  58.  
  59. def plot_d(filename,indice,hist, a = 1.5, cut_beggining = 0, cut_end = 'end'):
  60.     '''Trace la distribution des degrés, coupée si besoin.
  61.    cut_beggining et cut_end déterminent le début et la fin de ce qu'on veut prendre.'''
  62.     x,y = log_binning(indice,hist, a=a)
  63.     if cut_end=='end':
  64.         cut_end=len(x)
  65.     logx = np.log(np.array(x))
  66.     logy = np.log(np.array(y))
  67.     fit = np.polyfit(logx[cut_beggining:cut_end],logy[cut_beggining:cut_end],1)
  68.     # print(fit)
  69.  
  70.     plt.loglog(indice,hist, '.', label='DD')#, color='blue')
  71.     plt.loglog(x,y,'x', label='log binning', color='black')
  72.     plt.loglog(x[cut_beggining:cut_end],[xx**fit[0]*np.exp(fit[1]) for xx in x[cut_beggining:cut_end]], label=r'fit : $\alpha$={}'.format(round(fit[0],3)), color='red')
  73.     plt.title("Degree Distribution : " + filename[-13:-4])
  74.     plt.xlabel('Degree')
  75.     plt.ylabel('Count')
  76.     plt.legend()
  77.     plt.rcParams.update({'font.size': 8})
  78.     plt.grid()
  79.     plt.tight_layout()
  80.     plt.ylim(top=10**5,bottom=0.01)
  81.     plt.xlim(left=0.01,right=10**5)
  82.  
  83.     plt.savefig(filename)
  84.     plt.close()
  85.     return round(fit[0], 3)
  86. ### Fit
  87.  
  88.  
  89. def PL_function(x, a, b):
  90.     '''power-law function.'''
  91.     return a*x**b
  92.  
  93.  
  94. '''curve_fit(func,x_out,y_out): Fit la courbe (x_out,y_out) par la fonction func.
  95.    popt1_out correspond à la pente.'''
  96.  
  97.  
  98.  
  99.  
  100.  
  101. #La fonction suivante est juste utilisee pour l exemple
  102. def DD_power_law(N,alpha):
  103.     #Construit une DD en power law avec pente alpha
  104.     proba_PL = np.array([i**(-alpha) for i in range(1,N)])
  105.     proba_PL = proba_PL/sum(proba_PL)
  106.     while sum(proba_PL)>=1: # Juste parce que multinomial rale si la somme est >1. on est un peu en dessous de 1, mais de pas grand chose donc ca n'influence pas.
  107.         proba_PL = proba_PL/(1.00001*sum(proba_PL))
  108.     tirages = np.random.multinomial(N,proba_PL) # distribution des degres : tirage[i] donne le nombre de noeuds de degré (i+1)
  109.    
  110.     d = [] # liste des degrés
  111.     for x,v in enumerate(tirages):
  112.        for j in range(v):
  113.            d.append(x+1)
  114.          
  115.     ii = -1
  116.     while d[ii]==N-1: # Probleme avec le tirage ... la derniere proba est trop haute -> plusieurs noeuds de degres N-1. On les vire (arbitrairement mis comme des noeuds de degre 1).
  117.         d[ii]=1
  118.         ii-=1
  119.     return d
  120.  
  121.  
  122.  
  123.  
  124.  
  125. # d = DD_power_law(10**5,2.5) # On construit une Power-Law de pente -2.5 avec 10**5 points
  126.  
  127. def export_log_pl(d,filename):
  128.     indice, hist = histo(d)
  129.     slope = plot_d(filename,indice, hist, cut_beggining=3)
  130.  
  131.     x, y = log_binning(indice, hist, a=1.5)
  132.     fit_parameters, cov = curve_fit(PL_function, x, y)
  133.     # slope = fit_parameters[0]
  134.     return slope
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement