Ten kod (dołączony do posta) w C używa Newton - Raphson method do znalezienia pierwiastków wielomianu w określonym przedziale.Program metody Newtona (w języku C) działający w nieskończoność
Ten kod działa doskonale dla niektórych wielomianów, takich jak x^3 + x^2 + x + 1
, ale środowisko wykonawcze staje się nieskończone dla niektórych wielomianów, takich jak x^3 - 6*x^2 + 11*x - 6
. To jest ten kod działa dobrze dla wielomianów mających jeden lub zero root we wpisanym przedziale, ale jeśli więcej niż jeden katalog główny jest obecny, to działa w nieskończoność.
Proszę dać mi znać, jeśli ktoś znajdzie rozwiązanie tego problemu. Napisałem komentarze w kodzie, aby kierować czytelnikiem, ale jeśli ktoś ma trudności z zrozumieniem, może zapytać w komentarzach, wytłumaczę to.
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
int check(float num) //just a function to check for the correct input
{
char c;
scanf("%c",&c);
if(isalpha((int)c))
printf("you entered an alphabet\n");
else
printf("you entered a character, please retry\n");
return 0;
}
float func(float *p,int order,double x) //calculates the value of the function required in the formmula in main
{
double fc=0.0;
int i;
for(i=0;i<=order;i++)
{
fc=fc+(double)(*p)*pow(x,(double)i);
p++;
}
return fc;
}
float derv(float *q,int order,double x) //calculates the derivative of the function required in the formmula in main
{
double dv=0.0,i;
for(i=1;i<=order;i++)
{
dv=dv+(double)(*q)*(pow(x,(double)(i-1)))*(double)i;
q++;
}
return dv;
}
int main()
{
float coeff[1000];
int order,count=0,i,j=0;
char ch;
float a,b;
double val[5];
printf("roots of polynomial using newton and bisection method\n");
printf("enter the order of the equation\n");
while(scanf("%d",&order)!=1)
{
printf("invalid input.please retry\n");
while(getchar()!='\n'){}
}
printf("enter the cofficients\n");
for(i=0;i<=order;i++)
{
printf("for x^%d :",order-i);
printf("\n");
while(scanf("%f",&coeff[i])!=1)
{
check(coeff[i]);
}
}
while(getchar()!='\n'){} //this clears the buffer accumulated upto pressing enter
printf("the polynomial you entered is :\n");
for(i=0;i<=order;i++)
{
printf(" %fx^%d ",coeff[i],order-i);
}
printf("\n");
//while(getchar()!='\n'){};
/* fflush(stdout);
fflush(stdin);*/
printf("plese enter the interval domain [a,b]\n");
printf("enter a and b:\n");
scanf("%f %f",&a,&b);
while(getchar()!='\n'){}
printf("the entered interval is [%f,%f]",a,b);
fflush(stdout);
fflush(stdin);
//this array is used to choose a different value of x to apply newton's formula recurcively in an interval to scan it roperly for 3 roots
val[0]=(double)b;
val[1]=(double)a;
val[2]=(double)((a+b)/2);
double t,x=val[0],x1=0.0,roots[10];
while(1)
{
t=x1;
x1=(x-(func(&coeff[0],order,x)/derv(&coeff[0],order,x))); //this is the newton's formula
x=x1;
if((fabs(t - x1))<=0.0001 && count!=0)
{
roots[j]=x;
j++;
x=val[j]; // every time a root is encountered this stores the root in roots array and runs the loop again with different value of x to find other roots
t=0.0;
x1=0.0;
count=(-1);
if(j==3)
break;
}
count++;
}
printf("the roots are = \n");
int p=0;
for(j=0;j<3;j++)
{
if(j==0 && roots[j]>=a && roots[j]<=b)
{
printf(" %f ",roots[j]);
p++;
}
if(fabs(roots[j]-roots[j-1])>0.5 && j!=0 && roots[j]>=a && roots[j]<=b)
{
printf(" %f ",roots[j]);
p++;
}
}
if(p==0)
printf("Sorry,no roots are there in this interval \n");
return 0;
}
artykuł na [Metoda Newtona] (https://en.wikipedia.org/wiki/Newton % 27s_method) określa powody, dla których może się nie zbiegać. Prawdopodobnie napotkasz na niektóre z tych powodów. –