牛顿法解非线性方程组c++程序?

牛顿法解非线性方程组c++程序?,第1张

#include<iostream>

#include<cstdlib>

#include<cmath>

using

namespace

std

#define

N

2

//用来设置方程组的行数

#define

eps

2.2204e-16

double*

MatrixMultiply(double*

J,double

Y[])

double*

Inv(double

*J)

double

norm(double

Q[])

double*

F(double

X[])

double*

JF(double

X[])

int

method(double*

Y,double

epsilon)

int

newdim(double

P[],double

delta,double

epsilon,int

max1,double

*err)

{

double

*Y=NULL,*J=NULL,Q[2]={0},*Z=NULL,*temp=NULL

double

relerr=0.0

int

k=0,i=0,iter=0

Y=F(P)

for(k=1k<max1k++)

{

J=JF(P)

temp=MatrixMultiply(Inv(J),Y)

for(i=0i<Ni++)

Q[i]=P[i]-temp[i]

Z=F(Q)

for(i=0i<Ni++)

temp[i]=Q[i]-P[i]

*err=norm(temp)

relerr=*err/(norm(Q)+eps)

for(i=0i<Ni++)

P[i]=Q[i]

for(i=0i<Ni++)

Y[i]=Z[i]

iter=k

if((*err<delta)||(relerr<delta)||method(Y,epsilon))

break

}

return

iter

}

int

method(double*

Y,double

epsilon)

{

if(fabs(Y[0])<epsilon&&fabs(Y[1])<epsilon)

return

1

else

return

0

}

//矩阵乘法,要求,J为方阵,Y为与J维数相同的列向量

double

*MatrixMultiply(double*

J,double

Y[])

{

double

*X=NULL

int

i=0,j=0

X=(double*)malloc(N*sizeof(double))

for(i=0i<Ni++)

X[i]=0

for(i=0i<Ni++)

for(j=0j<Nj++)

X[i]+=J[i*N+j]*Y[j]

return

X

}

//二阶矩阵的求逆(在M次多项式曲线拟合算法文件中给出了对任意可逆矩阵的求逆算法)

double

*Inv(double

*J)

{

double

X[4]={0},temp=0.0

int

i=0

temp=1/(J[0]*J[3]-J[1]*J[2])

X[0]=J[3]

X[1]=-J[1]

X[2]=-J[2]

X[3]=J[0]

for(i=0i<4i++)

J[i]=temp*X[i]

return

J

}

double

norm(double

Q[])

{

double

max=0.0

int

i=0

for(i=0i<Ni++)

{

if(Q[i]>max)

max=Q[i]

}

return

max

}

double*

F(double

X[])

{

double

x=X[0]

double

y=X[1]

double

*Z=NULL

Z=(double*)malloc(2*sizeof(double))

Z[0]=x*x-2*x-y+0.5

Z[1]=x*x+4*y*y-4

return

Z

}

double*

JF(double

X[])

{

double

x=X[0]

double

y=X[1]

double

*W=NULL

W=(double*)malloc(4*sizeof(double))

W[0]=2*x-2

W[1]=-1

W[2]=2*x

W[3]=8*y

return

W

}

main()

{

double

P[2]={0}

double

delta=0.0,epsilon=0.0,err=0.0

int

max1=0,iter=0,i=0

cout<<"牛顿法解非线性方程组:\nx^2-4-y+2=0\nx^2+4*y^2-2=0\n"

cout<<"\n输入的初始近似值x0,y0\n"

for(i=0i<2i++)

cin>>P[i]

cout<<"请依次输入P的误差限,F(P)的误差限,最大迭代次数\n"

cin>>delta

cin>>epsilon

cin>>err

iter=newdim(P,delta,epsilon,max1,&err)

cout<<"收敛到P的解为:\n"

for(i=0i<2i++)

cout<<"X("<<i+1<<")="<<P[i]<<endl

cout<<"\n迭代次数为:

"<<iter

cout<<"\n."<<err<<endl

getchar()

}

Newton-Raphson 求解非线性方程组matlab源程序

matlab程序如下:

function hom

[P,iter,err]=newton('f','JF',[7.8e-0014.9e-0013.7e-001],0.01,0.001,1000)

disp(P)

disp(iter)

disp(err)

function Y=f(x,y,z)

Y=[x^2+y^2+z^2-1

2*x^2+y^2-4*z

3*x^2-4*y+z^2]

function y=JF(x,y,z)

f1='x^2+y^2+z^2-1'

f2='2*x^2+y^2-4*z'

f3='3*x^2-4*y+z^2'

df1x=diff(sym(f1),'x')

df1y=diff(sym(f1),'y')

df1z=diff(sym(f1),'z')

df2x=diff(sym(f2),'x')

df2y=diff(sym(f2),'y')

df2z=diff(sym(f2),'z')

df3x=diff(sym(f3),'x')

df3y=diff(sym(f3),'y')

df3z=diff(sym(f3),'z')

j=[df1x,df1y,df1zdf2x,df2y,df2zdf3x,df3y,df3z]

y=(j)

function [P,iter,err]=newton(F,JF,P,tolp,tolfp,max)

%输入P为初始猜测值,输出P则为近似解

%JF为相应的Jacobian矩阵

%tolp为P的允许误差

%tolfp为f(P)的允许误差

%max:循环次数

Y=f(F,P(1),P(2),P(3))

for k=1:max

J=f(JF,P(1),P(2),P(3))

Q=P-inv(J)*Y

Z=f(F,Q(1),Q(2),Q(3))

err=norm(Q-P)

P=Q

Y=Z

iter=k

if (err<tolp)||(abs(Y)<tolfp||abs(Y)<0.0001)

break

end

end

<pre lang="matlab" line="1" file="test.m">

function homework4

[P,iter,err]=newton('f','JF',[7.8e-0014.9e-0013.7e-001],0.01,0.001,1000)

disp(P)

disp(iter)

disp(err)

function Y=f(x,y,z)

Y=[x^2+y^2+z^2-1

2*x^2+y^2-4*z

3*x^2-4*y+z^2]

function y=JF(x,y,z)

f1='x^2+y^2+z^2-1'

f2='2*x^2+y^2-4*z'

f3='3*x^2-4*y+z^2'

df1x=diff(sym(f1),'x')

df1y=diff(sym(f1),'y')

df1z=diff(sym(f1),'z')

df2x=diff(sym(f2),'x')

df2y=diff(sym(f2),'y')

df2z=diff(sym(f2),'z')

df3x=diff(sym(f3),'x')

df3y=diff(sym(f3),'y')

df3z=diff(sym(f3),'z')

j=[df1x,df1y,df1zdf2x,df2y,df2zdf3x,df3y,df3z]

y=(j)

function [P,iter,err]=newton(F,JF,P,tolp,tolfp,max)

%输入P为初始猜测值,输出P则为近似解

%JF为相应的Jacobian矩阵

%tolp为P的允许误差

%tolfp为f(P)的允许误差

%max:循环次数

Y=f(F,P(1),P(2),P(3))

for k=1:max

J=f(JF,P(1),P(2),P(3))

Q=P-inv(J)*Y

Z=f(F,Q(1),Q(2),Q(3))

err=norm(Q-P)

P=Q

Y=Z

iter=k

if (err<tolp)||(abs(Y)<tolfp||abs(Y)<0.0001)

break

end

牛顿迭代法(Newton's method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。

中文名

牛顿迭代法

外文名

Newton's method

别名

牛顿-拉夫逊(拉弗森)方法

提出时间

17世纪

快速

导航

牛顿迭代公式

其他迭代算法

C语言代码

C++代码

matlab代码

Python代码

Java代码

JavaScript代码

Fortran代码

产生背景

多数方程不存在求根公式,因此求精确根非常困难,甚至不可解,从而寻找方程的近似根就显得特别重要。方法使用函数 的泰勒级数的前面几项来寻找方程 的根。牛顿迭代法是求方程根的重要方法之一,其最大优点是在方程 的单根附近具有平方收敛,而且该法还可以用来求方程的重根、复根,此时线性收敛,但是可通过一些方法变成超线性收敛。另外该方法广泛用于计算机编程中。

牛顿迭代公式

设 是 的根,选取 作为 的初始近似值,过点 做曲线 的切线 , ,则 与 轴交点的横坐标 ,称 为 的一次近似值。过点 做曲线 的切线,并求该切线与x轴交点的横坐标 ,称 为r的二次近似值。重复以上过程,得 的近似值序列,其中, 称为 的 次近似值,上式称为牛顿迭代公式。

用牛顿迭代法解非线性方程,是把非线性方程 线性化的一种近似方法。把 在点 的某邻域内展开成泰勒级数 ,取其线性部分(即泰勒展开的前两项),并令其等于0,即 ,以此作为非线性方程 的近似方程,若 ,则其解为 , 这样,得到牛顿迭代法的一个迭代关系式: 。

已经证明,如果是连续的,并且待求的零点是孤立的,那么在零点周围存在一个区域,只要初始值位于这个邻近区域内,那么牛顿法必定收敛。 并且,如果不为0, 那么牛顿法将具有平方收敛的性能. 粗略的说,这意味着每迭代一次,牛顿法结果的有效数字将增加一倍。

迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题。迭代算法是用计算机解决问题的一种基本方法。它利用计算机运算速度快、适合做重复性 *** 作的特点,让计算机对一组指令(或一定步骤)重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。

利用迭代算法解决问题,需要做好以下三个方面的工作:

一、确定迭代变量

在可以用迭代算法解决的问题中,至少存在一个可直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量。

二、建立迭代关系式

所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系)。迭代关系式的建立是解决迭代问题的关键,通常可以使用递推或倒推的方法来完成。

三、对迭代过程进行控制

在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题。不能让迭代过程无休止地执行下去。迭代过程的控制通常可分为两种情况:一种是所需的迭代次数是个确定的值,可以计算出来;另一种是所需的迭代次数无法确定。对于前一种情况,可以构建一个固定次数的循环来实现对迭代过程的控制;对于后一种情况,需要进一步分析得出可用来结束迭代过程的条件。

其他迭代算法

欧几里德算法

最经典的迭代算法是欧几里德算法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:

定理:gcd(a,b) = gcd(b,a mod b)

证明:a可以表示成a = kb + r,则r = a mod b。假设d是a,b的一个公约数,则有 a%d==0,b%d==0,而r = a - kb,因此r%d==0 ,因此d是(b,a mod b)的公约数

查看更多


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12157759.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存