3 * Arithmetic operations on polynomials
5 * In the following descriptions a, b, c are polynomials of degree
6 * na, nb, nc respectively. The degree of a polynomial cannot
7 * exceed a run-time value MAXPOLF. An operation that attempts
8 * to use or generate a polynomial of higher degree may produce a
9 * result that suffers truncation at degree MAXPOL. The value of
10 * MAXPOL is set by calling the function
14 * where maxpol is the desired maximum degree. This must be
15 * done prior to calling any of the other functions in this module.
16 * Memory for internal temporary polynomial storage is allocated
19 * Each polynomial is represented by an array containing its
20 * coefficients, together with a separately declared integer equal
21 * to the degree of the polynomial. The coefficients appear in
22 * ascending order; that is,
25 * a(x) = a[0] + a[1] * x + a[2] * x + ... + a[na] * x .
29 * sum = poleva( a, na, x ); Evaluate polynomial a(t) at t = x.
30 * polprtf( a, na, D ); Print the coefficients of a to D digits.
31 * polclrf( a, na ); Set a identically equal to zero, up to a[na].
32 * polmovf( a, na, b ); Set b = a.
33 * poladdf( a, na, b, nb, c ); c = b + a, nc = max(na,nb)
34 * polsubf( a, na, b, nb, c ); c = b - a, nc = max(na,nb)
35 * polmulf( a, na, b, nb, c ); c = b * a, nc = na+nb
40 * i = poldivf( a, na, b, nb, c ); c = b / a, nc = MAXPOL
42 * returns i = the degree of the first nonzero coefficient of a.
43 * The computed quotient c must be divided by x^i. An error message
44 * is printed if a is identically zero.
47 * Change of variables:
48 * If a and b are polynomials, and t = a(x), then
50 * is a polynomial found by substituting a(x) for t. The
51 * subroutine call for this is
53 * polsbtf( a, na, b, nb, c );
57 * poldivf() is an integer routine; polevaf() is float.
58 * Any of the arguments a, b, c may refer to the same array.
68 void printf(), sprintf(), exit();
72 void printf(), sprintf(), free(), exit();
75 /* near pointer version of malloc() */
76 /*#define malloc _nmalloc*/
77 /*#define free _nfree*/
79 /* Pointers to internal arrays. Note poldiv() allocates
80 * and deallocates some temporary arrays every time it is called.
82 static float *pt1 = 0;
83 static float *pt2 = 0;
84 static float *pt3 = 0;
86 /* Maximum degree of polynomial. */
90 /* Number of bytes (chars) in maximum size polynomial. */
94 /* Initialize max degree of polynomials
95 * and allocate temporary storage.
98 void polinif( int maxdeg )
100 int polinif( maxdeg )
106 psize = (maxdeg + 1) * sizeof(float);
108 /* Release previously allocated memory, if any. */
116 /* Allocate new arrays */
117 pt1 = (float * )malloc(psize); /* used by polsbt */
118 pt2 = (float * )malloc(psize); /* used by polsbt */
119 pt3 = (float * )malloc(psize); /* used by polmul */
121 /* Report if failure */
122 if( (pt1 == NULL) || (pt2 == NULL) || (pt3 == NULL) )
124 mtherr( "polinif", ERANGE );
134 /* Print the coefficients of a, with d decimal precision.
136 static char *form = "abcdefghijk";
139 void polprtf( float *a, int na, int d )
141 int polprtf( a, na, d )
149 /* Create format descriptor string for the printout.
150 * Do this partly by hand, since sprintf() may be too
151 * bug-ridden to accomplish this feat by itself.
156 (void )sprintf( p, "%d ", d1 );
161 (void )sprintf( p, "%d ", d );
170 /* Now do the printing.
174 for( i=0; i<=na; i++ )
176 /* Detect end of available line */
183 printf( form, a[i] );
196 void polclrf( register float *a, int n )
207 for( i=0; i<=n; i++ )
219 void polmovf( register float *a, int na, register float *b )
221 int polmovf( a, na, b )
222 register float *a, *b;
231 for( i=0; i<= na; i++ )
244 void polmulf( float a[], int na, float b[], int nb, float c[] )
246 int polmulf( a, na, b, nb, c )
255 polclrf( pt3, MAXPOLF );
257 for( i=0; i<=na; i++ )
260 for( j=0; j<=nb; j++ )
271 for( i=0; i<=nc; i++ )
284 void poladdf( float a[], int na, float b[], int nb, float c[] )
286 int poladdf( a, na, b, nb, c )
302 for( i=0; i<=n; i++ )
319 void polsubf( float a[], int na, float b[], int nb, float c[] )
321 int polsubf( a, na, b, nb, c )
337 for( i=0; i<=n; i++ )
356 int poldivf( float a[], int na, float b[], int nb, float c[] )
358 int poldivf( a, na, b, nb, c )
369 /* Allocate temporary arrays. This would be quicker
370 * if done automatically on the stack, but stack space
371 * may be hard to obtain on a small computer.
373 ta = (float * )malloc( psize );
374 polclrf( ta, MAXPOLF );
375 polmovf( a, na, ta );
377 tb = (float * )malloc( psize );
378 polclrf( tb, MAXPOLF );
379 polmovf( b, nb, tb );
381 tq = (float * )malloc( psize );
382 polclrf( tq, MAXPOLF );
384 /* What to do if leading (constant) coefficient
385 * of denominator is zero.
389 for( i=0; i<=na; i++ )
394 mtherr( "poldivf", SING );
398 /* Reduce the degree of the denominator. */
399 for( i=0; i<na; i++ )
406 printf( "poldivf singularity, divide quotient by x\n" );
412 /* Reduce degree of numerator. */
413 for( i=0; i<nb; i++ )
417 /* Call self, using reduced polynomials. */
418 sing += poldivf( ta, na, tb, nb, c );
422 /* Long division algorithm. ta[0] is nonzero.
424 for( i=0; i<=MAXPOLF; i++ )
427 for( j=0; j<=MAXPOLF; j++ )
432 tb[k] -= quot * ta[j];
436 /* Send quotient to output array. */
437 polmovf( tq, MAXPOLF, c );
441 /* Restore allocated memory. */
451 /* Change of variables
452 * Substitute a(y) for the variable x in b(x).
454 * c(x) = b(x) = b(a(y)).
458 void polsbtf( float a[], int na, float b[], int nb, float c[] )
460 int polsbtf( a, na, b, nb, c )
470 polclrf( pt1, MAXPOLF );
473 polclrf( pt2, MAXPOLF );
477 for( i=1; i<=nb; i++ )
479 /* Form ith power of a. */
480 polmulf( a, na, pt2, n2, pt2 );
483 /* Add the ith coefficient of b times the ith power of a. */
484 for( j=0; j<=n2; j++ )
488 pt1[j] += x * pt2[j];
495 for( i=0; i<=k; i++ )
505 /* Evaluate polynomial a(t) at t = x.
508 float polevaf( float *a, int na, float xx )
510 float polevaf( a, na, xx )
521 for( i=na-1; i>=0; i-- )