精华内容
下载资源
问答
  • 非线性拟合使用Matlab进行拟合是图像处理中线条变换的一个重点内容,本文将详解Matlab中的直线拟合和曲线拟合用法。关键函数:fittypeFit type for curve and surface fittingSyntaxffun = fittype(libname)ffun = ...

    Matlab 线性拟合 & 非线性拟合

    使用Matlab进行拟合是图像处理中线条变换的一个重点内容,本文将详解Matlab中的直线拟合和曲线拟合用法。

    关键函数:

    fittype

    Fit type for curve and surface fitting

    Syntax

    ffun = fittype(libname)

    ffun = fittype(expr)

    ffun = fittype({expr1,…,exprn})

    ffun = fittype(expr, Name, Value,…)

    ffun= fittype({expr1,…,exprn}, Name, Value,…)

    /***********************************线性拟合***********************************/

    线性拟合公式:

    coeff1 * term1 + coeff2 * term2 + coeff3 * term3 + ...

    其中,coefficient是系数,term都是x的一次项。

    线性拟合Example:

    Example1: y=kx+b;

    法1:

    x=[1,1.5,2,2.5,3];y=[0.9,1.7,2.2,2.6,3];

    p=polyfit(x,y,1);

    x1=linspace(min(x),max(x));

    y1=polyval(p,x1);

    plot(x,y,‘*’,x1,y1);

    结果:p =    1.0200    0.0400

    即y=1.0200 *x+ 0.0400

    法2:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];

    p=fittype(‘poly1’)

    f=fit(x,y,p)

    plot(f,x,y);

    运行结果:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];

    p=fittype(‘poly1’)

    f=fit(x,y,p)

    plot(f,x,y);

    p =

    Linear model Poly1:

    p(p1,p2,x) = p1*x + p2

    f =

    Linear model Poly1:

    f(x) = p1*x + p2

    Coefficients (with 95% confidence bounds):

    p1 =        1.02  (0.7192, 1.321)

    p2 =        0.04  (-0.5981, 0.6781)

    Example2:y=a*x + b*sin(x) + c

    法1:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];

    EXPR = {‘x’,‘sin(x)’,‘1’};

    p=fittype(EXPR)

    f=fit(x,y,p)

    plot(f,x,y);

    运行结果:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];

    EXPR = {‘x’,‘sin(x)’,‘1’};

    p=fittype(EXPR)

    f=fit(x,y,p)

    plot(f,x,y);

    p =

    Linear model:

    p(a,b,c,x) = a*x + b*sin(x) + c

    f =

    Linear model:

    f(x) = a*x + b*sin(x) + c

    Coefficients (with 95% confidence bounds):

    a =       1.249  (0.9856, 1.512)

    b =      0.6357  (0.03185, 1.24)

    c =     -0.8611  (-1.773, 0.05094)

    法2:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];

    p=fittype(‘a*x+b*sin(x)+c’,‘independent’,‘x’)

    f=fit(x,y,p)

    plot(f,x,y);

    运行结果:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];

    p=fittype(‘a*x+b*sin(x)+c’,‘independent’,‘x’)

    f=fit(x,y,p)

    plot(f,x,y);

    p =

    General model:

    p(a,b,c,x) = a*x+b*sin(x)+c

    Warning: Start point not provided, choosing random start

    point.

    > In fit>iCreateWarningFunction/nThrowWarning at 738

    In fit>iFit at 320

    In fit at 109

    f =

    General model:

    f(x) = a*x+b*sin(x)+c

    Coefficients (with 95% confidence bounds):

    a =       1.249  (0.9856, 1.512)

    b =      0.6357  (0.03185, 1.24)

    c =     -0.8611  (-1.773, 0.05094)

    /***********************************非线性拟合***********************************/

    Example:y=a*x^2+b*x+c

    法1:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];

    p=fittype(‘a*x.^2+b*x+c’,‘independent’,‘x’)

    f=fit(x,y,p)

    plot(f,x,y);

    运行结果:

    p =

    General model:

    p(a,b,c,x) = a*x.^2+b*x+c

    Warning: Start point not provided, choosing random start

    point.

    > In fit>iCreateWarningFunction/nThrowWarning at 738

    In fit>iFit at 320

    In fit at 109

    f =

    General model:

    f(x) = a*x.^2+b*x+c

    Coefficients (with 95% confidence bounds):

    a =     -0.2571  (-0.5681, 0.05386)

    b =       2.049  (0.791, 3.306)

    c =       -0.86  (-2.016, 0.2964)

    法2:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];

    %use c=0;

    c=0;

    p1=fittype(@(a,b,x) a*x.^2+b*x+c)

    f1=fit(x,y,p1)

    %use c=1;

    c=1;

    p2=fittype(@(a,b,x) a*x.^2+b*x+c)

    f2=fit(x,y,p2)

    %predict c

    p3=fittype(@(a,b,c,x) a*x.^2+b*x+c)

    f3=fit(x,y,p3)

    %show results

    scatter(x,y);%scatter point

    c1=plot(f1,‘b:*’);%blue

    hold on

    plot(f2,‘g:+’);%green

    hold on

    plot(f3,‘m:*’);%purple

    hold off

    喜欢 (0)or分享 (0)

    展开全文
  • Matlab 线性拟合 非线性拟合

    千次阅读 2019-01-24 12:04:24
    Matlab 线性拟合 非线性拟合
                   

    使用Matlab进行拟合是图像处理中线条变换的一个重点内容,本文将详解Matlab中的直线拟合和曲线拟合用法。

    关键函数:

    fittype

    Fit type for curve and surface fitting

    Syntax

    ffun = fittype(libname)
    ffun = fittype(expr)
    ffun = fittype({expr1,...,exprn})
    ffun = fittype(expr, Name, Value,...)
    ffun= fittype({expr1,...,exprn}, Name, Value,...)

    /***********************************线性拟合***********************************/

    线性拟合公式:

    coeff1 * term1 + coeff2 * term2 + coeff3 * term3 + ...
    其中,coefficient是系数,term都是x的一次项。

    线性拟合Example:

    Example1: y=kx+b;

    法1:

    x=[1,1.5,2,2.5,3];y=[0.9,1.7,2.2,2.6,3];p=polyfit(x,y,1);x1=linspace(min(x),max(x));y1=polyval(p,x1);plot(x,y,'*',x1,y1);
    结果:p =    1.0200    0.0400

    即y=1.0200 *x+ 0.0400

    法2:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];p=fittype('poly1')f=fit(x,y,p)plot(f,x,y);
    运行结果:

     x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];p=fittype('poly1')f=fit(x,y,p)plot(f,x,y);p =      Linear model Poly1:     p(p1,p2,x) = p1*x + p2f =      Linear model Poly1:     f(x) = p1*x + p2     Coefficients (with 95% confidence bounds):       p1 =        1.02  (0.7192, 1.321)       p2 =        0.04  (-0.5981, 0.6781)

    Example2:y=a*x + b*sin(x) + c

    法1:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];EXPR = {'x','sin(x)','1'};p=fittype(EXPR)f=fit(x,y,p)plot(f,x,y);

    运行结果:

     x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];EXPR = {'x','sin(x)','1'};p=fittype(EXPR)f=fit(x,y,p)plot(f,x,y);p =      Linear model:     p(a,b,c,x) = a*x + b*sin(x) + cf =      Linear model:     f(x) = a*x + b*sin(x) + c     Coefficients (with 95% confidence bounds):       a =       1.249  (0.9856, 1.512)       b =      0.6357  (0.03185, 1.24)       c =     -0.8611  (-1.773, 0.05094)

    法2:
    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3]; p=fittype('a*x+b*sin(x)+c','independent','x')f=fit(x,y,p)plot(f,x,y);
    运行结果:
    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3]; p=fittype('a*x+b*sin(x)+c','independent','x')f=fit(x,y,p)plot(f,x,y);p =      General model:     p(a,b,c,x) = a*x+b*sin(x)+cWarning: Start point not provided, choosing random startpoint. > In fit>iCreateWarningFunction/nThrowWarning at 738  In fit>iFit at 320  In fit at 109 f =      General model:     f(x) = a*x+b*sin(x)+c     Coefficients (with 95% confidence bounds):       a =       1.249  (0.9856, 1.512)       b =      0.6357  (0.03185, 1.24)       c =     -0.8611  (-1.773, 0.05094)


    /***********************************非线性拟合***********************************/

    Example:y=a*x^2+b*x+c

    法1:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3]; p=fittype('a*x.^2+b*x+c','independent','x')f=fit(x,y,p)plot(f,x,y);

    运行结果:

    p =      General model:     p(a,b,c,x) = a*x.^2+b*x+cWarning: Start point not provided, choosing random startpoint. > In fit>iCreateWarningFunction/nThrowWarning at 738  In fit>iFit at 320  In fit at 109 f =      General model:     f(x) = a*x.^2+b*x+c     Coefficients (with 95% confidence bounds):       a =     -0.2571  (-0.5681, 0.05386)       b =       2.049  (0.791, 3.306)       c =       -0.86  (-2.016, 0.2964)



    法2:

    x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];%use c=0;c=0;p1=fittype(@(a,b,x) a*x.^2+b*x+c)f1=fit(x,y,p1)%use c=1;c=1;p2=fittype(@(a,b,x) a*x.^2+b*x+c)f2=fit(x,y,p2)%predict cp3=fittype(@(a,b,c,x) a*x.^2+b*x+c)f3=fit(x,y,p3)%show resultsscatter(x,y);%scatter pointc1=plot(f1,'b:*');%bluehold onplot(f2,'g:+');%greenhold onplot(f3,'m:*');%purplehold off


               

    再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

    展开全文
  • Java 线性拟合、非线性拟合实例 前奏 工具包 apache common-math-3.6 JDK 1.6 线性拟合 public void main

    Python 中对数据处理,数学运算以及其他方面的功能、资料、代码。。。多得不得了啊。反观 Java,望而却步。还是写一个吧

    更新

    图可以查看Apache Commons-math 线性拟合、非线性拟合(二)文章中的介绍

    版本说明

    • JDK:1.8
    • commons-math:3.6.1

    一些基础知识

    • 线性:两个变量之间存在一次方函数关系,就称它们之间存在线性关系。也就是如下的函数:
      f(x)=kx+b f(x)=kx+b

    • 非线性:除了线性其他的都是非线性,例如:
      f(x)=ex f(x)=e^x

    • 矩阵:矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,可以理解为平面或者空间的坐标点。
      看大佬怎么说之>> B站-线性代数的本质 - 系列合集

    • 微分、积分:互为逆过程,一句话概括,微分就是求导,求某个点的极小变化量的斜率。积分是求一些列变化点的和,几何意义是面积
      看大佬怎么说之>> B站-微积分的本质 - 系列合集

    • 拟合:形象的说,拟合就是把平面上一系列的点,用一条光滑的曲线连接起来的过程。找到一条最符合这些散点的曲线,使得尽可能多的落在曲线上。常用的方法是最小二乘法。也就是最小二乘问题

    一些常用算法

    • 欧拉

    • 龙格库塔

    • 最小二乘法


    添加依赖

    Maven 中添加依赖

    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-math3 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-math3</artifactId>
        <version>3.6.1</version>
    </dependency>
    

    如果你是 Gradle

    // https://mvnrepository.com/artifact/org.apache.commons/commons-math3
    compile group: 'org.apache.commons', name: 'commons-math3', version: '3.6.1'
    

    如何使用和验证

    1. 假设函数已知
    2. 根据函数生成一系列数据
    3. 进行拟合
    4. 对比结果和已知函数

    例如
    f(x)=2x+3 f(x) = 2x + 3
    首先根绝函数生成 xx 取任意实数时的以及所对应的 f(x)f(x) 得到数据集 xyxy
    f(x,y)=(0,3),(1,5),(2,7)...(n,2n+3) f(x,y) = (0,3), (1,5), (2,7)...(n,2n+3)

    然后对这组数据进行拟合,然后和已知函数 f(x)f(x) 对比斜率 kk 以及截距 bb


    1. 线性拟合

    线性函数:
    f(x)=kx+b f(x) = kx + b

    假设函数为:

    f(x)=2x+3 f(x) = 2x + 3

    生成数据集合:

    // 已知函数 y = 2x + 3
    public double func(double x) {
        return 2 * x + 3;
    }
    
    // 生成待拟合数据
    public double[][] getPoints() {
        double[][] xy = new double[100][2];
        for (int x = 0; x < 100; x++) {
            xy[x][0] = x; // x
            xy[x][1] = func(x); // y
        }
        return xy;
    }
    

    添加数据集合,并进行拟合

    
    public void regression() {
        double[][] points = getPoints();
        SimpleRegression regression = new SimpleRegression();
        regression.addData(points); // 数据集
        /*
        * RegressionResults 中是拟合的结果
        * 其中重要的几个参数如下:
        *   parameters:
        *      0: b
        *      1: k
        *   globalFitInfo
        *      0: 平方误差之和, SSE
        *      1: 平方和, SST
        *      2: R 平方, RSQ
        *      3: 均方误差, MSE
        *      4: 调整后的 R 平方, adjRSQ
        *
        * */
        RegressionResults results = regression.regress();
    
        System.out.println("b = "+results.getParameterEstimate(0));
        System.out.println("k = "+results.getParameterEstimate(1));
        System.out.println("r^2 = "+results.getRSquared());
        System.out.println("adjusted r^2 = "+results.getAdjustedRSquared());
    }
    

    程序输出:

    b = 3.0
    k = 2.0
    r^2 = 1.0
    adjusted r^2 = 1.0
    

    和已知函数一样

    线性拟合比较简单,主要是 SimpleRegression 类的 regress() 方法,默认使用 最小二乘法优化器


    2. 一元多项式函数(曲线)

    非线性函数
    f(x)=a+bx+cx2+dx3+...+mxn f(x) = a + bx + cx^2 + dx^3 +...+ mx^n

    假设函数为

    f(x)=1+2x+3x2 f(x) = 1 + 2x + 3x^2

    生成数据集合:

    // 已知函数 y = 1 + 2x + 3x^2
    public double func(double x) {
        return 2 * x + 3;
    }
    
    // 生成待拟合数据
    public double[][] getPoints() {
        double[][] xy = new double[100][2];
        for (int x = 0; x < 100; x++) {
            xy[x][0] = x; // x
            xy[x][1] = func(x); // y
        }
        return xy;
    }
    
    

    进行非线性拟合

    public void curveFitter() {
        double[][] points = getPoints();/*待拟合数据*/
        ParametricUnivariateFunction function = new PolynomialFunction.Parametric();/*多项式函数*/
        // 不知道猜测值可以都设置 1
        double[] guess = {1, 2, 3}; /*猜测值 依次为 常数项、1次项、二次项*/
    
        // 初始化拟合
        SimpleCurveFitter curveFitter = SimpleCurveFitter.create(function,guess);
    
        // 添加数据点。带权重的点,我的理解这个点权重越大,拟合出来的曲线会更靠近这个点
        WeightedObservedPoints observedPoints = new WeightedObservedPoints();
        for (double[] point : points) {
            observedPoints.add(point[0], point[1]);
        }
        /*
        * best 为拟合结果
        * 依次为 常数项、1次项、二次项
        * 对应 y = a + bx + cx^2 中的 a, b, c
        * */
        double[] best = curveFitter.fit(observedPoints.toList());
        System.out.println(Arrays.toString(best));
    

    程序输出:

    [1.0, 2.0, 3.0]
    

    和已知函数一样
    一元多项式曲线的拟合多了一些步骤。但是总归也是不难的。主要是 SimpleCurveFitter 类以及 ParametricUnivariateFunction 接口。

    3. 自定义函数拟合

    总得来说,貌似线性和一元多项式都不难。不过,实际工作或者学术中,一般都是给一个看不懂的函数以及多元多项式,指数,对数等等。继续看吧。

    此处我用 commons-math 源码测试类中的例子

    假设有函数:
    f(x)=d+ad1+(xc)b f(x) = d + \frac{a-d}{1 + (\frac{x}{c})^b}
    需要拟合出 a,b,c,d 四个参数的值。

    方法:

    1. 实现 ParametricUnivariateFunction 接口
    2. 自定义函数,实现 value 方法
    3. 解偏微分方程,实现 gradient 方法
    4. 设置需要拟合的点
    5. SimpleCurveFitter#fit 方法进行拟合

    不着急写代码,先看这个接口的源码:

    /**
     * An interface representing a real function that depends on one independent
     * variable plus some extra parameters.
     *
     * @since 3.0
     */
    public interface ParametricUnivariateFunction {
        /**
         * Compute the value of the function.
         * 计算函数的值
         * @param x Point for which the function value should be computed.
         * @param parameters Function parameters.
         * @return the value.
         */
        double value(double x, double ... parameters);
    
        /**
         * Compute the gradient of the function with respect to its parameters.
         * 计算函数相对于某个参数的导数
         * @param x Point for which the function value should be computed.
         * @param parameters Function parameters.
         * @return the value.
         */
        double[] gradient(double x, double ... parameters);
    }
    
    • value 方法很简单,就是说计算函数 F(x)F(x) 的值。说人话就是自定义函数的
    • gradient 方法为返回一个数组,其实意思就是求偏微分方程,对每一个要拟合的参数求导就行

    不会偏微分方程? 点这里

    按格式输入你的方程=>输入自变量=>输入求导阶数(一般都是 1 阶)=>计算

    好了开始写代码吧,假设函数如下:
    f(x)=d+ad1+(xc)b f(x) = d + \frac{a-d}{1 + (\frac{x}{c})^b}

    自定义 MyFunction 实现 ParametricUnivariateFunction 接口:

    class MyFunction implements ParametricUnivariateFunction {
            public double value(double x, double ... parameters) {
                double a = parameters[0];
                double b = parameters[1];
                double c = parameters[2];
                double d = parameters[3];
                // 自定义函数
                return d + ((a - d) / (1 + Math.pow(x / c, b)));
            }
    
            public double[] gradient(double x, double ... parameters) {
                double a = parameters[0];
                double b = parameters[1];
                double c = parameters[2];
                double d = parameters[3];
    
                double[] gradients = new double[4];
                double den = 1 + FastMath.pow(x / c, b);
                // 对 a 求导
                gradients[0] = 1 / den; 
                // 对 b 求导
                gradients[1] = -((a - d) * Math.pow(x / c, b) * Math.log(x / c)) / (den * den); 
                // 对 c 求导
                gradients[2] = (b * Math.pow(x / c, b - 1) * (x / (c * c)) * (a - d)) / (den * den);
                // 对 d 求导
                gradients[3] = 1 - (1 / den); 
    
                return gradients;
    
            }
        }
    

    待拟合数据

    public double[][] getPoints(ParametricUnivariateFunction function,double[] value) {
        double[][] xy = new double[6][2];
        xy[0] = new double[]{15, 4443};
        xy[1] = new double[]{31, 8493};
        xy[2] = new double[]{62, 17586};
        xy[3] = new double[]{125, 30582};
        xy[4] = new double[]{250, 45087};
        xy[5] = new double[]{500, 50683};
        return xy;
    }
    

    拟合自定义函数

    public void curveFitter() {
        ParametricUnivariateFunction function = new MyFunction();/*多项式函数*/
         /*猜测值 依次为 a b c d 。必须和 gradient 方法返回数组对应*/
         // 不知道猜测值可以都设置 1
        double[] guess = {1500, 0.95, 65, 35000};
        double[][] points = getPoints(function, guess);/*待拟合数据*/
    
        // 初始化拟合
        SimpleCurveFitter curveFitter = SimpleCurveFitter.create(function,guess);
    
        // 添加数据点。带权重的点,我的理解这个点权重越大,拟合出来的曲线会更靠近这个点
        WeightedObservedPoints observedPoints = new WeightedObservedPoints();
        for (double[] point : points) {
            observedPoints.add(point[0], point[1]);
        }
        /*
        * best 为拟合结果 对应 a b c d
        * 可能会出现无法拟合的情况
        * 需要合理设置初始值
        * */
        double[] best = curveFitter.fit(observedPoints.toList());
        System.out.println(Arrays.toString(best));
        }
    

    程序输出:

    [2815.1544441348215, 1.6583960270447948, 111.512552365537, 55075.89946344415]
    

    和我们的猜测值相差不大。具体的得画图才知道具体拟合效果

    还有一种写法是用 CurveFitter 类添加集合不过已经过时了。SimpleCurveFitter 默认使用最小二乘法;
    common-math 测试类中的写法如下:

    LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer();
    CurveFitter<ParametricUnivariateFunction> curveFitter2 = new CurveFitter<ParametricUnivariateFunction>(optimizer);
    ParametricUnivariateFunction function = new MyFunction();/*多项式函数*/
    curveFitter2.addObservedPoint( 15,  4443);
    curveFitter2.addObservedPoint( 31,  8493);
    curveFitter2.addObservedPoint( 62, 17586);
    curveFitter2.addObservedPoint(125, 30582);
    curveFitter2.addObservedPoint(250, 45087);
    curveFitter2.addObservedPoint(500, 50683);
    double[] best = curveFitter2.fit(function, guess);
    

    总结

    后面考虑考虑用 Python 写个对照版本。加上函数图对照
    代码已上传到:
    GitHub
    Gitee

    更新

    图可以查看Apache Commons-math 线性拟合、非线性拟合(二)文章中的介绍

    展开全文
  • Labview非线性拟合

    2017-09-16 16:33:27
    Labview用LM算法非线性拟合,可以实现一组数据的非线性拟合,而不用知道具体的方程系数,我都觉得很烦了,能两句话说完,要那么多废话干嘛
  • 对于某些非线性函数,如指数函数y=e^(ax+b),也可以对函数转化后,求得精确的拟合结果,如上述指数函数可转化为x=(ln y)/a -b/a,同样可以求得具有全局最优拟合误差的拟合函数。上述函数都可以用MATLAB的regress函数...
    1.  前言(不在意来龙去脉的可忽略不看)
    对于多项式函数,可以用最小二乘法求得精确的拟合结果,使得拟合函数具有全局最优的拟合误差;对于某些非线性函数,如指数函数y=e^(ax+b),也可以对函数转化后,求得精确的拟合结果,如上述指数函数可转化为x=(ln y)/a -b/a,同样可以求得具有全局最优拟合误差的拟合函数。上述函数都可以用MATLAB的regress函数或者polyfit函数求得最优的拟合结果,或者可以用广义逆矩阵的最小二乘解计算而得。
    但是,对于大多数非线性函数,难以求得拟合误差全局最优的拟合结果,形如y=c1*e^(px)+c2*e^(qx)。这一类函数,一般做法是首先预估拟合函数的参数,以此作为初始值,采用迭代优化的方法求出局部最优的拟合参数,MATLAB中用lsqcurvefit或者nonlinfit函数求出拟合函数,拟合结果的准确性由选取的初始点决定,初始点的选取极为困难。


    2. 非线性拟合转化为线性拟合
    对于大多数指数函数、三角函数、多项式函数通过四则运算或者复合得到的函数,通常可以用线性微分方程来表示,形如y''+ay'+by=0的常系数线性微分方程则可以表示以下形式的函数:①y=C1*e^(p*x)+C2*e^(q*x);②y=C1*(1+C2*x)*e^(w*x);③y=e^(p*x)*(C1*sin (w*x)+C2*cos (w*x))。
    对于上述非线性函数,则可以通过拟合线性微分方程的系数,再计算出对应的非线性函数的参数,并利用样本数据作为初始条件,拟合出函数中的其他常数项。
    微分方程需要转化为差分方程:①y'(n)=(y(n+1)-y(n-1))/(x(n+1)-x(n-1));②y''(n)=(y(n+1)-2*y(n)+y(n-1))/((x(n+1)-x(n-1))/2)^2。
    通过拟合方程y''+ay'+by=0则可得到a和b,再通过求解二次方程r^2+a*r+b=0,得到两个解r1和r2。
    当r1和r2不相等时,则可得到函数y=C1*e^(r1*x)+C2*e^(r2*x),再利用样本数据线性拟合则可得到C1和C2。
    当r1=r2时,可得到函数y=C1*e^(r1x)+C2*x*e^(r1x),再利用样本数据线性拟合则可得到C1和C2。
    当r1和r2为共轭复数时,可得函数y=e^(a*x)*(C1*sin (b*x)+C2*cos (b*x)),其中a和b分别为r1的实部和虚部,再利用样本数据线性拟合则可得到C1和C2。


    事例MATLAB代码如下:
    % 产生样本数据
    x = linspace(0,98,50)';
    y = 0.9*exp(-0.2*x)-0.3*exp(-0.06*x)+10.57;
    plot(x,y)
    % 计算差分
    dyx = (y(3:end) - y(1:end-2))./(x(3:end) - x(1:end-2));
    ddyx = (y(3:end) - 2*y(2:end-1) + y(1:end-2))./(x(3:end) - x(1:end-2)).^2*4;
    % 拟合微分方程系数
    A = [dyx,y(2:end-1),-1*ones(length(dyx),1)];
    b = -ddyx;
    a = (A.'*A)\A.'*b;
    a(3) = a(3)/a(2);
    % 求解二次方程
    syms r
    r0 = double(solve(r^2+a(1)*r+a(2)))
    % 线性拟合得到常数项C1,C2
    A = [exp(r0(1)*x),exp(r0(2)*x)];
    C = (A.'*A)\A.'*(y-a(3))
    % 作图
    hold on
    plot(x,C(1)*exp(r0(1)*x)+C(2)*exp(r0(2)*x)+a(3),'r.')
    最后,还可以用lsqcurvefit函数进一步优化拟合结果,采用上述方法得到的参数作为初始点,可以修正差分方程拟合导致的误差。
    f = @(b,x)b(1)*exp(b(2)*x)+b(3)*exp(b(4)*x)+b(5);
    b0 = [C(1);r0(1);C(2);r0(2);a(3)];
    b1 = lsqcurvefit(f,b0,x,y)
    hold on
    plot(x,f(b1,x),'k.')

    展开全文
  • 资料仅可参考如有不妥请联系本人改正或者删除 * 2020年08月13日 matlab最小二乘法线性和非线性拟合 资料仅可参考如有不妥请联系本人改正或者删除 * 2020年08月13日 matlab最小二乘法线性和非线性拟合 资料仅可参考如...
  • Common-math 的使用可以看上一篇文章Java 使用apache commons-math 线性拟合、非线性拟合实例教程,这一篇主要是补充上一篇没有拟合结果图的问题。核心思想还是利用已知的函数加上随机函数生成散点,然后进行拟合,...
  • 非线性拟合工具

    热门讨论 2011-12-05 16:56:12
    当前非线性拟合和多元拟合的工具较少,这是针对常用的拟合算法,开发的一款数据拟合为主的软件。包括线性拟合的各种算法,非线性拟合的各种算法,以及多元拟合的各种算法。其中提供了很多非线性方程的模型,以满足...
  • 非线性拟合的消光比测量方法
  • 1 实验目的 实验内容 2掌握用数学软件求解拟合问题 1直观了解拟合基本内容 1拟合问题引例及基本理论 4实验作业 2用数学软件求解拟合问题 3应用实例 matlab最小二乘法线性和非线性拟合 8/15/2020 2 拟 合 2....
  • Matlab线性拟合和非线性拟合

    万次阅读 多人点赞 2019-01-23 09:25:36
    线性拟合 已知如下图像的x,y坐标,x = [1.0, 1.5, 2.0, 2.5, 3.0],y = [0.9, 1.7, 2.2, 2.6, 3.0],如何用一条直线去拟合下列散点? 代码: x = [1.0, 1.5, 2.0, 2.5, 3.0]'; y = [0.9, 1.7, 2.2, 2.6, 3.0]'...
  • 为克服光电探测器动态范围不足,难以在同一条件下精确测量线偏振器的最小光强透射率及最大光强透射率的问题,提出一种基于非线性拟合的消光比测量方法并搭建了相应的测量装置。该方法只需在限定的角度范围内旋转被...
  • 这是BP神经网络训练用于非线性拟合的MATLAB源代码,请大家参考!!!
  • python里面多元非线性回归有哪些方法SciPy 里面的子函数库optimize, 一般情况下可用curve_fit函数直接拟合或者leastsq做最小二乘第九句:简单的事重复做,你就是专家;重复的事用心做,你就是赢家。Python怎么实现...
  • 为了实现非线性拟合首先要定义在线函数;在实际问题中有时散点图作出后未必是多项式的图形可能像其他的曲线这时可以猜测曲线类型然后利用如下命令;根据右图我们猜测曲线为;拟合结果如右图所示红色为拟合曲线图形*为...
  • 使用Origin非线性拟合曲线案例,记载了使用origin进行非线性拟合曲线的方法。
  • 传统的BP神经网络分类和拟合精度不高,很...本程序运用遗传算法初始化BP神经网络的参数,使网络的非线性拟合和分类精度更高。对于想要进行非线性拟合和分类却无法建立数学模型的小伙伴,通过该方法也是一个较好的办法。
  • 使用C#的Mathnet类库实现最小二乘法非线性拟合 作者:linbor tinka
  • Matlab 线性拟合 & 非线性拟合

    万次阅读 2018-07-07 11:45:53
    使用Matlab进行拟合是图像处理中线条变换的一个重点内容,本文将详解Matlab中的直线拟合和曲线拟合用法。 关键函数: fittype Fit type for cu
  • 第七讲-matlab实现非线性拟合课件
  • MATLAB进行非线性拟合

    千次阅读 2020-04-20 16:59:39
    matlab进行非线性拟合常用最小二乘法,适用于:已经求解出函数,但含有未知数,不过已经收集到了一系列数据 1.lsqcurvefit 格式:[x, resnorm,r,flag]=lsqcurvefit(fun, c0,xdata,ydata) c0为初始解向量;xdata,...
  • TensorFlow非线性拟合

    2018-12-18 21:26:00
    1、心得: 在使用TensorFlow做非线性拟合的时候注意的一点就是输出层不能使用激活函数,这样就会把整个区间映射到激活函数的值域范围内无法收敛。 # coding:utf-8 import tensorflow as tf import numpy as np ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,621
精华内容 1,448
关键字:

非线性拟合