关于ode:如何解决Matlab中耦合系统的初始条件

How to address initial conditions for coupled system in Matlab

我们有一个每个10 ode的耦合系统。耦合出现在最后一个方程式中。

我考虑过使用10 2的矩阵作为初始条件,我在这里也跟随了一个类似的问题,标题相同,但仍然遇到相同的错误(\\'输入参数过多。')

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
time = [0 5];
x1_0 = [0 0 0 0 0 0 0 0 0 0];
x2_0 = [0 0 0 0 0 0 0 0 0 0];
initial = [x1_0;x2_0];
x = NaN(length(initial),2*length(time));

[t,x] = ode45(@ode,time,initial);


function [dxdt] = ode(x)

N = 2;

dxdt = NaN(10,2);

for i = 1:N
    dxdt(1,i) = x(6,i);
    dxdt(6,i) = (x(3,i)-x(4,i)+x(5,i)) - x(6,i) - x(1,i);
    dxdt(2,i) = x(7,i);
    dxdt(7,i) = (x(3,i)-x(4,i)+x(5,i)) - x(7,i) - x(2,i);
    dxdt(3,i) = x(8,i);
    dxdt(8,i) = (x(1,i)) - x(8,i) - x(3,i);
    dxdt(4,i) = x(9,i);
    dxdt(9,i) = (x(2,i)) - x(9,i) - x(4,i);
    dxdt(5,i) = x(10,i);
    if i == 1
        j = 2;
    elseif i == 2
        j = 1 ;
    end
    dxdt(10,i) = (x(3,j)-x(4,j)+x(5,j)) - x(10,i) - x(5,i);

end
end

如果我的错误是使用矩阵初始条件而不是向量,则使用1乘20的向量,并相应地调整ode的形式,这是不切实际的,我认为
-解决初始条件的另一种更有效的方法是
-我提供的输入中什么是不必要的,为什么?
-还有其他计算方法来表示耦合吗?

编辑:如果我使用以下选项:" function dxdt = ode(t,x)",则错误如下:

1
2
3
4
5
6
7
8
9
10
11
12
Error in Test11>ode (line 33)
dxdt(10,i) = (x(3,j)-x(4,j)+x(5,j)) - x(10,i) - x(5,i);

Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:});   % ODE15I sets args{1} to yp0.

Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options,
varargin);

Error in Test11 (line 9)
[t,x] = ode45(@ode,time,initial);

如果更改调用函数的方式,则:
" [t,x] = ode45(@(t,x)ode(x),时间,初始); "
结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Not enough input arguments.

Error in Test11>ode (line 19)
dxdt(1,i) = x(6,i);

Error in Test11>@(t,x)ode(x)

Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:});   % ODE15I sets args{1} to yp0.

Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options,
varargin);

Error in Test11 (line 9)
[t,x] = ode45(@(t,x)ode(x), time, initial);

错误'Too many input arguments.'是由以下事实引起的:您的ode函数仅接受一个变量x,而ode45向其传递了两个变量,即时间实例t和状态x。即使您的ode方程与当前时间无关,您也需要处理此输入参数。

要么让您的ode函数接受两个输入参数:

1
2
function dxdt = ode(t,x)
% etc

或者更改调用ode函数的方式:

1
[t,x] = ode45(@(t,x)ode(x), time, initial);

此外,我不认为ode45可以处理"状态矩阵",因此我确实将垂直于一个大状态向量的两个状态向量串联起来。如果您不想重写代码,请在循环之前和之后添加一些调整形状:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function [dxdt] = ode(xv)
    N = 2;
    dxdt = NaN(10,2);

    % reshape to two column vectors
    x = reshape(xv,[],2); % xv is one large column vector

    for ki = 1:N
        dxdt(1,ki) = x(6,ki);
        dxdt(6,ki) = (x(3,ki)-x(4,ki)+x(5,ki)) - x(6,ki) - x(1,ki);
        dxdt(2,ki) = x(7,ki);
        dxdt(7,ki) = (x(3,ki)-x(4,ki)+x(5,ki)) - x(7,ki) - x(2,ki);
        dxdt(3,ki) = x(8,ki);
        dxdt(8,ki) = (x(1,ki)) - x(8,ki) - x(3,ki);
        dxdt(4,ki) = x(9,ki);
        dxdt(9,ki) = (x(2,ki)) - x(9,ki) - x(4,ki);
        dxdt(5,ki) = x(10,ki);
        if ki == 1
            kj = 2;
        elseif ki == 2
            kj = 1;
        end
        dxdt(10,ki) = (x(3,kj)-x(4,kj)+x(5,kj)) - x(10,ki) - x(5,ki);
    end

    % reshape dxdt to one column vector
    dxdt = reshape(dxdt,[],1);

end