Changeset ae2b6b5 in sasmodels for sasmodels/kernel_iq.c


Ignore:
Timestamp:
Apr 18, 2016 12:23:35 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:
ee72c70
Parents:
f2f67a6
Message:

increase code correspondance between iq.c and iq.cl

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/kernel_iq.c

    rf2f67a6 rae2b6b5  
    5252  // Storage for the current parameter values.  These will be updated as we 
    5353  // walk the polydispersity cube. 
    54   local ParameterBlock local_values;  // current parameter values 
     54  ParameterBlock local_values;  // current parameter values 
    5555  double *pvec = (double *)(&local_values);  // Alias named parameters with a vector 
    5656  double norm; 
     
    7474    norm = CALL_VOLUME(local_values); 
    7575 
    76     const double scale = values[0]; 
    77     const double background = values[1]; 
    78     // result[nq] = norm; // Total volume normalization 
     76    double scale, background; 
     77    scale = values[0]; 
     78    background = values[1]; 
    7979 
    8080    #ifdef USE_OPENMP 
    8181    #pragma omp parallel for 
    8282    #endif 
    83     for (int i=0; i < nq; i++) { 
    84       double scattering = CALL_IQ(q, i, local_values); 
    85       result[i] = (norm>0. ? scale*scattering/norm + background : background); 
     83    for (int q_index=0; q_index < nq; q_index++) { 
     84      double scattering = CALL_IQ(q, q_index, local_values); 
     85      result[q_index] = (norm>0. ? scale*scattering/norm + background : background); 
    8686    } 
    8787    return; 
     
    8989 
    9090#if MAX_PD > 0 
    91   // If it is the first round initialize the result to zero, otherwise 
    92   // assume that the previous result has been passed back. 
    93   // Note: doing this even in the monodisperse case in order to handle the 
    94   // rare case where the model parameters are invalid and zero is returned. 
    95   // So slightly increased cost for slightly smaller code size. 
     91 
     92  // need product of weights at every Iq calc, so keep product of 
     93  // weights from the outer loops so that weight = partial_weight * fast_weight 
     94  double partial_weight; // product of weight w4*w3*w2 but not w1 
     95  double spherical_correction; // cosine correction for latitude variation 
     96  double weight; // product of partial_weight*w1*spherical_correction 
     97 
     98  // Location in the polydispersity hypercube, one index per dimension. 
     99  int pd_index[MAX_PD]; 
     100 
     101  // Location of the coordinated parameters in their own sub-cubes. 
     102  int offset[NPARS]; 
     103 
     104  // Number of coordinated indices 
     105  const int num_coord = details->num_coord; 
     106 
     107  // Number of elements in the longest polydispersity loop 
     108  const int fast_length = details->pd_length[0]; 
     109 
     110  // Trigger the reset behaviour that happens at the end the fast loop 
     111  // by setting the initial index >= weight vector length. 
     112  pd_index[0] = fast_length; 
     113 
     114  // Default the spherical correction to 1.0 in case it is not otherwise set 
     115  spherical_correction = 1.0; 
     116 
     117  // Since we are no longer looping over the entire polydispersity hypercube 
     118  // for each q, we need to track the result and normalization values between 
     119  // calls.  This means initializing them to 0 at the start and accumulating 
     120  // them between calls. 
     121  norm = pd_start == 0 ? 0.0 : result[nq]; 
    96122  if (pd_start == 0) { 
    97123    #ifdef USE_OPENMP 
    98124    #pragma omp parallel for 
    99125    #endif 
    100     for (int i=0; i < nq+1; i++) { 
    101       result[i] = 0.0; 
    102     } 
    103     norm = 0.0; 
    104   } else { 
    105     norm = result[nq]; 
    106   } 
    107  
    108   // need product of weights at every Iq calc, so keep product of 
    109   // weights from the outer loops so that weight = partial_weight * fast_weight 
    110   double partial_weight = NAN; // product of weight w4*w3*w2 but not w1 
    111   double spherical_correction = 1.0;  // cosine correction for latitude variation 
    112  
    113   // Location in the polydispersity hypercube, one index per dimension. 
    114   local int pd_index[MAX_PD]; 
    115  
    116   // Location of the coordinated parameters in their own sub-cubes. 
    117   local int offset[NPARS]; 
    118  
    119   // Trigger the reset behaviour that happens at the end the fast loop 
    120   // by setting the initial index >= weight vector length. 
    121   const int fast_length = details->pd_length[0]; 
    122   pd_index[0] = fast_length; 
    123  
    124   // Number of coordinated indices 
    125   const int num_coord = details->num_coord; 
     126    for (int q_index=0; q_index < nq; q_index++) { 
     127      result[q_index] = 0.0; 
     128    } 
     129  } 
    126130 
    127131  // Loop over the weights then loop over q, accumulating values 
     
    172176    } 
    173177 
    174     // Increment fast index 
    175     const double wi = weights[details->pd_offset[0] + pd_index[0]++]; 
    176     double weight = partial_weight*wi; 
     178    // Update fast parameters 
    177179    //printf("fast %d: ", loop_index); 
    178180    for (int k=0; k < num_coord; k++) { 
     
    189191    //printf("\n"); 
    190192 
     193    // Increment fast index 
     194    const double wi = weights[details->pd_offset[0] + pd_index[0]]; 
     195    weight = partial_weight*wi; 
     196    pd_index[0]++; 
     197 
    191198    #ifdef INVALID 
    192199    if (INVALID(local_values)) continue; 
     
    204211      #pragma omp parallel for 
    205212      #endif 
    206       for (int i=0; i < nq; i++) { 
    207         const double scattering = CALL_IQ(q, i, local_values); 
    208         result[i] += weight*scattering; 
    209       } 
    210     } 
    211   } 
    212  
    213   // End of the PD loop we can normalize 
     213      for (int q_index=0; q_index < nq; q_index++) { 
     214        const double scattering = CALL_IQ(q, q_index, local_values); 
     215        result[q_index] += weight*scattering; 
     216      } 
     217    } 
     218  } 
     219 
    214220  if (pd_stop >= details->total_pd) { 
    215     const double scale = values[0]; 
    216     const double background = values[1]; 
     221    // End of the PD loop we can normalize 
     222    double scale, background; 
     223    scale = values[0]; 
     224    background = values[1]; 
    217225    #ifdef USE_OPENMP 
    218226    #pragma omp parallel for 
    219227    #endif 
    220     for (int i=0; i < nq; i++) { 
    221       result[i] = (norm>0. ? scale*result[i]/norm + background : background); 
     228    for (int q_index=0; q_index < nq; q_index++) { 
     229      result[q_index] = (norm>0. ? scale*result[q_index]/norm + background : background); 
    222230    } 
    223231  } 
Note: See TracChangeset for help on using the changeset viewer.