Может ли scipy.integrate.odeint выводить внутренние вычисления

Мне нужно передать внутренние расчеты от звонка до 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.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
681
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Возможно, вы просто не можете использовать возвращаемые значения вашей функции 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. Это довольно хороший вариант использования.

Ах. Интересный. В этом случае я не рассматривал возможность использования глобальной переменной. Я обычно избегал глобальных переменных на других языках, и я предполагаю, что это все еще хорошая практика с python, но это тот случай, когда я кажусь чистым.

Chris 10.12.2018 15:51

Вы упомянули другие способы сделать это. Не могли бы вы перечислить пару мыслей о том, как лучше всего это сделать? Может быть, просто указание направления поможет мне придумать способ сделать это без глобальных переменных.

Chris 10.12.2018 15:53

На самом деле, теперь, когда я узнал немного больше и некоторые ключевые слова для того, что я пытаюсь сделать, кажется, что другие люди тоже нашли решения. Я собираюсь взглянуть на них еще раз, но если у кого-то еще есть такие же проблемы, они могут взглянуть и на них. ссылка на сайт, ссылка на сайт

Chris 10.12.2018 16:02

Я добавил еще один пример, который дает шаблон, который можно было бы использовать в более крупном проекте. Однако для простых коротких сценариев вам, вероятно, следует просто использовать global. Вы правы, что это довольно хороший вариант использования для одного.

tel 10.12.2018 16:13

Другие вопросы по теме