数学体操之牛顿数值法解方程的程序和图解

news/2024/9/22 22:23:17/

牛顿法是一种用来寻找函数零点的迭代方法,它基于以下思路,如果我们知道了一个函数在某个点的切线,那么函数的零点就可以通过切线与x轴的交点来近似计算。

给定一个函数f(x),找到零点x_0,过程如下:

选择初始点x_1,然后使用这个点处的切线来近似f(x),也就是说,找到下面这条直线:

y-f(x_1)=f'(x_1)(x-x_1)

这样,我们可以通过将其与x轴相交一获得更接近真实零点的新估计值x_2:

-f(x_1)=f'(x_1)(x-x_1)\Rightarrow x_2 = -\frac{f(x_1)}{f'(x_1)}+x_1

从上式可以看出,如果我们对x_1一次,则可以计算出一个更好的估计值x_2,然后我们可以不断重复此过程,直到达到我们满意的精度或次数为止。

下面举例说明:

用牛顿法求解一元二次方程,程序比较简单,利用导函数与横轴的交点的横坐标不断迭代即可,程序清单如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>//newton methond to get the root of
//equation of two degree f(x) = x^2-8x+9
//the deritive is f'(x) = 2x - 8;
static void newton_methed(void)
{// init value of start point. double x1 = 8.0, x2=0.0, y1, root;double k; // the gradient of f(x)while(fabs(x1-x2) > 1e-6) {x2=x1;k = 2 * x1 - 8;y1 = x1*x1 - 8*x1 + 9;root = (-1 * y1)/k + x1;  //according y-y1=k(x-x1)x1 = root;printf("root is %f.\n", root);}return;
}int main(void)
{newton_methed();return 0;
}

图解说明:

下图展示了迭代过程:

根值到了极度接近的阶段,宏观上已经看不出切线和坐标轴的交点,即便放大绘图,也会感受到工具渲染非常的吃力。下图展示了三次迭代后的效果,左边是原函数和坐标轴的交点,邮编是三伦迭代的切线和X轴的交点,可以看到,交点非常的接近了。

如果将迭代初始值甚至为一元二次函数的极点位置,程序将失效,原因是此时极点的切线位置和X轴平行,没有交点,算法无法执行下去。

对于这个例子来说,如果将初始的X1设置为4,算法将会输出非法值。

但是只要打破平衡,稍微偏离极点中心哪怕一点点,算法将给出正确的值,如果向左偏离,则得到左交点,如果向右偏离,将得到右交点,结合图形,很容易理解这些结论。

计算左边根的迭代示意图

一个不算简单的解方程问题,数形结合起来后,直观了很多,看来数学从高的观点往下看,往往会更有收获。

一个新的例子,自然对数求根:

geogebra得到的两个根是+/- 1.41.

程序:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>//newton methond to get the root of
//equation of two degree f(x) = x^2-8x+9
//the deritive is f'(x) = 2x - 8;
static void newton_methed1(void)
{// init value of start point. double x1 = 3.99999999, x2=0.0, y1, root;double k; // the gradient of f(x)while(fabs(x1-x2) > 1e-6) {x2=x1;k = 2 * x1 - 8;y1 = x1*x1 - 8*x1 + 9;root = (-1 * y1)/k + x1;  //according y-y1=k(x-x1)x1 = root;printf("root is %f.\n", root);}return;
}//newton methond to get the root of
//equation of two degree f(x) = log(x^2-1)
//the deritive is f'(x) = 2x/(x^2-1);
static void newton_methed2(float x1)
{// init value of start point. double x2=0.0, y1, root;double k; // the gradient of f(x)while(fabs(x1-x2) > 1e-6) {x2=x1;k = 2 * x1/(x1*x1 - 1);y1 = log(x1*x1-1);root = (-1 * y1)/k + x1;  //according y-y1=k(x-x1)x1 = root;printf("root is %f.\n", root);}return;
}int main(void)
{//newton_methed1();newton_methed2(3.999999999);newton_methed2(-3.999999999);return 0;
}

程序迭代过程,最终得到了正确的根:

迭代数次后的逼近位置:

总结:

牛顿法的主要优点是,它在每次迭代中都收敛的非常快,在实践中被证明比其他迭代方法更快,但是它也有缺点,就像例子中看到的,当函数具有多个局部零点时,算法的初始值可能导致收敛到错误的根。

解方程是一种近似数学,虽然有的时候能够获得方程的解析式,但大多数的时候(5次及以上的普通方程)是没有解析式的,这个时候只能通过数值解法得到近似解。即便对于有解析式可解方程,通常根也是无理数,没有精确解,所以解方程实际上是一件“差不多”就可以的事,所以计算机能够很好的胜任这份工作。


结束


http://www.ppmy.cn/news/43055.html

相关文章

Talk预告 | 新加坡国立大学郑奘巍 AAAI‘23 杰出论文:大批量学习算法加速推荐系统训练

本期为TechBeat人工智能社区第486期线上Talk&#xff01; 北京时间3月30日(周四)20:00&#xff0c;新加坡国立大学二年级博士生——郑奘巍的Talk将准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “大批量学习算法加速推荐系统训练”&#xff0c;届时将分…

从C出发 19 --- 函数定义细节剖析

因为编译器是自上而下执行代码的&#xff0c;当编译到 paw2 的时候不知道是什么东西&#xff0c;看起来像一个函数但是前面的代码没有发现它&#xff0c;这个时候编译器就会报错 为了防止编译器报错 应该在调用前先声明 &#xff0c;注意声明的三要素 声明的作用: 让编译器先…

【hello Linux】环境变量

目录 1. 环境变量的概念 2. 常见的环境变量 3. 查看环境变量 4. 和环境变量相关的命令 5. 环境变量的组织方式 6. 通过代码获取环境变量 7. 通过系统调用获取环境变量 Linux&#x1f337; 在开始今天的内容之前&#xff0c;先来看一幅图片吧&#xff01; 不知道你们是否和我一…

Stable Diffusion成为生产力工具(五):放大并修复老照片、马赛克照片、身份证件照

S&#xff1a;你安装stable diffusion就是为了看小姐姐么&#xff1f; I &#xff1a;当然不是&#xff0c;当然是为了公司的发展谋出路~~ 预先学习&#xff1a; 安装webui《Windows安装Stable Diffusion WebUI及问题解决记录》。运行使用时问题《Windows使用Stable Diffusion时…

计算机发展史-计算机基础知识总结(上)

随着计算机技术的不断发展&#xff0c;计算机已经成为人们日常生活中必不可少的一部分&#xff0c;而且它也对人类社会产生了巨大的影响。本文将从计算机的发展历史、计算机硬件和软件、操作系统、计算机网络、数据库等方面进行系统的介绍&#xff0c;为读者提供计算机基础知识…

springboot+thymeleaf实现发Html邮件自由

2019年&#xff0c;我刚接触测试架构和测试开发类的工作时&#xff0c;经常会有自动化发邮件的功能&#xff0c;大都是从各个平台自动化统计一些数据出来&#xff0c;每周定时发一封邮件给领导交差&#xff0c;回过头来再看看我发的邮件&#xff0c;不美观&#xff0c;不专业。…

LeetCode-152. 乘积最大子数组

目录思路动态规划题目来源 152. 乘积最大子数组 思路 这题跟LeetCode-53. 最大子数组和很像 最后把整个 dp 数组看一遍求最大值即可。因此状态转移方程可能是&#xff1a; dp[i] Math.max(dp[i-1]nums[i],nums[i]);说明&#xff1a;牢记状态的定义&#xff0c;一定以下标 i…

NDK RTMP直播客户端二

在之前完成的实战项目【FFmpeg音视频播放器】属于拉流范畴&#xff0c;接下来将完成推流工作&#xff0c;通过RTMP实现推流&#xff0c;即直播客户端。简单的说&#xff0c;就是将手机采集的音频数据和视频数据&#xff0c;推到服务器端。 接下来的RTMP直播客户端系列&#xff…