c++求解非线性方程组的牛顿顿迭代法
数值分析求解非线性方程根的二分法简单迭代法和牛顿迭代法

实验报告一:实验题目一、 实验目的掌握求解非线性方程根的二分法、简单迭代法和牛顿迭代法,并通过数值实验比较两种方法的收敛速度。
二、 实验内容1、编写二分法、并使用这两个程序计算02)(=-+=x e x x f 在[0, 1]区间的解,要求误差小于 410- ,比较两种方法收敛速度。
2、在利率问题中,若贷款额为20万元,月还款额为2160元,还期为10年,则年利率为多少?请使用牛顿迭代法求解。
3、由中子迁移理论,燃料棒的临界长度为下面方程的根,用牛顿迭代法求这个方程的最小正根。
4、用牛顿法求方程的根,精确至8位有效数字。
比较牛顿迭代法算单根和重根的收敛速度,并用改进的牛顿迭代法计算重根。
第1题:02)(=-+=x e x x f 区间[0,1] 函数画图可得函数零点约为0.5。
画图函数:function Test1()% f(x) 示意图, f(x) = x + exp(x) - 2; f(x) = 0r = 0:0.01:1;y = r + exp(r) - 2plot(r, y);grid on 二分法程序:计算调用函数:[c,num]=bisect(0,1,1e-4)function [c,num]=bisect(a,b,delta)%Input –a,b 是取值区间范围% -delta 是允许误差%Output -c 牛顿迭代法最后计算所得零点值% -num 是迭代次数ya = a + exp(a) - 2;yb = b + exp(b) - 2;if ya * yb>0return;endfor k=1:100c=(a+b)/2;yc= c + exp(c) - 2;if abs(yc)<=deltaa=c;b=c;elseif yb*yc>0b=c;yb=yc;elsea=c;ya=yc;endif abs(b-a)<deltanum=k; %num为迭代次数break;endendc=(a+b)/2;err=abs(b-a);yc = c + exp(c) - 2;牛顿迭代法程序:计算调用函数:[c,num]=newton(@func1,0.5,1e-4) 调用函数:function [y] = func1(x)y = x + exp(x) - 2;end迭代算法:function[c,num]=newton(func,p0,delta)%Input -func是运算公式% -p0是零点值% -delta是允许误差%Output -c牛顿迭代法最后计算所得零点值% -num是迭代次数num=-1;for k=1:1000y0=func(p0);dy0=diff(func([p0 p0+1e-8]))/1e-8;p1=p0-y0/dy0;err=abs(p1-p0);p0=p1;if(err<delta)num=k;%num为迭代次数break;endendc=p0;第2题:由题意得到算式:计算调用函数:[c,num]=newton(@func2,0.02,1e-8)程序:先用画图法估计出大概零点位置在0.02附近。
C++二元非线性方程组

二元非线性方程牛顿迭代法C++代码。
小弟需要解一个二元非线性方程组,虽然说matlab的解法是一两个代码的事,但是我的情况是需要在C++ 里面实现。
由于自己不熟悉C++代码和牛顿迭代法的解法,小弟最近在网上找了一些资料。
发现很多有问题的例子,纯粹是在误导别人,浪费别人的时间。
于是小弟自己在看了解法(牛顿迭代法)的基础上,自己通过C++ 语言实现了一些简单方程组的解法,分享给给大家。
1. 非线性方程组的解法原理我在网上找了一个资料,应该是中南大学计算机学院的教程,如下:注意,他这里的例子第二个方程应该是,x1*x2*x2+x1-10*x2+8经过观察,我发现其实对于2元方程来说:f(x1,x2)和g(x1,x2)。
牛顿迭代法里面的迭代量(Δx 1 和Δx 2) 可以如下表示。
(我看到网上很多例子用矩阵来表示,我表示看不太懂,而且根据网上贴出来的程序,发现有错误。
而我发现对于2元方程来说,用下面的表示方法更直观,更简单。
2元方程并不需要再学习矩阵的相关知识。
)()()()221121211,,,x x x f x x x f x x f x ∂∂+∂∂-=∆ ()()()221121212,x x x x g x ∂+∂-=∆2. 代码(运行环境, VS 2010, WIN 7 64)// Nonlinear.cpp : Defines the entry point for the console application.//#include"stdafx.h"#include<math.h>#include<iostream>using namespace std;int _tmain(int argc, _TCHAR* argv[]){double x1,x2; //变量x1,x2;double x1_0,x2_0; //变量x1,x2迭代前的值double x1_1,x2_1; //变量x1,x2迭代后的值double delta_x1,delta_x2; //变量double function_F,function_G; //方程f(x1,x2) 和g(x1,x2)double F_x1,F_x2; //方程f的偏导double G_x1,G_x2; //方程g的偏导double Error=1e-10; //给定的误差double Error_cout; //用来计算的误差int Steps; //运行步骤int Max_Steps=100000; //最大运行步骤x1 = 0.5;x2 = 0.5; //初始化初值x1_0 = x1;x2_0 = x2;for(Steps=1;Steps<=Max_Steps;Steps++){// 方程组, f(x1,x2), g(x1,x2)function_F = x1_0*x1_0-10.0*x1_0+x2_0*x2_0+8.0; // 10.0的意思是double类型,10 是指整数类型function_G = x1_0*x2_0*x2_0+x1_0-10.0*x2_0+8.0;// 偏导,F_x1 = 2.0*x1_0-10.0;F_x2 = 2.0*x2_0;G_x1 = x1_0*x1_0+1.0;G_x2 = 2.0*x1_0*x2_0-10.0;// 迭代delta_x1 = -function_F/(F_x1+F_x2);delta_x2 = -function_G/(G_x1+G_x2);x1_1 = x1_0 + delta_x1;x2_1 = x2_0 + delta_x2;x1_0 = x1_1; //迭代,将新计算的变量赋值给原始变量x2_0 = x2_1;Error_cout = fabs(delta_x1)+fabs(delta_x2);if(Error_cout<Error)break; //当迭代到某个次数时,变量变化不大的时候就不运行了}printf(" Run steps is %d\n",Steps);printf(" x1 is %lf\n",x1_0);printf(" x2 is %lf\n",x2_0);return 0;}运行结果为:当然,对于有些方程用这个方法是解不了的,大家可以查一下阻尼牛顿法!。
非线性方程求根—牛顿迭代法(新)

非线性方程求根——牛顿迭代法一、牛顿迭代法的基本思想基本思想:将非线性方程逐步归结为某种线性方程求解。
设方程f (x )=0有近似根x k (f `(x k )≠0),将f (x )在x k 展开:(ξ在x 和x k 之间)2()()()()()()2!k k k k f f x f x f x x x x x ξ'''=+-+-()()()()k k k f x f x f x x x '≈+-可设记该线性方程的根为x k +1,则()()()0k k k f x f x x x '+-=1()()k k k k f x x x f x +=-'故f (x )=0可近似表示为即为Newton 法迭代格式。
(k =0,1,……)例:用Newton 迭代法求方程310x x --=在x 0=1.5附近的近似实根。
解:32()1,()31f x x x f x x '=--=-迭代公式为312131kk k k k x x x x x +--=--计算步骤如下:(1)取初值x 0=1.5;(2)按照迭代公式计算x 1;(3)若|x 1-x 0|<=0.00001,终止迭代;否则,x 0=x 1;转(2);(4)输出迭代次数和近似根.二、牛顿迭代法的实现MATLAB求解程序设计:方程及一阶导数函数:function[fun,dfun]=fun0(x)fun=x^3-x-1;%求原函数的值dfun=3*x^2-1;%求一阶导数的值计算主程序:clearx0=1.5;[fun,dfun]=fun0(x0);x1=x0-fun/dfun;i=1;while abs(x1-x0)>1e-5x0=x1;[fun,dfun]=fun0(x0);x1=x0-fun/dfun;i=i+1;enddisp('the solution is x1=')x1disp('the iter time is ')i计算结果为:the solution is x1=x1 =1.3247the iter time isi =4可见经过4次迭代即到达要求的精度,原方程的一个近似实数根为1.3247.三、牛顿迭代法的收敛性牛顿迭代法的迭代函数:)()()(x f x f x x '-=ϕ222)]([)()()]([)()()]([1)(x f x f x f x f x f x f x f x '''='''-'-='ϕ设f (x *)=0,f `(x *)≠0,则ϕ`(x *)=0,故Newton 迭代法在x *附近至少平方收敛。
牛顿迭代法求解非线性方程组的解

10 简化牛顿法 简化牛顿法又称平行弦法,其迭代公式为
xk1 xk Cf (xk ),C 0, k 0,1,
(4-7)
从不动点迭代法的角度看,简化牛顿法的迭代函数(x) x Cf (x) ,下面讨论简
化牛顿法的收敛性。
若| '(x) ||1 Cf '(x) | 1 ,即取 0 Cf ' (x) 2 .在根 x* 附近成立,则迭代法
x k 的点 Pk 引切线,并将该切线与 x 轴的交点的横坐标 x k1 作为 x* 的新的近似值。 注意到切线方程为
y f (xk ) f '(xk )(x xk )
(4-4)
这样求得的值 x k1 比满足 f (xk ) f '(xk )(x xk ) 0 ,从而就是牛顿公式
x
k 1
| f (xk1) || f (xk ) |
(4-8)
满足此要求的算法称为下山法。
将牛顿法和下山法一起使用时,即在下山法保证函数值稳定下降的前提下,
用牛顿法加快收敛速度。为此,为此将牛顿法的计算结果
xk 1
xk
f (xk ) f ' (xk )
(4-9)
与前一步的近似值 xk 的适当加权平均作为新的改进值
代法中所遇到的 jacobi 矩阵难求的问题。
关键词:非线性方程组、牛顿迭代法、MATLAB、 jacobi 矩阵
一、前言 非线性方程组在实际问题中经常出现,并且在科学与工程计算中的地位越来
越来重要,很多常见的线性模型都是在一定条件下由非线性问题简化得到的,为 得到更符合实际的解答,往往需要直接研究非线性模型,然而从线性到非线性是 一个质的飞跃,方程的性质的不同,所以求解方法也有很大差别。本文主要介绍 关于非线性方程及方程组的数值解法,先分析非线性方程的数值解法,然后再延 伸到方程组的解法。
c++ 牛顿迭代法解方程组

c++ 牛顿迭代法解方程组牛顿迭代法是一种求解方程的数值方法,它通过迭代逼近的方式,不断接近方程的解。
首先,我们需要定义要解的方程组。
假设我们要求解的方程组为:f1(x1, x2, ..., xn) = 0f2(x1, x2, ..., xn) = 0...fn(x1, x2, ..., xn) = 0其中,f1, f2, ..., fn是方程组中的各个方程,x1, x2, ..., xn是方程组的未知数。
接下来,我们可以利用牛顿迭代法来求解这个方程组。
具体步骤如下:1. 首先,我们需要给出方程组的初始猜测解。
设初始解为x^(0) = (x1^(0), x2^(0), ..., xn^(0))。
2. 然后,我们计算方程组在初始解处的Jacobi矩阵J^(0),即:J^(0) = [[∂f1/∂x1, ∂f1/∂x2, ..., ∂f1/∂xn],[∂f2/∂x1, ∂f2/∂x2, ..., ∂f2/∂xn],...[∂fn/∂x1, ∂fn/∂x2, ..., ∂fn/∂xn]]其中,∂f/∂x表示方程f对未知数x的偏导数。
3. 接下来,我们计算方程组在初始解处的函数值向量F^(0),即:F^(0) = [f1(x1^(0), x2^(0), ..., xn^(0)),f2(x1^(0), x2^(0), ..., xn^(0)),...fn(x1^(0), x2^(0), ..., xn^(0))]4. 然后,我们可以利用牛顿迭代公式来更新解,即:x^(k+1) = x^(k) - (J^(k))^(-1) * F^(k)其中,x^(k)表示第k次迭代的解,J^(k)表示第k次迭代的Jacobi矩阵,F^(k)表示第k次迭代的函数值向量。
5. 将更新后的解x^(k+1)代入方程组,并重新计算Jacobi矩阵和函数值向量。
6. 重复步骤4和步骤5,直到满足迭代停止的条件。
常见的迭代停止条件有:达到最大迭代次数、解的变化小于某个阈值、函数值的范数小于某个阈值等。
c++ 牛顿迭代法解方程组

c++ 牛顿迭代法解方程组牛顿迭代法(Newton's Method)是一种用于解方程的迭代算法,可以用于解非线性方程组。
下面是使用 C++ 实现牛顿迭代法解方程组的示例:#include <iostream>#include <cmath>// 定义方程组中的函数double f1(double x, double y) {return x * x + y * y - 1;}double f2(double x, double y) {return x - y * y;}// 定义方程组中的偏导数double df1_dx(double x, double y) {return 2 * x;}double df1_dy(double x, double y) {return 2 * y;}double df2_dx(double x, double y) {return 1;}double df2_dy(double x, double y) {return -2 * y;}// 牛顿迭代法解方程组void newtonIteration(double x0, double y0, int maxIterations) { double epsilon = 1e-6; // 迭代精度double x = x0;double y = y0;for (int i = 0; i < maxIterations; i++) {double det = df1_dx(x, y) * df2_dy(x, y) - df1_dy(x, y) * df2_dx(x, y);double dx = (-f1(x, y) * df2_dy(x, y) + f2(x, y) * df1_dy(x, y)) / det;double dy = (f1(x, y) * df2_dx(x, y) - f2(x, y) * df1_dx(x, y)) / det;x += dx;y += dy;if (std::abs(dx) < epsilon && std::abs(dy) < epsilon) { std::cout << "Converged to solution: x = " << x << ", y = " << y << std::endl;return;}}std::cout << "Iteration did not converge to a solution" << std::endl;}int main() {double initialX = 0.5;double initialY = 0.5;int maxIterations = 100;newtonIteration(initialX, initialY, maxIterations);return 0;}在上述示例中,我们定义了一个方程组,包含两个方程 f1(x, y) = x^2 + y^2 - 1和f2(x, y) = x - y^2。
非线性方程的牛顿法

求函数 f x x 10 x 精度要求: 106
3
例题2
2
19.68x 10.944 的正实根
用Matlab画图,查看根的分布情形
从图形中我们可 以看出: 在x=7和x=8 之 间有一单根; 在x=1和x=2 之 间有一重根。
初值x0=8.0 时,计算的是单根, The iterative number is 28,The numerical solution is 7.600001481 初值x0=1.0 ,计算的是重根, The iterative number is 1356,The numerical solution is 1.198631981
重复上述过程
xk 1
f ( xk ) xk f ( xk )
牛顿法的几何意义
Tangent line : y f ( x0 ) f ( x0 )( x x0 )
y
f ( x0 ) x1 x0 f ( x0 )
x*
x2
x
x1 x0
牛顿法也称为切线法
f ( x1 ) x2 x1 f ( x1 )
例3:设C为正实数,导出用牛顿法求 C 的公式,并证明 2 en 迭代序列的误差 en xn C 满足 en 1 2 xn 2 x C 解:设 x C ,则 于是有
f ( x) x 2 C, f ' ( x) 2x, f ' ' ( x) 2
由于 f (0) C, f ( C 1) 2 C 1 0 ], 所以在 [0,1 C ] 内有一正根.又在 [0,1 C 内 f ' ( x) 0, f ' ' ( x) 0根据定理得牛顿迭代格式为:
非线性方程组的牛顿迭代法-最速下降法

数学软件实验任务书实验一 非线性方程组的牛顿迭代法 1 实验原理对于非线性方程11221212(,,,)(,,,)(,,,)n n n n f x x x f x x x f f x x x ⎛⎫ ⎪ ⎪= ⎪ ⎪⎝⎭ 在x (k )处按照多元函数的泰勒展开,并取线性项得到 ()()()()(1)()1111()()()()(1)()()122()()()()(1)()1(,,,)(,,,)()0(,,,)k k k k k k n n k k k k k k k n n n k k k k k k n n n nn f x x x x x f x x x x x f x f x x x x x +++⎛⎫⎛⎫- ⎪ ⎪- ⎪ ⎪'+= ⎪ ⎪ ⎪ ⎪ ⎪ ⎪-⎝⎭⎝⎭ 其中1111()n n n n f f x x f x f f x x ∂∂⎛⎫ ⎪∂∂ ⎪' ⎪= ⎪∂∂ ⎪ ⎪∂∂⎝⎭(1)()()()()()1111(1)()()()()()()1221(1)()()()()()1(,,,)(,,,)[()](,,,)k k k k k k n n k k k k k k k n n n k k k k k k n n n n n x x f x x x x x f x x x f x x x f x x x ++-+⎛⎫⎛⎫⎛⎫ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪'=- ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎝⎭⎝⎭⎝⎭ 2 数据来源计算非线性方程组22220.50440x x y x y ⎧--+=⎨+-=⎩ 初值取11x y ⎡⎤⎡⎤=⎢⎥⎢⎥⎣⎦⎣⎦3 实验步骤步骤一:编写牛顿迭代法的基本程序。
打开Editor 编辑器,输入以下语句:function [x,n,data]=new_ton(x0,tol)if nargin==1tol=1e-10;endx1=x0-f1(x0)/df1(x0);MATLAB 241 数值分析与应用n=1;%迭代过程while (norm(x1-x0)>tol)x0=x1;x1=x0-f1(x0)/df1(x0);n=n+1;%data 用来存放中间数据data(:,n)=x1;endx=x1;以文件名new_ton.m保存。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
牛顿迭代法c++程序设计
求解{0=x*x-2*x-y+0.5;
0=x*x+4*y*y-4;
}的方程
#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;cout<<endl;
do
{
iter=iter+1;
cout<<"第"<<iter<<" 次迭代开始"<<endl; //计算向量函数的因变量向量y0
ff(x0,y0); //计算雅克比矩阵jacobian
ffjacobian(x0,jacobian); //计算雅克比矩阵的逆矩阵invjacobian
inv_jacobian(jacobian,invjacobian); //由近似解向量x0 计算近似解向量x1
newdundiedai(x0, invjacobian,y0,x1); //计算差向量的1范数errornorm 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;
cout<<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<<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<<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;cout<<endl;
}。