使用 Fipy 估计 PDEs 系统的参数
Estimating the parameters of a PDEs system using Fipy
我正在使用涉及两个参数或常量的 Fipy 求解 PDE 系统,所以我想知道是否也可以在 Fipy 中估计这些参数,或者其他哪些库更适合。
注意:我知道 scipy 有一些功能(optimize.minimize 用于 MLE),但我不确定是否足以将它们应用于 Fipy 代码。
更新:对于下面的 PDE 系统,我想估计两个未知参数:"Beta" 和 "m"
在 Fipy 中求解这个偏微分方程的函数是这样的:
import scipy as sci
import fipy as fipy
import numpy as np
from fipy import *
# Grid
nx = 100
ny = 100
dx = 1.
dy = dx
mesh = Grid2D(nx=nx, ny=ny, dx=dx, dy=dy)
x = mesh.cellCenters[0]
y = mesh.cellCenters[1]
# Setting variable of results and adding inicial conditions
u = CellVariable(name="Individual 1", mesh=mesh, value=0.)
u.setValue(1., where=(50. < x) & (70. > x) & (50. < y) & (70. > y))
v = CellVariable(name="Individual 2", mesh=mesh, value=0.)
v.setValue(1., where=(40. < x) & (60. > x) & (40. < y) & (60. > y))
p = CellVariable(name= "Marks Individual 1", mesh=mesh, value=0.)
p.setValue(1., where=(50. < x) & (70. > x) & (50. < y) & (70. > y))
q = CellVariable(name= "Marks Individual 2", mesh=mesh, value=0.)
q.setValue(1., where=(40. < x) & (60. > x) & (40. < y) & (60. > y))
# Plotting inicial conditions
if __name__ == '__main__':
viewer = Viewer(u, v, datamin=0., datamax=1.)
viewer.plot()
# Setting PDE
def HRMLE(params):
m = params[0]
beta = params[1]
D = 1.
CU = CellVariable(mesh=mesh, rank=1)
CU[:]= 1.
CU.setValue(-1., where = (x > 60.) * [[[1], [0]]])
CU.setValue(-1., where = (y > 60.) * [[[0], [1]]])
CV = CellVariable(mesh=mesh, rank=1)
CV[:]=1.
CV.setValue(-1., where = (x > 50.) * [[[1], [0]]])
CV.setValue(-1., where = (y > 50.) * [[[0], [1]]])
# Transient formulation
eqU = TransientTerm() == DiffusionTerm(coeff=D) -\
ConvectionTerm(coeff=CU*q.value*beta)
eqV = TransientTerm() == DiffusionTerm(coeff=D) -\
ConvectionTerm(coeff=CV*p.value*beta)
eqP = TransientTerm() == u*(1 + m*q) - p
eqQ = TransientTerm() == v*(1 + m*p) - q
# Solving Transient term
timeStepDuration = 1.
steps = 50
t = timeStepDuration * steps
for step in range(steps):
eqU.solve(var=u, dt=timeStepDuration)
eqV.solve(var=v, dt=timeStepDuration)
eqP.solve(var=p, dt=timeStepDuration)
eqQ.solve(var=q, dt=timeStepDuration)
# Plotting results
#if __name__ == '__main__':
# vieweru = Viewer(u, datamin=0., datamax=1.)
# viewerv = Viewer(v, datamin=0., datamax=1.)
# vieweru.plot()
# viewerv.plot()
loglink = np.sum(np.log(u.value)) + np.sum(np.log(v.value))
return(loglink)
最后,对于最大似然标准,我想最大化:
设置初始值,并使用scipy
mb = [0., .5]
mb
results = sci.optimize.minimize(HRMLE, mb, method='Nelder-Mead')
results
结果显示的值始终接近我的参数初始值,这就是我不确定我的程序是否正确的原因。任何建议将不胜感激。
好吧,我已经意识到要最大化函数,必须将函数的输出乘以 -1,然后将其最小化。所以我的函数的输出应该是:
loglink = np.sum(np.log(u.value)) + np.sum(np.log(v.value))*-1
return(loglink)
另一方面,实际上最大化只是针对网格中的点列表,而不是针对 u1 和 u2 的所有值。
我正在使用涉及两个参数或常量的 Fipy 求解 PDE 系统,所以我想知道是否也可以在 Fipy 中估计这些参数,或者其他哪些库更适合。
注意:我知道 scipy 有一些功能(optimize.minimize 用于 MLE),但我不确定是否足以将它们应用于 Fipy 代码。
更新:对于下面的 PDE 系统,我想估计两个未知参数:"Beta" 和 "m"
在 Fipy 中求解这个偏微分方程的函数是这样的:
import scipy as sci
import fipy as fipy
import numpy as np
from fipy import *
# Grid
nx = 100
ny = 100
dx = 1.
dy = dx
mesh = Grid2D(nx=nx, ny=ny, dx=dx, dy=dy)
x = mesh.cellCenters[0]
y = mesh.cellCenters[1]
# Setting variable of results and adding inicial conditions
u = CellVariable(name="Individual 1", mesh=mesh, value=0.)
u.setValue(1., where=(50. < x) & (70. > x) & (50. < y) & (70. > y))
v = CellVariable(name="Individual 2", mesh=mesh, value=0.)
v.setValue(1., where=(40. < x) & (60. > x) & (40. < y) & (60. > y))
p = CellVariable(name= "Marks Individual 1", mesh=mesh, value=0.)
p.setValue(1., where=(50. < x) & (70. > x) & (50. < y) & (70. > y))
q = CellVariable(name= "Marks Individual 2", mesh=mesh, value=0.)
q.setValue(1., where=(40. < x) & (60. > x) & (40. < y) & (60. > y))
# Plotting inicial conditions
if __name__ == '__main__':
viewer = Viewer(u, v, datamin=0., datamax=1.)
viewer.plot()
# Setting PDE
def HRMLE(params):
m = params[0]
beta = params[1]
D = 1.
CU = CellVariable(mesh=mesh, rank=1)
CU[:]= 1.
CU.setValue(-1., where = (x > 60.) * [[[1], [0]]])
CU.setValue(-1., where = (y > 60.) * [[[0], [1]]])
CV = CellVariable(mesh=mesh, rank=1)
CV[:]=1.
CV.setValue(-1., where = (x > 50.) * [[[1], [0]]])
CV.setValue(-1., where = (y > 50.) * [[[0], [1]]])
# Transient formulation
eqU = TransientTerm() == DiffusionTerm(coeff=D) -\
ConvectionTerm(coeff=CU*q.value*beta)
eqV = TransientTerm() == DiffusionTerm(coeff=D) -\
ConvectionTerm(coeff=CV*p.value*beta)
eqP = TransientTerm() == u*(1 + m*q) - p
eqQ = TransientTerm() == v*(1 + m*p) - q
# Solving Transient term
timeStepDuration = 1.
steps = 50
t = timeStepDuration * steps
for step in range(steps):
eqU.solve(var=u, dt=timeStepDuration)
eqV.solve(var=v, dt=timeStepDuration)
eqP.solve(var=p, dt=timeStepDuration)
eqQ.solve(var=q, dt=timeStepDuration)
# Plotting results
#if __name__ == '__main__':
# vieweru = Viewer(u, datamin=0., datamax=1.)
# viewerv = Viewer(v, datamin=0., datamax=1.)
# vieweru.plot()
# viewerv.plot()
loglink = np.sum(np.log(u.value)) + np.sum(np.log(v.value))
return(loglink)
最后,对于最大似然标准,我想最大化:
设置初始值,并使用scipy
mb = [0., .5]
mb
results = sci.optimize.minimize(HRMLE, mb, method='Nelder-Mead')
results
结果显示的值始终接近我的参数初始值,这就是我不确定我的程序是否正确的原因。任何建议将不胜感激。
好吧,我已经意识到要最大化函数,必须将函数的输出乘以 -1,然后将其最小化。所以我的函数的输出应该是:
loglink = np.sum(np.log(u.value)) + np.sum(np.log(v.value))*-1
return(loglink)
另一方面,实际上最大化只是针对网格中的点列表,而不是针对 u1 和 u2 的所有值。