void root_pol(double *a, const int odr, Complex * x, const int a_zero, const double eps, const int itrat) { int i, j, k, l; double th, th1, th2, cm, cmax; Complex cden, cnum, c1, *deltx; deltx = cplx_getmem(odr + 1); if (!a_zero) for (i = 1; i <= odr; i++) a[i] /= a[0]; cmax = 0; for (i = 2; i <= odr; i++) { cm = odr * rad_root(fabs(a[i]), i); if (cm > cmax) cmax = cm; } th1 = PI * 2.0 / odr; th2 = th1 / 4.0; for (i = 1; i <= odr; i++) { th = th1 * (i - 1) + th2; x[i].re = cmax * cos(th); x[i].im = cmax * sin(th); } l = 1; do { for (i = 1; i <= odr; i++) { cden.re = 1.0; cden.im = 0.0; cnum.re = 1.0; cnum.im = 0.0; c1 = x[i]; for (j = 1; j <= odr; j++) { cnum = c_math(cnum, multiply, c1); cnum.re += a[j]; if (j != i) cden = c_math(cden, multiply, c_math(c1, minus, x[j])); } deltx[i] = c_math(cnum, divide, cden); x[i] = c_math(c1, minus, deltx[i]); } k = 1; while ((k <= odr) && (c_mag(deltx[k++]) <= eps)); l++; } while ((l <= itrat) && (k <= odr)); if (l > itrat) { fprintf(stderr, "root_pol : No convergence!\n"); exit(1); } return; }
int main(int argc, char *argv[]) { char *s; int c, k, odr = ORDER, itrat = ITER, form = 0, a_zero = 0; double *a, *d, eps = EPS; FILE *fp = stdin; complex *x; if ((cmnd = strrchr(argv[0], '/')) == NULL) cmnd = argv[0]; else cmnd++; while (--argc > 0) { if (*(s = *++argv) == '-') { c = *++s; switch (c) { case 'i': a_zero = 1; break; case 'r': form |= 1; break; case 's': form |= 2; break; case 'e': if (*++s == '\0') { s = *++argv; --argc; } eps = atof(s); break; case 'm': if (*++s == '\0') { s = *++argv; --argc; } odr = atoi(s); break; case 'n': if (*++s == '\0') { s = *++argv; --argc; } itrat = atoi(s); break; default: usage(); } } else fp = getfp(*argv, "rb"); } a = dgetmem(odr + 1); odr = freadf(a, sizeof(*a), odr, fp) - 1; d = dgetmem(odr + 1); x = cplx_getmem(odr + 1); for (k = 0; k <= odr; ++k) d[k] = a[k]; root_pol(d, odr, x, a_zero, eps, itrat); output_root_pol(x, odr, form); return (0); }