В своем ответе на вопрос о MSE, касающемся двумерного гамильтонова моделирования физики, я предложил использовать симплектический интегратор высшего порядка .
Тогда я подумал, что было бы неплохо продемонстрировать влияние разных временных шагов на глобальную точность методов с разными порядками, и я написал и запустил скрипт Python / Pylab для этого. Для сравнения я выбрал:
- ( leap2 ) Пример 2-го порядка Википедии, с которым я знаком, хотя я знаю его под именем leapfrog ,
- ( ruth3 ) Симплектический интегратор Рут 3-го порядка ,
- ( ruth4 ) Симплектический интегратор 4-го порядка Рут .
Странно то, что какой бы временной шаг я ни выбрал, метод Рут 3-го порядка кажется более точным в моем тесте, чем метод Рут 4-го порядка, даже на порядок.
Поэтому мой вопрос: что я здесь делаю не так? Подробности ниже.
Методы раскрывают свою силу в системах с разделимыми гамильтонианами, то есть теми, которые можно записать как
В нашей настройке мы можем нормализовать силы и импульсы по массам, к которым они применяются. Таким образом, силы превращаются в ускорения, а импульсы превращаются в скорости.
Симплектические интеграторы поставляются со специальными (заданными, постоянными) коэффициентами, которые я обозначу и . С этими коэффициентами один шаг для развития системы от времени до времени принимает вид
Для :
- Вычислить вектор всех ускорений, учитывая вектор всех положений
- Изменить вектор всех скоростей на
- Изменить вектор всех позиций на
Мудрость теперь заключается в коэффициентах. Это
Я интегрировал IVP с вышеупомянутыми методами над с размером шага с целым числом выбранным где-то между и . Принимая во внимание скорость прыжка 2 , я утроил для этого метода. Затем я нанес на график полученные кривые в фазовом пространстве и увеличил масштаб в где в идеале кривые должны снова прийти к .
Вот графики и увеличения для и :
Для , leap2 с размером шага случается , чтобы прибыть ближе к дому , чем ruth4 с размером шага . Для , ruth4 победы над leap2 . Однако ruth3 с тем же размером шага, что и ruth4 , прибывает гораздо ближе к дому, чем остальные, во всех настройках, которые я тестировал до сих пор.
Вот скрипт Python / Pylab:
import numpy as np
import matplotlib.pyplot as plt
def symplectic_integrate_step(qvt0, accel, dt, coeffs):
q,v,t = qvt0
for ai,bi in coeffs.T:
v += bi * accel(q,v,t) * dt
q += ai * v * dt
t += ai * dt
return q,v,t
def symplectic_integrate(qvt0, accel, t, coeffs):
q = np.empty_like(t)
v = np.empty_like(t)
qvt = qvt0
q[0] = qvt[0]
v[0] = qvt[1]
for i in xrange(1, len(t)):
qvt = symplectic_integrate_step(qvt, accel, t[i]-t[i-1], coeffs)
q[i] = qvt[0]
v[i] = qvt[1]
return q,v
c = np.math.pow(2.0, 1.0/3.0)
ruth4 = np.array([[0.5, 0.5*(1.0-c), 0.5*(1.0-c), 0.5],
[0.0, 1.0, -c, 1.0]]) / (2.0 - c)
ruth3 = np.array([[2.0/3.0, -2.0/3.0, 1.0], [7.0/24.0, 0.75, -1.0/24.0]])
leap2 = np.array([[0.5, 0.5], [0.0, 1.0]])
accel = lambda q,v,t: -q
qvt0 = (1.0, 0.0, 0.0)
tmax = 2.0 * np.math.pi
N = 36
fig, ax = plt.subplots(1, figsize=(6, 6))
ax.axis([-1.3, 1.3, -1.3, 1.3])
ax.set_aspect('equal')
ax.set_title(r"Phase plot $(y(t),y'(t))$")
ax.grid(True)
t = np.linspace(0.0, tmax, 3*N+1)
q,v = symplectic_integrate(qvt0, accel, t, leap2)
ax.plot(q, v, label='leap2 (%d steps)' % (3*N), color='black')
t = np.linspace(0.0, tmax, N+1)
q,v = symplectic_integrate(qvt0, accel, t, ruth3)
ax.plot(q, v, label='ruth3 (%d steps)' % N, color='red')
q,v = symplectic_integrate(qvt0, accel, t, ruth4)
ax.plot(q, v, label='ruth4 (%d steps)' % N, color='blue')
ax.legend(loc='center')
fig.show()
Я уже проверил на простые ошибки:
- Нет опечатка в Википедии. Я проверил ссылки, в частности ( 1 , 2 , 3 ).
- Я правильно понял последовательность коэффициентов. Если вы сравните с порядком в Википедии, обратите внимание, что последовательность операций оператора работает справа налево. Моя нумерация совпадает с Candy / Rozmus . И если я все же попробую другой порядок, результаты ухудшатся.
Мои подозрения:
- Неправильный порядок шага: может быть, схема 3-го порядка Рут имеет несколько меньшие подразумеваемые константы, и если бы размер шага был сделан очень маленьким, то метод 4-го порядка победил бы? Но я даже попробовал , и метод 3-го порядка все еще лучше.
- Неправильный тест: Что-то особенное в моем тесте позволяет методу Рут третьего порядка вести себя как метод высшего порядка?