如何在DiscreteCallback中读取指定时间对应的值?
How to read corresponding value at specified time in DiscreteCallback?
类似于, I am trying to solve this ODE with a time-dependent input parameter. It consists of a series of discrete callbacks。在某些时候,参数会发生变化(不是状态!)。时间和值存储在 nx2 Array
中。但是我无法获取affect
函数在指定时间找到对应的参数值。在给定的示例中,分配给 u[1]
的值通常是常量。考虑这个 MWE(使用非常类似于 Matlab 的方法),它在没有 回调的情况下正常工作 :
using DifferentialEquations
using Plots
function odm2prod(dx, x, params, t)
k_1, f_1, V_liq, X_in, Y_in, q_in = params
rho_1 = k_1*x[1]
q_prod = 0.52*f_1*x[1]
# Differential Equations
dx[1] = q_in/V_liq*(X_in - x[1]) - rho_1
dx[2] = q_in/V_liq*(Y_in - x[2])
end
x0 = [3.15, 1.5]
tspan = (0.0, 7.0)
params = [0.22, 43, 155, 249, 58, 0]
prob = ODEProblem(odm2prod, x0, tspan, params)
input = [1.0 60; 1.1 0; 2.0 60; 2.3 0; 4.0 430; 4.05 0]
dosetimes = input[:,1]
function affect!(integrator)
ind_t = findall(integrator.t == dosetimes)
integrator.p[6] = input[ind_t, 2]
end
cb = PresetTimeCallback(dosetimes, affect!)
sol = solve(prob, Tsit5(), callback=cb, saveat=1/12)
plot(sol, vars=[1, 2])
它不起作用。错误起源于第 22 行,因为在 Julia 中似乎没有定义将向量与标量进行比较,或者有一种我不知道的特殊语法。
我知道可以使用 time-dependent parameters in Julia,但我想这只适用于连续函数,而不适用于离散变化!?我已经查看了 interpolate
的帮助,但我不确定如何针对我的具体情况使用它。
有人可以告诉我如何让它工作吗?应该只需要几行代码。另外,我不一定希望 dosetimes
作为 sol.t
的一部分,除非它们重合。
您使用的 findall
错误,文档说
findall(f::Function, A)
Return a vector I
of the indices or keys of A
where f(A[I])
returns true
.
那么您必须考虑到搜索“all”的结果是一个列表。正如您所期望的那样,它只有一个元素,只使用第一个元素
function affect!(integrator)
ind_t = findall(t -> t==integrator.t, dosetimes)
integrator.p[6] = input[ind_t[1], 2]
end
然后你就明白了情节
类似于nx2 Array
中。但是我无法获取affect
函数在指定时间找到对应的参数值。在给定的示例中,分配给 u[1]
的值通常是常量。考虑这个 MWE(使用非常类似于 Matlab 的方法),它在没有 回调的情况下正常工作 :
using DifferentialEquations
using Plots
function odm2prod(dx, x, params, t)
k_1, f_1, V_liq, X_in, Y_in, q_in = params
rho_1 = k_1*x[1]
q_prod = 0.52*f_1*x[1]
# Differential Equations
dx[1] = q_in/V_liq*(X_in - x[1]) - rho_1
dx[2] = q_in/V_liq*(Y_in - x[2])
end
x0 = [3.15, 1.5]
tspan = (0.0, 7.0)
params = [0.22, 43, 155, 249, 58, 0]
prob = ODEProblem(odm2prod, x0, tspan, params)
input = [1.0 60; 1.1 0; 2.0 60; 2.3 0; 4.0 430; 4.05 0]
dosetimes = input[:,1]
function affect!(integrator)
ind_t = findall(integrator.t == dosetimes)
integrator.p[6] = input[ind_t, 2]
end
cb = PresetTimeCallback(dosetimes, affect!)
sol = solve(prob, Tsit5(), callback=cb, saveat=1/12)
plot(sol, vars=[1, 2])
它不起作用。错误起源于第 22 行,因为在 Julia 中似乎没有定义将向量与标量进行比较,或者有一种我不知道的特殊语法。
我知道可以使用 time-dependent parameters in Julia,但我想这只适用于连续函数,而不适用于离散变化!?我已经查看了 interpolate
的帮助,但我不确定如何针对我的具体情况使用它。
有人可以告诉我如何让它工作吗?应该只需要几行代码。另外,我不一定希望 dosetimes
作为 sol.t
的一部分,除非它们重合。
您使用的 findall
错误,文档说
findall(f::Function, A)
Return a vector
I
of the indices or keys ofA
wheref(A[I])
returnstrue
.
那么您必须考虑到搜索“all”的结果是一个列表。正如您所期望的那样,它只有一个元素,只使用第一个元素
function affect!(integrator)
ind_t = findall(t -> t==integrator.t, dosetimes)
integrator.p[6] = input[ind_t[1], 2]
end
然后你就明白了情节