在Matlab中的ode45中保存派生值 [英] Saving derivative values in ode45 in Matlab

查看:702
本文介绍了在Matlab中的ode45中保存派生值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在模拟具有质量弹簧和双摆的(有点奇怪)系统的运动方程,为此我有一个质量矩阵和函数f(x),并调用ode45进行求解

I'm simulating equations of motion for a (somewhat odd) system with mass-springs and double pendulum, for which I have a mass matrix and function f(x), and call ode45 to solve

M*x' = f(x,t);

我有5个状态变量,q = [QDot,phi,phiDot,r,rDot]'; (删除Q,因为没有任何依赖于它,QDot是当前的.) 现在,为了计算一些力,我还要保存rDotDot的计算值,该值由ode45为每个积分步骤计算,但是ode45并没有将其返回.我进行了一些搜索,但发现的唯一两个解决方案是 a)将其变成三阶问题,并将phiDotDot和rDotDot添加到状态向量.我想尽可能避免这种情况,因为它已经是非线性的了,这确实使事情变得更糟,并且浪费了计算时间.

I have 5 state variables, q= [ QDot, p phiDot, r, rDot]'; (removed Q because nothing depends on it, QDot is current.) Now, to calculate some forces, I would like to also save the calculated values of rDotDot, which ode45 calculates for each integration step, however ode45 doesn't give this back. I've searched around a bit, but the only two solutions I've found are to a) turn this into a 3rd order problem and add phiDotDot and rDotDot to the state vector. I would like to avoid this as much as possible, as it's already non-linear and this really makes matters a lot worse and blows up computation time.

b)扩展状态以直接计算函数,如此处.但是,在示例中,他说要在质量矩阵中添加零线.这是有道理的,因为否则它将积分导数,而不仅是在一点上求值,另一方面,它会使质量矩阵单数.似乎不适合我...

b) augment the state to directly calculate the function, as described here. However, in the example he says to make add a line of zeros in the mass matrix. It makes sense, since otherwise it will integrate the derivative and not just evaluate it at the one point, but on the other hand it makes the mass matrix singular. Doesn't seem to work for me...

这似乎是一件很基本的事情(想要状态向量的导数),有没有我明显没有想到的东西? (或者不太明显的事情也可以....)

This seems like such a basic thing (to want the derivative values of the state vector), is there something quite obvious that I'm not thinking of? (or something not so obvious would be ok too....)

哦,全局变量不是那么好,因为ode45在完善步长时多次调用f()函数,因此全局变量的大小和返回的状态向量q根本不匹配.

Oh, and global variables are not so great because ode45 calls the f() function several time while refining it's step, so the sizes of the global variable and the returned state vector q don't match at all.

万一有人需要它,这是代码:

In case someone needs it, here's the code:

%(Initialization of parameters are above this line)
   options = odeset('Mass',@massMatrix);
   [T,q] = ode45(@f, tspan,q0,options);

function dqdt = f(t,q,p)
    % q = [qDot phi phiDot r rDot]';

    dqdt = zeros(size(q));

    dqdt(1) = -R/L*q(1) - kb/L*q(3) +vs/L;
    dqdt(2) = q(3);
    dqdt(3) = kt*q(1) + mp*sin(q(2))*lp*g;
    dqdt(4) = q(5);
    dqdt(5) = mp*lp*cos(q(2))*q(3)^2 - ks*q(4) - (mb+mp)*g;
end

function M = massMatrix(~,q)
    M = [
        1 0 0 0 0;
        0 1 0 0 0;
        0 0 mp*lp^2 0 -mp*lp*sin(q(2));
        0 0 0 1 0;
        0 0 mp*lp*sin(q(2)) 0 (mb+mp)
        ];
end

推荐答案

最简单的解决方案是仅对ode45返回的每个值重新运行函数.

The easiest solution is to just re-run your function on each of the values returned by ode45.

最困难的解决方法是尝试将DotDots记录到其他地方(预先分配的矩阵,甚至是外部文件).问题是,如果ode45秘密地在怪异的地方进行评估,那么您可能最终会得到不需要的数据点.

The hard solution is to try to log your DotDots to some other place (a pre-allocated matrix or even an external file). The problem is that you might end up with unwanted data points if ode45 secretly does evaluations in weird places.

这篇关于在Matlab中的ode45中保存派生值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆