C语言解多次方程方法
- 格式:doc
- 大小:110.50 KB
- 文档页数:8
c语言解方程式In the realm of computer programming, C language stands as a powerful tool for numerical computations, including solving equations. When it comes to solving equations in C, there are several approaches that can be employed, depending on the nature and complexity of the equation.在计算机编程领域,C语言是一个用于数值计算(包括解方程式)的强大工具。
在C语言中解方程式时,可以根据方程式的性质和复杂度采用不同的方法。
For simple algebraic equations, such as linear or quadratic equations, we can implement algorithms that directly apply the relevant formulas to find the solution. For example, to solve a quadratic equation ax²+ bx + c = 0, we can use the quadratic formula x = [-b ± √(b² - 4ac)] / (2a). In C, we would calculate the discriminant, determine the sign of the root, and then compute the solutions accordingly.对于简单的代数方程,如线性方程或二次方程,我们可以实现直接应用相关公式的算法来找到解。
一 理论背景我们先考虑线性方程,线性方程组的解便不难得出了。
与线性方程相比,非线性方程问题无论是从理论上还是从计算公式上,都要复杂得多。
对于一般的非线性方程()0f x =,计算方程的根既无一定章程可寻也无直接法可言。
例如,求解高次方程组637 1.50x x x -+-=的根,求解含有指数和正弦函数的超越方程cos()0xe x π-=的零点。
解非线性方程或方程组也是计算方法中的一个主题。
在解方程方面,牛顿(I . Newton )提出了方程求根的一种迭代方法,被后人称为牛顿算法。
三百年来,人们一直用牛顿算法,改善牛顿算法,不断推广算法的应用范围。
牛顿算法,可以说是数值计算方面的最有影响的计算方法。
对于言程式()0f x =,如果()f x 是线性函数,则它的求根是容易的。
牛顿法实质上是一种线性化方法,其基本思想是将非线性方程式()f x 逐步归结为某种线性方程来求解。
解非线性方程组只是非线性方程的一种延伸和扩展。
二 主要理论 考虑方程组111(,...)0,.................(, 0n n n f x x f x x =⎧⎪⎨⎪=⎩ ()1 其中1,...,n f f 均为1(,...)n x x 多元函数。
若用向量记号记11(,...),(,...,)T n T n 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 Tnx x x = 将函数()F x 的分量()(1,...,)i f x i n =在()k x 用多元函数泰勒展开,并取其线性部分,则可表示为 ()()()()()()().k k k F x F xF 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 x x f x f x f x x x x F x f x f x f x x x x ∂∂∂⎡⎤⎢⎥∂∂∂⎢⎥⎢⎥∂∂∂⎢⎥∂∂∂⎢⎥'=⎢⎥⎢⎥⎢⎥⎢⎥∂∂∂⎢⎥∂∂∂⎣⎦L L MM M L(4) 称为()F x 为雅可比(Jacobi )矩阵。
C语言解线性方程的四种方法C语言解线性方程的四种方法发了好几天编了个解线性方程组的小程序,可第一次实战就大败而归。
经过半天的调试,仍找不出纠正的方法。
因为并不是算法的问题,而是因为自己对编译器处理浮点函数的方法不是很理解。
明明D=0的方阵解出来不等于0了,跟踪调试发现,计算过程程序对数据进行了舍去处理,导致最终结果不对。
不过如果没有浮点型的话,这个程序应该算不错了。
复制代码代码如下:#include#include#include#defineNUM100voidprint(void)/使用说明/{clrscr();printf("\n\n\n\n\n\t\t\t\tIntroduction\n");printf("\t--------------------------------------------------------------\n");printf("\tThisprogramwasdesignforcomputelinearequations. \n");printf("\tThewayofuseitisverysimple.\n");printf("\tFirst:Inputthenumberoftheequation;(Input0toexit)\ n");printf("\tSecond:Inputthecoefficientofeveryeqution;\n");printf("\tThird:Inputtheconstantofeveryeqution;\n");printf("\tLast:Chosethewayyouwantusetosolvetheequtions;\ n");printf("\tThat''sall,inputanykeytorunit...\n");printf("\t-------------------------By__TJX------------------------------\n");getch();}voidchose(void)/选择计算方法/{clrscr();fflush(stdin);printf("\n\n\n\n\n\t\tIntroduction\n");printf("\t\tChosetheway,please.\n");printf("\t\ta:Gausseliminant.\n");printf("\t\tb:Gauss_ydeliminant.\n");printf("\t\tc:Iterativeway.\n");printf("\t\td:Cramerway.\n");printf("\t\te:exit.\n");printf("\t\tBy__TJX\n");printf("\t\tPleasechoosenumber:\n");}voidinput(doublea1,doubleb1[],intnum)/数据输入/ {inti,j,t;doublep;charde1,de2;do{printf("Pleaseinputarraya[%d][%d]:\n",num,num);printf("Warn:Thefirstnumberofthearraymustn''tcontainzero!\ n");for(i=1;i<=num;i++){printf("Pleaseinputarraya[%d][]:\n",i);for(j=1;j<=num;j++){t=0;if(i==1&&j==1){do{if(t==0){scanf("%lf",&a1[i][j]);t++;}else{printf("Theinputisinvalid,pleaseinputagain:\n");scanf("% f",&a1[i][j]);}}while(a1[i][j]==0);}elsescanf("%lf",&a1[i][j]);}}printf("\nPleasecheckthevalueofarraya[%d][%d],pressYtoinp utagain.\n",num,num);do{de1=getch();}while(de1!=''y''&&de1!=''Y''&&de1!=''n''&&de1!=''N'');}while(de1==''y''||de1==''Y'');do{printf("Pleaseinputarrayb[%d]:\n",num);p=b1+1;for(i=1;i<=num;i++)scanf("%lf",p++);printf("\nPleasecheckthevalueofarrayb[%d],pressYtoinputag \n",num);do{de2=getch();}while(de2!=''y''&&de2!=''Y''&&de2!=''n''&&de2!=''N'');}while(de2==''y''||de2==''Y'');}intmax(doublet1,doublex1[],intn)/迭代子函数/{inti,temp=0;for(i=1;i<=n;i++)if(fabs(x1[i]-t1[i])>1e-2){temp=1;break;}/printf("%d",temp);/returntemp;}intddcompute(doublea1,doubleb1[],doublex1[],intn)/迭代法计算/{doublet;inti,j,k=0;doublesum1=0.0,sum2=0.0;t=(double)malloc(nsizeof(double));printf("\nPleaseInputTheInitialValueofx:\n");for(i=1;i<=n;i++)scanf("%lf",&x1[i]);do{k++;for(i=1;i<=n;i++)t[i]=x1[i];for(i=1;i<=n;i++){sum1=0.0;sum2=0.0;for(j=1;j<=i-1;j++)sum1=sum1+a1[i][j]x1[j];/printf("sum1=%0.4f",sum1);/for(j=i+1;j<=n;j++)sum2=sum2+a1[i][j]t[j];/printf("sum2= %0.4f",sum2);}/if(a1[i][i]==0||fabs(sum1)>1e+12||fabs(sum2)>1e+12){printf("\nWarning:Theseequtionscan''tbesolvebythisway!\n PressanyKeytocontinue...");getch();free(t);return0;}x1[i]=(b1[i]-sum1-sum2)/a1[i][i];}}while(max(t,x1,n));/for(i=1;i<=n;i++){if(i%3==0)printf("\n");printf("%.4f",x1[i]);}/free(t);return1;}intgscompute(doublea1,doubleb1[],doublex1[],intn)/高斯消元法计算/{inti,j,k;doublem,sum;for(k=1;k<=n-1;k++)for(i=k+1;i<=n;i++){if(a1[k][k]==0){printf("\nTheseequtionscan''tbesolveisthisw \nPressanyKeytocontinue...");getch();return0;}if((m=0-a1[i][k]/a1[k][k])==0){i++;continue;}else{for(j=k+1;j<=n;j++)a1[i][j]=a1[i][j]+a1[k][j]m;b1[i]=b1[i]+b1[k]m;}}/yixiajisuanxzhi/x1[n]=b1[n]/a1[n][n];for(i=n-1;i>=1;i--){sum=0.0;for(j=n;j>=i+1;j--)sum=sum+a1[i][j]x1[j];x1[i]=(b1[i]-sum)/a1[i][i];}return1;}intgs_ydcompute(doublea1,doubleb1[],doublex1[],intn)/高斯_约当法计算/{inti,j,k;doublem,sum;for(k=1;k<=n;k++){i=1;while(i<=n){if(a1[k][k]==0){printf("\nTheseequtionscan''tbesolveisthisw ay.\nPressanyKeytocontinue...");getch();return0;}if(i!=k){if((m=0-a1[i][k]/a1[k][k])==0){i++;continue;}else{for(j=k+1;j<=n;j++)a1[i][j]=a1[i][j]+a1[k][j]m;b1[i]=b1[i]+b1[k]m;}i++;}elsei++;}}/yixiajisuanxzhi/for(i=n;i>=1;i--)x1[i]=b1[i]/a1[i][i];return1;}doublecomputed(doublea,inth,intl,intc1,intn)/计算系数行列式D值/{inti,j,p=1;doublesum=0.0;if(h==n)sum=1.0;else{i=++h;c1[l]=0;for(j=1;j<=n;j++)if(c1[j])if(a[i][j]==0)p++;else{sum=sum+a[i][j]computed(a,i,j,c1,n)pow(-1,1+p);p++;}c1[l]=1;}returnsum;}voidncompute(doublea,doubleb[],doublex[],intn,intc,double h)/克莱姆法计算/{inti,j;doublet[NUM];for(j=1;j<=n;j++){for(i=1;i<=n;i++){t[i]=a[i][j];a[i][j]=b[i];}x[j]=computed(a,0,0,c,n)/h;for(i=1;i<=n;i++)a[i][j]=t[i];}}main(){doublex[NUM];doubleb[NUM];inti,j=2,n=0;intc;doublehe;charm,decision;doublea;a=(double)malloc(NUMsizeof(double));for(i=0;ia[i]=(double)malloc(NUMsizeof(double));print();do{clrscr();do{if(n>=NUM)printf("nistoolarge,pleaseinputagain:\n");elseprintf("Pleaseinputthetotalnumberoftheequationsn(n scanf("%d",&n);}while(n>NUM);if(n==0){for(i=1;ifree(a);exit(1);}input(a,b,n);c=(int)malloc((n+1)sizeof(int));memset(c,1,(n+1)sizeof(int));he=computed(a,0,0,c,n);if(fabs(he)>1e-4)Other:chose();do{m=getche();}while(m!=''a''&&m!=''b''&&m!=''A''&&m!=''B''&&m!=''c'' &&m!=''C''&&m!=''d''&&m!=''D''&&m!=''e''&&m!=''E'');switch(m){case''a'':;case''A'':j=gscompute(a,b,x,n);break;case''b'':;case''B'':j=gs_ydcompute(a,b,x,n);break;case''c'':;case''C'':j=ddcompute(a,b,x,n);break;case''d'':;case''D'':j=1;ncompute(a,b,x,n,c,he);break;case''e'':;case''E'':j=2;break;default:j=2;break;}if(j==1){clrscr();printf("\n\n\n\n");printf("D=%.4f\n",he);for(i=1;i<=n;i++){if(i%5==0)printf("\n");printf("%.4f",x[i]);}}elseif(j==0){printf("\nTheseequtionscan''tbesolveisthisway.\nPleasechos etheotherway.");gotoOther;}else{for(i=1;ifree(a);free(c);exit(1);}}elseprintf("\n\n\tD=%.4f\nThislinearequationshasn''taccurat eanswer!",he);printf("\nDoyouwanttocontinue?(Y/N)\n");do{decision=getchar();}while(decision!=''y''&&decision!=''Y''& &decision!=''n''&&decision!=''N'');}while(decision==''y''||decision==''Y'');for(i=1;ifree(a);free(c);}如对本文有所疑问,请点击进入脚本之家知识社区提问。
c语言求三次方程的根
三次方程是一种具有三个未知数的方程,它的一般形式为:ax^3 + bx^2 + cx + d = 0。
在求解三次方程时,我们可以使用多种方法,其中一种常用的方法是利用求根公式来求解。
求根公式是根据三次方程的系数使用的,因此我们首先需要确定方程的系数a、b、c和d。
接下来,我们使用求根公式来求解方程的根。
根据根的个数不同,我们可以得到以下几种情况:
1. 当方程有三个实根时,我们可以使用三次方程的求根公式来求解。
求根公式会得到三个实数解,分别为x1、x2和x3。
2. 当方程有一个实根和两个共轭复根时,我们可以使用复数的概念来求解方程。
求根公式会得到一个实数解x1和两个共轭复数解,分别为x2 = a + bi和x3 = a - bi(其中i为虚数单位)。
3. 当方程有三个不相等的实根时,我们可以使用Vieta定理来求解方程。
根据Vieta定理,我们可以通过方程的系数之间的关系来求得根的和、积和乘积,从而得到三个不相等的实数解。
综上所述,求解三次方程的根需要通过确定方程的系数,并借助求根公式、复数概念或Vieta定理来进行计算。
具体计算方法可以参考相关的数学教材或查询相关的数学知识。
c语言解方程本文介绍了使用C语言解决方程的相关内容,包括使用解方程程序的实际实现和九大经典题目的解法等。
一、使用C语言解决方程1、解方程程序的实际实现在使用C语言来解决方程时,需要定义一个函数来计算某个方程的根,具体过程如下:(1)首先,定义一个函数来实现计算方程根的功能,这里使用Newton-Raphson法,其中,f代表要计算的方程,x0为初始值,delta代表允许的-误差:double f(double x){// 求解方程return ...}double x0 = 1.0;double delta = 0.00001;// 使用Newton-Raphson法得到方程的根double x = x0;while (fabs(f(x)) > delta){x = x - f(x) / fPrime(x);// 计算下一个近似根// x即为方程的根(2)向函数传递参数,以求出方程的根,具体过程如下: double a, b, c; // 要求解的一元二次方程的系数int rootNum; // 方程根数,即解的个数// 特判:一元二次方程两端系数为零if (a == 0 && b == 0 && c == 0){rootNum = -1;}else if (a == 0 && b == 0){rootNum = 0;}else{// 求解方程的根double delta = b * b - 4 * a * c;if (delta < 0){rootNum = 0;else if (delta == 0){rootNum = 1;}else{rootNum = 2;}}return rootNum;2、九大经典题目(1)求给定数组的最大和// 使用C语言求数组的最大和: // 输入:数组arr,长度为n// 输出:最大和int maxSum(int arr[], int n) {int sum = 0;int maxSum = 0;for (int i = 0; i < n; i++) {sum = max(sum + arr[i], arr[i]);maxSum = max(sum, maxSum);}return maxSum;}(2)求三角形最大路径和// 使用C语言求解三角形的最大路径和: // 输入:数组tri,长度为n// 输出:最大路径和int maxPathSum(int tri[][], int n){int dp[n][n];int maxSum = 0;// 初始化dp数组dp[0][0] = tri[0][0];for (int i = 1; i < n; i++){dp[i][0] = dp[i-1][0] + tri[i][0];}for (int i = 1; i < n; i++){for (int j = 1; j <= i; j++){dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + tri[i][j]; }}for (int i = 0; i < n; i++){maxSum = max(dp[n-1][i], maxSum);}return maxSum;}二、结论C语言是最常用的编程语言之一,它可以用来解决各种方程,通过定义函数和设置条件语句,可以实现将方程求根。
c语言中怎么求解三个方程的交点In order to solve for the intersection point of three equations in C language, we can use various mathematical techniques and algorithms. One common method is to use the Gauss elimination method, which involves transforming the system of equations into row-echelon form and then back-substituting to find the values of the variables. This method is efficient and widely used in solving systems of linear equations.为了在C语言中解决三个方程的交点问题,我们可以使用各种数学技术和算法。
一个常见的方法是使用高斯消元法,这涉及将方程系统转化为行梯形形式,然后进行回代计算以找到变量的值。
这种方法在解线性方程组时是高效且广泛使用的。
Another approach is to use the matrix inversion method, where we represent the system of equations as a matrix equation and then find the inverse of the matrix using techniques like the LU decomposition. Once we have the inverse matrix, we can multiply it with the column matrix of constant terms to obtain the solution vector, which gives us the intersection point of the three equations. This method iscomputationally intensive but can be useful for solving complex systems of equations.另一种方法是使用矩阵求逆方法,我们将方程系统表示为矩阵方程,然后使用LU分解等技术找到矩阵的逆。
求解方程在指定区间的整数解是计算机编程中常见的问题,特别是在使用C语言进行数值计算时。
解决这个问题的方法有很多种,可以根据具体的方程形式和求解的要求来选择合适的方法。
本文将从几种常见的方程求解方法出发,分析在C语言中如何实现求解方程在指定区间的整数解。
一、方程求解方法1.1 遍历法遍历法是一种最简单直接的求解整数解的方法,它通过遍历指定区间内的所有整数,逐个代入方程进行求解,并判断是否满足方程的解。
这种方法适用于方程形式简单、区间范围较小的情况,但是当区间范围较大时,遍历法的计算量会非常大,效率较低。
1.2 数值逼近法数值逼近法是一种通过数值计算的方法,通过设定一个初始值,然后不断迭代计算来逼近方程的整数解。
当迭代的结果满足一定的条件时,即可得到方程的整数解。
这种方法适用于一些复杂的方程,可以利用数值计算的库函数来实现。
1.3 穷举法穷举法是一种将方程的解空间进行分割,然后在每个小空间中进行穷举求解的方法。
这种方法适用于一些具有规律性的方程,通过对方程的特性进行分析,可以得到解空间的具体位置和范围,然后利用循环结构进行穷举求解。
二、C语言实现2.1 遍历法实现在C语言中,我们可以利用循环结构来实现遍历法求解方程的整数解。
首先确定方程的形式和区间范围,然后通过循环结构依次代入每一个整数进行求解,最终得到满足方程的整数解。
需要注意的是,在循环中添加一些判断条件,可以提高求解的效率和精度。
2.2 数值逼近法实现数值逼近法需要利用数值计算的库函数来实现,C语言中常用的数值计算库有math.h和stdlib.h等。
通过设定初始值,并使用循环结构进行迭代计算,直到满足一定的条件为止,可以得到方程的整数解。
需要根据具体的方程形式和求解要求来选择合适的数值计算方法和库函数。
2.3 穷举法实现穷举法的实现需要首先对方程的特性进行分析,找出解空间的具体位置和范围,然后通过嵌套循环结构对解空间进行穷举求解。
在循环的每一步中,利用一些条件判断来筛选出满足方程的整数解。
c语言编写程序求多项式的方法多项式是数学中常见的表达式形式,由一系列项组成。
每个项包含一个系数和一个指数,其中系数是常数,指数是变量的幂。
在C语言中,我们可以编写程序来求解多项式,并计算其值。
首先,我们需要定义一个结构体来表示多项式的每个项,包含两个成员:系数和指数。
```ctypedef struct {float coefficient;int exponent;} Term;```接下来,我们可以编写一个函数来输入多项式,用户可以通过输入系数和指数来构建多项式。
函数将返回一个包含多项式的数组。
```cTerm* inputPolynomial(int termCount) {Term* polynomial = malloc(termCount * sizeof(Term));printf("请输入每个项的系数和指数:\n");for (int i = 0; i < termCount; i++) {printf("第 %d 项的系数:", i + 1);scanf("%f", &polynomial[i].coefficient);printf("第 %d 项的指数:", i + 1);scanf("%d", &polynomial[i].exponent);}return polynomial;}```然后,我们可以编写一个函数来计算多项式的值,在该函数中,我们将多项式的每一项与给定的变量值相乘,并将所有项的结果相加。
```cfloat calculatePolynomialValue(Term* polynomial, int termCount, float x) {float result = 0;for (int i = 0; i < termCount; i++) {float termResult = polynomial[i].coefficient * pow(x, polynomial[i].exponent);result += termResult;}return result;}```最后,我们还可以编写一个函数来输出多项式的表达式。
c语言求三次方程的根在数学中,三次方程是一个最高次数为3的多项式方程。
常见的三次方程的一般形式为Ax^3 + Bx^2 + Cx + D = 0,其中A、B、C和D是给定的常数。
解三次方程是求出满足上述方程的所有值的过程。
在C语言中,我们可以使用牛顿迭代法或者二分法来解决这个问题。
一、牛顿迭代法求解三次方程的根牛顿迭代法是一种非常常用的数值求根方法,它通过不断迭代逼近根的值,直到满足一定的精度要求。
对于已知的三次方程,我们可以通过牛顿迭代法求解其根。
具体步骤如下:1. 初始化一个估计根的值x,通常选择为0或者方程中一个首要项的系数的反数。
2. 使用迭代公式x = x - f(x) / f'(x)来计算新的x值,其中f(x)表示方程的值,f'(x)表示方程的导数。
3. 重复步骤2,直到满足迭代收敛的条件,一般是当x的变化足够小或者f(x)的值足够接近于零。
下面是使用C语言实现牛顿迭代法解三次方程的代码示例:```c#include <stdio.h>#include <math.h>#define EPSILON 0.00001double f(double x, double A, double B, double C, double D) {return A * pow(x, 3) + B * pow(x, 2) + C * x + D;}double derivative(double x, double A, double B, double C) {return 3 * A * pow(x, 2) + 2 * B * x + C;}double newtonRaphson(double x, double A, double B, double C, double D) { double h = f(x, A, B, C, D) / derivative(x, A, B, C);while (fabs(h) >= EPSILON) {h = f(x, A, B, C, D) / derivative(x, A, B, C);x = x - h;}return x;}int main() {double A, B, C, D;printf("Enter the coefficients A, B, C and D: ");scanf("%lf %lf %lf %lf", &A, &B, &C, &D);double initialGuess = -A; // 初始化一个估计根的值double root = newtonRaphson(initialGuess, A, B, C, D);printf("Root: %lf\n", root);return 0;}```二、二分法求解三次方程的根二分法也是一种常用的数值求根方法,它通过不断将区间划分为两段,然后根据函数值的符号来确定根所在的区间,最终逼近根的值。
c语言求解多项式多项式是数学中的一个重要概念,也是计算机科学中常用的数据结构之一。
在C语言中,我们可以使用数组来表示多项式,并通过相应的算法来求解多项式。
我们来了解一下什么是多项式。
多项式是由一系列项构成的代数表达式,每个项由一个系数和一个指数组成。
例如,2x^3 + 3x^2 - 4x + 1就是一个多项式,其中的项分别是2x^3、3x^2、-4x和1。
在C语言中,我们可以使用数组来表示多项式。
假设我们要表示一个3次多项式,可以使用一个长度为4的数组来存储多项式的系数,数组的下标对应着项的指数。
例如,数组poly[4]可以表示一个3次多项式,其中poly[0]表示常数项的系数,poly[1]表示x的系数,poly[2]表示x^2的系数,poly[3]表示x^3的系数。
接下来,我们来看一下如何求解多项式。
常见的求解多项式的方法有两种:代入法和霍纳法。
代入法是将多项式中的每一项代入给定的值,然后将所有项的结果相加。
例如,对于多项式2x^3 + 3x^2 - 4x + 1,如果要求解x=2时的值,可以将2代入多项式中的每一项,然后将结果相加,即2*2^3 + 3*2^2 - 4*2 + 1 = 17。
代入法的思路比较直观,但对于高次多项式来说,计算量较大。
霍纳法是一种更高效的求解多项式的方法。
它利用了多项式的等价变形,将多项式从左到右递推求解。
对于多项式a0 + a1x +a2x^2 + ... + anx^n,霍纳法的求解过程如下:1. 从右到左遍历多项式的系数,将当前系数乘以给定的值x,并加上前一个结果;2. 重复上述步骤,直到遍历完所有系数,得到最终结果。
例如,对于多项式2x^3 + 3x^2 - 4x + 1,如果要求解x=2时的值,可以按照霍纳法的步骤进行计算:1. 先将最高次项系数2与给定的值2相乘,得到4;2. 将上一步的结果4与次高次项系数3相加,得到7;3. 将上一步的结果7与次次高次项系数-4相乘,得到-28;4. 将上一步的结果-28与最低次项系数1相加,得到-27。
一 理论背景我们先考虑线性方程,线性方程组的解便不难得出了。
与线性方程相比,非线性方程问题无论是从理论上还是从计算公式上,都要复杂得多。
对于一般的非线性方程()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; }五.算法分析及改进措施牛顿法解非线性方程组是一种线性方法,即将非线性方程组以一线性方程组来近似,由此构造一种迭代格式,用以逐次逼近 所求的解案。