如何将时间相关变量包含在 Scilab 中的 ode-solver 中?

How to include time dependent variables into ode-solver in Scilab?

我目前正在求解非线性 ODE 系统。它是一组运动方程,我需要计算给定角度速度的位置角

我发现了如何使用列表添加依赖于时间的函数,但问题是如何添加同样依赖于时间但作为向量给出的参数。

简化就是写在下面的代码中。 c(t) 是一个时间函数。

function dx = f(t, x, c)

dx(1) = x(1)*sin(x(2))
dx(2) = c*x(2)*cos(x(1))
dx(3) = t*cos(x(3))
endfunction

c = 1:32; // values from measured signal, here simplyfied

y0 = [0.1;0.1;0.1];

t0 = 0;

t = 0:0.1:%pi;

y = ode(y0, t0, t, list (f, c));

关于如何将函数 table 转换为插值函数。


使用interpln线性插值

本质上,在右侧函数 dx=f(t,x,tc_arr) 中计算

function dx=f(t,x,tc_arr)
  c = interpln(tc_arr, t)
  dx(1) = x(1)*sin(x(2))
  dx(2) = c*x(2)*cos(x(1))
  dx(3) = t*cos(x(3))
endfunction

其中 tcarr 包含采样时间和采样值的数组。


测试信号示例

作为示例信号,取

t_sam = -1:0.5:4;
c_sam = sin(2*t_sam+1);

tc_arr = [ t_sam; c_sam ];

请注意,您始终需要采样时间来找出输入时间 t 与值数组的关系。

t = 1.23;
c = interpln(tc_arr, t)

returns c = - 0.2719243.


使用 interp1 一维插值(带样条)

你也可以使用其他函数,它在插值方法方面有更多选择。

function dx=f(t,x,t_sam,c_sam)
  c = interp1(t_sam, c_sam, t, "spline", "extrap")
  dx(1) = x(1)*sin(x(2))
  dx(2) = c*x(2)*cos(x(1))
  dx(3) = t*cos(x(3))
endfunction

对于比 LutzL 更通用的解决方案,您只需定义 c(t) 并从 de ODE 内部调用它:

function v = c(t)
    //definition of c(t)
    v = ...
endfunction

function dx = f(t, x, c)
    dx(1) = x(1)*sin(x(2))
    dx(2) = c(t)*x(2)*cos(x(1))
    dx(3) = t*cos(x(3))
endfunction

将所有想法放在一起给出了这个工作脚本:

function v = c(tc_arr,t)
    //definition of c(t)
    v = interpln(tc_arr,t)
endfunction

function dx = f(t, x, c, tc_arr)
    dx(1) = x(1)*sin(x(2))
    dx(2) = c(tc_arr, t)*x(2)*cos(x(1))
    dx(3) = t*cos(x(3))
endfunction

// measured signal (e.g. 10 samples here)
t_sam = linspace(0, %pi, 10)
c_sam = sin(2*t_sam+1)
tc_arr = [t_sam; c_sam]

y0 = [0.1;0.1;0.1];
t0 = 0;
t = 0:0.1:%pi;

y = ode(y0, t0, t, list(f, c, tc_arr));

plot(t,y)

如前所述,使用插值(此处为线性)允许在 t 的任意值处计算 c(t) 值,这是 ode 求解器所需要的。