Julia 如何在DiscreteCallback中读取指定时间对应的值?

Julia 如何在DiscreteCallback中读取指定时间对应的值?,julia,differential-equations,differentialequations.jl,Julia,Differential Equations,Differentialequations.jl,与之类似,我试图用一个与时间相关的输入参数来求解此ODE。它由一系列的步骤组成。在某些时候,参数会发生更改(而不是状态!)。时间和值存储在nx2数组中。但是我无法使用impact函数在指定的时间找到相应的参数值。在给定的示例中,分配给u[1]的值通常是常量。考虑这个MWE(用一个非常类似Matlab的方法),它正确地工作,没有回调: using DifferentialEquations using Plots function odm2prod(dx, x, params, t) k

与之类似,我试图用一个与时间相关的输入参数来求解此ODE。它由一系列的步骤组成。在某些时候,参数会发生更改(而不是状态!)。时间和值存储在
nx2数组中。但是我无法使用
impact
函数在指定的时间找到相应的参数值。在给定的示例中,分配给
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中似乎没有定义将向量与标量进行比较,或者有一种我不知道的特殊语法

我知道这是可以使用的,但我想这只适用于连续函数,而不是离散变化!?我还没有看过
插值的帮助,但我不知道如何在我的具体案例中使用它


有人能告诉我怎么让它工作吗?可能只需要几行代码。此外,我不一定要将
dosetimes
作为
sol.t
的一部分,除非它们一致。

文档中说,您使用的
findall
是错误的

findall(f::Function,A)

返回
a的索引或键的向量
I
,其中
f(a[I])
返回
true

然后,您必须考虑搜索“全部”的结果是一个列表。因为您希望它只有一个元素,所以只使用第一个元素

功能影响!(积分器)
ind\u t=findall(t->t==integrator.t,dosetimes)
积分器.p[6]=输入[ind_t[1],2]
结束
你知道情节了吗


实际上,我想用Julia的
findall
模拟Matlab的
ismember
函数。但是,我应该把论点放在相反的地方。。。无论如何,你的解决方案是有效的。另一种选择是使用Interpolations.jl,但是
先前的
插值的必要选项是。即使第一次
PresetTimeCallback
发生在初始时间点,例如
tspan[1]
时,我也惊讶地看到这项工作。我正在处理一个问题,
PresetTimeCallback
修改状态而不是参数。在这种情况下,回调不会在初始时间点触发。你知道这会有什么不同吗?不管怎样,如果它对某人有帮助:在第二种情况下,
影响修改一个状态,例如
integrator.u[1]+=input[ind_t[1],2]
一个解决方案可以包括两个步骤:a)使用
PresetTimeCallback(dosetimes,affect!,initialize=(c,u,t,integrator)->affect!(integrator))
(如中所述)。和b)修改
影响
检查
if(integrator.t in dosetimes)
,否则
findall
可能会抛出错误。您好@fabern,有一段时间没有在这里查看。我在编写《朱莉娅》中的第一步,看看是否可以永久地改变。但是这个跳跃特性是我所做的建模中的一个基本方面,所以我需要一个真正的解决方案。这似乎是一个有趣的选择,因为他们的
DosageRegimen
与我使用的提要非常相似。我最终会试一试的。