home *** CD-ROM | disk | FTP | other *** search
- /*
- * poly.c -- routines for manipulation of polynomials in one var
- *
- * (c) 1993, 1994 Han-Wen Nienhuys
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include "ray.h"
- #include "proto.h"
-
- /* fudge factor for small coeffs */
- #define FUDGE 1.0e-12
-
-
- PUBLIC void
- poly_copy(spoly *dst, spoly *src)
- {
- int i;
-
- dst->ord = src->ord;
-
- for (i = 0; i <= src->ord; i++)
- dst->coef[i] = src->coef[i];
- }
-
-
- PUBLIC void
- poly_multiply(spoly *dest, spoly *p1, spoly *p2)
- {
- int i,
- j;
-
- dest->ord = p1->ord + p2->ord;
- if (dest->ord > MAX_ORDER)
- errormsg("MAX_ORDER exceeded");
-
- for (i = 0; i <= dest->ord; i++) {
- dest->coef[i] = 0;
- for (j = 0; j <= i; j++)
- if (i - j <= p2->ord && j <= p1->ord)
- dest->coef[i] += p1->coef[j] * p2->coef[i - j];
- }
-
- }
-
-
- PUBLIC void
- poly_power(spoly *dst, int exponent, spoly *src)
- {
- spoly temp;
- int e;
-
- dst->ord = 0;
- dst->coef[0] = 1;
- e = exponent;
-
- /* classic int power. invariant: dst^exponent = dst*src ^ e */
- while (e > 0) {
- if (e % 2) {
- poly_multiply(&temp, dst, src);
- poly_copy(dst, &temp);
- e--;
- } else {
- poly_multiply(&temp, src, src);
- poly_copy(src, &temp);
- e /= 2;
- }
- }
- return;
- }
-
-
- PUBLIC void
- poly_clean(spoly *p)
- {
- int i;
-
- for (i = 0; i <= p->ord; i++) {
- if (ABS(p->coef[i]) < FUDGE)
- p->coef[i] = 0.0;
- }
-
- for (i = p->ord + 1; i <= MAX_ORDER; i++)
- p->coef[i] = 0;
-
- while (p->ord > 0 && p->coef[p->ord] == 0.0)
- p->ord--;
- }
-
-
- PUBLIC void
- poly_add(spoly *dst, spoly *p1, spoly *p2)
- {
- int i,
- tempord;
- double temp;
-
-
- tempord = MAX(p1->ord, p2->ord);
-
- for (i = 0; i <= tempord; i++) {
- temp = 0.0;
- if (i <= p1->ord)
- temp += p1->coef[i];
- if (i <= p2->ord)
- temp += p2->coef[i];
- dst->coef[i] = temp;
- }
- dst->ord = tempord;
- }
-
-
- PUBLIC void
- poly_scalmult(spoly *d, double fact)
- {
- int i;
-
- for (i = 0; i <= d->ord; i++)
- d->coef[i] *= fact;
- }
-
-
- PUBLIC void
- poly_sub(spoly *dst, spoly *p1, spoly *p2)
- {
- int i,
- tempord;
- double temp;
-
-
- tempord = MAX(p1->ord, p2->ord);
-
- for (i = 0; i <= tempord; i++) {
- temp = 0.0;
- if (i <= p1->ord)
- temp += p1->coef[i];
- if (i <= p2->ord)
- temp -= p2->coef[i];
- dst->coef[i] = temp;
- }
- dst->ord = tempord;
-
- }
-
-
- PUBLIC void
- poly_neg(spoly *dst, spoly *src)
- {
- int i;
-
- dst->ord = src->ord;
-
- for (i = 0; i <= src->ord; i++)
- dst->coef[i] = -src->coef[i];
- }
-
- /* print an spoly */
- PUBLIC void
- print_poly(spoly *p)
- {
- #ifdef DEBUG
- int d;
-
- d = p->ord;
- printf("poly ord %d: ", d);
- do {
- if (p->coef[d]) {
- printf("%lf", p->coef[d]);
- if (d == 1)
- printf(" t + ");
- else if (d > 1) {
- printf(" t^%d + ", d);
- }
- }
- }
- while (d-- > 0);
- printf("\n");
- #endif
- }
-