1 /*******************************************************************************
2 * chi2.cpp
3 *
4 * This module contains the function for the chi square distribution.
5 *
6 * This software is derived from the Cephes Math Library and is
7 * incorporated herein by permission of the author, Stephen L. Moshier.
8 *
9 * Cephes Math Library Release 2.0: April, 1987
10 * Copyright 1984, 1987 by Stephen L. Moshier
11 *
12 * The author reserves the right to distribute this material elsewhere under
13 * different terms. This file is provided within POV-Ray under the following
14 * terms:
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions are met:
18 *
19 * 1. Redistributions of source code must retain the above copyright notice,
20 * this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright notice,
22 * this list of conditions and the following disclaimer in the documentation
23 * and/or other materials provided with the distribution.
24 * 3. Neither the names of the copyright holders nor the names of contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 * ---------------------------------------------------------------------------
40 * $File: //depot/public/povray/3.x/source/backend/math/chi2.cpp $
41 * $Revision: #1 $
42 * $Change: 6069 $
43 * $DateTime: 2013/11/06 11:59:40 $
44 * $Author: chrisc $
45 *******************************************************************************/
46
47 // frame.h must always be the first POV file included (pulls in platform config)
48 #include "backend/frame.h"
49 #include "backend/math/chi2.h"
50 #include "base/pov_err.h"
51
52 // this must be the last file included
53 #include "base/povdebug.h"
54
55 namespace pov
56 {
57
58 /*
59 Cephes Math Library Release 2.0: April, 1987
60 Copyright 1984, 1987 by Stephen L. Moshier
61 Direct inquiries to 30 Frost Street, Cambridge, MA 02140
62 */
63
64 /*****************************************************************************
65 * Local preprocessor defines
66 ******************************************************************************/
67
68 const DBL MAXLGM = 2.556348e305;
69 const DBL BIG = 1.44115188075855872E+17;
70 const DBL MACHEP = 1.38777878078144567553E-17; /* 2**-56 */
71 const DBL MAXLOG = 8.8029691931113054295988E1; /* log(2**127) */
72 const DBL MAXNUM = 1.701411834604692317316873e38; /* 2**127 */
73 const DBL LOGPI = 1.14472988584940017414;
74
75 /*
76 * A[]: Stirling's formula expansion of log gamma
77 * B[], C[]: log gamma function between 2 and 3
78 */
79
80 const DBL A[] =
81 {
82 8.11614167470508450300E-4,
83 -5.95061904284301438324E-4,
84 7.93650340457716943945E-4,
85 -2.77777777730099687205E-3,
86 8.33333333333331927722E-2
87 };
88
89 const DBL B[] =
90 {
91 -1.37825152569120859100E3,
92 -3.88016315134637840924E4,
93 -3.31612992738871184744E5,
94 -1.16237097492762307383E6,
95 -1.72173700820839662146E6,
96 -8.53555664245765465627E5
97 };
98
99 const DBL C[] =
100 {
101 1.00000000000000000000E0,
102 -3.51815701436523470549E2,
103 -1.70642106651881159223E4,
104 -2.20528590553854454839E5,
105 -1.13933444367982507207E6,
106 -2.53252307177582951285E6,
107 -2.01889141433532773231E6
108 };
109
110 /* log(sqrt(2pi)) */
111
112 const DBL LS2PI = 0.91893853320467274178;
113
114 /* sqrt(2pi) */
115
116 const DBL s2pi = 2.50662827463100050242E0;
117
118 /* approximation for 0 <= |y - 0.5| <= 3/8 */
119
120 const DBL P0[5] =
121 {
122 -5.99633501014107895267E1,
123 9.80010754185999661536E1,
124 -5.66762857469070293439E1,
125 1.39312609387279679503E1,
126 -1.23916583867381258016E0,
127 };
128
129 const DBL Q0[8] =
130 {
131 /* 1.00000000000000000000E0,*/
132 1.95448858338141759834E0,
133 4.67627912898881538453E0,
134 8.63602421390890590575E1,
135 -2.25462687854119370527E2,
136 2.00260212380060660359E2,
137 -8.20372256168333339912E1,
138 1.59056225126211695515E1,
139 -1.18331621121330003142E0,
140 };
141
142 /*
143 * Approximation for interval z = sqrt(-2 log y ) between 2 and 8
144 * i.e., y between exp(-2) = .135 and exp(-32) = 1.27e-14.
145 */
146
147 const DBL P1[9] =
148 {
149 4.05544892305962419923E0,
150 3.15251094599893866154E1,
151 5.71628192246421288162E1,
152 4.40805073893200834700E1,
153 1.46849561928858024014E1,
154 2.18663306850790267539E0,
155 -1.40256079171354495875E-1,
156 -3.50424626827848203418E-2,
157 -8.57456785154685413611E-4,
158 };
159
160 const DBL Q1[8] =
161 {
162 /* 1.00000000000000000000E0,*/
163 1.57799883256466749731E1,
164 4.53907635128879210584E1,
165 4.13172038254672030440E1,
166 1.50425385692907503408E1,
167 2.50464946208309415979E0,
168 -1.42182922854787788574E-1,
169 -3.80806407691578277194E-2,
170 -9.33259480895457427372E-4,
171 };
172
173 /*
174 * Approximation for interval z = sqrt(-2 log y ) between 8 and 64
175 * i.e., y between exp(-32) = 1.27e-14 and exp(-2048) = 3.67e-890.
176 */
177
178 const DBL P2[9] =
179 {
180 3.23774891776946035970E0,
181 6.91522889068984211695E0,
182 3.93881025292474443415E0,
183 1.33303460815807542389E0,
184 2.01485389549179081538E-1,
185 1.23716634817820021358E-2,
186 3.01581553508235416007E-4,
187 2.65806974686737550832E-6,
188 6.23974539184983293730E-9,
189 };
190
191 const DBL Q2[8] =
192 {
193 /* 1.00000000000000000000E0,*/
194 6.02427039364742014255E0,
195 3.67983563856160859403E0,
196 1.37702099489081330271E0,
197 2.16236993594496635890E-1,
198 1.34204006088543189037E-2,
199 3.28014464682127739104E-4,
200 2.89247864745380683936E-6,
201 6.79019408009981274425E-9,
202 };
203
204
205 /*****************************************************************************
206 * Static functions
207 ******************************************************************************/
208
209 static DBL igami (DBL a, DBL y0);
210 static DBL lgam (DBL x, int *sgngam);
211 static DBL polevl (DBL x, const DBL * coef, int N);
212 static DBL p1evl (DBL x, const DBL * coef, int N);
213 static DBL igamc (DBL a, DBL x);
214 static DBL igam (DBL a, DBL x);
215 static DBL ndtri (DBL y0);
216
217
218
219 /* chdtri()
220 *
221 * Inverse of complemented Chi-square distribution
222 *
223 *
224 *
225 * SYNOPSIS:
226 *
227 * DBL df, x, y, chdtri();
228 *
229 * x = chdtri( df, y );
230 *
231 *
232 *
233 *
234 * DESCRIPTION:
235 *
236 * Finds the Chi-square argument x such that the integral
237 * from x to infinity of the Chi-square density is equal
238 * to the given cumulative probability y.
239 *
240 * This is accomplished using the inverse gamma integral
241 * function and the relation
242 *
243 * x/2 = igami( df/2, y );
244 *
245 *
246 *
247 *
248 * ACCURACY:
249 *
250 * See igami.c.
251 *
252 * ERROR MESSAGES:
253 *
254 * message condition value returned
255 * chdtri domain y < 0 or y > 1 0.0
256 * v < 1
257 *
258 */
259
chdtri(DBL df,DBL y)260 DBL chdtri(DBL df, DBL y)
261 {
262 DBL x;
263
264 if ((y < 0.0) || (y > 1.0) || (df < 1.0))
265 {
266 throw POV_EXCEPTION_STRING("Illegal values in chdtri().");
267
268 return (0.0);
269 }
270
271 x = igami(0.5 * df, y);
272
273 return (2.0 * x);
274 }
275
276
277
278 /* lgam()
279 *
280 * Natural logarithm of gamma function
281 *
282 *
283 *
284 * SYNOPSIS:
285 *
286 * DBL x, y, lgam();
287 *
288 * y = lgam( x );
289 *
290 *
291 *
292 * DESCRIPTION:
293 *
294 * Returns the base e (2.718...) logarithm of the absolute
295 * value of the gamma function of the argument.
296 * The sign (+1 or -1) of the gamma function is returned in a
297 * variable named sgngam.
298 *
299 * For arguments greater than 13, the logarithm of the gamma
300 * function is approximated by the logarithmic version of
301 * Stirling's formula using a polynomial approximation of
302 * degree 4. Arguments between -33 and +33 are reduced by
303 * recurrence to the interval [2,3] of a rational approximation.
304 * The cosecant reflection formula is employed for arguments
305 * less than -33.
306 *
307 * Arguments greater than MAXLGM return MAXNUM and an error
308 * message. MAXLGM = 2.035093e36 for DEC
309 * arithmetic or 2.556348e305 for IEEE arithmetic.
310 *
311 *
312 *
313 * ACCURACY:
314 *
315 *
316 * arithmetic domain # trials peak rms
317 * DEC 0, 3 7000 5.2e-17 1.3e-17
318 * DEC 2.718, 2.035e36 5000 3.9e-17 9.9e-18
319 * IEEE 0, 3 28000 5.4e-16 1.1e-16
320 * IEEE 2.718, 2.556e305 40000 3.5e-16 8.3e-17
321 * The error criterion was relative when the function magnitude
322 * was greater than one but absolute when it was less than one.
323 *
324 * The following test used the relative error criterion, though
325 * at certain points the relative error could be much higher than
326 * indicated.
327 * IEEE -200, -4 10000 4.8e-16 1.3e-16
328 *
329 */
330
lgam(DBL x,int * sgngam)331 static DBL lgam(DBL x, int *sgngam)
332 {
333 DBL p, q, w, z;
334 int i;
335
336 *sgngam = 1;
337
338 if (x < -34.0)
339 {
340 q = -x;
341 w = lgam(q, sgngam); /* note this modifies sgngam! */
342 p = floor(q);
343
344 if (p == q)
345 {
346 goto loverf;
347 }
348
349 i = p;
350
351 if ((i & 1) == 0)
352 {
353 *sgngam = -1;
354 }
355 else
356 {
357 *sgngam = 1;
358 }
359
360 z = q - p;
361
362 if (z > 0.5)
363 {
364 p += 1.0;
365
366 z = p - q;
367 }
368
369 z = q * sin(M_PI * z);
370
371 if (z == 0.0)
372 {
373 goto loverf;
374 }
375
376 /* z = log(M_PI) - log( z ) - w;*/
377
378 z = LOGPI - log(z) - w;
379
380 return (z);
381 }
382
383 if (x < 13.0)
384 {
385 z = 1.0;
386
387 while (x >= 3.0)
388 {
389 x -= 1.0;
390
391 z *= x;
392 }
393
394 while (x < 2.0)
395 {
396 if (x == 0.0)
397 {
398 goto loverf;
399 }
400
401 z /= x;
402
403 x += 1.0;
404 }
405
406 if (z < 0.0)
407 {
408 *sgngam = -1;
409
410 z = -z;
411 }
412 else
413 {
414 *sgngam = 1;
415 }
416
417 if (x == 2.0)
418 {
419 return (log(z));
420 }
421
422 x -= 2.0;
423
424 p = x * polevl(x, B, 5) / p1evl(x, C, 6);
425
426 return (log(z) + p);
427 }
428
429 if (x > MAXLGM)
430 {
431 loverf:
432 /*
433 mtherr("lgam", OVERFLOW);
434 */
435 return (*sgngam * MAXNUM);
436 }
437
438 q = (x - 0.5) * log(x) - x + LS2PI;
439
440 if (x > 1.0e8)
441 {
442 return (q);
443 }
444
445 p = 1.0 / (x * x);
446
447 if (x >= 1000.0)
448 {
449 q += ((7.9365079365079365079365e-4 * p -
450 2.7777777777777777777778e-3) * p +
451 0.0833333333333333333333) / x;
452 }
453 else
454 {
455 q += polevl(p, A, 4) / x;
456 }
457
458 return (q);
459 }
460
461
462
463 /* igamc()
464 *
465 * Complemented incomplete gamma integral
466 *
467 *
468 *
469 * SYNOPSIS:
470 *
471 * DBL a, x, y, igamc();
472 *
473 * y = igamc( a, x );
474 *
475 *
476 *
477 * DESCRIPTION:
478 *
479 * The function is defined by
480 *
481 *
482 * igamc(a,x) = 1 - igam(a,x)
483 *
484 * inf.
485 * -
486 * 1 | | -t a-1
487 * = ----- | e t dt.
488 * - | |
489 * | (a) -
490 * x
491 *
492 *
493 * In this implementation both arguments must be positive.
494 * The integral is evaluated by either a power series or
495 * continued fraction expansion, depending on the relative
496 * values of a and x.
497 *
498 *
499 *
500 * ACCURACY:
501 *
502 * Relative error:
503 * arithmetic domain # trials peak rms
504 * DEC 0,30 2000 2.7e-15 4.0e-16
505 * IEEE 0,30 60000 1.4e-12 6.3e-15
506 *
507 */
508
igamc(DBL a,DBL x)509 static DBL igamc(DBL a, DBL x)
510 {
511 DBL ans, c, yc, ax, y, z;
512 DBL pk, pkm1, pkm2, qk, qkm1, qkm2;
513 DBL r, t;
514 int sgngam = 0;
515
516 if ((x <= 0) || (a <= 0))
517 {
518 return (1.0);
519 }
520
521 if ((x < 1.0) || (x < a))
522 {
523 return (1.0 - igam(a, x));
524 }
525
526 ax = a * log(x) - x - lgam(a, &sgngam);
527
528 if (ax < -MAXLOG)
529 {
530 /*
531 mtherr("igamc", UNDERFLOW);
532 */
533 return (0.0);
534 }
535
536 ax = exp(ax);
537
538 /* continued fraction */
539
540 y = 1.0 - a;
541 z = x + y + 1.0;
542 c = 0.0;
543
544 pkm2 = 1.0;
545 qkm2 = x;
546 pkm1 = x + 1.0;
547 qkm1 = z * x;
548
549 ans = pkm1 / qkm1;
550
551 do
552 {
553 c += 1.0;
554 y += 1.0;
555 z += 2.0;
556
557 yc = y * c;
558
559 pk = pkm1 * z - pkm2 * yc;
560 qk = qkm1 * z - qkm2 * yc;
561
562 if (qk != 0)
563 {
564 r = pk / qk;
565 t = fabs((ans - r) / r);
566 ans = r;
567 }
568 else
569 {
570 t = 1.0;
571 }
572
573 pkm2 = pkm1;
574 pkm1 = pk;
575 qkm2 = qkm1;
576 qkm1 = qk;
577
578 if (fabs(pk) > BIG)
579 {
580 pkm2 /= BIG;
581 pkm1 /= BIG;
582 qkm2 /= BIG;
583 qkm1 /= BIG;
584 }
585 }
586 while (t > MACHEP);
587
588 return (ans * ax);
589 }
590
591
592
593 /* igam.c
594 *
595 * Incomplete gamma integral
596 *
597 *
598 *
599 * SYNOPSIS:
600 *
601 * DBL a, x, y, igam();
602 *
603 * y = igam( a, x );
604 *
605 *
606 *
607 * DESCRIPTION:
608 *
609 * The function is defined by
610 *
611 * x
612 * -
613 * 1 | | -t a-1
614 * igam(a,x) = ----- | e t dt.
615 * - | |
616 * | (a) -
617 * 0
618 *
619 *
620 * In this implementation both arguments must be positive.
621 * The integral is evaluated by either a power series or
622 * continued fraction expansion, depending on the relative
623 * values of a and x.
624 *
625 *
626 *
627 * ACCURACY:
628 *
629 * Relative error:
630 * arithmetic domain # trials peak rms
631 * DEC 0,30 4000 4.4e-15 6.3e-16
632 * IEEE 0,30 10000 3.6e-14 5.1e-15
633 *
634 */
635
636 /* left tail of incomplete gamma function:
637 *
638 * inf. k
639 * a -x - x
640 * x e > ----------
641 * - -
642 * k=0 | (a+k+1)
643 *
644 */
645
igam(DBL a,DBL x)646 static DBL igam(DBL a, DBL x)
647 {
648 DBL ans, ax, c, r;
649 int sgngam = 0;
650
651 if ((x <= 0) || (a <= 0))
652 {
653 return (0.0);
654 }
655
656 if ((x > 1.0) && (x > a))
657 {
658 return (1.0 - igamc(a, x));
659 }
660
661 /* Compute x**a * exp(-x) / gamma(a) */
662 ax = a * log(x) - x - lgam(a, &sgngam);
663
664 if (ax < -MAXLOG)
665 {
666 /*
667 mtherr("igam", UNDERFLOW);
668 */
669 return (0.0);
670 }
671
672 ax = exp(ax);
673
674 /* power series */
675 r = a;
676 c = 1.0;
677 ans = 1.0;
678
679 do
680 {
681 r += 1.0;
682 c *= x / r;
683 ans += c;
684 }
685 while (c / ans > MACHEP);
686
687 return (ans * ax / a);
688 }
689
690
691
692 /* igami()
693 *
694 * Inverse of complemented imcomplete gamma integral
695 *
696 *
697 *
698 * SYNOPSIS:
699 *
700 * DBL a, x, y, igami();
701 *
702 * x = igami( a, y );
703 *
704 *
705 *
706 * DESCRIPTION:
707 *
708 * Given y, the function finds x such that
709 *
710 * igamc( a, x ) = y.
711 *
712 * Starting with the approximate value
713 *
714 * 3
715 * x = a t
716 *
717 * where
718 *
719 * t = 1 - d - ndtri(y) sqrt(d)
720 *
721 * and
722 *
723 * d = 1/9a,
724 *
725 * the routine performs up to 10 Newton iterations to find the
726 * root of igamc(a,x) - y = 0.
727 *
728 *
729 * ACCURACY:
730 *
731 * Tested for a ranging from 0.5 to 30 and x from 0 to 0.5.
732 *
733 * Relative error:
734 * arithmetic domain # trials peak rms
735 * DEC 0,0.5 3400 8.8e-16 1.3e-16
736 * IEEE 0,0.5 10000 1.1e-14 1.0e-15
737 *
738 */
739
igami(DBL a,DBL y0)740 static DBL igami(DBL a, DBL y0)
741 {
742 DBL d, y, x0, lgm;
743 int i;
744 int sgngam = 0;
745
746 /* approximation to inverse function */
747 d = 1.0 / (9.0 * a);
748 y = (1.0 - d - ndtri(y0) * sqrt(d));
749
750 x0 = a * y * y * y;
751
752 lgm = lgam(a, &sgngam);
753
754 for (i = 0; i < 10; i++)
755 {
756 if (x0 <= 0.0)
757 {
758 /*
759 mtherr("igami", UNDERFLOW);
760 */
761 return (0.0);
762 }
763
764 y = igamc(a, x0);
765
766 /* compute the derivative of the function at this point */
767 d = (a - 1.0) * log(x0) - x0 - lgm;
768
769 if (d < -MAXLOG)
770 {
771 /*
772 mtherr("igami", UNDERFLOW);
773 */
774 goto done;
775 }
776
777 d = -exp(d);
778
779 /* compute the step to the next approximation of x */
780 if (d == 0.0)
781 {
782 goto done;
783 }
784
785 d = (y - y0) / d;
786
787 x0 = x0 - d;
788
789 if (i < 3)
790 {
791 continue;
792 }
793
794 if (fabs(d / x0) < 2.0 * MACHEP)
795 {
796 goto done;
797 }
798 }
799
800 done:
801
802 return (x0);
803 }
804
805
806
807 /* ndtri.c
808 *
809 * Inverse of Normal distribution function
810 *
811 *
812 *
813 * SYNOPSIS:
814 *
815 * DBL x, y, ndtri();
816 *
817 * x = ndtri( y );
818 *
819 *
820 *
821 * DESCRIPTION:
822 *
823 * Returns the argument, x, for which the area under the
824 * Gaussian probability density function (integrated from
825 * minus infinity to x) is equal to y.
826 *
827 *
828 * For small arguments 0 < y < exp(-2), the program computes
829 * z = sqrt( -2.0 * log(y) ); then the approximation is
830 * x = z - log(z)/z - (1/z) P(1/z) / Q(1/z).
831 * There are two rational functions P/Q, one for 0 < y < exp(-32)
832 * and the other for y up to exp(-2). For larger arguments,
833 * w = y - 0.5, and x/sqrt(2pi) = w + w**3 R(w**2)/S(w**2)).
834 *
835 *
836 * ACCURACY:
837 *
838 * Relative error:
839 * arithmetic domain # trials peak rms
840 * DEC 0.125, 1 5500 9.5e-17 2.1e-17
841 * DEC 6e-39, 0.135 3500 5.7e-17 1.3e-17
842 * IEEE 0.125, 1 20000 7.2e-16 1.3e-16
843 * IEEE 3e-308, 0.135 50000 4.6e-16 9.8e-17
844 *
845 *
846 * ERROR MESSAGES:
847 *
848 * message condition value returned
849 * ndtri domain x <= 0 -MAXNUM
850 * ndtri domain x >= 1 MAXNUM
851 *
852 */
853
ndtri(DBL y0)854 static DBL ndtri(DBL y0)
855 {
856 DBL x, y, z, y2, x0, x1;
857 int code;
858
859 if (y0 <= 0.0)
860 {
861 /*
862 mtherr("ndtri", DOMAIN);
863 */
864 return (-MAXNUM);
865 }
866
867 if (y0 >= 1.0)
868 {
869 /*
870 mtherr("ndtri", DOMAIN);
871 */
872 return (MAXNUM);
873 }
874
875 code = 1;
876
877 y = y0;
878
879 if (y > (1.0 - 0.13533528323661269189)) /* 0.135... = exp(-2) */
880 {
881 y = 1.0 - y;
882 code = 0;
883 }
884
885 if (y > 0.13533528323661269189)
886 {
887 y = y - 0.5;
888 y2 = y * y;
889 x = y + y * (y2 * polevl(y2, P0, 4) / p1evl(y2, Q0, 8));
890 x = x * s2pi;
891
892 return (x);
893 }
894
895 x = sqrt(-2.0 * log(y));
896 x0 = x - log(x) / x;
897
898 z = 1.0 / x;
899
900 if (x < 8.0) /* y > exp(-32) = 1.2664165549e-14 */
901 {
902 x1 = z * polevl(z, P1, 8) / p1evl(z, Q1, 8);
903 }
904 else
905 {
906 x1 = z * polevl(z, P2, 8) / p1evl(z, Q2, 8);
907 }
908
909 x = x0 - x1;
910
911 if (code != 0)
912 {
913 x = -x;
914 }
915
916 return (x);
917 }
918
919
920
921 /* polevl.c
922 * p1evl.c
923 *
924 * Evaluate polynomial
925 *
926 *
927 *
928 * SYNOPSIS:
929 *
930 * int N;
931 * DBL x, y, coef[N+1], polevl[];
932 *
933 * y = polevl( x, coef, N );
934 *
935 *
936 *
937 * DESCRIPTION:
938 *
939 * Evaluates polynomial of degree N:
940 *
941 * 2 N
942 * y = C + C x + C x +...+ C x
943 * 0 1 2 N
944 *
945 * Coefficients are stored in reverse order:
946 *
947 * coef[0] = C , ..., coef[N] = C .
948 * N 0
949 *
950 * The function p1evl() assumes that coef[N] = 1.0 and is
951 * omitted from the array. Its calling arguments are
952 * otherwise the same as polevl().
953 *
954 *
955 * SPEED:
956 *
957 * In the interest of speed, there are no checks for out
958 * of bounds arithmetic. This routine is used by most of
959 * the functions in the library. Depending on available
960 * equipment features, the user may wish to rewrite the
961 * program in microcode or assembly language.
962 *
963 */
964
polevl(DBL x,const DBL coef[],int N)965 static DBL polevl(DBL x, const DBL coef[], int N)
966 {
967 DBL ans;
968 int i;
969 DBL const *p;
970
971 p = coef;
972 ans = *p++;
973 i = N;
974
975 do
976 {
977 ans = ans * x + *p++;
978 }
979 while (--i);
980
981 return (ans);
982 }
983
984 /* p1evl() */
985 /* N
986 * Evaluate polynomial when coefficient of x is 1.0.
987 * Otherwise same as polevl.
988 */
989
p1evl(DBL x,const DBL coef[],int N)990 static DBL p1evl(DBL x, const DBL coef[], int N)
991 {
992 DBL ans;
993 DBL const *p;
994 int i;
995
996 p = coef;
997 ans = x + *p++;
998 i = N - 1;
999
1000 do
1001 {
1002 ans = ans * x + *p++;
1003 }
1004 while (--i);
1005
1006 return (ans);
1007 }
1008
1009 }
1010