- Timestamp:
- Mar 18, 2016 4:12:48 AM (9 years ago)
- 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:
- 2622b3f
- Parents:
- 03e8a6e (diff), c094758 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
explore/J1c.py
r0a6da3c rcbd37a7 9 9 10 10 11 SHOW_DIFF = True # True if show diff rather than function value 11 SHOW_DIFF = True # True if show diff rather than function value 12 #SHOW_DIFF = False # True if show diff rather than function value 12 13 LINEAR_X = False # True if q is linearly spaced instead of log spaced 14 #LINEAR_X = True # True if q is linearly spaced instead of log spaced 15 FUNCTION = "2*J1(x)/x" 13 16 14 def mp_ J1c(vec, bits=500):17 def mp_fn(vec, bits=500): 15 18 """ 16 19 Direct calculation using sympy multiprecision library. 17 20 """ 18 21 with mp.workprec(bits): 19 return [_mp_ J1c(mp.mpf(x)) for x in vec]22 return [_mp_fn(mp.mpf(x)) for x in vec] 20 23 21 def _mp_ J1c(x):24 def _mp_fn(x): 22 25 """ 23 Helper funciton for mp_j1c26 Actual function that gets evaluated. The caller just vectorizes. 24 27 """ 25 28 return mp.mpf(2)*mp.j1(x)/x 26 29 27 def np_ J1c(x, dtype):30 def np_fn(x, dtype): 28 31 """ 29 32 Direct calculation using scipy. … … 33 36 return np.asarray(2, dtype)*J1(x)/x 34 37 35 def cephes_J1c(x, dtype, n):38 def sasmodels_fn(x, dtype, platform='ocl'): 36 39 """ 37 40 Calculation using pade approximant. 38 41 """ 39 f = np.float64 if np.dtype(dtype) == np.float64 else np.float32 40 x = np.asarray(x, dtype) 41 ans = np.empty_like(x) 42 ax = abs(x) 43 44 # Branch a 45 a_idx = ax < f(8.0) 46 a_xsq = x[a_idx]**2 47 a_coeff1 = list(reversed((72362614232.0, -7895059235.0, 242396853.1, -2972611.439, 15704.48260, -30.16036606))) 48 a_coeff2 = list(reversed((144725228442.0, 2300535178.0, 18583304.74, 99447.43394, 376.9991397, 1.0))) 49 a_ans1 = np.polyval(np.asarray(a_coeff1[n:], dtype), a_xsq) 50 a_ans2 = np.polyval(np.asarray(a_coeff2[n:], dtype), a_xsq) 51 ans[a_idx] = f(2.0)*a_ans1/a_ans2 52 53 # Branch b 54 b_idx = ~a_idx 55 b_ax = ax[b_idx] 56 b_x = x[b_idx] 57 58 b_y = f(64.0)/(b_ax**2) 59 b_xx = b_ax - f(2.356194491) 60 b_coeff1 = list(reversed((1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6))) 61 b_coeff2 = list(reversed((0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6))) 62 b_ans1 = np.polyval(np.asarray(b_coeff1[n:], dtype),b_y) 63 b_ans2 = np.polyval(np.asarray(b_coeff2[n:], dtype), b_y) 64 b_sn, b_cn = np.sin(b_xx), np.cos(b_xx) 65 ans[b_idx] = np.sign(b_x)*np.sqrt(f(0.636619772)/b_ax) * (b_cn*b_ans1 - (f(8.0)/b_ax)*b_sn*b_ans2)*f(2.0)/b_x 66 67 return ans 68 69 def div_J1c(x, dtype): 70 f = np.float64 if np.dtype(dtype) == np.float64 else np.float32 71 x = np.asarray(x, dtype) 72 return f(2.0)*np.asarray([_J1(xi, f)/xi for xi in x], dtype) 73 74 def _J1(x, f): 75 ax = abs(x) 76 if ax < f(8.0): 77 y = x*x 78 ans1 = x*(f(72362614232.0) 79 + y*(f(-7895059235.0) 80 + y*(f(242396853.1) 81 + y*(f(-2972611.439) 82 + y*(f(15704.48260) 83 + y*(f(-30.16036606))))))) 84 ans2 = (f(144725228442.0) 85 + y*(f(2300535178.0) 86 + y*(f(18583304.74) 87 + y*(f(99447.43394) 88 + y*(f(376.9991397) 89 + y))))) 90 return ans1/ans2 91 else: 92 y = f(64.0)/(ax*ax) 93 xx = ax - f(2.356194491) 94 ans1 = (f(1.0) 95 + y*(f(0.183105e-2) 96 + y*(f(-0.3516396496e-4) 97 + y*(f(0.2457520174e-5) 98 + y*f(-0.240337019e-6))))) 99 ans2 = (f(0.04687499995) 100 + y*(f(-0.2002690873e-3) 101 + y*(f(0.8449199096e-5) 102 + y*(f(-0.88228987e-6) 103 + y*f(0.105787412e-6))))) 104 sn, cn = np.sin(xx), np.cos(xx) 105 ans = np.sqrt(f(0.636619772)/ax) * (cn*ans1 - (f(8.0)/ax)*sn*ans2) 106 return -ans if (x < f(0.0)) else ans 42 from sasmodels import core, data, direct_model 43 model = core.load_model('bessel', dtype=dtype) 44 calculator = direct_model.DirectModel(data.empty_data1D(x), model) 45 return calculator(background=0) 107 46 108 47 def plotdiff(x, target, actual, label): … … 113 52 """ 114 53 if SHOW_DIFF: 115 err = np.clip(abs((target-actual)/target), 0, 1) 54 err = abs((target-actual)/target) 55 #err = np.clip(err, 0, 1) 116 56 pylab.loglog(x, err, '-', label=label) 117 57 else: … … 119 59 pylab.semilogx(x, np.clip(actual,*limits), '-', label=label) 120 60 121 def compare(x, precision ):61 def compare(x, precision, target): 122 62 r""" 123 63 Compare the different computation methods using the given precision. 124 64 """ 125 target = np.asarray(mp_J1c(x), 'double') 126 #plotdiff(x, target, mp_J1c(x, 11), 'mp 11 bits') 127 plotdiff(x, target, np_J1c(x, precision), 'direct '+precision) 128 plotdiff(x, target, cephes_J1c(x, precision, 0), 'cephes '+precision) 129 #plotdiff(x, target, cephes_J1c(x, precision, 1), 'cephes '+precision) 130 #plotdiff(x, target, div_J1c(x, precision), 'cephes 2 J1(x)/x '+precision) 65 #plotdiff(x, target, mp_fn(x, 11), 'mp 11 bits') 66 plotdiff(x, target, np_fn(x, precision), 'numpy '+precision) 67 plotdiff(x, target, sasmodels_fn(x, precision, 0), 'sasmodels '+precision) 131 68 pylab.xlabel("qr (1/Ang)") 132 69 if SHOW_DIFF: 133 70 pylab.ylabel("relative error") 134 71 else: 135 pylab.ylabel( "2 J1(x)/x")72 pylab.ylabel(FUNCTION) 136 73 pylab.semilogx(x, target, '-', label="true value") 137 74 if LINEAR_X: … … 147 84 else: 148 85 qr = np.logspace(-3,5,400) 86 target = np.asarray(mp_fn(qr), 'double') 149 87 pylab.subplot(121) 150 compare(qr, 'single' )88 compare(qr, 'single', target) 151 89 pylab.legend(loc='best') 152 90 pylab.subplot(122) 153 compare(qr, 'double' )91 compare(qr, 'double', target) 154 92 pylab.legend(loc='best') 155 pylab.suptitle( '2 J1(x)/x')93 pylab.suptitle(FUNCTION) 156 94 157 95 if __name__ == "__main__":
Note: See TracChangeset
for help on using the changeset viewer.