1 | import numpy as np |
---|
2 | import scipy.stats |
---|
3 | |
---|
4 | from sasmodels.weights import Dispersion as BaseDispersion |
---|
5 | |
---|
6 | class Dispersion(BaseDispersion): |
---|
7 | r""" |
---|
8 | Gaussian dispersion, with 1-$\sigma$ width. |
---|
9 | |
---|
10 | .. math:: |
---|
11 | |
---|
12 | w = \exp\left(-\tfrac12 (x - c)^2/\sigma^2\right) |
---|
13 | |
---|
14 | $x$ points are chosen such that each interval has equal weight. |
---|
15 | |
---|
16 | This works surprisingly poorly. Try:: |
---|
17 | |
---|
18 | $ sascomp cylinder -2d theta=45 phi=20 phi_pd_type=gaussian_eq \ |
---|
19 | phi_pd_n=100,1000 radius=50 length=2*radius -midq phi_pd=5 |
---|
20 | |
---|
21 | Leaving it here for others to improve. |
---|
22 | """ |
---|
23 | type = "gaussian_eq" |
---|
24 | default = dict(npts=35, width=0, nsigmas=3) |
---|
25 | |
---|
26 | def _weights(self, center, sigma, lb, ub): |
---|
27 | # Use the gaussian distribution from scipy.stats |
---|
28 | dist = scipy.stats.norm(center, sigma) |
---|
29 | |
---|
30 | # Find the mid-points of the cdf intervals |
---|
31 | cdf = np.linspace(0, 1, self.npts+2)[1:-1] |
---|
32 | x = dist.ppf(cdf) |
---|
33 | |
---|
34 | # Since we are equally spaced in cdf, all weights are the same |
---|
35 | wx = np.ones_like(x) |
---|
36 | |
---|
37 | # Truncate the distribution in case the parameter value is limited |
---|
38 | index = (x >= lb) & (x <= ub) |
---|
39 | x, wx = x[index], wx[index] |
---|
40 | |
---|
41 | return x, wx |
---|
42 | |
---|