牛顿迭代法求解多元高阶方程组

#include<iostream>
#include<cmath>
#define N 2                     // 非线性方程组中方程个数、未知量个数 

#define Epsilon 0.0001             // 差向量1范数的上限
#define Max     100               //最大迭代次数
#define k1       -1.22785792e-001
#define k2       1.37477946e-002
using namespace  std;
const int N2=2*N;
int X = 0;
int Y = 1;

int test(float x, float y);

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);
   test( x1[0],  x1[1]);
return 0;
}

void ff(float xx[N],float yy[N])              //调用函数
{
	float x,y;
	int i;
    x=xx[0];
	y=xx[1];
	float r = x * x + y * y;
	yy[0]=(1 + k1 * r + k2 * r * r) * x - X;
	yy[1]=(1 + k1 * r + k2 * r * r) * y - Y;                   //计算初值位置的值

    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];
	float r = x * x + y * y;
	//jacobian have n*n element                   //计算函数雅克比的值
	yy[0][0]=1 + k1 * r + k2 * r * r + 2 * k1 * x * x + 4 * k2 * x * x * r ;
	yy[0][1]=2 * k1 * x * y + 4 * k2 * x * y * r;
	yy[1][0]=2 * k1 * x * y + 4 * k2 * x * y * r;
	yy[1][1]=1 + k1 * r + k2 * r * r + 2 * k1 * y * y + 4 * k2 * y * y * r;

   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;cout<<endl;

}

int test(float x, float y)
{
	float ep = 0.01;
	float r = x * x + y * y;
	if ( ((1 + k1 * r + k2 * r * r) * x - X) < ep && ((1 + k1 * r + k2 * r * r) * y - Y)<ep)
      printf("ok!\n");
	else
		printf("error!\n");
	return 0;

}
时间: 2024-11-07 01:36:26

牛顿迭代法求解多元高阶方程组的相关文章

利用牛顿迭代法求解非线性方程组

最近一个哥们,是用牛顿迭代法求解一个四变量方程组的最优解问题,从网上找了代码去改进,但是总会有点不如意的地方,迭代的次数过多,但是却没有提高精度,真是令人揪心! 经分析,发现是这个方程组中存在很多局部的极值点,是用牛顿迭代法不能不免进入局部极值的问题,更程序的初始值有关! 发现自己好久没有是用Matlab了,顺便从网上查了查代码,自己来修改一下! 先普及一下牛顿迭代法:(来自百度百科) 牛顿迭代法(Newton's method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson m

牛顿迭代法求解平方根

牛顿迭代法求解平方根 2015-05-16 10:30 2492人阅读 评论(1) 收藏 举报 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 一个实例 迭代简介 牛顿迭代法 牛顿迭代法简介 简单推导 泰勒公式推导 延伸与应用 一个实例 //java实现的sqrt类和方法 public class sqrt { public static double sqrt(double n) { if (n<0) return Double.NaN; double err = 1e

牛顿迭代法求Logistic回归

接着上次的一篇文章:http://blog.csdn.net/acdreamers/article/details/27365941 在上次这篇文章中,对于Logistic回归问题,我们已经写出它的最大似然函数,现在来求最大似然估计.所以对似 然函数求偏导数,得到了个方程,即 由于我们只要根据这个方程解出所有的即可,但是这不是一件容易的事,还有Logistic回归求的是最大似 然估计,我们在多元函数求极值问题中也说过,导数等于零的点可能是极大值,极小值或者非极值.所以还要靠一个 叫Hessian

C语言之基本算法25—牛顿迭代法求方程近似根

//牛顿迭代法! /* ============================================================ 题目:用牛顿迭代法求解3*x*x*x-2*x*x-16=0的近似解. ============================================================ */ #include<stdio.h> #include<math.h> #define E 1e-8 double hs(double x) {

算法分析基础——差消法求解高阶递推方程

差消法,简单来讲,就是对高阶的递推方程作差,转化为一阶方程后再运用迭代法.有了迭代法的基础后,差消法理解起来就很容易了.这里举出对快速排序的分析加以说明. 对于快排,我们知道选择不同的轴值,会导致不同的算法效率.最坏的情况下,选取的轴值恰好是待排序数组的最值,那么排序的效率就会退化为线性时间.现在我们来估算平均情况下快速排序的时间复杂度. 设T(n)为待排序数组长度为n时,快速排序算法需要的比较次数.那么T(1) = 0,而T(n)的递推方程相对于轴值的选取有如下n种情况: T(n) = T(0

NOIP2001 一元三次方程求解[导数+牛顿迭代法]

题目描述 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1.要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位. 提示:记方程f(x)=0,若存在2个数x1和x2,且x1<x2,f(x1)*f(x2)<0,则在(x1,x2)之间一定有一个根. 输入输出格式 输入格式: 一行,4个实数A,B,C,D. 输

牛顿迭代法(Newton&#39;s Method)

牛顿迭代法(Newton's Method) 简介 牛顿迭代法(简称牛顿法)由英国著名的数学家牛顿爵士最早提出.但是,这一方法在牛顿生前并未公开发表. 牛顿法的作用是使用迭代的方法来求解函数方程的根.简单地说,牛顿法就是不断求取切线的过程. 对于形如f(x)=0的方程,首先任意估算一个解x0,再把该估计值代入原方程中.由于一般不会正好选择到正确的解,所以有f(x)=a.这时计算函数在x0处的斜率,和这条斜率与x轴的交点x1. f(x)=0中精确解的意义是,当取得解的时候,函数值为零(即f(x)的

Atitit 迭代法&#160;&#160;“二分法”和“牛顿迭代法&#160;attilax总结

Atitit 迭代法  "二分法"和"牛顿迭代法 attilax总结 1.1. ."二分法"和"牛顿迭代法"属于近似迭代法1 1.2. 直接法(或者称为一次解法),即一次性的快速解决问题,1 1.3. 最常见的迭代法是"二分法 牛顿法.还包括以下算法1 1.4.  二分法(dichotomie)1 1.5. 牛顿迭代法(Newton's method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method

牛顿迭代法 求方程根

牛顿迭代法 牛顿迭代法(Newton's method)又称为牛顿-拉夫逊方法(Newton-Raphson method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法.多数方程不存在求根公式,因此求精确根非常困难,甚至不可能,从而寻找方程的近似根就显得特别重要. 方法使用函数f(x)的泰勒级数的前面几项来寻找方程f(x) = 0的根.牛顿迭代法是求方程根的重要方法之一,其最大优点是在方程f(x) = 0的单根附近具有平方收敛,而且该法还可以用来求方程的重根.复根,此时线性