#python #python-3.x #numpy #numpy-ndarray
#python #python-3.x #numpy #numpy-ndarray
Вопрос:
Я пытаюсь построить орбиту звезды в заданном потенциале. Сначала я инициализирую положение и скорость и получаю ускорение из положения в соответствии с заданным потенциалом.
Затем я увеличиваю время с определенным временным шагом и вычисляю орбиту. Проблема возникает, когда я пытаюсь сохранить вычисленные позиции в пустом списке. Вот мой код:
## Initial position, velocity, and acceleration
r = np.array([20., 20., 0.])
v = np.array([0., 1., 0.])
g = acc(*r) #calculates acceleration from a function
## empty list to store position data
posdata = []
## Orbit integration
dt = 0.1
for t in np.arange(0, 1000, dt):
v = 0.5 * g * dt
r = v * dt
if t%100 == 0:
print(r) #check if r actually changes
g = acc(*r)
v = 0.5 * g * dt
posdata.append(r)
Это то, что я ожидаю получить:
posdata
>>> [array([19.999875, 20.099875, 0.]), array([19.99950125, 20.19950001, 0.]), array([19.99887999, 20.29887502, 0.]), ...]
Но на самом деле я понимаю это:
>>> [array([-17.57080611, -34.03696644, 0.]), array([-17.57080611, -34.03696644, 0.]), array([-17.57080611, -34.03696644, 0.])]
Все элементы идентичны последнему вычисленному элементу. Как вы можете видеть, я проверил, r
действительно ли что-то меняется, и это происходит. Я думаю, это связано с тем, что r
это массив, но я не знаю, как это исправить.
Комментарии:
1.
r
во время цикла остается один и тот же объект, поэтому вы добавляете один и тот же объект кposdata
на каждой итерации. Быстрое исправление:r = r v*dt
,
Ответ №1:
Вы добавляете один и тот же объект каждый раз, когда создаете список из множества ссылок на один и тот же объект.
[r, r, r, r, r, r, r]
Поскольку объект является изменяемым, при обновлении объекта изменение влияет на весь ваш список ссылок.
Вам нужно создать копию объекта, когда вы добавляете его в свой список.
Попробуйте это вместо
posdata.append(r.copy())
Теперь у вас будет другой объект в каждом расположении списка.
[r1, r2, r3, r4, r5, r6, r7]
Ответ №2:
Когда вы добавляете массив r в список, добавляется только ссылка на объект array. И поскольку объекты numpy.array изменяемы, все ссылки обновляются на месте. Для этого вы можете либо
- добавьте массив в виде списка к posdata в виде списка
posdata.append(r.tolist())
Или
-
добавьте массив в качестве нового объекта numpy.array в posdata
posdata.append(np.array(r))
Ответ №3:
Я столкнулся с той же проблемой. Мое решение состоит в том, чтобы изменить =
в уравнении r = v * dt
на r = r v * dt
, а затем добавить его в список.