病态方程求根
来源:互联网 发布:明道软件官网 编辑:程序博客网 时间:2024/04/30 01:43
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
//连乘表达式
double function(double x)
{
int i;
double s=1;
for(i=1;i<21;i++)
s*=(x-i);
return(s);
}
double diff(double x)
{
int i;
double s=0;
for(i=1;i<21;i++)
s+=function(x)/(x-i);
return(s);
}
int qr(long double *a,int n,long double *u,long double *v,long double eps,int itmax)
{
int i,j,k,ii,jj,kk;
long double x,y,p,q,r;
long double q00,q01,q02,q11,q12,q22; /* 用于求Q*/
int is1,is2,n1;
long double *a1;
long double b,c,s;
if(itmax == 0) /* 已经不能再迭代*/
{
printf("fail/n");
return(0);
}
if(n==1) /* 矩阵是1阶*/
{
u[0] = a[0];
v[0] = 0.0;
return(1);
}
if(n==2)
{
b = (a[0]+a[3]);
c = a[0]*a[3]-a[1]*a[2];
s = b*b-4.0*c;
y = sqrt(fabs(s));
if (s > 0.0)
{
if(b > 0.0)
u[0] = (b+y)/2.0;
else
u[0]=(b-y)/2.0;
v[0]=0.0;
u[1]=c/u[0]; v[1]=0.0;
}
else
{
u[0] = b/2.0; v[0] = y/2.0;
u[1] = u[0]; v[1] = -v[0];
}
return(1);
}
is1 = 0;
is2 = 0;
while(is2 < n-1)
{
is2++;
j = is2*n+is2;
if(fabs(a[j-1]) < eps*(fabs(a[j-n-1])+fabs(a[j])))
{
n1 = is2-is1;
a1 = (long double*)malloc(n1*n1*sizeof(long double));
for(i=0; i<n1; i++)
for(j=0; j<n1; j++)
a1[i*n1+j] = a[(i+is1)*n+j+is1];
qr(a1,n1,u+is1,v+is1,eps,itmax);
free(a1);
is1 = is2;
}
}
if(is1>0 && is1<n)
{
n1=n-is1;
a1=(long double*)malloc(n1*n1*sizeof(long double));
for(i=0; i<n1; i++)
for(j=0; j<n1; j++)
a1[i*n1+j] = a[(i+is1)*n+j+is1];
qr(a1,n1,u+is1,v+is1,eps,itmax);
free(a1);
return(1);
}
else if(is1 == n)
return(1);
for (k=0; k<n-1; k++)
{
if(k==0)
{
x = a[(n-2)*n+n-2]+a[n*n-1];
y = a[(n-2)*n+n-2]*a[n*n-1]-a[(n-2)*n+n-1]*a[(n-1)*n+n-2];
p = a[0]*(a[0]-x)+a[1]*a[n]+y;
q = a[n]*(a[0]+a[n+1]-x);
r = a[n]*a[2*n+1];
}
else
{
p = a[k*n+k-1];
q = a[(k+1)*n+k-1];
if(k != n-2)
r= a[(k+2)*n+k-1];
else
r= 0.0;
}
if ((fabs(p)+fabs(q)+fabs(r))!=0.0)
{
if(p<0.0)
s = -sqrt(p*p+q*q+r*r);
else
s = sqrt(p*p+q*q+r*r);
if(k!=0)
a[k*n+k-1]=-s;
q00 = -p/s;
q01 = -q/s;
q02 = -r/s;
q11 = -q00-q02*r/(p+s);
q12 = q01*r/(p+s);
q22 = -q00-q01*q/(p+s);
for(j=k; j<n; j++)
{
ii = k*n+j;
jj = (k+1)*n+j;
kk = (k+2)*n+j;
p = q00*a[ii]+q01*a[jj];
q = q01*a[ii]+q11*a[jj];
r = q02*a[ii]+q12*a[jj];
if (k!=n-2)
{
p = p+q02*a[kk];
q = q+q12*a[kk];
r = r+q22*a[kk];
a[kk] = r;
}
a[ii] = p;
a[jj] = q;
}
j=k+3;
if(j>=n-1)
j=n-1;
for(i=0; i<=j; i++)
{
ii = i*n+k;
jj = i*n+k+1;
p = q00*a[ii]+q01*a[jj];
q = q01*a[ii]+q11*a[jj];
r = q02*a[ii]+q12*a[jj];
if(k!=n-2)
{
kk = i*n+k+2;
p = p+q02*a[kk];
q = q+q12*a[kk];
r = r+q22*a[kk];
a[kk]=r;
}
a[ii]=p;
a[jj]=q;
}
}
if(k > 0)
{
a[(k+1)*n+k-1] = 0.0;
if(k != n-2)
a[(k+2)*n+k-1] = 0.0;
}
}
i = qr(a,n,u,v,eps,itmax-1);
return(i);
}
void main()
{
int i,j,n=20;
double x0,x[20];
long double eps=1.0e-12; //eps 精度要求,用于判断元素是否为0
int itmax=50000; ////itmax 最大迭代次数
long double u[20],v[20]; ////u 保存特征值的实部.
long double *H;
long double b[21]={1,-2.09999999880791e2,20615,-1.256850e6,5.3327946e7,
-1.672280820e9,4.0171771630e10,-7.56111184500e11,1.1310276995381e13,
-1.35585182899530e14,1.307535010540400e15,-1.0142299865511500e16,6.3030812099294900e16,
-3.11333643161391000e17,1.206647803780370000e18,-3.599979517947610000e18,8.037811822645050000e18,
-1.2870931245151000000e19,1.3803759753640700000e19,-8.752948036761600000e18,2.432902008176640000e18};
for(i=0;i<20;i++)
{
x[i]=i+1.1;
}
printf("原方程的根如下:/n");
for(j=0;j<20;j++)
{
do
{
x0=x[j];
x[j]=x0-function(x0)/diff(x0);
}while(fabs(x[j]-x0)>1e-8);
printf("x[%d]=%lf/n",j,x[j]);
}
printf("方程的19次系数做微小扰动+pow(2,-23)后的解如下:/n");
H=(long double*)malloc(sizeof(long double)*n*n); /* 生成的上H矩阵*/
for(i=0;i<n;i++)
H[i]=-1.0*b[i+1]/b[0]; /* 第一行*/
for(i=n;i<n*n;i++)
H[i]=0.0; /* 下面为0*/
for(i=1;i<n;i++)
H[i*n+i-1]=1.0; /* 次对角线为1*/
qr(H,n,u,v,eps,itmax);
for(j=19;j>=0;j--)
{
if(v[j]>0)
printf("x[%d]=%.12lf+%.12lfi/n",20-j,u[j],v[j]);
else if(v[j]<0)
printf("x[%d]=%.12lf%.12lfi/n",20-j,u[j],v[j]);
else
printf("x[%d]=%.12lf/n",20-j,u[j]);
}
}
- 病态方程求根
- 方程求根
- 方程求根!
- 方程求根二分法
- 方程求根二分法
- Matlab非线性方程求根
- 多项式方程求根
- 非线性方程求根
- 方程求根问题
- hdu4569 模方程求根
- 一元二次求根方程
- 非线性方程求根迭代法
- solve it--非线性方程求根
- 关于一元三次方程求根
- 一元三次方程求根公式
- 一元四次方程求根公式
- 病态
- 一元三次方程求根公式的解法
- Replace,Instr函数不区别大小写的方法
- Mac OSX 10.6 install gnuplot
- 如何用sys as sysdba权限连接数据库进行Exp/Imp
- f1513.cpp 非错误异常,跳出深循环
- Android 开发类库
- 病态方程求根
- codeblocks IDE汉化
- Android开发指南-窗口小部件(App Widgets)
- Oracle 修改表名
- 解压tar.gz
- 宏定义妙用(一)
- vs2005 快捷键
- ZJUT1010 诡秘的余数 大数对一位数求余
- 多任务,多进程,多线程解析