polynf.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. /* polynf.c
  2. * polyrf.c
  3. * Arithmetic operations on polynomials
  4. *
  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
  11. *
  12. * polinif( maxpol );
  13. *
  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
  17. * by polinif().
  18. *
  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,
  23. *
  24. * 2 na
  25. * a(x) = a[0] + a[1] * x + a[2] * x + ... + a[na] * x .
  26. *
  27. *
  28. *
  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
  36. *
  37. *
  38. * Division:
  39. *
  40. * i = poldivf( a, na, b, nb, c ); c = b / a, nc = MAXPOL
  41. *
  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.
  45. *
  46. *
  47. * Change of variables:
  48. * If a and b are polynomials, and t = a(x), then
  49. * c(t) = b(a(x))
  50. * is a polynomial found by substituting a(x) for t. The
  51. * subroutine call for this is
  52. *
  53. * polsbtf( a, na, b, nb, c );
  54. *
  55. *
  56. * Notes:
  57. * poldivf() is an integer routine; polevaf() is float.
  58. * Any of the arguments a, b, c may refer to the same array.
  59. *
  60. */
  61. #ifndef NULL
  62. #define NULL 0
  63. #endif
  64. #include <math.h>
  65. #ifdef ANSIC
  66. void printf(), sprintf(), exit();
  67. void free(void *);
  68. void *malloc(int);
  69. #else
  70. void printf(), sprintf(), free(), exit();
  71. void *malloc();
  72. #endif
  73. /* near pointer version of malloc() */
  74. /*#define malloc _nmalloc*/
  75. /*#define free _nfree*/
  76. /* Pointers to internal arrays. Note poldiv() allocates
  77. * and deallocates some temporary arrays every time it is called.
  78. */
  79. static float *pt1 = 0;
  80. static float *pt2 = 0;
  81. static float *pt3 = 0;
  82. /* Maximum degree of polynomial. */
  83. int MAXPOLF = 0;
  84. extern int MAXPOLF;
  85. /* Number of bytes (chars) in maximum size polynomial. */
  86. static int psize = 0;
  87. /* Initialize max degree of polynomials
  88. * and allocate temporary storage.
  89. */
  90. #ifdef ANSIC
  91. void polinif( int maxdeg )
  92. #else
  93. int polinif( maxdeg )
  94. int maxdeg;
  95. #endif
  96. {
  97. MAXPOLF = maxdeg;
  98. psize = (maxdeg + 1) * sizeof(float);
  99. /* Release previously allocated memory, if any. */
  100. if( pt3 )
  101. free(pt3);
  102. if( pt2 )
  103. free(pt2);
  104. if( pt1 )
  105. free(pt1);
  106. /* Allocate new arrays */
  107. pt1 = (float * )malloc(psize); /* used by polsbtf */
  108. pt2 = (float * )malloc(psize); /* used by polsbtf */
  109. pt3 = (float * )malloc(psize); /* used by polmul */
  110. /* Report if failure */
  111. if( (pt1 == NULL) || (pt2 == NULL) || (pt3 == NULL) )
  112. {
  113. mtherr( "polinif", ERANGE );
  114. exit(1);
  115. }
  116. #if !ANSIC
  117. return 0;
  118. #endif
  119. }
  120. /* Print the coefficients of a, with d decimal precision.
  121. */
  122. static char *form = "abcdefghijk";
  123. #ifdef ANSIC
  124. void polprtf( float *a, int na, int d )
  125. #else
  126. int polprtf( a, na, d )
  127. float a[];
  128. int na, d;
  129. #endif
  130. {
  131. int i, j, d1;
  132. char *p;
  133. /* Create format descriptor string for the printout.
  134. * Do this partly by hand, since sprintf() may be too
  135. * bug-ridden to accomplish this feat by itself.
  136. */
  137. p = form;
  138. *p++ = '%';
  139. d1 = d + 8;
  140. (void )sprintf( p, "%d ", d1 );
  141. p += 1;
  142. if( d1 >= 10 )
  143. p += 1;
  144. *p++ = '.';
  145. (void )sprintf( p, "%d ", d );
  146. p += 1;
  147. if( d >= 10 )
  148. p += 1;
  149. *p++ = 'e';
  150. *p++ = ' ';
  151. *p++ = '\0';
  152. /* Now do the printing.
  153. */
  154. d1 += 1;
  155. j = 0;
  156. for( i=0; i<=na; i++ )
  157. {
  158. /* Detect end of available line */
  159. j += d1;
  160. if( j >= 78 )
  161. {
  162. printf( "\n" );
  163. j = d1;
  164. }
  165. printf( form, a[i] );
  166. }
  167. printf( "\n" );
  168. #if !ANSIC
  169. return 0;
  170. #endif
  171. }
  172. /* Set a = 0.
  173. */
  174. #ifdef ANSIC
  175. void polclrf( register float *a, int n )
  176. #else
  177. int polclrf( a, n )
  178. register float *a;
  179. int n;
  180. #endif
  181. {
  182. int i;
  183. if( n > MAXPOLF )
  184. n = MAXPOLF;
  185. for( i=0; i<=n; i++ )
  186. *a++ = 0.0;
  187. #if !ANSIC
  188. return 0;
  189. #endif
  190. }
  191. /* Set b = a.
  192. */
  193. #ifdef ANSIC
  194. void polmovf( register float *a, int na, register float *b )
  195. #else
  196. int polmovf( a, na, b )
  197. register float *a, *b;
  198. int na;
  199. #endif
  200. {
  201. int i;
  202. if( na > MAXPOLF )
  203. na = MAXPOLF;
  204. for( i=0; i<= na; i++ )
  205. {
  206. *b++ = *a++;
  207. }
  208. #if !ANSIC
  209. return 0;
  210. #endif
  211. }
  212. /* c = b * a.
  213. */
  214. #ifdef ANSIC
  215. void polmulf( float a[], int na, float b[], int nb, float c[] )
  216. #else
  217. int polmulf( a, na, b, nb, c )
  218. float a[], b[], c[];
  219. int na, nb;
  220. #endif
  221. {
  222. int i, j, k, nc;
  223. float x;
  224. nc = na + nb;
  225. polclrf( pt3, MAXPOLF );
  226. for( i=0; i<=na; i++ )
  227. {
  228. x = a[i];
  229. for( j=0; j<=nb; j++ )
  230. {
  231. k = i + j;
  232. if( k > MAXPOLF )
  233. break;
  234. pt3[k] += x * b[j];
  235. }
  236. }
  237. if( nc > MAXPOLF )
  238. nc = MAXPOLF;
  239. for( i=0; i<=nc; i++ )
  240. c[i] = pt3[i];
  241. #if !ANSIC
  242. return 0;
  243. #endif
  244. }
  245. /* c = b + a.
  246. */
  247. #ifdef ANSIC
  248. void poladdf( float a[], int na, float b[], int nb, float c[] )
  249. #else
  250. int poladdf( a, na, b, nb, c )
  251. float a[], b[], c[];
  252. int na, nb;
  253. #endif
  254. {
  255. int i, n;
  256. if( na > nb )
  257. n = na;
  258. else
  259. n = nb;
  260. if( n > MAXPOLF )
  261. n = MAXPOLF;
  262. for( i=0; i<=n; i++ )
  263. {
  264. if( i > na )
  265. c[i] = b[i];
  266. else if( i > nb )
  267. c[i] = a[i];
  268. else
  269. c[i] = b[i] + a[i];
  270. }
  271. #if !ANSIC
  272. return 0;
  273. #endif
  274. }
  275. /* c = b - a.
  276. */
  277. #ifdef ANSIC
  278. void polsubf( float a[], int na, float b[], int nb, float c[] )
  279. #else
  280. int polsubf( a, na, b, nb, c )
  281. float a[], b[], c[];
  282. int na, nb;
  283. #endif
  284. {
  285. int i, n;
  286. if( na > nb )
  287. n = na;
  288. else
  289. n = nb;
  290. if( n > MAXPOLF )
  291. n = MAXPOLF;
  292. for( i=0; i<=n; i++ )
  293. {
  294. if( i > na )
  295. c[i] = b[i];
  296. else if( i > nb )
  297. c[i] = -a[i];
  298. else
  299. c[i] = b[i] - a[i];
  300. }
  301. #if !ANSIC
  302. return 0;
  303. #endif
  304. }
  305. /* c = b/a
  306. */
  307. #ifdef ANSIC
  308. int poldivf( float a[], int na, float b[], int nb, float c[] )
  309. #else
  310. int poldivf( a, na, b, nb, c )
  311. float a[], b[], c[];
  312. int na, nb;
  313. #endif
  314. {
  315. float quot;
  316. float *ta, *tb, *tq;
  317. int i, j, k, sing;
  318. sing = 0;
  319. /* Allocate temporary arrays. This would be quicker
  320. * if done automatically on the stack, but stack space
  321. * may be hard to obtain on a small computer.
  322. */
  323. ta = (float * )malloc( psize );
  324. polclrf( ta, MAXPOLF );
  325. polmovf( a, na, ta );
  326. tb = (float * )malloc( psize );
  327. polclrf( tb, MAXPOLF );
  328. polmovf( b, nb, tb );
  329. tq = (float * )malloc( psize );
  330. polclrf( tq, MAXPOLF );
  331. /* What to do if leading (constant) coefficient
  332. * of denominator is zero.
  333. */
  334. if( a[0] == 0.0 )
  335. {
  336. for( i=0; i<=na; i++ )
  337. {
  338. if( ta[i] != 0.0 )
  339. goto nzero;
  340. }
  341. mtherr( "poldivf", SING );
  342. goto done;
  343. nzero:
  344. /* Reduce the degree of the denominator. */
  345. for( i=0; i<na; i++ )
  346. ta[i] = ta[i+1];
  347. ta[na] = 0.0;
  348. if( b[0] != 0.0 )
  349. {
  350. /* Optional message:
  351. printf( "poldivf singularity, divide quotient by x\n" );
  352. */
  353. sing += 1;
  354. }
  355. else
  356. {
  357. /* Reduce degree of numerator. */
  358. for( i=0; i<nb; i++ )
  359. tb[i] = tb[i+1];
  360. tb[nb] = 0.0;
  361. }
  362. /* Call self, using reduced polynomials. */
  363. sing += poldivf( ta, na, tb, nb, c );
  364. goto done;
  365. }
  366. /* Long division algorithm. ta[0] is nonzero.
  367. */
  368. for( i=0; i<=MAXPOLF; i++ )
  369. {
  370. quot = tb[i]/ta[0];
  371. for( j=0; j<=MAXPOLF; j++ )
  372. {
  373. k = j + i;
  374. if( k > MAXPOLF )
  375. break;
  376. tb[k] -= quot * ta[j];
  377. }
  378. tq[i] = quot;
  379. }
  380. /* Send quotient to output array. */
  381. polmovf( tq, MAXPOLF, c );
  382. done:
  383. /* Restore allocated memory. */
  384. free(tq);
  385. free(tb);
  386. free(ta);
  387. return( sing );
  388. }
  389. /* Change of variables
  390. * Substitute a(y) for the variable x in b(x).
  391. * x = a(y)
  392. * c(x) = b(x) = b(a(y)).
  393. */
  394. #ifdef ANSIC
  395. void polsbtf( float a[], int na, float b[], int nb, float c[] )
  396. #else
  397. int polsbtf( a, na, b, nb, c )
  398. float a[], b[], c[];
  399. int na, nb;
  400. #endif
  401. {
  402. int i, j, k, n2;
  403. float x;
  404. /* 0th degree term:
  405. */
  406. polclrf( pt1, MAXPOLF );
  407. pt1[0] = b[0];
  408. polclrf( pt2, MAXPOLF );
  409. pt2[0] = 1.0;
  410. n2 = 0;
  411. for( i=1; i<=nb; i++ )
  412. {
  413. /* Form ith power of a. */
  414. polmulf( a, na, pt2, n2, pt2 );
  415. n2 += na;
  416. x = b[i];
  417. /* Add the ith coefficient of b times the ith power of a. */
  418. for( j=0; j<=n2; j++ )
  419. {
  420. if( j > MAXPOLF )
  421. break;
  422. pt1[j] += x * pt2[j];
  423. }
  424. }
  425. k = n2 + nb;
  426. if( k > MAXPOLF )
  427. k = MAXPOLF;
  428. for( i=0; i<=k; i++ )
  429. c[i] = pt1[i];
  430. #if !ANSIC
  431. return 0;
  432. #endif
  433. }
  434. /* Evaluate polynomial a(t) at t = x.
  435. */
  436. float polevaf( float *a, int na, float xx )
  437. {
  438. float x, s;
  439. int i;
  440. x = xx;
  441. s = a[na];
  442. for( i=na-1; i>=0; i-- )
  443. {
  444. s = s * x + a[i];
  445. }
  446. return(s);
  447. }