\ Horner Evaluation of a polynomial by the Horner method \ Forth Scientific Library Algorithm #3 \ This routine evaluates an Nth order polynomial Y(X) at point X \ Y(X) = \sum_i=0^N a[i] x^i (NOTE: N+1 COEFFICIENTS) \ by the Horner scheme. This algorithm minimizes the number of multiplications \ required to evaluate the polynomial. \ The implementation demonstrates the use of array aliasing. \ This code conforms with ANS requiring: \ 1. The Floating-Point word set \ 2. The immediate word '%' which takes the next token \ and converts it to a floating-point literal \ 3. Uses words 'Private:', 'Public:' and 'Reset_Search_Order' \ to control the visibility of internal code. \ 4. The immediate word '&' to get the address of an array \ function at either compile or run time. \ 5. Uses the words 'DArray' and '&!' to alias arrays. \ 6. Test code uses 'ExpInt' for real exponential integrals \ (code for the dependencies , 3, 4, and 5 above are in the file 'fsl_util' ) \ This algorithm is described in many places, e.g., \ Conte, S.D. and C. deBoor, 1972; Elementary Numerical Analysis, an algorithmic \ approach, McGraw-Hill, New York, 396 pages \ (c) Copyright 1994 Everett F. Carter. Permission is granted by the \ author to use this software for any application provided this \ copyright notice is preserved. \ ( HORNER V1.5 31 October 1994 EFC ) \ include lib/ansfloat.4th \ include lib/fsl-util.4th \ include lib/fexpint.4th \ include lib/fexp.4th \ include lib/flnflog.4th [UNDEFINED] }horner [IF] [UNDEFINED] fsl-array [IF] [ABORT] [THEN] : }Horner ( &a n -- , f: x -- y[x] ) SWAP VALUE ha{ 0 s>f -1 SWAP DO FOVER F* ha{ I } F@ F+ -1 +LOOP FSWAP FDROP ; false [IF] \ test code ============================================= 6 FLOAT [*] 1 [+] ARRAY ArrayZ{ 5 FLOAT [*] 1 [+] ARRAY ArrayY{ 5 FLOAT [*] 1 [+] ARRAY ArrayW{ FLOAT ArrayZ{ FSL-ARRAY FLOAT ArrayY{ FSL-ARRAY FLOAT ArrayW{ FSL-ARRAY :THIS ArrayZ{ DOES> (FSL-ARRAY) ; :THIS ArrayY{ DOES> (FSL-ARRAY) ; :THIS ArrayW{ DOES> (FSL-ARRAY) ; \ initialize with data for real exponential integral : horner_init ( -- ) S" 0.00107857" s>float ArrayZ{ 5 } F! S" -0.00976004" s>float ArrayZ{ 4 } F! S" 0.05519968" s>float ArrayZ{ 3 } F! S" -0.24991055" s>float ArrayZ{ 2 } F! S" 0.99999193" s>float ArrayZ{ 1 } F! S" -0.57721566" s>float ArrayZ{ 0 } F! 1 s>f ArrayY{ 4 } F! S" 8.5733287401" s>float ArrayY{ 3 } F! S" 18.059016973" s>float ArrayY{ 2 } F! S" 8.6347608925" s>float ArrayY{ 1 } F! S" 0.2677737343" s>float ArrayY{ 0 } F! 1 s>f ArrayW{ 4 } F! S" 9.5733223454" s>float ArrayW{ 3 } F! S" 25.6329561486" s>float ArrayW{ 2 } F! S" 21.0996530827" s>float ArrayW{ 1 } F! S" 3.9584969228" s>float ArrayW{ 0 } F! ; : local_exp ( -- , f: x -- expint[x] ) FDUP f1.0 F< IF FDUP ArrayZ{ 5 }Horner FSWAP FLN F- ELSE FDUP ArrayY{ 4 }Horner FOVER ArrayW{ 4 }Horner F/ FOVER F/ FSWAP -1 s>f F* FEXP F* THEN ; : do_both ( -- , f: x -- ) FDUP FDUP ." X = " F. ." Horner: " local_exp F. ." ExpInt: " fexpint F. CR ; \ compare ExpInt as coded in V1.0 against the general purpose \ Horner routine : horner_test ( -- ) horner_init CR s" 0.2" s>float do_both s" 0.5" s>float do_both 1 s>f do_both 2 s>f do_both 5 s>f do_both 10 s>f do_both ; fclear 10 set-precision horner_test [THEN] [THEN]