Цель
Я превратил двойной for loop
в один for loop
, используя vectorization
. Теперь я хотел бы избавиться от последних loop
.
Я хочу slice
* Nx3 array
координат и рассчитать расстояния между нарезанной частью и оставшейся частью без используя для l oop.
Два случая
(1) срез всегда равен 3x3
.
(2) срез является переменным, т. Е. Mx3
, где М всегда значительно меньше, чем N
Векторизация взаимодействия 1 строки среза, взаимодействующей с остатком, проста. Тем не менее, я застрял, используя для цикла l oop, чтобы сделать (в случае среза размером 3) 3 цикла, чтобы вычислить все расстояния.
Контекст:
Массив Nx3 это координаты атома, срез - это все атомы в определенной молекуле c. Я хочу рассчитать энергию данной молекулы, взаимодействующей с остальной системой. Первым шагом является вычисление расстояний между каждым атомом в молекуле, со всеми другими атомами. Вторая часть состоит в том, чтобы использовать эти расстояния в функции для вычисления энергии, и это выходит за рамки этого вопроса.
Вот то, что у меня есть для рабочего минимального примера (у меня есть vectorized
внутренний l oop, но нужно (очень хотелось бы ...) vectorize
outer loop
. Что l oop не всегда будет иметь только размер 3, а python
медленный для циклов.
Минимальный рабочий пример
import numpy as np
box=10 # simulation box is size 10 for this example
r = np.random.rand(1000,3) * box # avoids huge numbers later by scaling coords
start=0 #fixed starting index for example (first atom)
end=2 #fixed ending index for example (last atom)
rj=np.delete(r, np.arange(start,end), 0)
ri = r[np.arange(start,end),:]
atoms_in_molecule, coords = np.shape(ri)
energy = 0
for a in range(atoms_in_molecule):
rij = ri[a,:] - rj # I want to get rid of this 'a' index dependance
rij = rij - np.rint(rij/box)*box # periodic boundary conditions - necessary
rij_sq = np.sum(rij**2,axis=1)
# perform energy calculation using rij_sq
ener = 4 * ((1/rij_sq)**12 - (1/rij_sq)**6) # dummy LJ, do not optimize
energy += np.sum(ener)
print(energy)
Этот вопрос не касается оптимизации векторизации, которая у меня уже есть. Я поиграл с pdist / cdist и другими. Все, что я хочу, это избавиться от досадно за l oop над атомами. Остальное я оптимизирую.