julia微分方程多数据集的参数估计

julia微分方程多数据集的参数估计,julia,mathematical-optimization,least-squares,differentialequations.jl,Julia,Mathematical Optimization,Least Squares,Differentialequations.jl,我一直在寻找,但我找不到一种直接的方法来使用julia中的微分方程参数估计来拟合多个数据集。假设我们有一个带两个参数的简单微分方程: f1 = function (du,u,p,t) du[1] = - p[1]*p[2] * u[1] end 我们有u[1]与t的实验数据集。每个数据集具有不同的p[2]值和/或不同的初始条件。p[1]是我们要估计的参数。 我可以通过求解for循环中的微分方程来实现这一点,该循环迭代不同的初始条件和p[2]值,将解存储在数组中,并根据实验数据创建损失函数。

我一直在寻找,但我找不到一种直接的方法来使用julia中的微分方程参数估计来拟合多个数据集。假设我们有一个带两个参数的简单微分方程:

f1 = function (du,u,p,t)
  du[1] = - p[1]*p[2] * u[1]
end
我们有u[1]与t的实验数据集。每个数据集具有不同的p[2]值和/或不同的初始条件。p[1]是我们要估计的参数。 我可以通过求解for循环中的微分方程来实现这一点,该循环迭代不同的初始条件和p[2]值,将解存储在数组中,并根据实验数据创建损失函数。我想知道是否有一种方法可以减少代码行数,例如使用
DiffEqBase.problem\u new\u parameters
来设置每个数据集的条件。在将模型与实验数据进行拟合时,这是一种非常常见的情况,但我在文档中找不到一个好的示例

提前谢谢大家,

致意

编辑1 上述案例只是一个简化的例子。为了使其成为一个实际案例,我们可以从以下代码中创建一些虚假的实验数据:

using DifferentialEquations

# ODE function
f1 = function (du,u,p,t)
  du[1] = - p[1]*p[2] * u[1]
end

# Initial conditions and parameter values.
# p1 is the parameter to be estimated.
# p2 and u0 are experimental parameters known for each dataset.
u0 = [1.,2.]
p1 = .3
p2 = [.1,.2]
tspan = (0.,10.)
t=linspace(0,10,5)


# Creating data for 1st experimental dataset.
## Experimental conditions: u0 = 1. ; p[2] = .1
prob1 = ODEProblem(f1,[u0[1]],tspan,[p1,p2[1]])
sol1=solve(prob1,Tsit5(),saveat=t)

# Creating data for 2nd experimental dataset.
## Experimental conditions: u0 = 1. ; p[2] = .2
prob2 = ODEProblem(f1,[u0[1]],tspan,[p1,p2[2]])
sol2=solve(prob2,Tsit5(),saveat=t)

# Creating data for 3rd experimental dataset.
## Experimental conditions: u0 = 2. ; p[2] = .1
prob3 = ODEProblem(f1,[u0[2]],tspan,[p1,p2[1]])
sol3=solve(prob3,Tsit5(),saveat=t)
sol1、sol2和sol3现在是我们的实验数据,每个数据集使用不同的初始条件和p[2]组合(表示一些实验变量(例如,温度、流量…)


目标是使用实验数据sol1、sol2和sol3估算p[1]的值,让
不同的Qbase。问题\u新参数
或另一种替代方法在实验条件下迭代。

您可以做的是创建一个Montecarlo问题,同时解决所有三个问题:

function prob_func(prob,i,repeat)
  i < 3 ? u0 = [1.0] : u0 = [2.0]
  i == 2 ? p = (prob.p[1],0.2) : p = (prob.p[1],0.1)
  ODEProblem{true}(f1,u0,(0.0,10.0),p)
end
prob = MonteCarloProblem(prob1,prob_func = prob_func)

@time sol = solve(prob,Tsit5(),saveat=t,parallel_type = :none,
                  num_monte = 3)
最后,您需要告诉它如何将优化参数与其解决的问题关联起来。在这里,我们的Montecarlo问题包含一个
prob
,每当它产生问题时,它都会从中提取
p[1]
。我们要优化的值是
p[1]
,因此:

function my_problem_new_parameters(prob,p)
  prob.prob.p[1] = p[1]
  prob
end
现在,我们的目标正是将这些部分结合在一起:

obj = build_loss_objective(prob,Tsit5(),loss,
                           prob_generator = my_problem_new_parameters,
                           num_monte = 3,
                           saveat = t)
现在,让我们将其应用于Optim.jl的Brent方法:

using Optim
res = optimize(obj,0.0,1.0)

Results of Optimization Algorithm
 * Algorithm: Brent's Method
 * Search Interval: [0.000000, 1.000000]
 * Minimizer: 3.000000e-01
 * Minimum: 2.004680e-20
 * Iterations: 10
 * Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): true
 * Objective Function Calls: 11

您可以创建一个MonteCarloProblem,同时解决所有三个问题:

function prob_func(prob,i,repeat)
  i < 3 ? u0 = [1.0] : u0 = [2.0]
  i == 2 ? p = (prob.p[1],0.2) : p = (prob.p[1],0.1)
  ODEProblem{true}(f1,u0,(0.0,10.0),p)
end
prob = MonteCarloProblem(prob1,prob_func = prob_func)

@time sol = solve(prob,Tsit5(),saveat=t,parallel_type = :none,
                  num_monte = 3)
最后,您需要告诉它如何将优化参数与其解决的问题关联起来。在这里,我们的Montecarlo问题包含一个
prob
,每当它产生问题时,它都会从中提取
p[1]
。我们要优化的值是
p[1]
,因此:

function my_problem_new_parameters(prob,p)
  prob.prob.p[1] = p[1]
  prob
end
现在,我们的目标正是将这些部分结合在一起:

obj = build_loss_objective(prob,Tsit5(),loss,
                           prob_generator = my_problem_new_parameters,
                           num_monte = 3,
                           saveat = t)
现在,让我们将其应用于Optim.jl的Brent方法:

using Optim
res = optimize(obj,0.0,1.0)

Results of Optimization Algorithm
 * Algorithm: Brent's Method
 * Search Interval: [0.000000, 1.000000]
 * Minimizer: 3.000000e-01
 * Minimum: 2.004680e-20
 * Iterations: 10
 * Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): true
 * Objective Function Calls: 11

分享一些示例数据集分享一些示例数据集谢谢,这是我一直在寻找的!回到这个问题,我有一个好奇心要补充。我一直在测试,当目标函数是montecarlo问题时,在目标函数中使用saveat是必要的,但它不是用于常规ODE问题,我想它是插值sol(t[I])。当尝试在不使用saveat的情况下优化Montecarlo问题时,该问题会收敛到错误的解决方案。至少有两个选项中的一个是有用的:1.为每个Montecarlo迭代指定saveat(因为不同的数据集可能有不同的时间点)2.在sol[i](t[j]中使用插值)我们可能可以在库端处理这个问题。请打开一个问题。谢谢,这就是我要找的!回到这个问题,我有一个好奇心要补充。我一直在测试,在目标函数中使用saveat在montecarlo问题时是必要的,但它不是用于常规ODE问题,我想它是插值sol(t[i])。当尝试在不使用saveat的情况下优化Montecarlo问题时,问题会收敛到错误的解决方案。至少有两个选项中的一个是有用的:1.为每个Montecarlo迭代指定saveat(因为不同的数据集可能有不同的时间点)2.在sol[i](t[j]中使用插值)我们可能可以在图书馆方面处理这个问题。请打开一个问题。