Я пытаюсь реализовать метод Рунге-Кутты порядка 4. Я получаю ошибку типа: «невозможно умножить последовательность на не-целое типа« numpy.float64 »в расчетах k1, k2, k3, k4. Кто-нибудь знает обходной путь?
def rk4(f, Y0, t0, tf, n):
t = np.linspace(t0, tf, n+1)
Y = np.array([Y0]*(n+1))
h = t[1]-t[0]
for i in range(n):
k1 = h * f(Y[i], t[i])
k2 = h * f(Y[i]+0.5*k1, t[i]+0.5*h)
k3 = h * f(Y[i]+0.5*k2, t[i]+0.5*h)
k4 = h * f(Y[i]+k3, t[i]+h)
Y[i+1] = Y[i] + (k1+2*(k2+k3)+k4)/6.0
return Y, t
В настоящее время я использую Python 3.8.
Вы не возвращаете пустой массив из своей функции f
. Список может быть «умножен» только на целое число и производит повторения копий списка, а не то, что вы ожидаете от векторного умножения.
Вы можете решить это непосредственно в этой функции, обернув возвращаемые значения в массив numpy или предоставив оболочку
def rk4(f, Y0, t0, tf, n):
func = lambda Y,t: np.array(f(Y,t))
...
for i in range(n):
k1 = h * func(Y[i], t[i])
...
ваше предложение отлично работает, я нашел альтернативное решение, просто переведя возвращаемое значение моей функции f в массив с помощью функции numpy numpy.asarray()
Да, это то, что я имел в виду под «непосредственно в этой функции».
Возможно, как общий вопрос для этих реализаций числового интегратора. Я реализовал две разные версии, одна из которых выполняет полную интеграцию для всех необходимых мне временных шагов, а другая — только один временной шаг. И затем я использую этот временной шаг позже, чтобы вычислить мое численное решение с новым циклом. Мне было интересно, следует ли предпочесть тот или другой, или даже имеет значение, в каком порядке я выполняю шаги?
Я сделал более длинный поток мыслей в stackoverflow.com/questions/64866887, но, по сути, вы должны добиться повторного использования векторов наклона k1,... каким-то образом. Существуют способы для обеих стратегий, использование степперного класса обычно более гибкое. В целом, в python это непросто, вам придется исследовать каждый шаг, если массив данных перезаписывается или изменяется на вновь выделенный массив. Есть способы всегда использовать один и тот же массив для возвращаемого значения в функции ODE, что может привести к другим новым проблемам с псевдонимами,...
Какой язык программирования вы используете?