Changeset 41e7f2e in sasmodels for sasmodels/weights.py


Ignore:
Timestamp:
Oct 1, 2016 2:04:51 PM (8 years ago)
Author:
ajj
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:
3a45c2c
Parents:
80013a6 (diff), 2f46e83 (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.
Message:

Merge branch 'master' into ticket651

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/weights.py

    r733a3e1 r41e7f2e  
    22SAS distributions for polydispersity. 
    33""" 
    4 from __future__ import division 
     4# TODO: include dispersion docs with the disperser models 
     5from __future__ import division, print_function 
     6 
    57from math import sqrt  # type: ignore 
     8from collections import OrderedDict 
     9 
    610import numpy as np  # type: ignore 
    711from scipy.special import gammaln  # type: ignore 
     
    5660            else: 
    5761                return np.array([], 'd'), np.array([], 'd') 
    58         return self._weights(center, sigma, lb, ub) 
     62        x, px = self._weights(center, sigma, lb, ub) 
     63        return x, px 
    5964 
    6065    def _weights(self, center, sigma, lb, ub): 
     
    8186    default = dict(npts=35, width=0, nsigmas=3) 
    8287    def _weights(self, center, sigma, lb, ub): 
     88        # TODO: sample high probability regions more densely 
     89        # i.e., step uniformly in cumulative density rather than x value 
     90        # so weight = 1/Npts for all weights, but values are unevenly spaced 
    8391        x = self._linspace(center, sigma, lb, ub) 
    8492        px = np.exp((x-center)**2 / (-2.0 * sigma * sigma)) 
     
    97105    default = dict(npts=35, width=0, nsigmas=1.70325) 
    98106    def _weights(self, center, sigma, lb, ub): 
    99         x = self._linspace(center, sigma*sqrt(3.0), lb, ub) 
    100         px = np.ones_like(x) 
    101         return x, px 
     107        x = self._linspace(center, sigma, lb, ub) 
     108        x = x[np.fabs(x-center) <= np.fabs(sigma)*sqrt(3.0)] 
     109        return x, np.ones_like(x) 
    102110 
    103111 
     
    114122    def _weights(self, center, sigma, lb, ub): 
    115123        x = self._linspace(center, sigma, max(lb, 1e-8), max(ub, 1e-8)) 
    116         px = np.exp(-0.5*(np.log(x)-center)**2/sigma**2)/(x*sigma) 
     124        # sigma in the lognormal function is in ln(R) space, thus needs converting 
     125        sig = np.fabs(sigma/center) 
     126        px = np.exp(-0.5*((np.log(x)-np.log(center))/sig)**2)/(x*sig) 
    117127        return x, px 
    118128 
     
    167177 
    168178    def _weights(self, center, sigma, lb, ub): 
    169         # TODO: interpolate into the array dispersion using npts 
    170         x = center + self.values*sigma 
     179        # TODO: rebin the array dispersion using npts 
     180        # TODO: use a distribution that can be recentered and scaled 
     181        x = self.values 
     182        #x = center + self.values*sigma 
    171183        idx = (x >= lb) & (x <= ub) 
    172184        x = x[idx] 
     
    176188 
    177189# dispersion name -> disperser lookup table. 
    178 MODELS = dict((d.type, d) for d in ( 
    179     GaussianDispersion, RectangleDispersion, 
    180     ArrayDispersion, SchulzDispersion, LogNormalDispersion 
     190# Maintain order since this is used by sasview GUI to order the options in 
     191# the dispersion type combobox. 
     192MODELS = OrderedDict((d.type, d) for d in ( 
     193    RectangleDispersion, 
     194    ArrayDispersion, 
     195    LogNormalDispersion, 
     196    GaussianDispersion, 
     197    SchulzDispersion, 
    181198)) 
    182199 
     
    196213    *value* is the value of the parameter in the model. 
    197214 
    198     *limits* is [lb, ub], the lower and upper bound of the weight value. 
     215    *limits* is [lb, ub], the lower and upper bound on the possible values. 
    199216 
    200217    *relative* is true if *width* is defined in proportion to the value 
     
    203220    Returns *(value, weight)*, where *value* and *weight* are vectors. 
    204221    """ 
     222    if disperser == "array": 
     223        raise NotImplementedError("Don't handle arrays through get_weights; use values and weights directly") 
    205224    cls = MODELS[disperser] 
    206225    obj = cls(n, width, nsigmas) 
    207226    v, w = obj.get_weights(value, limits[0], limits[1], relative) 
    208227    return v, w 
     228 
     229 
     230def plot_weights(model_info, pairs): 
     231    # type: (ModelInfo, List[Tuple[np.ndarray, np.ndarray]]) -> None 
     232    """ 
     233    Plot the weights returned by :func:`get_weights`. 
     234 
     235    *model_info* is 
     236    :param model_info: 
     237    :param pairs: 
     238    :return: 
     239    """ 
     240    import pylab 
     241 
     242    if any(len(values)>1 for values, weights in pairs): 
     243        labels = [p.name for p in model_info.parameters.call_parameters] 
     244        pylab.interactive(True) 
     245        pylab.figure() 
     246        for (v,w), s in zip(pairs, labels): 
     247            if len(v) > 1: 
     248                #print("weights for", s, v, w) 
     249                pylab.plot(v, w, '-o', label=s) 
     250        pylab.grid(True) 
     251        pylab.legend() 
     252        #pylab.show() 
Note: See TracChangeset for help on using the changeset viewer.