Changeset ae2b6b5 in sasmodels for sasmodels/kernel_iq.c
- Timestamp:
- Apr 18, 2016 12:23:35 AM (8 years ago)
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/kernel_iq.c
rf2f67a6 rae2b6b5 52 52 // Storage for the current parameter values. These will be updated as we 53 53 // walk the polydispersity cube. 54 localParameterBlock local_values; // current parameter values54 ParameterBlock local_values; // current parameter values 55 55 double *pvec = (double *)(&local_values); // Alias named parameters with a vector 56 56 double norm; … … 74 74 norm = CALL_VOLUME(local_values); 75 75 76 const double scale = values[0];77 const double background = values[1];78 // result[nq] = norm; // Total volume normalization76 double scale, background; 77 scale = values[0]; 78 background = values[1]; 79 79 80 80 #ifdef USE_OPENMP 81 81 #pragma omp parallel for 82 82 #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); 86 86 } 87 87 return; … … 89 89 90 90 #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]; 96 122 if (pd_start == 0) { 97 123 #ifdef USE_OPENMP 98 124 #pragma omp parallel for 99 125 #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 } 126 130 127 131 // Loop over the weights then loop over q, accumulating values … … 172 176 } 173 177 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 177 179 //printf("fast %d: ", loop_index); 178 180 for (int k=0; k < num_coord; k++) { … … 189 191 //printf("\n"); 190 192 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 191 198 #ifdef INVALID 192 199 if (INVALID(local_values)) continue; … … 204 211 #pragma omp parallel for 205 212 #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 214 220 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]; 217 225 #ifdef USE_OPENMP 218 226 #pragma omp parallel for 219 227 #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); 222 230 } 223 231 }
Note: See TracChangeset
for help on using the changeset viewer.