Changeset 5ff1b03 in sasmodels for sasmodels/generate.py


Ignore:
Timestamp:
Mar 25, 2016 11:44:37 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:
c499331
Parents:
ba32cdd
Message:

working kerneldll

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/generate.py

    r380e8c9 r5ff1b03  
    508508        # faster by not using/transferring the volume normalizations, but 
    509509        # the ifdef's reduce readability more than is worthwhile. 
    510         call_volume = "#define CALL_VOLUME(v) 0.0" 
     510        call_volume = "#define CALL_VOLUME(v) 1.0" 
    511511    source.append(call_volume) 
    512512 
     
    579579    model_info['max_pd'] = min(partable.num_pd, MAX_PD) 
    580580 
     581class CoordinationDetails(object): 
     582    def __init__(self, model_info): 
     583        max_pd = model_info['max_pd'] 
     584        npars = len(model_info['parameters'].kernel_pars()) 
     585        par_offset = 4*max_pd 
     586        self.details = np.zeros(par_offset + 3*npars + 4, 'i4') 
     587 
     588        # generate views on different parts of the array 
     589        self._pd_par     = self.details[0*max_pd:1*max_pd] 
     590        self._pd_length  = self.details[1*max_pd:2*max_pd] 
     591        self._pd_offset  = self.details[2*max_pd:3*max_pd] 
     592        self._pd_stride  = self.details[3*max_pd:4*max_pd] 
     593        self._par_offset = self.details[par_offset+0*npars:par_offset+1*npars] 
     594        self._par_coord  = self.details[par_offset+1*npars:par_offset+2*npars] 
     595        self._pd_coord   = self.details[par_offset+2*npars:par_offset+3*npars] 
     596 
     597        # theta_par is fixed 
     598        self.details[-1] = model_info['parameters'].theta_par 
     599 
     600    @property 
     601    def ctypes(self): return self.details.ctypes 
     602    @property 
     603    def pd_par(self): return self._pd_par 
     604    @property 
     605    def pd_length(self): return self._pd_length 
     606    @property 
     607    def pd_offset(self): return self._pd_offset 
     608    @property 
     609    def pd_stride(self): return self._pd_stride 
     610    @property 
     611    def pd_coord(self): return self._pd_coord 
     612    @property 
     613    def par_coord(self): return self._par_coord 
     614    @property 
     615    def par_offset(self): return self._par_offset 
     616    @property 
     617    def num_coord(self): return self.details[-2] 
     618    @num_coord.setter 
     619    def num_coord(self, v): self.details[-2] = v 
     620    @property 
     621    def total_pd(self): return self.details[-3] 
     622    @total_pd.setter 
     623    def total_pd(self, v): self.details[-3] = v 
     624    @property 
     625    def num_active(self): return self.details[-4] 
     626    @num_active.setter 
     627    def num_active(self, v): self.details[-4] = v 
     628 
     629    def show(self): 
     630        print("total_pd", self.total_pd) 
     631        print("num_active", self.num_active) 
     632        print("pd_par", self.pd_par) 
     633        print("pd_length", self.pd_length) 
     634        print("pd_offset", self.pd_offset) 
     635        print("pd_stride", self.pd_stride) 
     636        print("par_offsets", self.par_offset) 
     637        print("num_coord", self.num_coord) 
     638        print("par_coord", self.par_coord) 
     639        print("pd_coord", self.pd_coord) 
     640        print("theta par", self.details[-1]) 
     641 
    581642def mono_details(model_info): 
    582     # TODO: move max_pd into ParameterTable? 
    583     max_pd = model_info['max_pd'] 
    584     pars = model_info['parameters'].kernel_pars() 
    585     npars = len(pars) 
    586     par_offset = 5*max_pd 
    587     constants_offset = par_offset + 3*npars 
    588  
    589     details = np.zeros(constants_offset + 2, 'int32') 
    590     details[0*max_pd:1*max_pd] = range(max_pd)       # pd_par: arbitrary order; use first 
    591     details[1*max_pd:2*max_pd] = [1]*max_pd          # pd_length: only one element 
    592     details[2*max_pd:3*max_pd] = range(max_pd)       # pd_offset: consecutive 1.0 weights 
    593     details[3*max_pd:4*max_pd] = [1]*max_pd          # pd_stride: vectors of length 1 
    594     details[4*max_pd:5*max_pd] = [0]*max_pd          # pd_isvol: doens't matter if no norm 
    595     details[par_offset+0*npars:par_offset+1*npars] = range(2, npars+2) # par_offset: skip scale and background 
    596     details[par_offset+1*npars:par_offset+2*npars] = [0]*npars         # no coordination 
    597     #details[p+npars] = 1 # par_coord[0] is coordinated with the first par? 
    598     details[par_offset+2*npars:par_offset+3*npars] = 0 # fast coord with 0 
    599     details[constants_offset]   = 1     # fast_coord_count: one fast index 
    600     details[constants_offset+1] = -1    # theta_par: None 
     643    details = CoordinationDetails(model_info) 
     644    # The zero defaults for monodisperse systems are mostly fine 
     645    details.par_offset[:] = np.arange(2, len(details.par_offset)+2) 
    601646    return details 
    602647 
    603648def poly_details(model_info, weights): 
    604649    weights = weights[2:] 
    605  
    606     # TODO: move max_pd into ParameterTable? 
    607650    max_pd = model_info['max_pd'] 
    608     pars = model_info['parameters'].kernel_pars() 
    609     npars = len(pars) 
    610     par_offset = 5*max_pd 
    611     constants_offset = par_offset + 3*npars 
    612651 
    613652    # Decreasing list of polydispersity lengths 
    614653    # Note: the reversing view, x[::-1], does not require a copy 
    615654    pd_length = np.array([len(w) for w in weights]) 
     655    num_active = np.sum(pd_length>1) 
     656    if num_active > max_pd: 
     657        raise ValueError("Too many polydisperse parameters") 
     658 
    616659    pd_offset = np.cumsum(np.hstack((0, pd_length))) 
    617     pd_isvol = np.array([p.type=='volume' for p in pars]) 
    618     idx = np.argsort(pd_length)[::-1][:max_pd] 
    619     pd_stride = np.cumprod(np.hstack((1, pd_length[idx][:-1]))) 
    620     par_offsets = np.cumsum(np.hstack((2, pd_length)))[:-1] 
    621     coord_offset = par_offset+npars 
    622     fast_coord_offset = par_offset+2*npars 
    623  
    624     theta_par = -1 
    625     if 'theta_par' in model_info: 
    626         theta_par = model_info['theta_par'] 
    627         if theta_par >= 0 and pd_length[theta_par] <= 1: 
    628             theta_par = -1 
    629  
    630     details = np.empty(constants_offset + 2, 'int32') 
    631     details[0*max_pd:1*max_pd] = idx             # pd_par 
    632     details[1*max_pd:2*max_pd] = pd_length[idx] 
    633     details[2*max_pd:3*max_pd] = pd_offset[idx] 
    634     details[3*max_pd:4*max_pd] = pd_stride 
    635     details[4*max_pd:5*max_pd] = pd_isvol[idx] 
    636     details[par_offset+0*npars:par_offset+1*npars] = par_offsets 
    637     details[par_offset+1*npars:par_offset+2*npars] = 0  # no coordination for most 
    638     for k,parameter_num in enumerate(idx): 
    639         details[coord_offset+parameter_num] = 2**k 
    640     details[fast_coord_offset] = idx[0] 
    641     details[fast_coord_offset+1:fast_coord_offset+npars] = 0  # no fast coord with 0 
    642     details[constants_offset] = 1   # fast_coord_count: one fast index 
    643     details[constants_offset+1] = theta_par 
    644     print("polydispersity details") 
    645     print_details(model_info, details) 
     660    idx = np.argsort(pd_length)[::-1][:num_active] 
     661    par_length = np.array([max(len(w),1) for w in weights]) 
     662    pd_stride = np.cumprod(np.hstack((1, par_length[idx]))) 
     663    par_offsets = np.cumsum(np.hstack((2, par_length))) 
     664 
     665    details = CoordinationDetails(model_info) 
     666    details.pd_par[:num_active] = idx 
     667    details.pd_length[:num_active] = pd_length[idx] 
     668    details.pd_offset[:num_active] = pd_offset[idx] 
     669    details.pd_stride[:num_active] = pd_stride[:-1] 
     670    details.par_offset[:] = par_offsets[:-1] 
     671    details.total_pd = pd_stride[-1] 
     672    details.num_active = num_active 
     673    # Without constraints coordinated parameters are just the pd parameters 
     674    details.par_coord[:num_active] = idx 
     675    details.pd_coord[:num_active] = 2**np.arange(num_active) 
     676    details.num_coord = num_active 
     677    #details.show() 
    646678    return details 
    647  
    648 def print_details(model_info, details): 
    649     max_pd = model_info['max_pd'] 
    650     pars = model_info['parameters'].kernel_pars() 
    651     npars = len(pars) 
    652     par_offset = 5*max_pd 
    653     constants_offset = par_offset + 3*npars 
    654  
    655     print("pd_par", details[0*max_pd:1*max_pd]) 
    656     print("pd_length", details[1*max_pd:2*max_pd]) 
    657     print("pd_offset", details[2*max_pd:3*max_pd]) 
    658     print("pd_stride", details[3*max_pd:4*max_pd]) 
    659     print("pd_isvol", details[4*max_pd:5*max_pd]) 
    660     print("par_offsets", details[par_offset+0*npars:par_offset+1*npars]) 
    661     print("par_coord", details[par_offset+1*npars:par_offset+2*npars]) 
    662     print("fast_coord_pars", details[par_offset+2*npars:par_offset+3*npars]) 
    663     print("fast_coord_count", details[constants_offset]) 
    664     print("theta par", details[constants_offset+1]) 
    665679 
    666680def constrained_poly_details(model_info, weights, constraints): 
Note: See TracChangeset for help on using the changeset viewer.