牛顿迭代法求解二元非线性方程组,C++代码实现

2023-11-17

整体迭代公式就是

X^{k+1}=X^{k}-J^{-1}\bullet F

上式中

X=\begin{bmatrix} x1\\ x2\end{bmatrix}F=\begin{bmatrix} f1\\ f2\end{bmatrix}

JF的雅克比矩阵,J= \begin{bmatrix} df1dx1 & df1dx2\\ df2dx1 & df2dx2 \end{bmatrix}

J^{-1}为雅克比矩阵的逆矩阵

实例:

求解\left\{\begin{matrix} x^{2}-2x-y=-0.5\\ x^{2}+4y^{2}=4\end{matrix}\right.的x和y的解。

上面求根问题可转化为F= \begin{bmatrix} x^{2}-2x-y+0.5\\ x^{2}+4y^{2}-4\end{bmatrix}=0的问题,即可用牛顿迭代法求解此二元非线性方程。

具体求解过程代码如下所示

//线性方程组中方程个数、未知量个数
#include <iostream> 
#include <cmath>
#define N 2 // 非线性方程组中方程个数、未知量个数
#define Epsilon 0.0001 // 差向量1范数的上限
#define Max 100 //最大迭代次数
using namespace std;
const int N2=2*N;
int main()
{
	void ff(float xx[N],float yy[N]); 
	
	//计算向量函数的因变量向量yy[N]
	void ffjacobian(float xx[N],float yy[N][N]);
	
	//计算雅克比矩阵yy[N][N]
	void inv_jacobian(float yy[N][N],float inv[N][N]); 
	
	//计算雅克比矩阵的逆矩阵inv
	void newdundiedai(float x0[N], float inv[N][N],float y0[N],float x1[N]); 
	
	//由近似解向量x0 计算近似解向量x1
	float x0[N]={2.0,0.25},y0[N],jacobian[N][N],invjacobian[N][N],x1[N],errornorm;
	
	int i,j,iter=0;
	
	//如果取消对x0的初始化,撤销下面两行的注释符,就可以由键盘向x0读入初始近似解向量
	/*
	for( i=0;i<N;i++)
		cin>>x0[i];
	*/
	cout<<"初始近似解向量:"<<endl;
	
	for (i=0;i<N;i++) 
		cout<<x0[i]<<"	";
	
	cout<<endl<<endl;
	
	//牛顿迭代法迭代求解过程 
	do
	{
		iter=iter+1;
		for(int xx=0;xx<=30;xx++)  
			cout<<"==";
		cout<<endl;
		cout<<"第"<<iter<<"次迭代开始"<<endl; 
		
		ff(x0,y0); 
		
		//计算雅克比矩阵jacobian
		ffjacobian(x0,jacobian); 
		
		//计算雅克比矩阵的逆矩阵invjacobian
		inv_jacobian(jacobian,invjacobian); 
		
		//由近似解向量x0 计算近似解向量x1
		newdundiedai(x0, invjacobian,y0,x1); 
		
		//计算差向量的1范数errornorm errornorm=0;
		errornorm = 0;
		for (i=0;i<N;i++)
			errornorm=errornorm+fabs(x1[i]-x0[i]);
		
		if (errornorm<Epsilon) break;
		
		for (i=0;i<N;i++)
			x0[i]=x1[i];
	
	}while (iter<Max);
	
	return 0;
}

void ff(float xx[N],float yy[N]) //调用函数
{
	float x,y;
	int i;
	x=xx[0];
	y=xx[1];
	yy[0]=x*x-2*x-y+0.5;
	yy[1]=x*x+4*y*y-4; //计算初值位置的值
	cout<<"向量函数的因变量向量是:"<<endl;
	for( i=0;i<N;i++)
		cout<<yy[i]<<"	";
	cout<<endl<<endl;
}

void ffjacobian(float xx[N],float yy[N][N])
{
	float x,y;
	int i,j;
	x=xx[0];
	y=xx[1];
	//jacobian have n*n element 
	
	//计算函数雅克比的值
	yy[0][0]=2*x-2;
	yy[0][1]=-1;
	yy[1][0]=2*x;
	yy[1][1]=8*y;
	
	cout<<"雅克比矩阵是:"<<endl;
	
	for( i=0;i<N;i++)
	{
		for(j=0;j<N;j++)
			cout<<yy[i][j]<<"	";
		cout<<endl;
	}
	
	cout<<endl;

}

void inv_jacobian(float yy[N][N],float inv[N][N]) 
{
	float aug[N][N2],L;
	int i,j,k;

	cout<<"开始计算雅克比矩阵的逆矩阵:"<<endl;

	for(i=0;i<N;i++)
	{
		for(j=0;j<N;j++)
			aug[i][j]=yy[i][j];
	
		for(j=N;j<N2;j++)
			if(j==i+N) aug[i][j]=1;
			else aug[i][j]=0;
	}
	
	for (i=0;i<N;i++)
	{ 
		for(j=0;j<N2;j++)
			cout<<aug[i][j]<<" ";
		cout<<endl;
	}
	
	cout<<endl;
	for (i=0;i<N;i++)
	{
		for (k=i+1;k<N;k++)
		{
			L=-aug[k][i]/aug[i][i];
			for(j=i;j<N2;j++)
				aug[k][j]=aug[k][j]+L*aug[i][j];
		}
	}
	
	for (i=0;i<N;i++)
	{
		for(j=0;j<N2;j++)
			cout<<aug[i][j]<<"	";
		cout<<endl;
	
	}
	cout<<endl;
	
	for (i=N-1;i>0;i--)
	{
		for (k=i-1;k>=0;k--)
		{
			L=-aug[k][i]/aug[i][i];
			for(j=N2-1;j>=0;j--)
				aug[k][j]=aug[k][j]+L*aug[i][j];
		}
	}
	
	for (i=0;i<N;i++)
	{
		for(j=0;j<N2;j++)
			cout<<aug[i][j]<<"	";
		cout<<endl;
	}
	
	cout<<endl;
	for (i=N-1;i>=0;i--)
		for(j=N2-1;j>=0;j--)
			aug[i][j]=aug[i][j]/aug[i][i];
	
	for (i=0;i<N;i++)
	{ 
		for(j=0;j<N2;j++)
			cout<<aug[i][j]<<"	";
		
		cout<<endl;
		
		for(j=N;j<N2;j++)
			inv[i][j-N]=aug[i][j];
	}
	
	cout<<endl;
	
	cout<<"雅克比矩阵的逆矩阵:"<<endl;
	for (i=0;i<N;i++)
	{ 
		for(j=0;j<N;j++)
			cout<<inv[i][j]<<"	";
		cout<<endl;
	}
	
	cout<<endl;

}

void newdundiedai(float x0[N], float inv[N][N],float y0[N],float x1[N]) 
{
	
	int i,j;
	float sum=0;
	for(i=0;i<N;i++)
	{ 
		sum=0;
		for(j=0;j<N;j++)
			sum=sum+inv[i][j]*y0[j];
		x1[i]=x0[i]-sum;
	}
	cout<<"近似解向量:"<<endl;
	for (i=0;i<N;i++)
		cout<<x1[i]<<"	";
	cout<<endl<<endl;

}

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

牛顿迭代法求解二元非线性方程组,C++代码实现 的相关文章

随机推荐

  • 用vue3+elementplus做的一个滚动菜单栏的组件

    目录 起因 概览 设计及解决思路 1 滚动条竖起来 2 绑定菜单 3 吸附 优化 组件全部代码 起因 在elementplus中看到了滚动条绑定了slider 但是这个感觉很不实用 在底部 而且横向滚动 最常见的应该是那种固定在左上角的带着
  • 交叉编译适配mips架构的GDB

    交叉编译GDB 交叉编译GDB 1 下载GDB源码 2 解压并创建安装目录 3 编译安装 4 可能遇到的错误解决方法 1 下载termcap 2 将上面的编译安装gdb的脚本改一下 3 对于最后的权限不够无法删除PC机上termcap h文
  • 使用UE4(UnrealEngine)创建工程

    UE4系列文章目录 文章目录 UE4系列文章目录 前言 一 步骤 1 打开UE4软件 2 新建工程 3 选择游戏类型模板 4 项目设置 运行游戏 前言 使用UE4 UnrealEngine 创建工程 我这里的ue4版本是4 27 2 一 步
  • stm32循迹小车详细制作过程(附加完全版代码)

    stm32循迹小车详细制作过程 一 材料准备 1 主控板 Stm32f103c8t6 推荐 便宜够用 2 下载器 USB转TTL串口模块 3 电源 12v锂电池组 配套充电器 推荐下图这种 方便 好接线 12v 12v 12v 4 电机驱动
  • No module named ‘dateutil‘解决

    运行程序报错 无法直接pip install dateutil 需要pip install python dateutil
  • [非线性控制理论]6_滑模控制 (sliding mode control)

    非线性控制理论 1 Lyapunov直接方法 非线性控制理论 2 不变性原理 非线性控制理论 3 基础反馈稳定控制器设计 非线性控制理论 4 反馈线性化 反步法 非线性控制理论 5 自适应控制器 Adaptive controller 非线
  • CF 935E - Fafa and Ancient Mathematics

    CF 935E Fafa and Ancient Mathematics 题目描述 定义合法数学表达式 E E E 为一个数或两个合法数学表达式中间加上一个加或减运算符 并且在外面加上一对括号 给定一个合法数学表达式 将其中加减运算符用
  • QML Image内部缓存导致的问题

    QML Image BUG BUG描述 两个界面login qml 和 modify qml 页面 内部代码大致如下 Camera id camera imageProcessing whiteBalanceMode CameraImage
  • python实现vlookup_干货一:怎么在python里面实现vlookup

    vlookup应该是excel里用的比较多的功能 我刚接触excel的时候 反正觉得这个功能非常神奇 省了很多事 但是用久了以后就发现vlookup的限制太多了 第一大痛点 只能往右边 gt 找 如果要往左边找 最笨的办法就是把要找的col
  • rpm软件包解读

    一 linux应用程序与系统命令关系 二 典型应用程序的目录结构 三 常见的软件包封装类型 RPM包管理工具 RPM软件包管理器RED HAT PACKAGE MANAGER 由Red Hat公司提出 被众多linux发行版所采用 建立统一
  • 【机器学习】Q-Learning详细介绍

    Q learning Q learning 是一种机器学习方法 它使模型能够通过采取正确的操作来迭代学习和改进 Q learning属于强化学习的算法 通过强化学习 可以训练机器学习模型来模仿动物或儿童的学习方式 好的行为会得到奖励或加强
  • 如何从几何角度上理解方程组只有一个解_线性方程组的解集及其几何意义

    由于这三者之间的等价关系 我们解决现实问题时可以自由选取其中任意一个作为模型 我个人认为 线性方程组是最 质朴 的形式 向量方程则是与几何建立了关系 这将方便我们进行更直观的推理 矩阵方程则是向量方程的一种 封装 是向量方程的一种抽象 它将
  • Hotspot 垃圾回收之ConcurrentMarkSweepThread 源码解析

    目录 一 ConcurrentGCThread 二 SurrogateLockerThread 1 make 2 loop manipulatePLL 三 ConcurrentMarkSweepThread 1 定义 2 start和构造方
  • 微服务系列(六) 服务熔断与服务降级

    一 背景 分布式系统环境下 服务间类似依赖非常常见 一个业务调用通常依赖多个基础服务 如下图 对于同步调用 当库存服务不可用时 商品服务请求线程被阻塞 当有大批量请求调用库存服务时 最终可能导致整个商品服务资源耗尽 无法继续对外提供服务 并
  • element-ui表格列el-table-column如何根据数据不同显示不同的值,获取prop值

    方法一 格式化数据 在使用element ui的表格时 有时候后台给你的字段和你要显示在表格列里的内容不一致 例如后台给的字段是state 它的值为true或false 要求显示在表格里是 正确 或 错误 这时可以给el table col
  • FreeRTOS轻量级同步--任务通知

    1 简介 在FreeRTOS的配置参数中的configUSE TASK NOTIFICATIONS宏打开 一般RTOS会默认打开 如图1所示 图1 notify宏开关 RTOS在创建任务时 会创建一个32位的通知值ulNotifiedVal
  • C#中await Task.Run 返回值

    using System using System Text using System Collections Generic using System Threading using System Threading Tasks name
  • Cadence Allegro PCB设计88问解析(十一) 之 Allegro中文件自动保存时间设置

    一个学习信号完整性的layout工程师 大家在设计图纸或者编辑文档时 最常点击的应该就是保存图标了 谁也不想因为软件闪退 电脑断电等情况 我们的劳动成果就白白的消失了 在我们用Allegro进行PCB设计 就会有一个自动保存的功能 每隔一段
  • 一文看懂L1、L2正则化的区别

    正则化是一种为了减小测试误差的行为 有时候会增加训练误差 我们在构造机器学习模型时 最终目的是让模型在面对新数据的时候 可以有很好的表现 当你用比较复杂的模型比如神经网络 去拟合数据时 很容易出现过拟合现象 训练集表现很好 测试集表现较差
  • 牛顿迭代法求解二元非线性方程组,C++代码实现

    整体迭代公式就是 上式中 为的雅克比矩阵 为雅克比矩阵的逆矩阵 实例 求解的x和y的解 上面求根问题可转化为的问题 即可用牛顿迭代法求解此二元非线性方程 具体求解过程代码如下所示 线性方程组中方程个数 未知量个数 include