[fun-gen] add Halley method
This commit is contained in:
parent
5078ef1578
commit
022e2cf2e1
@ -48,7 +48,7 @@ criticals_add(long double complex z)
|
|||||||
if (idx >= MAX_CRITICALS)
|
if (idx >= MAX_CRITICALS)
|
||||||
return;
|
return;
|
||||||
for (i = 0; i < idx; i++)
|
for (i = 0; i < idx; i++)
|
||||||
if (cabsl(z - criticals[i]) < 1.0e-9)
|
if (cabsl(z - criticals[i]) < 1.0e-8)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
criticals[idx++] = z;
|
criticals[idx++] = z;
|
||||||
|
87
fun-gen.c
87
fun-gen.c
@ -46,13 +46,26 @@ poly_init(struct poly *p, unsigned int degree, const char *expr)
|
|||||||
static void
|
static void
|
||||||
poly_derivate(struct poly p, struct poly *dp, const char *expr)
|
poly_derivate(struct poly p, struct poly *dp, const char *expr)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
int i;
|
||||||
|
|
||||||
poly_init(dp, p.degree == 0 ? 0 : p.degree - 1, expr);
|
poly_init(dp, p.degree == 0 ? 0 : p.degree - 1, expr);
|
||||||
for (i = p.degree; i > 0; i--)
|
for (i = p.degree; i > 0; i--)
|
||||||
dp->coefs[i - 1] = p.coefs[i] * i;
|
dp->coefs[i - 1] = p.coefs[i] * i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
poly_multiply(struct poly p, struct poly q, struct poly *f, const char *expr)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
poly_init(f, p.degree + q.degree, expr);
|
||||||
|
for (i = 0; i <= f->degree; i++)
|
||||||
|
f->coefs[i] = 0.0;
|
||||||
|
for (i = 0; i <= p.degree; i++)
|
||||||
|
for (j = 0; j <= q.degree; j++)
|
||||||
|
f->coefs[j + i] += p.coefs[i] * q.coefs[j];
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
poly_cmp(const void *vp, const void *vq)
|
poly_cmp(const void *vp, const void *vq)
|
||||||
{
|
{
|
||||||
@ -113,6 +126,17 @@ print_funs(struct poly p, struct poly q)
|
|||||||
{
|
{
|
||||||
struct poly polys[6];
|
struct poly polys[6];
|
||||||
struct poly dp, ddp, dq, ddq;
|
struct poly dp, ddp, dq, ddq;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i <= MIN(p.degree, q.degree)
|
||||||
|
&& p.coefs[i] == 0.0 && q.coefs[i] == 0.0; i++)
|
||||||
|
;
|
||||||
|
for (j = i; j <= p.degree; j++)
|
||||||
|
p.coefs[j - i] = p.coefs[j];
|
||||||
|
p.degree -= i;
|
||||||
|
for (j = i; j <= q.degree; j++)
|
||||||
|
q.coefs[j - i] = q.coefs[j];
|
||||||
|
q.degree -= i;
|
||||||
|
|
||||||
polys[0] = p;
|
polys[0] = p;
|
||||||
polys[1] = q;
|
polys[1] = q;
|
||||||
@ -169,7 +193,8 @@ usage(void)
|
|||||||
const char *p = xgetprogname();
|
const char *p = xgetprogname();
|
||||||
fprintf(stderr, "Usage:\n"
|
fprintf(stderr, "Usage:\n"
|
||||||
"\t%s p-degree q-degree p-coefs q-coefs\n"
|
"\t%s p-degree q-degree p-coefs q-coefs\n"
|
||||||
"\t%s -n p-degree p-coefs\n", p, p);
|
"\t%s -h p-degree p-coefs\n"
|
||||||
|
"\t%s -n p-degree p-coefs\n", p, p, p);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,6 +229,51 @@ do_poly_div(int argc, char *argv[])
|
|||||||
poly_free(&q);
|
poly_free(&q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_halley(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct poly f, df, ddf, p, q, s, t, u;
|
||||||
|
int i, j, f_degree;
|
||||||
|
|
||||||
|
if (argc < 1)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
f_degree = parse_integer(argv[0], 0, MAX_DEGREE);
|
||||||
|
if (argc != f_degree + 1 + 1)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
poly_init(&f, f_degree, "f");
|
||||||
|
for (j = 0, i = 1 + f.degree;
|
||||||
|
i > 0;
|
||||||
|
i--, j++)
|
||||||
|
f.coefs[j] = parse_double(argv[i]);
|
||||||
|
|
||||||
|
poly_derivate(f, &df, "df");
|
||||||
|
poly_derivate(df, &ddf, "ddf");
|
||||||
|
poly_multiply(f, df, &s, "f_df");
|
||||||
|
poly_multiply(df, df, &t, "df_df");
|
||||||
|
poly_multiply(f, ddf, &u, "f_ddf");
|
||||||
|
|
||||||
|
poly_init(&p, MAX(MAX(t.degree, u.degree) + 1, s.degree), "p");
|
||||||
|
poly_init(&q, MAX(t.degree, u.degree), "q");
|
||||||
|
|
||||||
|
for (i = 0; i <= q.degree; i++)
|
||||||
|
q.coefs[i] = 2.0 * t.coefs[i] - u.coefs[i];
|
||||||
|
for (i = 0; i <= p.degree; i++)
|
||||||
|
p.coefs[i] = (i == 0 ? 0.0 : q.coefs[i - 1])
|
||||||
|
- 2.0L * (i <= s.degree ? s.coefs[i] : 0.0);
|
||||||
|
|
||||||
|
print_funs(p, q);
|
||||||
|
poly_free(&f);
|
||||||
|
poly_free(&df);
|
||||||
|
poly_free(&ddf);
|
||||||
|
poly_free(&s);
|
||||||
|
poly_free(&t);
|
||||||
|
poly_free(&u);
|
||||||
|
poly_free(&p);
|
||||||
|
poly_free(&q);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_newton(int argc, char *argv[])
|
do_newton(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -237,11 +307,14 @@ do_newton(int argc, char *argv[])
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int ch, nflag;
|
int ch, hflag, nflag;
|
||||||
|
|
||||||
nflag = 0;
|
hflag = nflag = 0;
|
||||||
while ((ch = getopt(argc, argv, "n")) != -1)
|
while ((ch = getopt(argc, argv, "hn")) != -1)
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
case 'h':
|
||||||
|
hflag = 1;
|
||||||
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
nflag = 1;
|
nflag = 1;
|
||||||
break;
|
break;
|
||||||
@ -251,7 +324,9 @@ main(int argc, char *argv[])
|
|||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
if (nflag)
|
if (hflag)
|
||||||
|
do_halley(argc, argv);
|
||||||
|
else if (nflag)
|
||||||
do_newton(argc, argv);
|
do_newton(argc, argv);
|
||||||
else
|
else
|
||||||
do_poly_div(argc, argv);
|
do_poly_div(argc, argv);
|
||||||
|
Loading…
Reference in New Issue
Block a user