Changeset 3f8584a2 in sasmodels for sasmodels/models/lib/sas_JN.c


Ignore:
Timestamp:
Jul 27, 2016 3:53:07 AM (8 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
c047acf
Parents:
56547a8
Message:

clean separation between float/double bessel functions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/models/lib/sas_JN.c

    r4937980 r3f8584a2  
    4848*/ 
    4949 
    50 double sas_JN( int n, double x ); 
    51  
    52 double sas_JN( int n, double x ) { 
    53  
     50#if FLOAT_SIZE > 4 
     51 
     52double jn( int n, double x ); 
     53double jn( int n, double x ) { 
     54 
     55    // PAK: seems to be machine epsilon/2 
    5456    const double MACHEP = 1.11022302462515654042E-16; 
    5557    double pkm2, pkm1, pk, xk, r, ans; 
     
    5759 
    5860    if( n < 0 ) { 
    59             n = -n; 
    60             if( (n & 1) == 0 )  /* -1**n */ 
    61                     sign = 1; 
    62             else 
    63                     sign = -1; 
    64         } 
    65     else 
    66             sign = 1; 
     61        n = -n; 
     62        if( (n & 1) == 0 )      /* -1**n */ 
     63            sign = 1; 
     64        else 
     65            sign = -1; 
     66    } else { 
     67        sign = 1; 
     68    } 
    6769 
    6870    if( x < 0.0 ) { 
    69             if( n & 1 ) 
    70                     sign = -sign; 
    71             x = -x; 
    72         } 
     71        if( n & 1 ) 
     72            sign = -sign; 
     73    x = -x; 
     74    } 
    7375 
    7476    if( n == 0 ) 
    75             return( sign * sas_J0(x) ); 
     77        return( sign * j0(x) ); 
    7678    if( n == 1 ) 
    77             return( sign * sas_J1(x) ); 
     79        return( sign * j1(x) ); 
    7880    if( n == 2 ) 
    79             return( sign * (2.0 * sas_J1(x) / x  -  sas_J0(x)) ); 
     81        return( sign * (2.0 * j1(x) / x  -  j0(x)) ); 
    8082 
    8183    if( x < MACHEP ) 
    82             return( 0.0 ); 
    83  
    84     #if FLOAT_SIZE > 4 
    85         k = 53; 
    86     #else 
    87         k = 24; 
    88     #endif 
    89  
     84        return( 0.0 ); 
     85 
     86    k = 53; 
    9087    pk = 2 * (n + k); 
    9188    ans = pk; 
     
    9390 
    9491    do { 
    95             pk -= 2.0; 
    96             ans = pk - (xk/ans); 
    97         } while( --k > 0 ); 
     92        pk -= 2.0; 
     93        ans = pk - (xk/ans); 
     94    } while( --k > 0 ); 
    9895 
    9996    /* backward recurrence */ 
     
    10198    pk = 1.0; 
    10299 
    103     #if FLOAT_SIZE > 4 
    104         ans = x/ans; 
    105         pkm1 = 1.0/ans; 
    106  
    107         k = n-1; 
    108         r = 2 * k; 
    109  
    110         do { 
    111             pkm2 = (pkm1 * r  -  pk * x) / x; 
    112                 pk = pkm1; 
    113                 pkm1 = pkm2; 
    114                 r -= 2.0; 
    115             } while( --k > 0 ); 
    116  
    117         if( fabs(pk) > fabs(pkm1) ) 
    118                 ans = sas_J1(x)/pk; 
     100    ans = x/ans; 
     101    pkm1 = 1.0/ans; 
     102 
     103    k = n-1; 
     104    r = 2 * k; 
     105 
     106    do { 
     107        pkm2 = (pkm1 * r  -  pk * x) / x; 
     108        pk = pkm1; 
     109        pkm1 = pkm2; 
     110        r -= 2.0; 
     111    } while( --k > 0 ); 
     112 
     113    if( fabs(pk) > fabs(pkm1) ) 
     114        ans = j1(x)/pk; 
     115    else 
     116        ans = j0(x)/pkm1; 
     117 
     118    return( sign * ans ); 
     119} 
     120 
     121#else 
     122 
     123float jnf(int n, float x) 
     124{ 
     125    // PAK: seems to be machine epsilon/2 
     126    const double MACHEP = 5.9604645e-08; 
     127    float pkm2, pkm1, pk, xk, r, ans; 
     128    int k, sign; 
     129 
     130    if( n < 0 ) { 
     131        n = -n; 
     132        if( (n & 1) == 0 ) /* -1**n */ 
     133            sign = 1; 
    119134        else 
    120                 ans = sas_J0(x)/pkm1; 
    121  
    122             return( sign * ans ); 
    123  
    124     #else 
    125         const double xinv = 1.0/x; 
    126         pkm1 = ans * xinv; 
    127         k = n-1; 
    128         r = (float )(2 * k); 
    129  
    130         do { 
    131                 pkm2 = (pkm1 * r  -  pk * x) * xinv; 
    132                 pk = pkm1; 
    133                 pkm1 = pkm2; 
    134                 r -= 2.0; 
    135             } 
    136         while( --k > 0 ); 
    137  
    138         r = pk; 
    139         if( r < 0 ) 
    140                 r = -r; 
    141         ans = pkm1; 
    142         if( ans < 0 ) 
    143                 ans = -ans; 
    144  
    145         if( r > ans )  /* if( fabs(pk) > fabs(pkm1) ) */ 
    146                 ans = sign * sas_J1(x)/pk; 
    147         else 
    148                 ans = sign * sas_J0(x)/pkm1; 
    149         return( ans ); 
    150     #endif 
     135            sign = -1; 
     136    } else { 
     137        sign = 1; 
     138    } 
     139 
     140    if( x < 0.0 ) { 
     141        if( n & 1 ) 
     142            sign = -sign; 
     143        x = -x; 
     144    } 
     145 
     146    if( n == 0 ) 
     147        return( sign * j0f(x) ); 
     148    if( n == 1 ) 
     149        return( sign * j1f(x) ); 
     150    if( n == 2 ) 
     151        return( sign * (2.0 * j1f(x) / x  -  j0f(x)) ); 
     152 
     153    if( x < MACHEP ) 
     154        return( 0.0 ); 
     155 
     156    k = 24; 
     157    pk = 2 * (n + k); 
     158    ans = pk; 
     159    xk = x * x; 
     160 
     161    do { 
     162        pk -= 2.0; 
     163        ans = pk - (xk/ans); 
     164    } while( --k > 0 ); 
     165 
     166    /* backward recurrence */ 
     167 
     168    pk = 1.0; 
     169 
     170    const float xinv = 1.0/x; 
     171    pkm1 = ans * xinv; 
     172    k = n-1; 
     173    r = (float )(2 * k); 
     174 
     175    do { 
     176        pkm2 = (pkm1 * r  -  pk * x) * xinv; 
     177        pk = pkm1; 
     178        pkm1 = pkm2; 
     179        r -= 2.0; 
     180    } while( --k > 0 ); 
     181 
     182    r = pk; 
     183    if( r < 0 ) 
     184        r = -r; 
     185    ans = pkm1; 
     186    if( ans < 0 ) 
     187        ans = -ans; 
     188 
     189    if( r > ans )  /* if( fabs(pk) > fabs(pkm1) ) */ 
     190        ans = sign * j1f(x)/pk; 
     191    else 
     192        ans = sign * j0f(x)/pkm1; 
     193    return( ans ); 
    151194} 
    152  
     195#endif 
     196 
     197#if FLOAT_SIZE>4 
     198#define sas_JN jn 
     199#else 
     200#define sas_JN jnf 
     201#endif 
Note: See TracChangeset for help on using the changeset viewer.