一 理论背景我们先考虑线性方程,线性方程组的解便不难得出了。
与线性方程相比,非线性方程问题无论是从理论上还是从计算公式上,都要复杂得多。
对于一般的非线性方程()0f x =,计算方程的根既无一定章程可寻也无直接法可言。
例如,求解高次方程组637 1.50x x x -+-=的根,求解含有指数和正弦函数的超越方程cos()0xe x π-=的零点。
解非线性方程或方程组也是计算方法中的一个主题。
在解方程方面,牛顿(I . Newton )提出了方程求根的一种迭代方法,被后人称为牛顿算法。
三百年来,人们一直用牛顿算法,改善牛顿算法,不断推广算法的应用范围。
牛顿算法,可以说是数值计算方面的最有影响的计算方法。
对于言程式()0f x =,如果()f x 是线性函数,则它的求根是容易的。
牛顿法实质上是一种线性化方法,其基本思想是将非线性方程式()f x 逐步归结为某种线性方程来求解。
解非线性方程组只是非线性方程的一种延伸和扩展。
二 主要理论 考虑方程组111(,...)0,.................(,...)0.n n n f x x f x x =⎧⎪⎨⎪=⎩ ()1其中1,...,nf f 均为1(,...)n x x 多元函数。
若用向量记号记11(,...),(,...,)T n Tn n x x x R F f f =∈=,()1 就可写成()0.F x = (2)当2,n ≥,且(1,...,)i f i n =中至少有一个是自变量(1,...,)i x i n =的非线性函数时,则称方程组(1)为非线性方程组。
非线性方程组求根问题是前面介绍的方程即(1)n =求根的直接推广,实际上只要把单变量函数()f x 看成向量函数()F x 则可将单变量方程求根方法推广到方程组(2)。
若已给出方程组(2)的一个近似根 ()1(,...,),k k k Tn xx x = 将函数()F x 的分量()(1,...,)i f x i n =在()k x 用多元函数泰勒展开,并取其线性部分,则可表示为()()()()()()().k k k F x F x F x x x '≈+-令上式右端为零,得到线性方程组()()()()()(),k k k F x x x F x '-=- (3)其中111122221212()()()()()()()()()()n n n n n n f x f x f x x xx f x f x f x x xx F x f x f x f x x x x ∂∂∂⎡⎤⎢⎥∂∂∂⎢⎥⎢⎥∂∂∂⎢⎥∂∂∂⎢⎥'=⎢⎥⎢⎥⎢⎥⎢⎥∂∂∂⎢⎥∂∂∂⎣⎦(4)称为()F x 为雅可比(Jacobi )矩阵。
求解线性方程组(3),并记解为(1)k x +,则得(1)()()1()()()k k k k x x F x F x +-'=- (0,1,...).k = (5)这就是解非线性方程组(2)的牛顿法。
三.算法牛顿法主要思想是用(1)()()1()()()k k k k x x F x F x +-'=-(0,1,...).k = 进行迭代 。
因此首先需要算出()F x 的雅可比矩阵()F x ',再求过()F x '求出它的逆1()F x -',当它达到某个精度(x_k)时即停止迭代。
具体算法如下:1. 首先宏定义方程组()F x ,确定步长_x 和精度(x_k);2.求()F x 的雅可比矩阵()F x ';可用111(,...,,...,)(,...,_,...,)(,...,,...,)_i j n i j n i j n jf x x x f x x x x f x x x x x ∂+-=∂求出雅可比矩阵; 3.求雅可比矩阵()F x '的逆1()F x -';将()F x '右乘一个单位矩阵1001⎛⎫⎪ ⎪ ⎪⎝⎭,通过单位矩阵变换实现求()F x ' 的逆,用指针来存贮。
4. 雅可比矩阵()F x '与其逆1()F x -'的相乘;5. 用(5)来迭代;6.当精度ix_k 大于x_k 时,重复执行2——5步,直到精度小于或等于x_k 停止迭代,ix_k 就是最后的迭代结果。
其中i x_k =四.代码#include <iostream.h> #include <stdlib.h> #include <math.h> #include <conio.h>#define f0(x1,x2) (x1+2*x2-3)#define f1(x1,x2) (2*x1*x1+x2*x2-5) #define x_ 0.000001 #define matrixNum 2double *matrixF2(double *x); int y=0; void main() {int i,j,n; double p,*x; double *b; double *matrixF; //矩阵Fdouble *matrixF_; //矩阵F 的雅可比矩阵的逆b=(double *)malloc(matrixNum);matrixF=(double *)malloc(matrixNum);matrixF_=(double *)malloc(matrixNum*matrixNum);cout<<"请输入初值:";for(i=0;i<matrixNum;i++)cin>>*(x+i);do{p=0.0;for(i=0;i<matrixNum;i++)*(b+i)=0;*matrixF=f0(*x,*(x+1));*(matrixF+1)=f1(*x,*(x+1));matrixF_=matrixF2(x);for(i=0;i<matrixNum;i++){for(j=0;j<matrixNum;j++)*(b+i)+=*(matrixF_+i*matrixNum+j)*(*(matrixF+j));*(x+i)=*(x+i)-*(b+i);cout<<*(x+i)<<" ";}cout<<endl;for(i=0;i<matrixNum;i++)p+=pow(*(b+i),2);y++;}while(sqrt(p)>x_);cout<<"停止迭代,最终迭代结果为"<<*x<<','<<*(x+1)<<""<<endl;delete [] matrixF;delete [] matrixF_;getch();}double *matrixF2(double *x){int i,j;double t;double *matrixF1; //矩阵F的雅可比矩阵double *matrixF2; //矩阵F的雅可比矩阵的逆matrixF1=(double *)malloc(matrixNum*matrixNum);matrixF2=(double *)malloc(matrixNum*matrixNum);for(i=0;i<matrixNum;i++)for(j=0;j<matrixNum;j++)if(i==j)*(matrixF2+i*matrixNum+j)=1;else *(matrixF2+i*matrixNum+j)=0;*matrixF1=(f0((*x+x_),*(x+1))-f0(*x,*(x+1)))/x_;*(matrixF1+1)=(f0(*x,(*(x+1)+x_))-f0(*x,*(x+1)))/x_;*(matrixF1+2)=(f1((*x+x_),*(x+1))-f1(*x,*(x+1)))/x_;*(matrixF1+3)=(f1(*x,(*(x+1)+x_))-f1(*x,*(x+1)))/x_;//for(i=0;i<matrixNum;i++)// cout<<*(x+i)<<endl;cout<<"矩阵F在["<<*x<<','<<*(x+1)<<"]的雅可比矩阵"<<endl;for(i=0;i<matrixNum;i++){for(j=0;j<matrixNum;j++)cout<<*(matrixF1+i*matrixNum+j)<<" ";cout<<endl;}//求矩阵F的雅可比矩阵的逆t=*matrixF1;for(i=0,j=0;j<matrixNum;j++){*(matrixF1+i*matrixNum+j)/=t;*(matrixF2+i*matrixNum+j)/=t;}t=*(matrixF1+1*matrixNum);for(i=1,j=0;j<matrixNum;j++){*(matrixF1+i*matrixNum+j)-=*(matrixF1+j)*t;*(matrixF2+i*matrixNum+j)-=*(matrixF2+j)*t;}t=*(matrixF1+1*matrixNum+1);for(i=1,j=0;j<matrixNum;j++){*(matrixF1+i*matrixNum+j)/=t;*(matrixF2+i*matrixNum+j)/=t;}t=*(matrixF1+1);for(i=i,j=0;j<matrixNum;j++){*(matrixF1+j)-=*(matrixF1+i*matrixNum+j)*t;*(matrixF2+j)-=*(matrixF2+i*matrixNum+j)*t;}for(i=0;i<matrixNum;i++){for(j=0;j<matrixNum;j++)cout<<*(matrixF1+i*matrixNum+j)<<" ";cout<<endl;}for(i=0;i<matrixNum;i++) { for(j=0;j<matrixNum;j++) cout<<*(matrixF2+i*matrixNum+j)<<" "; cout<<endl; } cout<<"第"<<y<<"次迭代结果为"<<*x<<','<<*(x+1)<<""<<endl; getch();return matrixF2; delete [] matrixF1; delete [] matrixF2; }五.算法分析及改进措施牛顿法解非线性方程组是一种线性方法,即将非线性方程组以一线性方程组来近似,由此构造一种迭代格式,用以逐次逼近 所求的解案。