如何监视SciPy.odeint的过程? [英] How to monitor the process of SciPy.odeint?

查看:49
本文介绍了如何监视SciPy.odeint的过程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

SciPy可以通过scipy.integrate.odeint或其他软件包来求解ode方程,但是在函数完全求解后才能给出结果.但是,如果ode函数非常复杂,则该程序将花费大量时间(一到两天)才能得出整个结果.那么,如何控制求解方程的步骤(当方程尚未完全求解时打印出结果)?

SciPy can solve ode equations by scipy.integrate.odeint or other packages, but it gives result after the function has been solved completely. However, if the ode function is very complex, the program will take a lot of time(one or two days) to give the whole result. So how can I mointor the step it solve the equations(print out result when the equation hasn't been solved completely)?

推荐答案

当我在寻找答案时,找不到满意的答案.因此,我使用 tqdm 项目.希望对您有帮助.

When I was googling for an answer, I couldn't find a satisfactory one. So I made a simple gist with a proof-of-concept solution using the tqdm project. Hope that helps you.

主持人请我解释上面链接中的情况.

Moderators asked me to give an explanation of what is going on in the link above.

首先,我正在使用scipy的OOP版本的 odeint ( solve_ivp ),但是您可以将其改回 odeint .假设您要从时间 T0 T1 进行积分,并且希望每0.1%的进度显示进度.您可以修改ode函数以使用两个额外的参数,一个 pbar (进度条)和一个 state (集成的当前状态).像这样:

First of all, I am using scipy's OOP version of odeint (solve_ivp) but you could adapt it back to odeint. Say you want to integrate from time T0 to T1 and you want to show progress for every 0.1% of progress. You can modify your ode function to take two extra parameters, a pbar (progress bar) and a state (current state of integration). Like so:

def fun(t, y, omega, pbar, state):
    # state is a list containing last updated time t:
    # state = [last_t, dt]
    # I used a list because its values can be carried between function
    # calls throughout the ODE integration
    last_t, dt = state
    
    # let's subdivide t_span into 1000 parts
    # call update(n) here where n = (t - last_t) / dt
    time.sleep(0.1)
    n = int((t - last_t)/dt)
    pbar.update(n)
    
    # we need this to take into account that n is a rounded number.
    state[0] = last_t + dt * n
    
    # YOUR CODE HERE
    dydt = 1j * y * omega
    return dydt

这是必需的,因为函数本身必须知道它的位置,但是scipy的 odeint 并没有真正为函数提供此上下文.然后,您可以将 fun 与以下代码集成:

This is necessary because the function itself must know where it is located, but scipy's odeint doesn't really give this context to the function. Then, you can integrate fun with the following code:

T0 = 0
T1 = 1
t_span = (T0, T1)
omega = 20
y0 = np.array([1], dtype=np.complex)
t_eval = np.arange(*t_span, 0.25/omega)

with tqdm(total=1000, unit="‰") as pbar:
    sol = solve_ivp(
        fun,
        t_span,
        y0,
        t_eval=t_eval,
        args=[omega, pbar, [T0, (T1-T0)/1000]],
    )

请注意, args 中的任何可变变量(如列表)都被实例化一次,并且可以在函数中进行更改.建议不要使用全局变量.

Note that anything mutable (like a list) in the args is instantiated once and can be changed from within the function. I recommend doing this rather than using a global variable.

这将显示如下所示的进度条:

This will show a progress bar that looks like this:

100%|█████████▉| 999/1000 [00:13<00:00, 71.69‰/s]

这篇关于如何监视SciPy.odeint的过程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆