Changeset f9245d4 in sasmodels


Ignore:
Timestamp:
Mar 20, 2016 11:43:34 AM (3 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:
f78a2a1
Parents:
0cbcec4
Message:

update design, noting that bkg/scale are special

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/kernel_iq.c

    r0cbcec4 rf9245d4  
    1313 
    1414/* 
    15 The environment needs to provide the following #defines 
     15The environment needs to provide the following #defines: 
     16 
    1617   USE_OPENCL is defined if running in opencl 
    1718   KERNEL declares a function to be available externally 
    1819   KERNEL_NAME is the name of the function being declared 
    1920   NPARS is the number of parameters in the kernel 
    20    PARAMETER_TABLE is the declaration of the parameters to the kernel. 
     21   PARAMETER_DECL is the declaration of the parameters to the kernel. 
    2122 
    2223       Cylinder: 
    2324 
    24            #define PARAMETER_TABLE \ 
     25           #define PARAMETER_DECL \ 
    2526           double length; \ 
    2627           double radius; \ 
    2728           double sld; \ 
    2829           double sld_solvent 
     30 
     31       Note: scale and background are not included 
    2932 
    3033       Multi-shell cylinder (10 shell max): 
     
    6568           #define INVALID(var) (var.bell_radius > var.radius) 
    6669 
     70       Model with complicated constraints: 
     71 
     72           inline bool constrained(p1, p2, p3) { return expression; } 
     73           #define INVALID(var) constrained(var.p1, var.p2, var.p3) 
     74 
     75   IQ_FUNC could be Iq or Iqxy 
     76   IQ_PARS could be q[i] or q[2*i],q[2*i+1] 
     77 
    6778Our design supports a limited number of polydispersity loops, wherein 
    6879we need to cycle through the values of the polydispersity, calculate 
     
    7283calculator treats the parameter set as one long vector. 
    7384 
    74 Let's assume we have 6 polydisperse parameters 
    75 0 : sld_solvent {s1 = constant} 
    76 1: sld_material {s2 = constant} 
    77 2: radius   {r = vector of 10pts} 
    78 3: lenghth {l = vector of 30pts} 
    79 4: background {b = constant} 
    80 5: scale {s = constant} 
     85Let's assume we have 6 parameters in the model, with two polydisperse:: 
     86 
     87    0: scale        {scl = constant} 
     88    1: background   {bkg = constant} 
     89    5: length       {l = vector of 30pts} 
     90    4: radius       {r = vector of 10pts} 
     91    3: sld          {s = constant/(radius**2*length)} 
     92    2: sld_solvent  {s2 = constant} 
     93 
     94This generates the following call to the kernel (where x stands for an 
     95arbitrary value that is not used by the kernel evaluator): 
     96 
     97    NPARS = 4  // scale and background are in all models 
     98    problem { 
     99        pd_par = {5, 4, x, x}     // parameters *radius* and *length* vary 
     100        pd_length = {30,10,0,0}   // *length* has more, so it is first 
     101        pd_offset = {10,0,x,x}    // *length* starts at index 10 in weights 
     102        pd_stride = {1,30,300,300} // cumulative product of pd length 
     103        par_offset = {2, 3, 303, 313}  // parameter offsets 
     104        par_coord = {0, 3, 2, 1} // bitmap of parameter dependencies 
     105        fast_coord_count = 2  // two parameters vary with *length* distribution 
     106        fast_coord_index = {5, 3, x, x, x, x} 
     107    } 
     108 
     109    weight = { l0, .., l29, r0, .., r9} 
     110    pars = { scl, bkg, l0, ..., l29, r0, r1, ..., r9, 
     111             s[l0,r0], ... s[l0,r9], s[l1,r0], ... s[l29,r9] , s2} 
     112 
     113    nq = 130 
     114    q = { q0, q1, ..., q130, x, x }  # pad to 8 element boundary 
     115    result = {r1, ..., r130, norm, vol, vol_norm, x, x, x, x, x, x, x} 
     116 
    81117 
    82118The polydisperse parameters are stored in as an array of parameter 
    83119indices, one for each polydisperse parameter, stored in pd_par[n]. 
    84 For the above mentioned expample that will give pd_par = {3, 2, x, x}, 
    85 where x stands for abitrary number and 3 corresponds to longest parameter (lenght). 
    86120Non-polydisperse parameters do not appear in this array. Each polydisperse 
    87121parameter has a weight vector whose length is stored in pd_length[n], 
    88 In our case pd_length = {30,10,0,0}. The weights are stored in 
    89 a contiguous vector of weights for all parameters, with the starting position 
    90 for the each parameter stored in pd_offset[n] (pd_offset = {10,0,x,x}. 
    91 The values corresponding to the weights are stored together in a 
    92 separate weights[] vector, with offset stored in par_offset[pd_par[n]]. 
    93 In the above mentioned example weight = {r0, .., r9, l0, .., l29}. 
    94 Polydisperse parameters should be stored in decreasing order of length 
    95 for highest efficiency. 
     122The weights are stored in a contiguous vector of weights for all 
     123parameters, with the starting position for the each parameter stored 
     124in pd_offset[n].  The values corresponding to the weights are stored 
     125together in a separate weights[] vector, with offset stored in 
     126par_offset[pd_par[n]]. Polydisperse parameters should be stored in 
     127decreasing order of length for highest efficiency. 
    96128 
    97129We limit the number of polydisperse dimensions to MAX_PD (currently 4). 
     
    136168 
    137169If there is no polydispersity we pretend that it is polydisperisty with one 
    138 parameter. 
     170parameter, pd_start=0 and pd_stop=1.  We may or may not short circuit the 
     171calculation in this case, depending on how much time it saves. 
    139172 
    140173The problem details structure can be allocated and sent in as an integer 
     
    184217} ParameterBlock; 
    185218 
    186  
     219#define FULL_KERNEL_NAME KERNEL_NAME ## _ ## IQ_FUNC 
    187220KERNEL 
    188 void KERNEL_NAME( 
     221void FULL_KERNEL_NAME( 
    189222    int nq,                 // number of q values 
    190223    global const ProblemDetails *problem, 
     
    193226    global const double *q, // nq q values, with padding to boundary 
    194227    global double *result,  // nq return values, again with padding 
    195     global int *offset,     // nq+padding space for current parameter index 
    196228    const double cutoff,    // cutoff in the polydispersity weight product 
    197229    const int pd_start,     // where we are in the polydispersity loop 
     
    202234  // Storage for the current parameter values.  These will be updated as we 
    203235  // walk the polydispersity cube. 
    204   local ParameterBlock local_pars; 
     236  local ParameterBlock local_pars;  // current parameter values 
    205237  const double *parvec = &local_pars;  // Alias named parameters with a vector 
     238 
     239  local int offset[NPARS-2]; 
    206240 
    207241#if defined(USE_SHORTCUT_OPTIMIZATION) 
     
    209243    // Shouldn't need to copy!! 
    210244    for (int k=0; k < NPARS; k++) { 
    211       parvec[k] = pars[k]; 
     245      parvec[k] = pars[k+2];  // skip scale and background 
    212246    } 
    213247 
     
    218252    { 
    219253      const double scattering = IQ_FUNC(IQ_PARS, IQ_PARAMETERS); 
    220       result[i] += local_pars.scale*scattering + local_pars.background; 
     254      result[i] += pars[0]*scattering + pars[1]; 
    221255    } 
    222256    return; 
     
    254288  local int pd_index[PD_MAX]; 
    255289 
    256   // Set the initial index greater than its vector length in order to 
    257   // trigger the reset behaviour that happens at the end the fast loop. 
     290  // Trigger the reset behaviour that happens at the end the fast loop 
     291  // by setting the initial index >= weight vector length. 
    258292  pd_index[0] = pd_length[0]; 
    259293 
     
    329363        result[i] *= norm_vol/vol; 
    330364      } 
    331         result[i] = local_pars.scale*result[i]/norm+local_pars.background; 
     365        result[i] = pars[0]*result[i]/norm + pars[1]; 
    332366    } 
    333367  } 
Note: See TracChangeset for help on using the changeset viewer.