source: sasmodels/explore/J1.py @ 3b12dea

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 3b12dea was a5af4e1, checked in by wojciech, 9 years ago

Polevl fixed

  • Property mode set to 100644
File size: 2.9 KB
Line 
1r"""
2Show numerical precision of $2 J_1(x)/x$.
3"""
4
5import numpy as np
6#from sympy.mpmath import mp
7from mpmath import mp
8#import matplotlib; matplotlib.use('TkAgg')
9import pylab
10
11
12SHOW_DIFF = True # True if show diff rather than function value
13#SHOW_DIFF = False # True if show diff rather than function value
14LINEAR_X = False  # True if q is linearly spaced instead of log spaced
15#LINEAR_X = True # True if q is linearly spaced instead of log spaced
16FUNCTION = "J1(x)"
17
18def mp_fn(vec, bits=500):
19    """
20    Direct calculation using sympy multiprecision library.
21    """
22    with mp.workprec(bits):
23        return [_mp_fn(mp.mpf(x)) for x in vec]
24
25def _mp_fn(x):
26    """
27    Actual function that gets evaluated.  The caller just vectorizes.
28    """
29    #return mp.mpf(2)*mp.j1(x)/x
30    return mp.j1(x)
31
32def np_fn(x, dtype):
33    """
34    Direct calculation using scipy.
35    """
36    from scipy.special import j1 as J1
37    x = np.asarray(x, dtype)
38    #return np.asarray(2, dtype)*J1(x)/x
39    return J1(x)
40
41def sasmodels_fn(x, dtype, platform='ocl'):
42    """
43    Calculation using pade approximant.
44    """
45    from sasmodels import core, data, direct_model
46    model = core.load_model('bessel', dtype=dtype)
47    calculator = direct_model.DirectModel(data.empty_data1D(x), model)
48    #ret = calculator(background=0)
49    #print ret
50    return calculator(background=0)
51
52def plotdiff(x, target, actual, label):
53    """
54    Plot the computed value.
55
56    Use relative error if SHOW_DIFF, otherwise just plot the value directly.
57    """
58    if SHOW_DIFF:
59        err = abs((target-actual)/target)
60        #err = np.clip(err, 0, 1)
61        pylab.loglog(x, err, '-', label=label)
62    else:
63        limits = np.min(target), np.max(target)
64        pylab.semilogx(x, np.clip(actual,*limits),  '-', label=label)
65
66def compare(x, precision, target):
67    r"""
68    Compare the different computation methods using the given precision.
69    """
70    #plotdiff(x, target, mp_fn(x, 11), 'mp 11 bits')
71    plotdiff(x, target, np_fn(x, precision), 'numpy '+precision)
72    plotdiff(x, target, sasmodels_fn(x, precision, 0), 'sasmodels '+precision)
73    pylab.xlabel("qr (1/Ang)")
74    if SHOW_DIFF:
75        pylab.ylabel("relative error")
76    else:
77        pylab.ylabel(FUNCTION)
78        pylab.semilogx(x, target,  '-', label="true value")
79    if LINEAR_X:
80        pylab.xscale('linear')
81
82def main():
83    r"""
84    Compare accuracy of different methods for computing $3 j_1(x)/x$.
85    :return:
86    """
87    if LINEAR_X:
88        qr = np.linspace(1,1000,2000)
89    else:
90        qr = np.logspace(-3,5,400)
91    target = np.asarray(mp_fn(qr), 'double')
92    pylab.subplot(121)
93    compare(qr, 'single', target)
94    pylab.legend(loc='best')
95    pylab.subplot(122)
96    compare(qr, 'double', target)
97    pylab.legend(loc='best')
98    pylab.suptitle(FUNCTION)
99
100if __name__ == "__main__":
101    #print "\n".join(str(x) for x in mp_J1c([1e-6,1e-5,1e-4,1e-3]))
102    main()
103    pylab.show()
Note: See TracBrowser for help on using the repository browser.