// ニュートン法による非線形方程式の解法
#include<stdio.h>
#include<math.h>
#define EPSILON 1.0E-7
// 反復におけるxの変動幅の縮小限界
double a[20];
// 係数
double r,root;
// r:近似値初期値
int
n,k;
// n次方程式 ,k:反復回数
double f(double),df(double); // df:df/dx
int sw;
// sw=0 : no convergent
void main()
{
char ym,yn;
int i;
double
Newton(void);
printf("\n\n------------------Newton
Method------------------\n\n");
printf("方程式の次数 : n = ?");
scanf("%d",&n);
printf("係数(高次から) : a[i] = ? (i=0,,,%2d)\n",n);
printf("各値は、空欄で区切る");
for(i=0;i<=n;i++)
scanf("%lf",&a[i]);
www:sw=1;
printf("解の近似計算の初期値 : r = ?");
scanf("%lf",&r);
printf("\n");
if(f(r)==0)
printf("
root = %f\n\n",r);
else
{
if(df(r)<0.0001)
{
printf("df:%lf",df(r));
printf("初期値rが不適当です.\n");
printf("No
convergent. because f'(r)=0 or f'(r)is very small.\n\n");
}
else
{
if(sw)
{
root
= Newton();
printf("公差<%10.8lfで反復計算を打ち切りました.\n\n",EPSILON);
printf("収束値(解):
root = %f\n\n",root);
}
else
printf("no
convergent !\n\n");
}
}
printf("別の初期値で再度計算しますか.<y/n>?");
ym=getchar();
yn=getchar();
if(yn=='y'||yn=='Y') goto www;
}
double Newton()
{
double
d,dd,x;
k=0;
do
{
k++;
x=r-f(r)/df(r);
d=fabs(x-r);
printf("k=%2d
: x=%11.8lf\n",k,x);
r=x;
if(k>1)
if(d>dd)
{
sw=0;
break;
}
dd=d;
}
while(d>EPSILON);
return x;
}
double f(double x)
{
double
b[20];
int i;
b[0]=a[0];
for(i=1;i<=n;i++)
b[i]=b[i-1]*x+a[i];
return
b[n];
}
double df(double x)
{
double
c[20];
int i;
c[0]=n*a[0];
for(i=1;i<n;i++)
c[i]=c[i-1]*x+(n-i)*a[i];
return
c[n-1];
}