/* This function computes the fresnel F and G functions with dfloat accuracy
over -inf,inf.  It divides the real line into 3 regions.  The first (0,1) uses
a division of 1/100, and a taylor series.  The second region (1,5)
uses reciprocal divisions, and a taylor series also.  The third region (5,inf)
uses the asymptotic series.  This routine could be improved by using
lazy evaluation to increase speed in the initialization.
*/

load("fresnel_linear_values.mac")$
define_variable(FRESNEL_RECIPROCAL,1.0d0,any_check,
   "Point to switch to reciprocal values")$
define_variable(FRESNEL_ASYMPTOTIC,5.0d0,any_check,
   "Point to switch to asymptotic series")$
define_variable(FRESNEL_DIVISION,100,any_check,
   "Number of divisions")$
define_variable(FRESNEL_X,0,any_check, "Array constant")$
define_variable(FRESNEL_F,1,any_check, "Array constant")$
define_variable(FRESNEL_G,2,any_check, "Array constant")$
array(fresnel_a,2,2*FRESNEL_DIVISION+1)$
define_variable(fresnel_Ftaylor, 8.33333333333334d-3 *
   (u *
     (u *
       (u *
         (u *
           (u * x0 *
             (x0 *
              (x0 * (9.74090910340024d+2 * f0 - 3.0601968478528d+2 * g0 * x0^2)
               - 2.79056490122698d+2)
              + 4.65094150204496d+2 * g0)
             + x0^2 *
	         (x0 * (4.87045455170012d+2 * f0 * x0 - 1.55031383401498d+2)
                  + 9.30188300408994d+2 * g0)
            - 1.4804406601634d+2 * f0)
           + x0 * (6.20125533605996d+2 * g0 * x0^2 - 5.9217626406536d+2 * f0)
          + 1.25663706143592d+2)
         + x0 * (1.88495559215388d+2 - 5.9217626406536d+2 * f0 * x0)
        - 1.88495559215388d+2 * g0)
      - 3.76991118430774d+2 * g0 * x0)
    + 1.2d+2 * f0),any_check,"Taylor series for F about x0")$
define_variable(fresnel_Gtaylor, 8.33333333333334d-3 *
   (u * 
    (u *
     (u *
      (u *
       (x0 *
        (x0 *
         (4.87045455170012d+2 * g0 * x0^2 - 9.30188300408994d+2 * f0)
         + 2.46740110027234d+2)
        + u *
	  (x0 *
	   (x0^2 *
            (x0 *
             (3.0601968478528d+2 * f0 * x0 - 9.74090910340024d+1)
             + 9.74090910340024d+2 * g0)
            - 4.65094150204496d+2 * f0)
           + 7.89568352087148d+1)
        - 1.4804406601634d+2 * g0)
       + x0 * (x0 * (1.97392088021786d+2 - 6.20125533605996d+2 * f0 * x0)
       - 5.9217626406536d+2 * g0))
      - 5.9217626406536d+2 * g0 * x0^2 + 1.88495559215388d+2 * f0)
     + 3.76991118430774d+2 * f0 * x0 - 1.2d+2)
    + 1.2d+2 * g0),any_check,"Taylor series for G about x0")$

fresnel_InitLinear():=block([i:0],
   for l in fresnel_linear_values do (
      fresnel_a[FRESNEL_X,i]:first(l),
      block([x0:first(l),f0:second(l),g0:third(l)],
         fresnel_a[FRESNEL_F,i]:
            funmake(lambda,[[x],block([u:x-x0],ev(fresnel_Ftaylor))]),
         fresnel_a[FRESNEL_G,i]:
            funmake(lambda,[[x],block([u:x-x0],ev(fresnel_Gtaylor))])),
      i:i+1
   )
)$
fresnel_init():=block(
   fresnel_InitLinear()
)$
fresnelF(x):=block()$
fresnelG(x):=block()$
fresnel_init()$
