Matlab中

时间:2017-01-24 10:10:28

标签: matlab ode

简介

我使用Matlab通过使用ODE45数值求解二阶常微分方程组来模拟一些动态系统。我从Mathworks(最后的教程链接)找到了一个很棒的教程,介绍了如何做到这一点。

在本教程中,方程组在x和y中是明确的,如下所示:

x''=-D(y) * x' * sqrt(x'^2 + y'^2)
y''=-D(y) * y' * sqrt(x'^2 + y'^2) + g(y)

上述两个等式都形成了y'' = f(x,x',y,y')

问题

然而,我遇到了方程组,其中变量无法明确求解,如示例所示。例如,其中一个系统具有以下3个二阶常微分方程组:

y双素数方程

y'' - .5*L*(x''*sin(x) + x'^2*cos(x) + (k/m)*y - g = 0

x双素数方程

.33*L^2*x'' - .5*L*y''sin(x) - .33*L^2*C*cos(x) + .5*g*L*sin(x) = 0

单个素数是一阶导数 双素数是二阶导数 给出L,g,m,k和C参数。

如何使用Matlab数值求解一组二阶常微分方程,其中二阶无法明确求解?

谢谢!

2 个答案:

答案 0 :(得分:1)

您的第二个系统的格式为

a11*x'' + a12*y'' = f1(x,y,x',y')
a21*x'' + a22*y'' = f2(x,y,x',y')

您可以将其解析为线性系统

[x'', y''] = A\f

或在这种情况下明确使用Cramer的规则

x'' = ( a22*f1 - a12*f2 ) / (a11*a22 - a12*a21)
相应地

y''

我强烈建议在代码中保留中间变量,以减少键入错误的机会,避免多次计算相同的表达式。

代码看起来像这样(未经测试)

function dz = odefunc(t,z)
    x=z(1); dx=z(2); y=z(3); dy=z(4);
    A = [  [-.5*L*sin(x),  1] ;  [.33*L^2,  -0.5*L*sin(x)]  ]
    b = [ [dx^2*cos(x) + (k/m)*y-g]; [-.33*L^2*C*cos(x) + .5*g*L*sin(x)] ]

    d2 = A\b

    dz = [ dx, d2(1), dy, d2(2) ]
end

答案 1 :(得分:0)

是的,你的方法是正确的! 我在下面发布以下代码:

count

这是ode45的函数句柄文件:

%Rotating Pendulum Sym Main
clc
clear all;

%Define parameters

global M K L g C;
M = 1;
K = 25.6;
L = 1;
C = 1;
g = 9.8;


% define initial values for theta, thetad, del, deld
e_0 = 1;
ed_0 = 0;
theta_0 = 0;
thetad_0 = .5;
initialValues = [e_0, ed_0, theta_0, thetad_0];

% Set a timespan
t_initial = 0;
t_final = 36;
dt = .01;
N = (t_final - t_initial)/dt;
timeSpan = linspace(t_final, t_initial, N);

% Run ode45 to get z (theta, thetad, del, deld)
[t, z] = ode45(@RotSpngHndl, timeSpan, initialValues);

%initialize variables
e = zeros(N,1);
ed = zeros(N,1);
theta = zeros(N,1);
thetad = zeros(N,1);
T = zeros(N,1);
V = zeros(N,1);
x = zeros(N,1);
y = zeros(N,1);

for i = 1:N
    e(i) = z(i, 1);
    ed(i) = z(i, 2);
    theta(i) = z(i, 3);
    thetad(i) = z(i, 4);
    T(i) = .5*M*(ed(i)^2 + (1/3)*L^2*C*sin(theta(i)) + (1/3)*L^2*thetad(i)^2 - L*ed(i)*thetad(i)*sin(theta(i)));
    V(i) = -M*g*(e(i) + .5*L*cos(theta(i)));
    E(i) = T(i) + V(i);
end

figure(1)
plot(t, T,'r');
hold on;
plot(t, V,'b');
plot(t,E,'y');
title('Energy');
xlabel('time(sec)');
legend('Kinetic Energy', 'Potential Energy', 'Total Energy');