Ho scritto uno script Python per calcolare la distanza tra due punti nello spazio 3D tenendo conto delle condizioni al contorno periodiche. Il problema è che ho bisogno di fare questo calcolo per molti, molti punti e il calcolo è piuttosto lento. Ecco la mia funzione.Ottimizzazione del calcolo della distanza Python tenendo conto delle condizioni al contorno periodiche
def PBCdist(coord1,coord2,UC):
dx = coord1[0] - coord2[0]
if (abs(dx) > UC[0]*0.5):
dx = UC[0] - dx
dy = coord1[1] - coord2[1]
if (abs(dy) > UC[1]*0.5):
dy = UC[1] - dy
dz = coord1[2] - coord2[2]
if (abs(dz) > UC[2]*0.5):
dz = UC[2] - dz
dist = np.sqrt(dx**2 + dy**2 + dz**2)
return dist
ho quindi chiamare la funzione in modo
for i, coord2 in enumerate(coordlist):
if (PBCdist(coord1,coord2,UC) < radius):
do something with i
Di recente ho letto che posso aumentare notevolmente le prestazioni utilizzando la lista di comprensione. I seguenti lavori per il caso non PBC, ma non per il caso PBC
coord_indices = [i for i, y in enumerate([np.sqrt(np.sum((coord2-coord1)**2)) for coord2 in coordlist]) if y < radius]
for i in coord_indices:
do something
C'è qualche modo per fare l'equivalente di questo per il caso PBC? C'è un'alternativa che funzionerebbe meglio?
Si utilizza NumPy, quindi è necessario vettorializzare il ciclo per migliorare le prestazioni. Qual è esattamente la struttura di 'coordlist'? Dovrebbe essere un array NumPy bidimensionale per essere in grado di ottimizzare il loop con gli ufunc NumPy. –
coordlist è una matrice numpy con forma approssimativamente (5711,3). lo stesso coordlist proviene da una lista più ampia, quindi faccio un loop su coordlist 20.000 volte e quell'elenco di coordlist viene ripetuto circa 50 volte ... si ottiene l'immagine. – johnjax
Ho cercato la funzione vectorize in NumPy. La documentazione dice: ["La funzione vectorize viene fornita principalmente per comodità, non per prestazioni. L'implementazione è essenzialmente un ciclo for."] (Http://docs.scipy.org/doc/numpy/reference/generated/numpy. vectorize.html) – johnjax