blob: 35593a5bc026b524659a278879d5bc7800323f50 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "newton.h"
#include "horners.h"
#include "values.h"
extern void allroots(int No,double Po[],int N,double Pn[]);
extern void deflat(int No,double Po[],int N,double Pn[],double ROOT);
int main(void) {
static double A[] = {4.1,-3.9,-1.0,1.0};
int N = 3;
int J;
printf("DEBUG: %g %g\n",2.69065*2.69065*2.69065,2.69065*2.69065);
printf("==============================================================\n");
printf("Find all roots of\n");
for (J=N;J>0;J--) {
printf("%g",d_abs(A[J]));
if (A[J-1] < 0)
printf("x**%d - ",J);
else
printf("x**%d + ",J);
}
printf("%g\n",d_abs(A[0]));
printf("using NEWTON method.\n");
printf("==============================================================\n");
allroots(N,A,N,A);
return 0;
}
void allroots(int No,double Po[],int N,double Pn[])
/* Computes the Maximum interval that all the roots for the polynomial P
can contain with |root| < |P[0]| + |P[1]| + ... + |P[n]| \ |P[n]| where
P[i] is the coefficent of the Ith degree of the polynomial
Next it looks for a change of sign of F(x) on the range, when it finds one
it calls a METHOD for finding an individual root and then repeats the
process with the range now starting just after the last found root */
{
int I; /* counter */
double ROOT;
double LOWER,UPPER; /* lower and upperbound of all roots of P */
UPPER = 0;
for (I=0;I<=N;I++)
UPPER += d_abs(Pn[I]);
UPPER /= d_abs(Pn[N]);
LOWER = -UPPER - 1.0;
if (N == 0)
printf("No roots\n");
else
if (N == 1) {
ROOT = -Pn[0]/Pn[1];
printf(" ROOT = %g\n",ROOT);
}
else
if (N == 2) {
ROOT = (-Pn[1] + sqrt(Pn[1]*Pn[1] - 4*Pn[2]*Pn[0]))/(2*Pn[2]);
printf(" ROOT = %g (from quadratic formula)\n",ROOT);
ROOT = (-Pn[1] - sqrt(Pn[1]*Pn[1] - 4*Pn[2]*Pn[0]))/(2*Pn[2]);
printf(" ROOT = %g (from quadratic formula)\n",ROOT);
}
else {
ROOT = newton(N,Pn,LOWER,UPPER);
deflat(No,Po,N,Pn,ROOT);
}
}
void deflat(int No,double Po[],int N,double Pn[],double ROOT)
{
double *TP;
int I,J;
if (N != No) {
printf("----> Refine Root on the Orginal Polynomial (non-deflated)\n");
newton(No,Po,ROOT-.5,ROOT+.5);
}
TP = (double *) calloc(N,sizeof(ROOT));
TP[N-1]=Pn[N];
for (I=N-2;I>=0;I--)
TP[I] = TP[I+1]*ROOT+Pn[I+1];
for (J=N;J>0;J--) {
printf("%g",d_abs(Pn[J]));
if (Pn[J-1] < 0)
printf("x**%d - ",J);
else
printf("x**%d + ",J);
}
printf("%g\n",d_abs(Pn[0]));
printf(" DEFLATED to\n(x - %g)*(",ROOT);
for (J=N-1;J>0;J--) {
printf("%g",d_abs(TP[J]));
if (TP[J-1] < 0)
printf("x**%d - ",J);
else
printf("x**%d + ",J);
}
printf("%g)\n",d_abs(TP[0]));
if (N == 3) {
ROOT = (-TP[1] + sqrt(TP[1]*TP[1] - 4*TP[2]*TP[0]))/(2*TP[2]);
printf("\n ROOT = %g (from quadratic formula)\n",ROOT);
printf("----> Refine Root on the Orginal Polynomial (non-deflated)\n");
newton(No,Po,ROOT-.5,ROOT+.5);
ROOT = (-TP[1] - sqrt(TP[1]*TP[1] - 4*TP[2]*TP[0]))/(2*TP[2]);
printf(" ROOT = %g (from quadratic formula)\n",ROOT);
printf("----> Refine Root on the Orginal Polynomial (non-deflated)\n");
newton(No,Po,ROOT-.5,ROOT+.5);
}
else {
allroots(No,Po,N-1,TP);
}
free(TP);
}