我正在尝试使用 solve_ivp 求解 ODE 系统,并且每次求解器调用该函数时,我都想更改该函数的局部变量。 特别是我想更新拉格朗日乘数 (lambdas_i),以便 solve_ivp 的下一个时间步使用前一个的值。 (''reconstruct'' 函数来自一个 python 模块,它使用一种方法从给定时刻重建大小分布) 有没有办法做到这一点?我将在下面发布代码:
import time
import numpy as np
import scipy.integrate as integrate
from numpy import sqrt, sin, cos, pi
import math
import pylab as pp
from pymaxent import reconstruct
start = time.time()
'''Initialize variables'''
t=np.linspace(0, 60,31)
tspan=(0,60)
initial_m=[]
for i in range(4):
def distr(L,i=i):
return (L**i)*0.0399*np.exp(-((L-50)**2)/200)
m, err=integrate.quad(distr, 0, np.inf)
print('m(',i,')=',m)
initial_m.append(m)
''' Solving ode system using Maximum Entropy, G(L)=1+0.002*L'''
def moments(t,y):
m0 = y[0]
m1 = y[1]
m2 = y[2]
m3 = y[3]
Lmean=m1
σ=(m2-Lmean**2)**(1/2)
Lmin=Lmean-3*σ
Lmax=Lmean+4*σ
bnds=[Lmin,Lmax]
L=np.linspace(Lmin,Lmax)
sol, lambdas_i= reconstruct(mu=y ,bnds=bnds)
print(lambdas_i)
dm0dt=0
def moment1(L):
return(sol(L)+0.002*sol(L)*L)
dm1dt, err1=integrate.quad(moment1,Lmin,Lmax)
def moment2(L):
return(2*L*(sol(L)+0.002*sol(L)*L))
dm2dt, err2=integrate.quad(moment2,Lmin,Lmax)
def moment3(L):
return(3*L**2*(sol(L)+0.002*sol(L)*L))
dm3dt, err3=integrate.quad(moment3,Lmin,Lmax)
return(dm0dt,dm1dt,dm2dt,dm3dt)
'''Χρήση της BDF, step by step'''
r=integrate.solve_ivp(moments,tspan,initial_m,method='BDF',jac=None,t_eval=t,rtol=10**(-3))
end = time.time()
print('Total time =',{end-start})
答案 0 :(得分:0)
这是实现您想要的一种方法。我不会使用您的实际代码,而是使用更简单的示例问题,您可以使用相同的策略来解决您的问题。
def seq():
l = [1, 0]
while True:
p = l[1]
n = l[0] + p
l = [p, n]
print(n)
input()
上面是一个示例函数,它将打印斐波那契数列的下一项(或第一项)。 (其中每一项都是前两项的总和。)在这种情况下,input
仅用于在每次迭代之间暂停(因为它是无限的)。现在要将其转换为生成器,以提供更大的灵活性,您可以将函数重写为:
def seq():
l = [1, 0]
while True:
p = l[1]
n = l[0] + p
l = [p, n]
yield n
现在,如果您想获得相同的结果,您可以:
for item in seq():
print(item)
input()
然而,这基本上是无用的。当您想收集序列的下一个数字时,生成器的作用就出现了,但是在代码的任何一点。不一定在循环内重复直到你完成。你可以做到这一点:
gen = seq()
next(gen) # returns 1
next(gen) # returns 1
next(gen) # returns 2
next(gen) # returns 3
next(gen) # returns 5
等等...
解决这个问题的另一种方法是使用全局变量而不是局部变量。
l = [1, 0]
def seq():
p = l[1]
n = l[0] + p
l[0] = p
l[1] = n
return n
变量l
定义在函数外部,而不是内部,所以函数退出时不会被丢弃。 (以与之前相同的方式运行代码:)
while True:
print(seq())
input()
这两者都应该可以在您的代码中实现。