二分法-牛顿法-求sqrt


title: 二分法 牛顿法 求sqrt
comments: true
categories:

  • Algorithm
    tags:
  • Algorithm
  • C++
    date: 2019-03-21 10:47:38

使用二分法

首先确定二分法查找的首尾区间,然后根据abs(mid^2-target)<eps的误差进行区间的移动,寻找满足精度的位置

存在的问题:

  • 第一步寻找合适的搜索区间,我们从函数曲线上可以看出,y=x和y=√x在x=1时交集;
  • 当待开根号数在(0,1)之间时,搜索区间也在(0,1),当待开根号数tar>1时,区间在[1,x]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3el4PZu0-1576236781089)(http://po7b8zci3.bkt.clouddn.com/15531498785073.jpg)]

实现

float found(float x,float eps,float s,float e){
    float mid = s+(e-s)/2.0;
    float tmp = mid*mid - x;

    if(abs(tmp) <= err){
        return mid;
    }
    if(tmp >0){
        return found(x,eps,s,mid);
    }else{
        return found(x,eps,mid,e);
    }
}

float sqrt(float x,float eps){
    if (x<0) return -1;
    if (x==0) return 0;

    if(0<x && x<1){
        return found(x,eps,0.,1.);
    }else{
        return found(x,eps,1,x);
    }
    
}

二分法的非递归实现

float found(float x,float eps,float s,float e){
    float mid = (e+s)/2.0;
    float tmp =  mid*mid - x;
    
    while(abs(tmp) > eps){
        printf("cnt %d %f %f %f \n ",cnt,s,e,mid);

        if(tmp>0){
            e = mid;
        }else{
            s = mid;
        }
        mid=(s+e)/2;
        tmp = mid*mid - x;
    }
    return mid;
}

使用牛顿迭代法

仔细思考一下就能发现,我们需要解决的问题可以简单化理解。

  • 从函数意义上理解:我们是要求函数f(x) = x²,使f(x) = num的近似解,即x² - num = 0的近似解。
  • 从几何意义上理解:我们是要求抛物线g(x) = x² - num与x轴交点(g(x) = 0)最接近的点。

实现


float NewTown(float x,float eps){
    float x0,x1= x/2.0;

    int cnt=0;

    while(abs(x1-x0) >= eps){
        x0 = x1;
        printf("cnt:  %d  %f \n ",cnt,x0);
        x1 = x0 - (x0*x0-x)/(2.0*x0);
//        x1 = 1.0/2*(x0+x/x0);
        cnt++;
    }
    
    return x1;
}

使用牛顿迭代法求多项式的一个根

定区间,找中点,中值计算两边看。 
同号去,异号算,零点落在异号间。

实现


float NewTown2(){
    float x,x1=1;
    int a=1,b=2,c=3,d=4;

    float f,f1;

    while(abs(x1-x) >0.001){
        x=x1;
        f = ((a*x+b)*x+c)*x + d;
        f1 = (3*a*x+2*b)*x+c;
        x1 = x - f/f1;
    }

    printf("newtown2 %.10f",x1);
    return x1;

}

牛顿迭代法

五次及以上多项式方程没有根式解(就是没有像二次方程那样的万能公式)

  • 牛顿迭代法(Newton’s method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。

  • 切线是曲线的线性逼近

  • 求高阶方程式的近似解,
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t6ijUoIP-1576236781090)(http://po7b8zci3.bkt.clouddn.com/15531543539924.jpg)]

比如我们要开平方根,则可以转换为求x^2 - a = 0的实数根,根据x_n+1 = x_n - f(x_n)/f’(x_n) ,不断迭代新的切线,直到找到近似解,f(x)和x轴的交点

不收敛的情况:
驻点

起始点不幸选择了驻点,从几何上看切线根本没有根。

越来越远离的不收敛

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v0fcY15e-1576236781091)(http://po7b8zci3.bkt.clouddn.com/15531548601931.jpg)]

循环震荡的不收敛

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PskEgjVi-1576236781093)(http://po7b8zci3.bkt.clouddn.com/15531550374784.jpg)]

不能完整求出所有的根

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D5WtvezB-1576236781096)(http://po7b8zci3.bkt.clouddn.com/15531549206795.jpg)]

总结

应用牛顿-拉弗森方法,要注意以下问题:
函数在整个定义域内最好是二阶可导的
起始点对求根计算影响重大,可以增加一些别的判断手段进行试错

牛顿法求极值 梯度下降求极值

其实牛顿迭代法也可以很方便的求极值,只要x=x−f’(x)/f"(x)
这样求的就是,f’(x)与x轴的交点,既导数的零点,也即是f(x)的极值点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-feBh9guZ-1576236781101)(http://po7b8zci3.bkt.clouddn.com/15531575573419.jpg)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 目的: (1)通过采用牛顿迭代法、弦截法和二分法根的程序设计,使学生更加系统地理解和掌握C语言函数间参数传递方法、数组和指针的应用等编程技巧。培养学生综合利用C语言进行科学计算,使学生将所学知识转化为分析和设计数学中的实际问题的能力,学会查资料和工具书。 (2)提高学生建立程序文档、归纳总结的能力。 (3)进一步巩固和灵活运用先修课程《计算机文化基础》有关文字处理、图表分析、数据归整、应用软件之间图表、数据共享等信息技术处理的综合能力。 2. 基本要: (1)要用模块化设计和C语言的思想来完成程序的设计; (2)要分别编写牛顿迭代法、弦截法和二分法根的函数,分别存到不同的.CPP文件中; (3)在VC++6.0环境中,学会调试程序的方法,及时查究错误,独立调试完成。 (4)程序调试通过后,完成程序文档的整理,加必要的注释。 一般解一元方程,常用采用的方法有:牛顿迭代法、弦截法和二分法等。 牛顿迭代法根 〖〖f(x)=a〗_0 x〗^n 〖〖 + a〗_1 x〗^(n-1) +⋯+〖 a〗_(n-2) x^2 +〖 a〗_(n-1) x +〖 a〗_n=0 f(x)在〖 x〗_0附近的根。 计算公式:〖 x〗_(n+1)=〖 x〗_n- f(〖 x〗_n )/(f(〖 x〗_n)) ́ 精度:ε=|〖 x〗_(n+1)-〖 x〗_n|<1.0e-m ,m=6。 牛顿迭代法 所的根:满足精度的〖 x〗_n 二分法 任取两点〖 x〗_1和〖 x〗_2,判断(〖 x〗_1, 〖 x〗_2)有无实根。如下图所示,如果f(〖 x〗_1 )和f(〖 x〗_2 )符号相反,说明(〖 x〗_1, 〖 x〗_2)之间有一实根。取(〖 x〗_1, 〖 x〗_2)的中点x,检查f(x)和f(〖 x〗_1 )是否同符号,如果不同号,说明实根在(〖 x〗_1,x)区间,x作为新的〖 x〗_2,舍弃(x, 〖 x〗_2)区间;若同号,则实根在(x, 〖 x〗_2)区间,x作为新的〖 x〗_1, 舍弃(〖 x〗_1,x)区间。再根据新的〖 x〗_1 、 〖 x〗_2,找中点,重复上述步骤。直到|〖 x〗_1-〖 x〗_2|〖<10〗^(-6)时,x =(〖 x〗_1+〖 x〗_2)/2为所。 (3)弦截法 取f(〖 x〗_1 )与f(〖 x〗_2 )连线与x轴的交点x,从(〖 x〗_1, x)和(x, 〖 x〗_2)两个区间中取舍的方法与二分法相同。 计算公式为: 判断f(〖 x〗_1 )与f(〖 x〗_2 )是否同符号的方法与二分法采用的方法相同。直到先后两次出的x的值之差小于〖10〗^(-6)为止。 分别用牛顿迭代法、弦截法和二分法下列方程的根,分析比较各种方法的迭代次数及精度。 〖f(x)=x〗^3 〖- 2x〗^2 +7x +4=0 牛顿迭代法的初值:x=0.5; 弦截法〖 x〗_1,〖 x〗_2的初值:-1,1 二分法〖 x〗_1,〖 x〗_2的初值:-1,0 精度要:|〖 x〗_1-〖 x〗_2| 〖<10〗^(-6)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值