我正在努力解决ode45

时间:2013-11-11 10:40:16

标签: matlab

我正在尝试用 ode45解决问题。

在ode45中,使用x'和x''。那么,我想从ode45开车到x的等式。

我尝试用polyfit函数解决。

polyfit(t,y,4)

但发生错误'X和Y向量必须大小相同。'

我不知道应该怎么做。

在我看来,它似乎能够用积分函数来解决。这是正确的??

如果您处理它,并告诉我如何解决,将非常感激。

以下代码:

我的代码是用主脚本和函数构建的。

clear
global L M m f Jw rw Fz Cd p A bw fw Nw g uw seta Te Tb y_curve X Q
L=[0 0.025 0.05 0.1 0.125 0.15 0.175 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1];
M=[0 0.225 0.45 0.65 0.685 0.705 0.69 0.68 0.65 0.635 0.63 0.6275 0.625 0.6225 0.62 0.6175 0.615 0.6125 0.610 0.6075 0.6050 0.6 0.5975 0.5950];

m = 1400;  f= 0.01;  Jw = 0.65; rw= 0.31; Fz = 3560; Cd = 0.5; p = 1.202; 
A = 1.95; bw = 0; fw = 0; Nw = 4; g = 9.81; uw = 0; seta = 0; Te = 0; Tb = 1000;
X=polyfit(L,M,20);
x_curve = 0:0.025:1;
y_curve = polyval(X,x_curve);
[t,i] = ode45('dot',[0:0.1:1],[20 20]);
Q = polyfit(t,i,4);
%subplot(1, 2, 1);
%plot(L,M,'p',x_curve,y_curve,'m');
xlabel('Lamda')
ylabel('mu'); grid;

%subplot(1, 2, 2);
plot(t,i); grid on;
xlabel('time(s)');
ylabel('x');

function xdot = dot(t,x)
global m f Jw rw Fz Cd p A Nw Te Tb g Y X 
%UNTITLED2 Summary of this function goes here
%Detailed explanation goes here
xdot = zeros(2,1);

lamda = (x(2)-x(1))/x(1);

Y=X(1,1)*(lamda)^20+X(1,2)*(lamda)^19+X(1,3)*(lamda)^18+X(1,4)*(lamda)^17+X(1,5)*(lamda)^16+X(1,6)*(lamda)^15+X(1,7)*(lamda)^14+X(1,8)*(lamda)^13+X(1,9)*(lamda)^12+X(1,10)*(lamda)^11+X(1,11)*(lamda)^10+X(1,12)*(lamda)^9+X(1,13)*(lamda)^8+X(1,14)*(lamda)^7+X(1,15)*(lamda)^6+X(1,16)*(lamda)^5+X(1,17)*(lamda)^4+X(1,18)*(lamda)^3+X(1,19)*(lamda)^2+X(1,20)*(lamda)^1+X(1,21);
xdot(1)=(-0.5*p*Cd*A*((x(1)*rw)^2)-f*m*g+(Nw*Y*Fz))/(rw*m); 
xdot(2)=(Te-Tb-rw*Y*Fz)/Jw;
end

1 个答案:

答案 0 :(得分:1)

相对简单:输出i宽2列(因为x中有两个元素),但t中只有1列。所以:

Q1 = polyfit(t,i(:,1), 4);
Q2 = polyfit(t,i(:,2), 4);

诀窍。

然而,我在多项式拟合中也遇到了条件问题。您可以使用scale / shift选项解决此问题,如help polyfit中所述。

在你的衍生物中某处还有一个奇点,因为最后的几个条目是由NaN无限制增长的值之一引起的xdot。因此,您获得NaNQ1的全部Q2

以下是实现此更改的代码版本,并展示了一些被广泛认为优于您当前风格的编程实践:

  • Don't. Use. Global. Variables.
  • 首选功能而不是脚本
  • 记录每个不同原子操作的意图(“命令块”)
  • 选择提供代码基本自我记录的变量名称
  • 不要过度使用括号。在必要的地方使用括号,或者在显着改善阅读时使用括号。
  • 数学运算符之间的间距。使识别术语和理解什么属于什么更容易 - 这是一个很好的错误来源。
  • 对齐代码。您只编写一次代码,但读取数百次 - 使 部分最简单。
  • 在MATLAB中:如果您发现自己正在进行重复的复制粘贴工作,或者一行代码超过85列标记,那么可能会有更短,更易读,更易理解,更易于维护的“矢量化”方式。

这可以在这里工作(R2010a):

function myFun

    %// Your data
    L = [0 0.025 0.05 0.1 0.125 0.15 0.175 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1];
    M = [0 0.225 0.45 0.65 0.685 0.705 0.69 0.68 0.65 0.635 0.63 0.6275 0.625 0.6225 0.62 0.6175 0.615 0.6125 0.610 0.6075 0.6050 0.6 0.5975 0.5950];

    %// Your coefficients
    A    = 1.95;     m  = 1400;  
    bw   = 0;        f  = 0.01;  
    fw   = 0;        Jw = 0.65; 
    Nw   = 4;        rw = 0.31; 
    g    = 9.81;     Fz = 3560; 
    uw   = 0;        Cd = 0.5; 
    seta = 0;        p  = 1.202;
    Te   = 0;        N  = 20;   %// (degree of polynomial)
    Tb   = 1000;

    %// Find best-fitting polynomial
    [X,~,mu] = polyfit(L,M,N);

    %// Or, if you like, a much faster alternative:
    %// X = bsxfun(@power, (L(:)-mean(L))/std(L), N:-1:0)\M(:);

    %// Plot the poly over the data 
    %// DEBUG -- put a space between the percent sign and brace below to include
    %{ 
    subplot(2,1,1), hold on
    x_curve = 0:0.025:1;
    y_curve = polyval(X,x_curve, [], mu);
    plot(L,M,'p',x_curve,y_curve,'m');
    xlabel('Lambda')
    ylabel('mu'); 
    grid on
    %}

    %// Carry out the integration
    tspan = [0 1];
    x0    = [20 20];
    [t,i] = ode45(@dxdt, tspan, x0);

    %// Fit a polynomal through the solutions
    Q1 = polyfit(t,i(:,1), 4);
    Q2 = polyfit(t,i(:,2), 4);

    %// Plot integration results        
    %// DEBUG -- put a space between the percent sign and brace below to include
    %{
    subplot(2,1,2), hold on
    plot(t,i); 
    grid on    
    xlabel('time(s)');
    ylabel('x');
    %}

    %// The time derivative
    function xdot = dxdt(~,x)

        %// Polynomial value for these X
        Y = ((x(2)-x(1))/x(1)).^(N:-1:0) * X.';  %'

        %// The derivative:
        xdot = [
            (-p/2*Cd*A*(x(1)*rw)^2 - f*m*g + Nw*Y*Fz)/rw/m
            (Te - Tb - rw*Y*Fz)/Jw
         ];

    end    

end

请注意%//%'只是为每个人制作SO工作代码格式。