Мне нужно передать внутренние расчеты от звонка до odeint. Обычно я снова пересчитываю значения после завершения интеграции, но я бы предпочел выполнять все вычисления в вызываемой функции для odeint.
Мои задачи не требуют больших вычислительных ресурсов, поэтому допустимо небольшое дополнительное снижение производительности при выполнении вычислений внутри решателя од.
from scipy.integrate import odeint
import numpy as np
def eom(y, t):
internal_calc = y/(t+1)
xdot = y
return xdot, internal_calc
if __name__ == '__main__':
t = np.linspace(0, 5, 100)
y0 = 1.0 # the initial condition
output, internal_calc = odeint(eom, y0, t)
Этот код не запускается, но, надеюсь, показывает, что мне нужно. Я хочу получить значение «internal_calc» из функции eom для каждого прохода через интегратор.
Я поискал варианты, но один из лучших программистов на Python, которых я знаю, посоветовал мне написать собственный интегратор, чтобы я мог делать то, что хочу.
Прежде чем я это сделал, я подумал, что спрошу, есть ли у кого-нибудь еще метод получения значений из решателя odeint.






Возможно, вы просто не можете использовать возвращаемые значения вашей функции eom. Значит, вам нужен другой способ перебросить данные из eom. Есть много-много разных способов сделать это. Самый простой, вероятно, просто использовать глобальную переменную:
import scipy.integrate as spi
count = 0
def pend(t, y):
global count
theta, omega = y
dydt = [omega, -.25*omega - 5*np.sin(theta)]
count += 1
return dydt
sol = spi.solve_ivp(pend, [0, 10], [np.pi - 0.1, 0.0])
print(count)
Вывод:
182
Также обратите внимание, что в приведенном выше коде я использовал solve_ivp вместо odeint. odeint документы говорит, что при написании нового кода вы должны теперь использовать solve_ivp вместо старого odeint.
Если бы это был мой собственный код, я бы, вероятно, выполнил задачу, передав объект аккумулятора в частичную версию моей функции:
class Acc:
def __init__(self):
self.x = 0
def __str__(self):
return str(self.x)
def pend_partial(acc):
def pend(t, y):
theta, omega = y
dydt = [omega, -.25*omega - 5*np.sin(theta)]
acc.x += 1
return dydt
return pend
count = Acc()
sol = spi.solve_ivp(pend_partial(count), [0, 10], [np.pi - 0.1, 0.0])
print(count)
Вывод:
182
Однако, если вы просто пишете короткий сценарий или что-то в этом роде, вам, вероятно, следует просто использовать более простой подход global. Это довольно хороший вариант использования.
Вы упомянули другие способы сделать это. Не могли бы вы перечислить пару мыслей о том, как лучше всего это сделать? Может быть, просто указание направления поможет мне придумать способ сделать это без глобальных переменных.
На самом деле, теперь, когда я узнал немного больше и некоторые ключевые слова для того, что я пытаюсь сделать, кажется, что другие люди тоже нашли решения. Я собираюсь взглянуть на них еще раз, но если у кого-то еще есть такие же проблемы, они могут взглянуть и на них. ссылка на сайт, ссылка на сайт
Я добавил еще один пример, который дает шаблон, который можно было бы использовать в более крупном проекте. Однако для простых коротких сценариев вам, вероятно, следует просто использовать global. Вы правы, что это довольно хороший вариант использования для одного.
Ах. Интересный. В этом случае я не рассматривал возможность использования глобальной переменной. Я обычно избегал глобальных переменных на других языках, и я предполагаю, что это все еще хорошая практика с python, но это тот случай, когда я кажусь чистым.