Changes in explore/precision.py [fba9ca0:ee60aa7] in sasmodels
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
explore/precision.py
rfba9ca0 ree60aa7 95 95 neg: [-100,100] 96 96 97 For arbitrary range use "start:stop:steps:scale" where scale is98 one of log, lin, or linear.99 100 97 *diff* is "relative", "absolute" or "none" 101 98 … … 105 102 linear = not xrange.startswith("log") 106 103 if xrange == "zoom": 107 start, stop,steps = 1000, 1010, 2000104 lin_min, lin_max, lin_steps = 1000, 1010, 2000 108 105 elif xrange == "neg": 109 start, stop,steps = -100.1, 100.1, 2000106 lin_min, lin_max, lin_steps = -100.1, 100.1, 2000 110 107 elif xrange == "linear": 111 start, stop,steps = 1, 1000, 2000112 start, stop,steps = 0.001, 2, 2000108 lin_min, lin_max, lin_steps = 1, 1000, 2000 109 lin_min, lin_max, lin_steps = 0.001, 2, 2000 113 110 elif xrange == "log": 114 start, stop,steps = -3, 5, 400111 log_min, log_max, log_steps = -3, 5, 400 115 112 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 124 114 else: 125 115 raise ValueError("unknown range "+xrange) … … 131 121 # value to x in the given precision. 132 122 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') 137 127 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) 139 129 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') 144 134 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)] 146 136 147 137 target = self.call_mpmath(qr, bits=500) … … 186 176 """ 187 177 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') 189 179 #err = np.clip(err, 0, 1) 190 180 pylab.loglog(x, err, '-', label=label) … … 207 197 return model_info 208 198 209 # Hack to allow second parameter A in two parameter functions210 A = 1211 def parse_extra_pars():212 global A213 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 226 199 227 200 # =============== FUNCTION DEFINITIONS ================ … … 326 299 ) 327 300 add_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(347 301 name="erf(x)", 348 302 mp_function=mp.erf, … … 403 357 ) 404 358 add_function( 405 name=" debye",359 name="gauss_coil", 406 360 mp_function=lambda x: 2*(mp.exp(-x**2) + x**2 - 1)/x**4, 407 361 np_function=lambda x: 2*(np.expm1(-x**2) + x**2)/x**4, 408 362 ocl_function=make_ocl(""" 409 363 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) { 411 367 const double x = qsq; 412 368 if (0) { // 0.36 single … … 418 374 const double B1=3./8., B2=3./56., B3=1./336.; 419 375 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 double376 } else if (0) { // 1.0 for single, 0.25 for double 421 377 // PadeApproximant[2*Exp[-x^2] + x^2-1)/x^4, {x, 0, 8}] 422 378 const double A1=1./15., A2=1./60, A3=0., A4=1./75600.; … … 431 387 /(((((B5*x + B4)*x + B3)*x + B2)*x + B1)*x + 1.); 432 388 } 433 } else if (qsq < 1.) { // Taylor series; 0.9 for single, 0.25 for double389 } else if (qsq < 0.8) { 434 390 const double x = qsq; 435 391 const double C0 = +1.; … … 509 465 lanczos_gamma = """\ 510 466 const double coeff[] = { 511 76.18009172947146, -86.50532032941677,512 24.01409824083091, -1.231739572450155,467 76.18009172947146, -86.50532032941677, 468 24.01409824083091, -1.231739572450155, 513 469 0.1208650973866179e-2,-0.5395239384953e-5 514 470 }; … … 521 477 """ 522 478 add_function( 523 name="log gamma(x)",479 name="log gamma(x)", 524 480 mp_function=mp.loggamma, 525 481 np_function=scipy.special.gammaln, … … 645 601 646 602 ALL_FUNCTIONS = set(FUNCTIONS.keys()) 647 ALL_FUNCTIONS.discard("loggamma") # use cephes-based gammaln instead603 ALL_FUNCTIONS.discard("loggamma") # OCL version not ready yet 648 604 ALL_FUNCTIONS.discard("3j1/x:taylor") 649 605 ALL_FUNCTIONS.discard("3j1/x:trig") … … 661 617 -r indicates that the relative error should be plotted (default), 662 618 -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] 624 and name is "all" or one of: 674 625 """+names) 675 626 sys.exit(1)
Note: See TracChangeset
for help on using the changeset viewer.