Changeset a738209 in sasmodels for sasmodels/kernelpy.py


Ignore:
Timestamp:
Jul 15, 2016 7:33:33 AM (8 years ago)
Author:
Paul Kienzle <pkienzle@…>
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:
def2c1b
Parents:
98ba1fc
Message:

simplify kernels by remove coordination parameter logic

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/kernelpy.py

    r7ae2b7f ra738209  
    77:class:`kernelcl.GpuModel` and :class:`kerneldll.DllModel`. 
    88""" 
     9from __future__ import division, print_function 
     10 
    911import numpy as np  # type: ignore 
    1012from numpy import pi, cos  #type: ignore 
     
    153155                        else (lambda: 1.0)) 
    154156 
    155     def __call__(self, call_details, weights, values, cutoff): 
     157    def __call__(self, call_details, values, cutoff): 
    156158        assert isinstance(call_details, details.CallDetails) 
    157159        res = _loops(self._parameter_vector, self._form, self._volume, 
    158                      self.q_input.nq, call_details, weights, values, cutoff) 
     160                     self.q_input.nq, call_details, values, cutoff) 
    159161        return res 
    160162 
     
    166168        self.q_input = None 
    167169 
    168 def _loops(parameters, form, form_volume, nq, call_details, 
    169            weights, values, cutoff): 
     170def _loops(parameters, form, form_volume, nq, details, 
     171           values, cutoff): 
    170172    # type: (np.ndarray, Callable[[], np.ndarray], Callable[[], float], int, details.CallDetails, np.ndarray, np.ndarray, float) -> None 
    171173    ################################################################ 
     
    178180    #                                                              # 
    179181    ################################################################ 
    180     parameters[:] = values[call_details.par_offset] 
     182    NPARS = len(parameters) 
     183    parameters[:] = values[2:NPARS+2] 
    181184    scale, background = values[0], values[1] 
    182     if call_details.num_active == 0: 
     185    if details.num_active == 0: 
    183186        norm = float(form_volume()) 
    184187        if norm > 0.0: 
     
    187190            return np.ones(nq, 'd')*background 
    188191 
     192    pd_value = values[2+NPARS:2+NPARS+details.pd_sum] 
     193    pd_weight = values[2+NPARS+details.pd_sum:] 
     194 
     195    pd_norm = 0.0 
     196    spherical_correction = 1.0 
    189197    partial_weight = np.NaN 
    190     spherical_correction = 1.0 
    191     pd_stride = call_details.pd_stride[:call_details.num_active] 
    192     pd_length = call_details.pd_length[:call_details.num_active] 
    193     pd_offset = call_details.pd_offset[:call_details.num_active] 
    194     pd_index = np.empty_like(pd_offset) 
    195     offset = np.empty_like(call_details.par_offset) 
    196     theta = call_details.theta_par 
    197     fast_length = pd_length[0] 
    198     pd_index[0] = fast_length 
     198    weight =np.NaN 
     199 
     200    p0_par = details.pd_par[0] 
     201    p0_is_theta = (p0_par == details.theta_par) 
     202    p0_length = details.pd_length[0] 
     203    p0_index = p0_length 
     204    p0_offset = details.pd_offset[0] 
     205 
     206    pd_par = details.pd_par[:details.num_active] 
     207    pd_offset = details.pd_offset[:details.num_active] 
     208    pd_stride = details.pd_stride[:details.num_active] 
     209    pd_length = details.pd_length[:details.num_active] 
     210 
    199211    total = np.zeros(nq, 'd') 
    200     norm = 0.0 
    201     for loop_index in range(call_details.total_pd): 
     212    for loop_index in range(details.pd_prod): 
    202213        # update polydispersity parameter values 
    203         if pd_index[0] == fast_length: 
    204             pd_index[:] = (loop_index/pd_stride)%pd_length 
    205             partial_weight = np.prod(weights[pd_offset+pd_index][1:]) 
    206             for k in range(call_details.num_coord): 
    207                 par = call_details.par_coord[k] 
    208                 coord = call_details.pd_coord[k] 
    209                 this_offset = call_details.par_offset[par] 
    210                 block_size = 1 
    211                 for bit in range(len(pd_offset)): 
    212                     if coord&1: 
    213                         this_offset += block_size * pd_index[bit] 
    214                         block_size *= pd_length[bit] 
    215                     coord >>= 1 
    216                     if coord == 0: break 
    217                 offset[par] = this_offset 
    218                 parameters[par] = values[this_offset] 
    219                 if par == theta and not (call_details.par_coord[k]&1): 
    220                     spherical_correction = max(abs(cos(pi/180 * parameters[theta])), 1e-6) 
    221         for k in range(call_details.num_coord): 
    222             if call_details.pd_coord[k]&1: 
    223                 #par = call_details.par_coord[k] 
    224                 parameters[par] = values[offset[par]] 
    225                 #print "par",par,offset[par],parameters[par+2] 
    226                 offset[par] += 1 
    227                 if par == theta: 
    228                     spherical_correction = max(abs(cos(pi/180 * parameters[theta])), 1e-6) 
    229  
    230         weight = partial_weight * weights[pd_offset[0] + pd_index[0]] 
    231         pd_index[0] += 1 
     214        if p0_index == p0_length: 
     215            pd_index = (loop_index//pd_stride)%pd_length 
     216            parameters[pd_par] = pd_value[pd_offset+pd_index] 
     217            partial_weight = np.prod(pd_weight[pd_offset+pd_index][1:]) 
     218            if details.theta_par >= 0: 
     219                spherical_correction = max(abs(cos(pi/180 * parameters[details.theta_par])), 1e-6) 
     220            p0_index = loop_index%p0_length 
     221 
     222        weight = partial_weight * pd_weight[p0_offset + p0_index] 
     223        parameters[p0_par] = pd_value[p0_offset + p0_index] 
     224        if p0_is_theta: 
     225            spherical_correction = max(abs(cos(pi/180 * parameters[p0_par])), 1e-6) 
     226        p0_index += 1 
    232227        if weight > cutoff: 
    233228            # Call the scattering function 
     
    241236            weight *= spherical_correction 
    242237            total += weight * I 
    243             norm += weight * form_volume() 
    244  
    245     if norm > 0.0: 
    246         return (scale/norm)*total + background 
     238            pd_norm += weight * form_volume() 
     239 
     240    if pd_norm > 0.0: 
     241        return (scale/pd_norm)*total + background 
    247242    else: 
    248243        return np.ones(nq, 'd')*background 
Note: See TracChangeset for help on using the changeset viewer.