Changes in explore/precision.py [fba9ca0:ee60aa7] in sasmodels


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • explore/precision.py

    rfba9ca0 ree60aa7  
    9595            neg:    [-100,100] 
    9696 
    97         For arbitrary range use "start:stop:steps:scale" where scale is 
    98         one of log, lin, or linear. 
    99  
    10097        *diff* is "relative", "absolute" or "none" 
    10198 
     
    105102        linear = not xrange.startswith("log") 
    106103        if xrange == "zoom": 
    107             start, stop, steps = 1000, 1010, 2000 
     104            lin_min, lin_max, lin_steps = 1000, 1010, 2000 
    108105        elif xrange == "neg": 
    109             start, stop, steps = -100.1, 100.1, 2000 
     106            lin_min, lin_max, lin_steps = -100.1, 100.1, 2000 
    110107        elif xrange == "linear": 
    111             start, stop, steps = 1, 1000, 2000 
    112             start, stop, steps = 0.001, 2, 2000 
     108            lin_min, lin_max, lin_steps = 1, 1000, 2000 
     109            lin_min, lin_max, lin_steps = 0.001, 2, 2000 
    113110        elif xrange == "log": 
    114             start, stop, steps = -3, 5, 400 
     111            log_min, log_max, log_steps = -3, 5, 400 
    115112        elif xrange == "logq": 
    116             start, stop, steps = -4, 1, 400 
    117         elif ':' in xrange: 
    118             parts = xrange.split(':') 
    119             linear = parts[3] != "log" if len(parts) == 4 else True 
    120             steps = int(parts[2]) if len(parts) > 2 else 400 
    121             start = float(parts[0]) 
    122             stop = float(parts[1]) 
    123  
     113            log_min, log_max, log_steps = -4, 1, 400 
    124114        else: 
    125115            raise ValueError("unknown range "+xrange) 
     
    131121            # value to x in the given precision. 
    132122            if linear: 
    133                 start = max(start, self.limits[0]) 
    134                 stop = min(stop, self.limits[1]) 
    135                 qrf = np.linspace(start, stop, steps, dtype='single') 
    136                 #qrf = np.linspace(start, stop, steps, dtype='double') 
     123                lin_min = max(lin_min, self.limits[0]) 
     124                lin_max = min(lin_max, self.limits[1]) 
     125                qrf = np.linspace(lin_min, lin_max, lin_steps, dtype='single') 
     126                #qrf = np.linspace(lin_min, lin_max, lin_steps, dtype='double') 
    137127                qr = [mp.mpf(float(v)) for v in qrf] 
    138                 #qr = mp.linspace(start, stop, steps) 
     128                #qr = mp.linspace(lin_min, lin_max, lin_steps) 
    139129            else: 
    140                 start = np.log10(max(10**start, self.limits[0])) 
    141                 stop = np.log10(min(10**stop, self.limits[1])) 
    142                 qrf = np.logspace(start, stop, steps, dtype='single') 
    143                 #qrf = np.logspace(start, stop, steps, dtype='double') 
     130                log_min = np.log10(max(10**log_min, self.limits[0])) 
     131                log_max = np.log10(min(10**log_max, self.limits[1])) 
     132                qrf = np.logspace(log_min, log_max, log_steps, dtype='single') 
     133                #qrf = np.logspace(log_min, log_max, log_steps, dtype='double') 
    144134                qr = [mp.mpf(float(v)) for v in qrf] 
    145                 #qr = [10**v for v in mp.linspace(start, stop, steps)] 
     135                #qr = [10**v for v in mp.linspace(log_min, log_max, log_steps)] 
    146136 
    147137        target = self.call_mpmath(qr, bits=500) 
     
    186176    """ 
    187177    if diff == "relative": 
    188         err = np.array([(abs((t-a)/t) if t != 0 else a) for t, a in zip(target, actual)], 'd') 
     178        err = np.array([abs((t-a)/t) for t, a in zip(target, actual)], 'd') 
    189179        #err = np.clip(err, 0, 1) 
    190180        pylab.loglog(x, err, '-', label=label) 
     
    207197    return model_info 
    208198 
    209 # Hack to allow second parameter A in two parameter functions 
    210 A = 1 
    211 def parse_extra_pars(): 
    212     global A 
    213  
    214     A_str = str(A) 
    215     pop = [] 
    216     for k, v in enumerate(sys.argv[1:]): 
    217         if v.startswith("A="): 
    218             A_str = v[2:] 
    219             pop.append(k+1) 
    220     if pop: 
    221         sys.argv = [v for k, v in enumerate(sys.argv) if k not in pop] 
    222         A = float(A_str) 
    223  
    224 parse_extra_pars() 
    225  
    226199 
    227200# =============== FUNCTION DEFINITIONS ================ 
     
    326299) 
    327300add_function( 
    328     name="gammaln(x)", 
    329     mp_function=mp.loggamma, 
    330     np_function=scipy.special.gammaln, 
    331     ocl_function=make_ocl("return sas_gammaln(q);", "sas_gammaln", ["lib/sas_gammainc.c"]), 
    332     #ocl_function=make_ocl("return lgamma(q);", "sas_gammaln"), 
    333 ) 
    334 add_function( 
    335     name="gammainc(x)", 
    336     mp_function=lambda x, a=A: mp.gammainc(a, a=0, b=x)/mp.gamma(a), 
    337     np_function=lambda x, a=A: scipy.special.gammainc(a, x), 
    338     ocl_function=make_ocl("return sas_gammainc(%.15g,q);"%A, "sas_gammainc", ["lib/sas_gammainc.c"]), 
    339 ) 
    340 add_function( 
    341     name="gammaincc(x)", 
    342     mp_function=lambda x, a=A: mp.gammainc(a, a=x, b=mp.inf)/mp.gamma(a), 
    343     np_function=lambda x, a=A: scipy.special.gammaincc(a, x), 
    344     ocl_function=make_ocl("return sas_gammaincc(%.15g,q);"%A, "sas_gammaincc", ["lib/sas_gammainc.c"]), 
    345 ) 
    346 add_function( 
    347301    name="erf(x)", 
    348302    mp_function=mp.erf, 
     
    403357) 
    404358add_function( 
    405     name="debye", 
     359    name="gauss_coil", 
    406360    mp_function=lambda x: 2*(mp.exp(-x**2) + x**2 - 1)/x**4, 
    407361    np_function=lambda x: 2*(np.expm1(-x**2) + x**2)/x**4, 
    408362    ocl_function=make_ocl(""" 
    409363    const double qsq = q*q; 
    410     if (qsq < 1.0) { // Pade approximation 
     364    // For double: use O(5) Pade with 0.5 cutoff (10 mad + 1 divide) 
     365    // For single: use O(7) Taylor with 0.8 cutoff (7 mad) 
     366    if (qsq < 0.0) { 
    411367        const double x = qsq; 
    412368        if (0) { // 0.36 single 
     
    418374            const double B1=3./8., B2=3./56., B3=1./336.; 
    419375            return (((A3*x + A2)*x + A1)*x + 1.)/(((B3*x + B2)*x + B1)*x + 1.); 
    420         } else if (1) { // 1.0 for single, 0.25 for double 
     376        } else if (0) { // 1.0 for single, 0.25 for double 
    421377            // PadeApproximant[2*Exp[-x^2] + x^2-1)/x^4, {x, 0, 8}] 
    422378            const double A1=1./15., A2=1./60, A3=0., A4=1./75600.; 
     
    431387                  /(((((B5*x + B4)*x + B3)*x + B2)*x + B1)*x + 1.); 
    432388        } 
    433     } else if (qsq < 1.) { // Taylor series; 0.9 for single, 0.25 for double 
     389    } else if (qsq < 0.8) { 
    434390        const double x = qsq; 
    435391        const double C0 = +1.; 
     
    509465lanczos_gamma = """\ 
    510466    const double coeff[] = { 
    511             76.18009172947146, -86.50532032941677, 
    512             24.01409824083091, -1.231739572450155, 
     467            76.18009172947146,     -86.50532032941677, 
     468            24.01409824083091,     -1.231739572450155, 
    513469            0.1208650973866179e-2,-0.5395239384953e-5 
    514470            }; 
     
    521477""" 
    522478add_function( 
    523     name="loggamma(x)", 
     479    name="log gamma(x)", 
    524480    mp_function=mp.loggamma, 
    525481    np_function=scipy.special.gammaln, 
     
    645601 
    646602ALL_FUNCTIONS = set(FUNCTIONS.keys()) 
    647 ALL_FUNCTIONS.discard("loggamma")  # use cephes-based gammaln instead 
     603ALL_FUNCTIONS.discard("loggamma")  # OCL version not ready yet 
    648604ALL_FUNCTIONS.discard("3j1/x:taylor") 
    649605ALL_FUNCTIONS.discard("3j1/x:trig") 
     
    661617    -r indicates that the relative error should be plotted (default), 
    662618    -x<range> indicates the steps in x, where <range> is one of the following 
    663         log indicates log stepping in [10^-3, 10^5] (default) 
    664         logq indicates log stepping in [10^-4, 10^1] 
    665         linear indicates linear stepping in [1, 1000] 
    666         zoom indicates linear stepping in [1000, 1010] 
    667         neg indicates linear stepping in [-100.1, 100.1] 
    668         start:stop:n[:stepping] indicates an n-step plot in [start, stop] 
    669             or [10^start, 10^stop] if stepping is "log" (default n=400) 
    670 Some functions (notably gammainc/gammaincc) have an additional parameter A 
    671 which can be set from the command line as A=value.  Default is A=1. 
    672  
    673 Name is one of: 
     619      log indicates log stepping in [10^-3, 10^5] (default) 
     620      logq indicates log stepping in [10^-4, 10^1] 
     621      linear indicates linear stepping in [1, 1000] 
     622      zoom indicates linear stepping in [1000, 1010] 
     623      neg indicates linear stepping in [-100.1, 100.1] 
     624and name is "all" or one of: 
    674625    """+names) 
    675626    sys.exit(1) 
Note: See TracChangeset for help on using the changeset viewer.