2 /* Square root, sine, cosine, and arctangent of polynomial.
3 * See polyn.c for data structures and discussion.
9 extern double atan2 ( double, double );
10 extern double sqrt ( double );
11 extern double fabs ( double );
12 extern double sin ( double );
13 extern double cos ( double );
14 extern void polclr ( double *a, int n );
15 extern void polmov ( double *a, int na, double *b );
16 extern void polmul ( double a[], int na, double b[], int nb, double c[] );
17 extern void poladd ( double a[], int na, double b[], int nb, double c[] );
18 extern void polsub ( double a[], int na, double b[], int nb, double c[] );
19 extern int poldiv ( double a[], int na, double b[], int nb, double c[] );
20 extern void polsbt ( double a[], int na, double b[], int nb, double c[] );
21 extern void * malloc ( long );
22 extern void free ( void * );
24 double atan2(), sqrt(), fabs(), sin(), cos();
25 void polclr(), polmov(), polsbt(), poladd(), polsub(), polmul();
31 /* Highest degree of polynomial to be handled
32 by the polyn.c subroutine package. */
34 /* Highest degree actually initialized at runtime. */
37 /* Taylor series coefficients for various functions
40 0.0, 1.0, 0.0, -1.0/3.0, 0.0,
41 1.0/5.0, 0.0, -1.0/7.0, 0.0, 1.0/9.0, 0.0, -1.0/11.0,
42 0.0, 1.0/13.0, 0.0, -1.0/15.0, 0.0 };
45 0.0, 1.0, 0.0, -1.0/6.0, 0.0, 1.0/120.0, 0.0,
46 -1.0/5040.0, 0.0, 1.0/362880.0, 0.0, -1.0/39916800.0,
47 0.0, 1.0/6227020800.0, 0.0, -1.0/1.307674368e12, 0.0};
50 1.0, 0.0, -1.0/2.0, 0.0, 1.0/24.0, 0.0,
51 -1.0/720.0, 0.0, 1.0/40320.0, 0.0, -1.0/3628800.0, 0.0,
52 1.0/479001600.0, 0.0, -1.0/8.7179291e10, 0.0, 1.0/2.0922789888e13};
55 0.0, 1.0, 0.0, 1.0/6.0, 0.0,
56 3.0/40.0, 0.0, 15.0/336.0, 0.0, 105.0/3456.0, 0.0, 945.0/42240.0,
57 0.0, 10395.0/599040.0 , 0.0, 135135.0/9676800.0 , 0.0
60 /* Square root of 1 + x. */
62 1.0, 1./2., -1./8., 1./16., -5./128., 7./256., -21./1024., 33./2048.,
63 -429./32768., 715./65536., -2431./262144., 4199./524288., -29393./4194304.,
64 52003./8388608., -185725./33554432., 334305./67108864.,
65 -9694845./2147483648.};
67 /* Arctangent of the ratio num/den of two polynomials.
70 polatn( num, den, ans, nn )
71 double num[], den[], ans[];
75 double *polq, *polu, *polt;
80 mtherr ("polatn", OVERFLOW);
83 /* arctan( a + b ) = arctan(a) + arctan( b/(1 + ab + a**2) ) */
86 if( (t == 0.0) && (a == 0.0 ) )
91 t = atan2( t, a ); /* arctan(num/den), the ANSI argument order */
92 polq = (double * )malloc( (MAXPOL+1) * sizeof (double) );
93 polu = (double * )malloc( (MAXPOL+1) * sizeof (double) );
94 polt = (double * )malloc( (MAXPOL+1) * sizeof (double) );
95 polclr( polq, MAXPOL );
96 i = poldiv( den, nn, num, nn, polq );
98 polq[0] = 0.0; /* b */
99 polmov( polq, nn, polu ); /* b */
100 /* Form the polynomial
102 where a is a scalar. */
103 for( i=0; i<=nn; i++ )
105 polu[0] += 1.0 + a * a;
106 poldiv( polu, nn, polq, nn, polt ); /* divide into b */
107 polsbt( polt, nn, patan, nn, polu ); /* arctan(b) */
108 polu[0] += t; /* plus arctan(a) */
109 polmov( polu, nn, ans );
117 /* Square root of a polynomial.
118 * Assumes the lowest degree nonzero term is dominant
119 * and of even degree. An error message is given
120 * if the Newton iteration does not converge.
123 polsqt( pol, ans, nn )
137 mtherr ("polatn", OVERFLOW);
140 x = (double * )malloc( (MAXPOL+1) * sizeof (double) );
141 y = (double * )malloc( (MAXPOL+1) * sizeof (double) );
142 polmov( pol, nn, x );
145 /* Find lowest degree nonzero term. */
147 for( n=0; n<nn; n++ )
152 polmov( y, nn, ans );
161 printf("error, sqrt of odd polynomial\n");
166 poldiv (y, nn, pol, N, x);
170 for( i=1; i<=nn; i++ )
173 /* series development sqrt(1+x) = 1 + x / 2 - x**2 / 8 + x**3 / 16
174 hopes that first (constant) term is greater than what follows */
175 polsbt( x, nn, psqrt, nn, y);
177 for( i=0; i<=nn; i++ )
180 /* If first nonzero coefficient was at degree n > 0, multiply by
186 polmul (x, nn, y, nn, y);
189 /* Newton iterations */
190 for( n=0; n<10; n++ )
192 poldiv( y, nn, pol, nn, z );
193 poladd( y, nn, z, nn, y );
194 for( i=0; i<=nn; i++ )
196 for( i=0; i<=nn; i++ )
198 u = fabs( y[i] - z[i] );
205 printf( "square root did not converge\n" );
209 polmov( y, nn, ans );
216 /* Sine of a polynomial.
217 * The computation uses
218 * sin(a+b) = sin(a) cos(b) + cos(a) sin(b)
219 * where a is the constant term of the polynomial and
220 * b is the sum of the rest of the terms.
221 * Since sin(b) and cos(b) are computed by series expansions,
222 * the value of b should be small.
235 mtherr ("polatn", OVERFLOW);
238 w = (double * )malloc( (MAXPOL+1) * sizeof (double) );
239 c = (double * )malloc( (MAXPOL+1) * sizeof (double) );
243 /* a, in the description, is x[0]. b is the polynomial x - x[0]. */
247 polsbt( w, nn, pcos, nn, c );
250 for( i=0; i<=nn; i++ )
253 polsbt( w, nn, psin, nn, y );
256 for( i=0; i<=nn; i++ )
258 poladd( c, nn, y, nn, y );
264 /* Cosine of a polynomial.
265 * The computation uses
266 * cos(a+b) = cos(a) cos(b) - sin(a) sin(b)
267 * where a is the constant term of the polynomial and
268 * b is the sum of the rest of the terms.
269 * Since sin(b) and cos(b) are computed by series expansions,
270 * the value of b should be small.
284 mtherr ("polatn", OVERFLOW);
287 w = (double * )malloc( (MAXPOL+1) * sizeof (double) );
288 c = (double * )malloc( (MAXPOL+1) * sizeof (double) );
295 polsbt( w, nn, pcos, nn, c );
298 for( i=0; i<=nn; i++ )
301 polsbt( w, nn, psin, nn, y );
304 for( i=0; i<=nn; i++ )
306 polsub( y, nn, c, nn, y );