\ Gauss The Gaussian (Normal) probablity function ACM Algorithm #209 \ Calulates, z = 1/sqrt( 2 pi ) \int_-\infty^x exp( - 0.5 u^2 ) du \ by means of polynomial approximations. Accurate to 6 places. \ Forth Scientific Library Algorithm #42 \ This is an ANS Forth program requiring: \ 1. The Floating-Point word set \ 2. Uses the words 'FLOAT' and ARRAY to create floating point arrays. \ 3. The word '}' to dereference a one-dimensional array. \ 4. Uses the FSL word '}Horner' for fast polynomial evaluation. \ 5. The compilation of the test code is controlled by \ the conditional compilation words in the \ Programming-Tools wordset. \ Collected Algorithms from ACM, Volume 1 Algorithms 1-220, \ 1980; Association for Computing Machinery Inc., New York, \ ISBN 0-89791-017-6 \ (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. \ ( GAUSS V1.0 2 November 1994 EFC ) \ include lib/ansfloat.4th \ include lib/fsl-util.4th [UNDEFINED] gauss [IF] [UNDEFINED] }horner [IF] include lib/horner.4th [THEN] 15 FLOAT [*] 1 [+] ARRAY big{ FLOAT big{ FSL-ARRAY :THIS big{ DOES> (FSL-ARRAY) ; 9 FLOAT [*] 1 [+] ARRAY small{ FLOAT small{ FSL-ARRAY :THIS small{ DOES> (FSL-ARRAY) ; : init-gauss S" 0.999936657524" S>FLOAT big{ 0 } F! S" 0.000535310849" S>FLOAT big{ 1 } F! S" -0.002141268741" S>FLOAT big{ 2 } F! S" 0.005353579108" S>FLOAT big{ 3 } F! S" -0.009279453341" S>FLOAT big{ 4 } F! S" 0.011630447319" S>FLOAT big{ 5 } F! S" -0.010557625006" S>FLOAT big{ 6 } F! S" 0.006549791214" S>FLOAT big{ 7 } F! S" -0.002034254874" S>FLOAT big{ 8 } F! S" -0.000794620820" S>FLOAT big{ 9 } F! S" 0.001390604284" S>FLOAT big{ 10 } F! S" -0.000676904986" S>FLOAT big{ 11 } F! S" -0.000019538132" S>FLOAT big{ 12 } F! S" 0.000152529290" S>FLOAT big{ 13 } F! S" -0.000045255659" S>FLOAT big{ 14 } F! S" 0.797884560593" S>FLOAT small{ 0 } F! S" -0.531923007300" S>FLOAT small{ 1 } F! S" 0.319152932694" S>FLOAT small{ 2 } F! S" -0.151968751364" S>FLOAT small{ 3 } F! S" 0.059054035624" S>FLOAT small{ 4 } F! S" -0.019198292004" S>FLOAT small{ 5 } F! S" 0.005198775019" S>FLOAT small{ 6 } F! S" -0.001075204047" S>FLOAT small{ 7 } F! S" 0.000124818987" S>FLOAT small{ 8 } F! ; : gauss-small-y ( -- ) ( F: y -- z ) FDUP FDUP F* small{ 8 }Horner F* 2 S>F F* ; : gauss-mid-y ( -- ) ( F: y -- z ) 2 S>F F- big{ 14 }Horner ; fclear init-gauss : gauss ( -- ) ( f: x -- gauss{x} ) FDUP F0= IF F0< 0 S>F ELSE FDUP F0< \ push flag for sign of x FABS 2 S>F F/ FDUP 1 S>F F< IF gauss-small-y ELSE FDUP S" 4.85" S>FLOAT F< IF gauss-mid-y ELSE FDROP 1 S>F THEN THEN THEN IF ( x < 0 ) FNEGATE THEN 1 S>F F+ 2 S>F F/ ; [DEFINED] 4TH# [IF] hide big{ hide small{ hide init-gauss hide gauss-small-y hide gauss-mid-y [THEN] false [IF] \ test code ======================================== : gauss-test ( -- ) fclear 10 set-precision CR ." gauss( 5.0 ) = " S" 5.0" S>FLOAT gauss F. ." (should be 1.0) " CR ." gauss( -1.5 ) = " S" -1.5" S>FLOAT gauss F. ." (should be 0.0668072) " CR ." gauss( -0.5 ) = " S" -0.5" S>FLOAT gauss F. ." (should be 0.308538) " CR ." gauss( 0.5 ) = " S" 0.5" S>FLOAT gauss F. ." (should be 0.691462) " CR CR ; gauss-test [THEN] [THEN]