我是Matlab编程的初学者,也是Runge-Kutta方法的初学者。
我尝试使用4阶Runge-Kutta方法为我的项目工作解决耦合ODE系统。
这是我的问题......
G = 1.4;
g = 1.4;
k = 0;
z = 0;
b = 0.166667;
syms n;
x2 = symfun(sym('x2(n)'),[n]);
x1 = symfun(sym('x1(n)'),[n]);
x3 = symfun(sym('x3(n)'),[n]);
x4 = symfun(sym('x4(n)'),[n]);
x5 = symfun(sym('x5(n)'),[n]);
k1 = [x2 * x1 *n *(1 - z * x2)*(x1 - n) - 2 * x3 * n *(1 - z * x2) - x4^2 * x2 *(1 - z * x2)- G *x3 *x2 ]./ [( G * x3 - (x1 - n)^2 * x2 *(1 - z * x2)) * n];
k2 = [x2 * (1 - z * x2)*(x1 * x2 * ( x1 - 2 *n)*( x1 - n) + 2* x3 * n + x4^2 * x2 ) ]./ [( G * x3 - (x1 - n)^2 * x2 *(1 - z * x2)) * n * (x1 - n)];
k3 = [x3 * x2 * (2 * n * x1 - n)^2 * ( 1 - z * x2) + G * x1 * (x1 - 2 *n)* (x1 - n) + x4^2 * G]./ [( G * x3 - (x1 - n)^2 * x2 *(1 - z * x2)) * n * (x1 - n)];
k4 = [x4 * ( x1 + n)] ./ [n * (x1- n)];
k5 = - [x5] ./ [n * (x1- n)];
f = @(n,x) [k1; k2; k3; k4; k5];
[n,xa] = ode45(f,[0 1],[1-b 1/b 1-b 0.01 0.02]);
错误
使用odearguments时出错(第93行)
@(N,X)[K1; K2; K3; K4; K5]返回长度为1的向量,但长度为
初始条件向量是5.返回的向量 @(N,X)[K1; K2; K3; K4; K5]和初始条件向量必须有
相同数量的元素。
ode45错误(第114行)
[neq,tspan,ntspan,next,t0,tfinal,tdir,y0,f0,odeArgs,
odeFcn,...
请指导我如何使用四阶Runge-Kutta方法解决上述问题...
答案 0 :(得分:1)
错误源于使用符号函数(与函数句柄混合)和数值解算器。
您需要为ode45
创建数字函数才能正常运行(我还将所有[
和]
替换为(
和)
进行分组):< / p>
G = 1.4;
g = 1.4;
k = 0;
z = 0;
b = 0.166667;
k1 = @(n,x) (x(2) * x(1)*n *(1 - z * x(2))*(x(1) - n) - 2 * x(3) * n *(1 - z * x(2)) - x(4)^2 * x(2) *(1 - z * x(2))- G *x(3) *x(2)) ./ (( G * x(3) - (x(1) - n)^2 * x(2) *(1 - z * x(2))) * n);
k2 = @(n,x) (x(2) * (1 - z * x(2))*(x(1) * x(2) * ( x(1) - 2 *n)*( x(1) - n) + 2* x(3) * n + x(4)^2 * x(2) )) ./ (( G * x(3) - (x(1) - n)^2 * x(2) *(1 - z * x(2))) * n * (x(1) - n));
k3 = @(n,x) (x(3) * x(2) * (2 * n * x(1) - n)^2 * ( 1 - z * x(2)) + G * x(1) * (x(1) - 2 *n)* (x(1) - n) + x(4)^2 * G)./ (( G * x(3) - (x(1) - n)^2 * x(2) *(1 - z * x(2))) * n * (x(1) - n));
k4 = @(n,x) (x(4) * (x(1) + n)) ./ (n * (x(1)- n));
k5 = @(n,x) - x(5) ./ (n * (x(1)- n));
f = @(n,x) [k1(n,x); k2(n,x); k3(n,x); k4(n,x); k5(n,x)];
[n,xa] = ode45(f,[0 1],[1-b 1/b 1-b 0.01 0.02]);
这适用于我安装的Matlab。
但是,由于函数生成NaNs
,因此输出全部为Infs
;我可能通过更换括号引入了错误,但我不知道实际的方程是什么,所以我将把它留给你。 :)
答案 1 :(得分:1)
一般情况下,请先咨询文档。如果不可用,请使用您选择的搜索引擎,例如https://www.google.de/search?q=matlab+ode45+example查找第一个结果https://de.mathworks.com/help/matlab/ref/ode45.html
在那里你找到了一个多维的例子
function dy = rigid(t,y)
dy = zeros(3,1); % a column vector
dy(1) = y(2) * y(3);
dy(2) = -y(1) * y(3);
dy(3) = -0.51 * y(1) * y(2);
end
options = odeset('RelTol',1e-4,'AbsTol',[1e-4 1e-4 1e-5]);
[T,Y] = ode45(@rigid,[0 12],[0 1 1],options);
plot(T,Y(:,1),'-',T,Y(:,2),'-.',T,Y(:,3),'.')
可以用作蓝图。在相关页面https://de.mathworks.com/help/matlab/math/ordinary-differential-equations.html中,他们使用与第一个示例中的van der Pol等式更接近的语法
function dydt = vdp1(t,y)
dydt = [y(2); (1-y(1)^2)*y(2)-y(1)];
end
[t,y] = ode45(@vdp1,[0 20],[2; 0]);
plot(t,y(:,1),'-',t,y(:,2),'--')
title('Solution of van der Pol Equation, \mu = 1');
xlabel('time t');
ylabel('solution y');
legend('y_1','y_2')
按照这些示例,将代码重写为
G = 1.4;
g = 1.4;
k = 0;
z = 0;
b = 0.166667;
function dotx = dxdn(n,x)
t1 = n*(x1-n)
t2 = x(2)*(1 - z * x(2))
den123 = ( G * x(3) - (x(1) - n)^2 * t2)
k1 = ( x(1)*t1*t2 - 2 * x(3) * n *(1 - z * x(2)) - x(4)^2 * t2- G *x(3) *x(2) ) / (den123*n);
k2 = ( t2*(x(1) * x(2) * ( x(1) - 2 *n)*( x(1) - n) + 2* x(3) * n + x(4)^2 * x(2) ) ) / (den123 * t1);
k3 = ( x(3) * (2 * n * x(1) - n)^2 * t2 + G * x(1) * (x(1) - 2 *n)* (x(1) - n) + x(4)^2 * G ) / (den123*t1);
k4 = ( x(4) * ( x(1) + n) ) / t1;
k5 = - x(5) / t1;
dotx = [k1; k2; k3; k4; k5];
end
[n,xa] = ode45(@dxdn,[0.001 1],[1-b; 1/b; 1-b; 0.01; 0.02]);
由于在n=0
处除以零,你无法在该奇点中开始迭代。在上面的代码中,通过从一些(非常)小的正n
开始来缓解这种情况,您也可以尝试从n=1e-8
开始或更小。所有组件的斜率都非常大,因此积分可能很慢,结果可能不会过于精确接近零。要在math.stackexchange论坛中正确处理单数ODE,请