基于C++的非线性方程的解法研究及实现

2023-10-27

【基于C++的非线性方程的解法研究及实现】

【前言】

关于非线性方程f(x) = 0的根的解法目前分为三类,二分法,试值法和不动点迭代法

本文实例为寻找f(x) = x2 - 2x在区间[-1, 3]内精度在0.05以内的实根

代码中的set用于保存答案

【1.二分法】

二分法又称二分区间法,是求解非线性方程近似根的一种常用的简单方法。

在这里插入图片描述
算法:
在这里插入图片描述
【代码实现】

inline float f(float x) { return x * x - 2 * x; }
inline float binary_search(float l, float r, float k) {
	float left = l, right = r;
	while (true) {
		float x = (left + right) / 2;
		float fa = f(left), fx = f(x);
		if (fa * fx < 0) right = x;
		else left = x;
		if (abs(right - left) <= 2 * k) return x;
	}
}
inline void solve_division(float l, float r, float k) {
	set<float> ans;
	for (float i = l; i < r; i += k) {  //将区间分为(r - l) / k个分别进行查找
		float fa = f(i), fb = f(i + k);
		if (fa == 0) ans.insert(i);
		else if (fb == 0) ans.insert(i + k);
		else if (fa * fb < 0)  ans.insert(binary_search(i, i + k, k));
	}
	cout << "The root of the equation is(division):" << endl;
	for (auto& it : ans) {
		printf("%.2f\n", it);
	}
}

【2.试值法】

在这里插入图片描述

该算法与二分法的不同点在于将二分法中x = (a + b) / 2换做如下操作

在这里插入图片描述

【代码实现】

inline float tryvalue_search(float l, float r, float k) {
	float left = l, right = r;
	while (true) {
		float x = right - (right - left) * f(right) / (f(right) - f(left));  // 不同点
		float fa = f(left), fx = f(x);
		if (fa * fx < 0) right = x;
		else left = x;
		if (abs(right - left) <= 2 * k) return x;
	}
}
inline void solve_tryvalue(float l, float r, float k) {
	set<float> ans;
	for (float i = l; i < r; i += k) {
		float fa = f(i), fb = f(i + k);
		if (fa == 0) ans.insert(i);
		else if (fb == 0) ans.insert(i + k);
		else if (fa * fb < 0) {
			float x = tryvalue_search(i, i + k, k);
			ans.insert(x);
		}
	}
	cout << "The root of the equation is(tryvalue):" << endl;
	for (auto& it : ans) {
		printf("%.2f\n", it);
	}
}

【3.不动点迭代法】

在这里插入图片描述

大致意思就是由f(x) = 0建立一个函数g(x) = x,让x1 = g(x0), x2 = g(x1), x3 = g(x2) … xn = g(n - 1)…由于当n趋于无穷时若xn = g(n),那么若xi = g(xi)可得xi为f(x)的一个实根

在这里插入图片描述
那么以f(x) = x2 - 2x为例

g1(x) = x2 / 2
g2(x) = sqrt(2x)
g3(x) = x2 - x

由于不知道函数是否发散,我们设置一个迭代次数cnt,表示若cnt次内未收敛返回空值

由于x0的取值不确定,我们同样将区间分为(r - l) / k个,对于每个端点值进行cnt次的迭代

【代码实现】

#define eps 1e-6
typedef float(*ff)(float);
inline float judge(float x) { return abs(x) <= eps ? 0 : x; }  //当数值小于1e-6是认为它是0
inline float g1(float x) { return x * x / 2; }
inline float g2(float x) { return sqrt(2 * x); }
inline float g3(float x) { return x * x - x; }
inline void g_iteration(double x, double k, int cnt, ff g, set<float>& s) {
	if (!judge(x - g(x))) {
		s.insert(judge(x));
		return;
	}
	if (!cnt) return;
	g_iteration(g(x), k, cnt - 1, g, s);
}
inline void solve_iteration(float l, float r, float k, int cnt, ff g) {
    //cnt为迭代次数
	set<float> ans;
	for (float i = l; i < r; i += k) {
		g_iteration(g(i), k, cnt, g, ans);
	}
	cout << "The root of the equation is(solve_iteration):" << endl;
	for (auto& it : ans) {
		printf("%.6f\n", it);
	}
}

【程序源码】

#include <bits/stdc++.h>
using namespace std;
#define eps 1e-6
typedef float(*ff)(float);
inline float f(float x) { return x * x - 2 * x; }
inline float binary_search(float l, float r, float k) {
	float left = l, right = r;
	while (true) {
		float x = (left + right) / 2;
		float fa = f(left), fx = f(x);
		if (fa * fx < 0) right = x;
		else left = x;
		if (abs(right - left) <= 2 * k) return x;
	}
}
inline void solve_division(float l, float r, float k) {
	set<float> ans;
	for (float i = l; i < r; i += k) {
		float fa = f(i), fb = f(i + k);
		if (fa == 0) ans.insert(i);
		else if (fb == 0) ans.insert(i + k);
		else if (fa * fb < 0)  ans.insert(binary_search(i, i + k, k));
	}
	cout << "The root of the equation is(division):" << endl;
	for (auto& it : ans) {
		printf("%.2f\n", it);
	}
}
inline float tryvalue_search(float l, float r, float k) {
	float left = l, right = r;
	while (true) {
		float x = right - (right - left) * f(right) / (f(right) - f(left));
		float fa = f(left), fx = f(x);
		if (fa * fx < 0) right = x;
		else left = x;
		if (abs(right - left) <= 2 * k) return x;
	}
}
inline void solve_tryvalue(float l, float r, float k) {
	set<float> ans;
	for (float i = l; i < r; i += k) {
		float fa = f(i), fb = f(i + k);
		if (fa == 0) ans.insert(i);
		else if (fb == 0) ans.insert(i + k);
		else if (fa * fb < 0) {
			float x = tryvalue_search(i, i + k, k);
			ans.insert(x);
		}
	}
	cout << "The root of the equation is(tryvalue):" << endl;
	for (auto& it : ans) {
		printf("%.2f\n", it);
	}
}
inline float judge(float x) { return abs(x) <= eps ? 0 : x; }
inline float g1(float x) { return x * x / 2; }
inline float g2(float x) { return sqrt(2 * x); }
inline float g3(float x) { return x * x - x; }
inline void g_iteration(double x, double k, int cnt, ff g, set<float>& s) {
	if (!judge(x - g(x))) {
		s.insert(judge(x));
		return;
	}
	if (!cnt) return;
	g_iteration(g(x), k, cnt - 1, g, s);
}
inline void solve_iteration(float l, float r, float k, int cnt, ff g) {
	set<float> ans;
	for (float i = l; i < r; i += k) {
		g_iteration(g(i), k, cnt, g, ans);
	}
	cout << "The root of the equation is(solve_iteration):" << endl;
	for (auto& it : ans) {
		printf("%.6f\n", it);
	}
}
int main() {
	solve_division(-1, 3, 0.05);
	solve_tryvalue(-1, 3, 0.05);
	cout << "g1:" << endl;
	solve_iteration(-1, 3, 0.05, 50, g1);
	cout << "g2:" << endl;
	solve_iteration(-1, 3, 0.05, 50, g2);
	cout << "g3:" << endl;
	solve_iteration(-1, 3, 0.05, 50, g3);
	return 0;
}

【运行结果】

在这里插入图片描述

【结果分析】

可以看到三种方法均能够找到该方程的近似根,在不动点迭代法中,g1只能找到根x = 0,而g2和g3可以找到根x = 0和x = 2

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于C++的非线性方程的解法研究及实现 的相关文章

  • arcgis创建公里格网并计算格网内点的平均值最后形成马赛克式栅格图

    生成公里格网 在搜索框搜索create fishnet 点击create fishnet output feature class 输出格网的位置和名字 template extent 公里格网的范围 和什么层相同 cell size wi
  • 电脑壁纸链接

    电脑壁纸链接 一 壁纸网站 1 彼岸图网 2 H128壁纸 3 Wallhaven 4 Wallhere 二 游戏壁纸 英雄联盟 神泣 鬼泣 女神联盟2 崩坏3 三国杀 QQ飞车 QQ炫舞 阴阳师 幻塔 王者荣耀 逆战 上古王冠 永恒魔法
  • 大学生选课抢课如何提高选中概率

    作者位于哈尔滨某高校 选课总是激动人心的一件大事 但是明明与同学一起进的系统 他就能顺利选课 而我却被强退出来 无数辛酸让我知道了一些道理 写下这篇文章给学弟学妹们作为参考 原理 问 为什么大多数学校教务系统选课时都会卡 答 学校教务系统平
  • Linus谈优秀程序员的三种品质

    转自 http blog dyngr com blog 2013 09 26 junio c hamano interview 引言 今天我们的嘉宾 是分布式版本管理系统Git的主要维护者 同时也是 入门Git 一书的作者 滨野纯先生 而这
  • 课程设计总结

    1 政府职能部门 望细分 具体 课程压缩所致 2 企业家 结构好 利于规划 参考 强烈希望协调与管理融合进来 3 工程师 技术人员 指导行强 望精化 深化 细化 4 学生 利于未来规划 创业 就业 发展 学习方向等等 老师总结课程缺陷 1
  • 10款Visual Studio实用插件

    目录 前言 Visual Studio插件搜索 Visual Studio插件市场 ReSharper 付费 GitHub Copilot 付费 CodeMaid 免费 CSharpier 免费 Visual Studio Theme Pa
  • 水文数据产品的网站

    主要记录在平常用到的水文数据产品的网站 包括水库 湖泊 河流等 1 hydroweb 官网 https www theia land fr en hydroweb 界面 下载后的数据是txt格式 如需转成csv 可这样批量操作 import
  • 电源学习总结(六)——BUCK设计

    降压型开关电源 BUCK 是实际应用中较为广泛使用的电路 本文来详细说一说相关的设计细节 这里不考虑集成的开关电源 分控制和驱动 开关管 电感等部分讲 文章目录 基本结构 控制和驱动 开关管 自举电容 电感 电容 工作频率选择 其他注意事项
  • App\led\led.h(6): warning: #1295-D: Deprecated declaration LED_Init - give arg types

    如图所示操作即可 如图所示操作即可 如图所示操作即可
  • 不能安装64位office提示已安装32位的

    问题描述 安装64位office办公软件的时候提示已经安装32位的office办公软件所以无法继续安装 但实际上之前安装的32位的office办公软件已经卸载了 问题现象截图如下 解决办法 从问题描述中 我们其实已经能够看出问题原因了 类似
  • sentinel3数据批量下载——sentinelsat

    本文主要记录利用sentinelsat包批量下载sentinel2数据 转载 https blog csdn net mrzhy1 article details 107044828 方法一 直接利用sentinelsat包 1 senti
  • Ant-Maven-Gradle

    make Makefile学习 peterYong 博客园 ant ant 工具 milkty 博客园 maven 学习Maven这一篇就够了 轻松的小希的博客 CSDN博客 学Maven 这篇万余字的教程 真的够用了 江南一点雨 博客园
  • Blender51个基本操作

    一 选择操作 编辑模式 1 右键 选择 2 A 全选 3 B 左键 矩形选择 4 B 中键点击 矩形移除选择 5 C 左键 圆形选择 6 C 中键点击 圆形移除选择 7 滚轮滑动 圆形选择框大小 8 Ctrl 左键 扇形选择 9 Ctrl
  • 【软件测试】用例篇

    一 什么是测试用例 测试用例 向被测试系统发起的一组集合 这组集合包含测试数据 测试步骤 测试平台 预期结果 二 为什么在测试前要设计测试用例 三 基于需求设计测试用例 3 1测试是我们测试人员进行测试的依据 3 2测试人员首先要分析需求
  • 突发!ITELLYOU要改版了!

    微信公众号 网管小贾 个人博客 www sysadm cc 经常下载Windows系统镜像的老司机中 我敢保证十之八九对 MSDN 我告诉你 这个网站再熟悉不过 可是对于新手小白们来说 这个站TA究竟是个啥 其实 MSDN 我告诉你 是个名
  • PTP/IP协议

    PTP IP PTP over IP 是一个通过IP连接 建立在 Picture Transfer Protocol PTP 上的传输层 我之所以在了解这个东西是因为有一台 Nikon 相机支持 WLAN 和手机传输相片 但是APP设计得极
  • 亲密关系沟通-【正向情绪】创造一场愉快的沟通体验

    为什么有的时候聊天越聊越开心 有时候却让你意兴阑珊 正向情绪体验 积极议题 充分发挥 谁都喜欢被看见 让他不断得到关注 得到你持续的关注 你知道吗 我这个月业绩第一 哇 你超棒的 哪里哪里 话题聊不下去 你给他夸奖 他只能谦虚 天哪你怎么做
  • fl studio20中文内测版下载2024最新完美实现汉化

    fl studio20是一款众所周知的水果编曲软件 能够剪辑 混音 录音 它的矢量界面能更好用在4K 5K甚至8K显示器上 还可以可以编曲 剪辑 录音 混音 让你的计算机成为全功能录音室 不论是在功能上面还是用户界面上都是数一数二的 但该软
  • Mac/Linux虚拟机CrossOver2024新版下载使用教程

    CrossOver不像Parallels或VMware的模拟器 而是实实在在Mac OS X系统上运行的一个软件 该软件可以让用户在mac是上直接运行windows软件 本文为大家带来的是CrossOver Mac版安装教程 CrossOv
  • 液晶偏振光栅

    1 偏振 光是横波 在垂直于光的传播方向的平面内光波振动 即E矢量振动 各方向振幅都相等的光为自然光 只在某一方向有光振动的光称为线偏振光 各方向光振动都有 但振幅不同的光叫部分偏振光 螺旋着振动的光称圆偏振光 分旋和右旋 2 庞加莱球表示

随机推荐

  • mciSendString的介绍

    转载至 http blog sina com cn s blog 149e9d2ec0102wzcn html 使用MCI API 源文件中需要包含头文件Mmsystem h 在Project gt Settings gt Link gt
  • Windows 10 自带录制工具

    从知乎上学来的 Windows 10上自带的游戏录制工具 按Win G呼出 可录制游戏和任何一个桌面程序 可以截屏 不能控制录制的质量 录制出来的视频大小适中 只能录制一个程序 切换程序会导致录制停止 输出格式是mp4 视频编码H 264
  • sqlplus连接、登录命令大全(选择实例登录、连接远程数据库实例等等)

    1 默认实例登录 sqlplus username password 如 sqlplus tas yn tas yn 2 选择实例登录 sqlplus username password net service name 如 sqlplus
  • vue 获取微信定位经纬度,并调用高德地图解析出详细地址

    第一步 安装weixin js sdk 命令 npm i S weixin js sdk 或者 npm install weixin js sdk 第二步 在需要的地方引用 import wx from weixin js sdk 第三步
  • 《C和指针》笔记27:递归

    递归所需要的两个特性 存在限制条件 当符合这个条件时递归便不再继续 每次递归调用之后越来越接近这个限制条件 这里没有用计算阶乘和菲波那契数列的例子说明递归 作者指出前者递归并没有提供任何优越之处 而后者效率之低是非常恐怖的 下面程序的目的是
  • matlab中more_sols,薛定宇教授大讲堂(卷Ⅳ):MATLAB最优化计算最新章节_薛定宇著_掌阅小说网...

    2 4 联立方程组的精确求解 前面介绍过 利用图解方法只能求出给定方程的实数根 并不能求出方程的复数根 具体例子可以参见例2 12 另外 如果联立方程有多个实数根 则只能用图形方法绘制出根所在的位置 并不能直接得出根的具体值 需要逐个根进行
  • Java 获取文件Jar包中读取文件

    本文介绍java多种方式从classpath url以及jar中读取文件 文章目录 各种路径获取方式 IDEA中输出的结果 执行JAR包所输出的结果 外部类读取Jar包中的配置文件 判断 是class文件执行还是jar文件执行 各种路径获取
  • 如何画出一张优秀的软件文档视图

    技术传播的价值 不仅仅体现在通过商业化产品和开源项目来缩短我们构建应用的路径 加速业务的上线速率 也体现在优秀工程师的工作效率提升 产品性能优化和用户体验改善等经验方面的分享 以提高我们的专业能力 接下来 阿里巴巴技术专家三画 将分享自己和
  • 用户注意到用户计算机中千兆位网卡,网络设备互联考试习题

    1 下面那种网络互连设备和网络层关系最密切 C A 中继器 B 交换机 C 路由器 D 网关 2 下面那种说法是错误的 B A 中继器可以连接一个以太网UTP 线缆上的设备和一个在以太网同轴电缆上的设备 B 中继器可以增加网络的带宽 C 中
  • Node.js笔记:SerialPort(串口)模块使用(基于9.x.x)

    文章目录 目的 模块安装 基础使用 扫描端口 打开端口 发送数据 接收数据 错误处理 数据解析器 SerialPort类 构造方法 属性 事件 方法 命令行工具 总结 目的 上位机与各种电路模块间常常采用串口进行通讯 Node js中可以使
  • VSCode查找和替换正则表达式转义字符整理

    你也可以通过我的独立博客 www huliujia com 获取本篇文章 使用VSCode进行查找 替换时 经常需要用到正则表达式 一段时间不用就忘了 每次要用的时候都要耽误很多时间去查找 所以整理了一份很全的放在这里 这个其实是 NET使
  • Telnet找不到时的安装(启动)教程 (Windows)

    目录 前言 启动Windows功能 Step1 打开控制面板 Step2 点击程序 注意 不是卸载程序 Step3 点击 启动或关闭Windows功能 Step4 勾选 Telnet客户端 Step5 点击确认 等待启动 Step6 启动完
  • java: 非法字符: ‘\ufeff’

    导入项目运行后会发现如下错误 java 非法字符 ufeff java 需要class interface或enum 原因 编码问题 将UTF 8换成GBK 然后再将GBK转换为UTF 8即可
  • 2.4 等比数列

    学习步骤 如果我要学习等比数列 我会按照以下步骤进行学习 定义和性质 首先了解等比数列的定义和性质 包括公比 首项 通项公式 求和公式等 例题练习 通过练习一些简单的例题来理解等比数列的概念和性质 并能够灵活应用公式解决问题 深入理解 通过
  • Python 基础合集7:类和实例

    一 前言 本小节主要梳理类和实例的基本知识 包含类及其属性 方法的定义和调用 类的实例及其属性 方法的定义和调用 还介绍了3个魔法函数 init str repr 和私有化变量的使用 环境说明 Python 3 6 windows11 64
  • 关于kali安装nessus打不开网页?

    大家好 我想请教大家一个问题 我在kali上面安装的是10 4版本的nessus 后来压缩到tmp之后 我复制到etc里 我开启了这个nessus服务 但是显示这个 我擦 不知道怎么回事 换了一个8版本的也不行 然后最终的问题就是浏览器打不
  • 数据类型和取值以及运算符

    数据类型分为基本数据类型和引用数据类型 一 基本数据类型又分为 1 数值型 byte short int long float double 2 布尔型 booleanl 3 字符型 char 二 引用数据类型 类 接口 抽象类 数组 常用
  • 大一统,windows下安装linux的最新方式

    抛弃虚拟机和双系统 在windows下使用linux 为啥要执着于linux 入坑指南 安装windows terminal 开启子系统功能 下载Ubuntu系统 更改命令主题 把oh my zsh 项目 Clone 下来 复制 zshrc
  • RFC2367 PF_KEY键管理API

    组织 中国互动出版网 http www china pub com RFC文档中文翻译计划 http www china pub com compters emook aboutemook htm E mail ouyang china p
  • 基于C++的非线性方程的解法研究及实现

    基于C 的非线性方程的解法研究及实现 前言 关于非线性方程f x 0的根的解法目前分为三类 二分法 试值法和不动点迭代法 本文实例为寻找f x x2 2x在区间 1 3 内精度在0 05以内的实根 代码中的set用于保存答案 1 二分法 二