zoukankan      html  css  js  c++  java
  • matlab练习程序(非线性常微分方程组参数拟合)

    线性常微分方程组参数拟合类似,我们要用差分代替微分,然后进行插值处理,然后构造最小化函数。

    最后用最优化方法处理该函数即可。

    这里举个例子,先随便设一个非线性微分方程组,并给定初值:

     

    然后定义最小化函数:

    最后用之前介绍的非线性最优化方法解决。

    matlab代码如下:

    clear all;close all;clc;
    
    bsrc = rand(4,1);
    [t,h] = ode45(@(t,x)test1(t,x,bsrc),[0 100],[1 1]);
    plot(t,h(:,1),'r');
    hold on;
    plot(t,h(:,2),'r');
    
    hold on;
    t = t(1:3:2*end/3);
    x1 = h(1:3:2*end/3,1);
    x2 = h(1:3:2*end/3,2);
    plot(t,x1,'ro');
    plot(t,x2,'ro');
    
    T=min(t):0.1:max(t);        %插值处理,如果数据多,也可以不插值
    X1=spline(t,x1,T)';
    X2=spline(t,x2,T)';
    plot(T,X1,'b.');
    plot(T,X2,'b.');
    
    dX1 = diff(X1)*10; dX1=[dX1;dX1(end)];
    dX2 = diff(X2)*10; dX2=[dX2;dX2(end)];
    
    %BFGS求解
    syms k1 k2 k3 k4;
    ff = sum((dX1 - (k1*exp(1./X1)+k4*sin(X2))).^2+(dX2-(cos(X1)*k2+k3*(1./X2))).^2);
    dff1 = diff(ff,k1);dff2 = diff(ff,k2);
    dff3 = diff(ff,k3);dff4 = diff(ff,k4);
    
    f = inline(char(ff),'k1','k2','k3','k4');
    g1 = inline(char(dff1),'k1','k2','k3','k4');
    g2 = inline(char(dff2),'k1','k2','k3','k4');
    g3 = inline(char(dff3),'k1','k2','k3','k4');
    g4 = inline(char(dff4),'k1','k2','k3','k4');
    
    b = rand(4,1);
    rho=0.2;sigma=0.2;
    H=eye(4);
    
    re=[];
    for i=1:1000
        g=[g1(b(1),b(2),b(3),b(4));
            g2(b(1),b(2),b(3),b(4));
            g3(b(1),b(2),b(3),b(4));
            g4(b(1),b(2),b(3),b(4));];
        
        dk=-inv(H)*g;
        mk=1;
        
        for j=1:50
            new=f(b(1)+rho^j*dk(1),...
                b(2)+rho^j*dk(2),...
                b(3)+rho^j*dk(3),...
                b(4)+rho^j*dk(4));
            
            old=f(b(1),b(2),b(3),b(4));
            if new < old +sigma*rho^j*g'*dk
                mk=j;
                break;
            end
        end
        
        norm(g)
        if norm(g)<1e-30 || isnan(new)
            break;
        end
        
        b = b + rho^mk*dk;
        gg=[g1(b(1),b(2),b(3),b(4));
            g2(b(1),b(2),b(3),b(4));
            g3(b(1),b(2),b(3),b(4));
            g4(b(1),b(2),b(3),b(4));];
        
        q = gg - g;             %q = g(k+1)-g(k)
        p = rho^mk*dk;          %p = x(k+1)-x(k)
        H = H - (H*p*p'*H)/(p'*H*p) + (q*q')/(q'*p);    %矩阵更新
        
    end
    
    bsrc
    b
    
    [t,h] = ode45(@(t,x)test1(t,x,b),[0 100],[1 1]);
    plot(t,h(:,1),'g');
    hold on;
    plot(t,h(:,2),'g');

    test1.m:

    function dy=test1(t,x,A)
    a = A(1);       
    b = A(2);     
    c = A(3);
    d = A(4);
    dy=[a*exp(1/x(1))+d*sin(x(2));
       cos(x(1))*b+c/x(2)];

    结果如下:

    上面这个结果还算可以。

    不过由于是非线性微分方程组,参数差一点就可能导致系统后续差别越来越大,所谓混沌与蝴蝶效应。

    所以大多数拟合的结果类似下面或更糟:

    注:

      后来我又看了一下,其实这里还是属于线性系数的,因为a,b,c,d四个系数并没在非线性函数中。

      非线性系数我做了几次试验,效果不甚理想,后面有时间再写一篇。

  • 相关阅读:
    ssh-keygen的使用方法(无密码访问)
    ubuntu solute two different terminals cmd
    ubuntu 查看系统是32位还是64位
    pyplot 绘图与可视化
    python 正则表达式的处理
    python&pandas 与mysql 连接
    Ubuntu 11.10 H3C iNode 客户端安装
    Vijos1055(极大子矩阵)
    Vijos1055(极大子矩阵)
    luoguP2701 [USACO5.3]巨大的牛棚Big Barn(极大子矩阵)
  • 原文地址:https://www.cnblogs.com/tiandsp/p/14397573.html
Copyright © 2011-2022 走看看