Changes in / [f475f90:d0462cf] in sasmodels
- Location:
- sasmodels
- Files:
-
- 4 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/details.py
r767dca8 rce99754 193 193 #print("off:",offset) 194 194 195 # Check that we ar n't using too many polydispersity loops195 # Check that we aren't using too many polydispersity loops 196 196 num_active = np.sum(length > 1) 197 197 max_pd = model_info.parameters.max_pd … … 318 318 parameter set in the vector. 319 319 """ 320 value, dispersity, weight = zip(*mesh)320 _, dispersity, weight = zip(*mesh) 321 321 #weight = [w if len(w)>0 else [1.] for w in weight] 322 322 weight = np.vstack([v.flatten() for v in meshgrid(*weight)]) -
sasmodels/kernel_iq.c
r4991048 r6aee3ab 13 13 // NOTE: the following macros are defined in generate.py: 14 14 // 15 // MAX_PD : the maximum number of dispersity loops allowed 15 // MAX_PD : the maximum number of dispersity loops allowed for this model, 16 // which will be at most modelinfo.MAX_PD. 16 17 // NUM_PARS : the number of parameters in the parameter table 17 18 // NUM_VALUES : the number of values to skip at the start of the … … 282 283 #endif 283 284 284 // Storage for the current parameter values. These will be updated as we 285 // walk the dispersity mesh. 285 // ** Fill in the local values table ** 286 // Storage for the current parameter values. 287 // These will be updated as we walk the dispersity mesh. 286 288 ParameterBlock local_values; 287 289 // values[0] is scale 290 // values[1] is background 291 #ifdef USE_OPENMP 292 #pragma omp parallel for 293 #endif 294 for (int i=0; i < NUM_PARS; i++) { 295 local_values.vector[i] = values[2+i]; 296 //if (q_index==0) printf("p%d = %g\n",i, local_values.vector[i]); 297 } 298 //if (q_index==0) printf("NUM_VALUES:%d NUM_PARS:%d MAX_PD:%d\n", NUM_VALUES, NUM_PARS, MAX_PD); 299 //if (q_index==0) printf("start:%d stop:%d\n", pd_start, pd_stop); 300 301 // ** Precompute magnatism values ** 288 302 #if defined(MAGNETIC) && NUM_MAGNETIC>0 289 303 // Location of the sld parameters in the parameter vector. … … 302 316 #endif // MAGNETIC 303 317 304 // Fill in the initial variables 305 // values[0] is scale 306 // values[1] is background 307 #ifdef USE_OPENMP 308 #pragma omp parallel for 309 #endif 310 for (int i=0; i < NUM_PARS; i++) { 311 local_values.vector[i] = values[2+i]; 312 //if (q_index==0) printf("p%d = %g\n",i, local_values.vector[i]); 313 } 314 //if (q_index==0) printf("NUM_VALUES:%d NUM_PARS:%d MAX_PD:%d\n", NUM_VALUES, NUM_PARS, MAX_PD); 315 //if (q_index==0) printf("start:%d stop:%d\n", pd_start, pd_stop); 316 318 // ** Fill in the initial results ** 317 319 // If pd_start is zero that means that we are starting a new calculation, 318 320 // and must initialize the result to zero. Otherwise, we are restarting … … 336 338 for (int q_index=0; q_index < nq; q_index++) result[q_index] = 0.0; 337 339 } 338 //if (q_index==0) printf("start %d %g %g\n", pd_start, pd_norm, result[0]);340 //if (q_index==0) printf("start %d %g %g\n", pd_start, pd_norm, result[0]); 339 341 #endif // !USE_OPENCL 340 342 … … 390 392 PD_OPEN(0,1) 391 393 392 ... main loop body ... 394 // ... main loop body ... 395 APPLY_PROJECTION // convert jitter values to spherical coords 396 BUILD_ROTATION // construct the rotation matrix qxy => qabc 397 for each q 398 FETCH_Q // set qx,qy from the q input vector 399 APPLY_ROTATION // convert qx,qy to qa,qb,qc 400 CALL_KERNEL // scattering = Iqxy(qa, qb, qc, p1, p2, ...) 393 401 394 402 ++step; // increment counter representing position in dispersity mesh … … 412 420 */ 413 421 414 // Define looping variables 415 #define PD_INIT(_LOOP) \ 416 const int n##_LOOP = details->pd_length[_LOOP]; \ 417 const int p##_LOOP = details->pd_par[_LOOP]; \ 418 global const double *v##_LOOP = pd_value + details->pd_offset[_LOOP]; \ 419 global const double *w##_LOOP = pd_weight + details->pd_offset[_LOOP]; \ 420 int i##_LOOP = (pd_start/details->pd_stride[_LOOP])%n##_LOOP; 421 422 // Jump into the middle of the dispersity loop 423 #define PD_OPEN(_LOOP,_OUTER) \ 424 while (i##_LOOP < n##_LOOP) { \ 425 local_values.vector[p##_LOOP] = v##_LOOP[i##_LOOP]; \ 426 const double weight##_LOOP = w##_LOOP[i##_LOOP] * weight##_OUTER; 427 428 // create the variable "weight#=1.0" where # is the outermost level+1 (=MAX_PD). 429 #define _PD_OUTERMOST_WEIGHT(_n) const double weight##_n = 1.0; 430 #define PD_OUTERMOST_WEIGHT(_n) _PD_OUTERMOST_WEIGHT(_n) 431 432 // Close out the loop 433 #define PD_CLOSE(_LOOP) \ 434 if (step >= pd_stop) break; \ 435 ++i##_LOOP; \ 436 } \ 437 i##_LOOP = 0; 438 439 // The main loop body is essentially: 440 // 441 // BUILD_ROTATION // construct the rotation matrix qxy => qabc 442 // for each q 443 // FETCH_Q // set qx,qy from the q input vector 444 // APPLY_ROTATION // convert qx,qy to qa,qb,qc 445 // CALL_KERNEL // scattering = Iqxy(qa, qb, qc, p1, p2, ...) 446 // 422 423 // ** prepare inner loops ** 424 447 425 // Depending on the shape type (radial, axial, triaxial), the variables 448 // and calling parameters will be slightly different. These macros 449 // capture the differences in one spot so the rest of the code is easier 450 // to read. 426 // and calling parameters in the loop body will be slightly different. 427 // Macros capture the differences in one spot so the rest of the code 428 // is easier to read. The code below both declares variables for the 429 // inner loop and defines the macros that use them. 451 430 452 431 #if defined(CALL_IQ) … … 486 465 // psi and dpsi are only for IQ_ABC, so they are processed here. 487 466 const double psi = values[details->theta_par+4]; 467 local_values.table.psi = 0.; 488 468 #define BUILD_ROTATION() qabc_rotation(&rotation, theta, phi, psi, dtheta, dphi, local_values.table.psi) 489 469 #define APPLY_ROTATION() qabc_apply(rotation, qx, qy, &qa, &qb, &qc) … … 501 481 const double theta = values[details->theta_par+2]; 502 482 const double phi = values[details->theta_par+3]; 483 // Make sure jitter angle defaults to zero if there is no jitter distribution 484 local_values.table.theta = 0.; 485 local_values.table.phi = 0.; 503 486 // The "jitter" angles (dtheta, dphi, dpsi) are stored with the 504 487 // dispersity values and copied to the local parameter table as … … 523 506 #endif // !spherosymmetric projection 524 507 508 // ** define looping macros ** 509 510 // Define looping variables 511 #define PD_INIT(_LOOP) \ 512 const int n##_LOOP = details->pd_length[_LOOP]; \ 513 const int p##_LOOP = details->pd_par[_LOOP]; \ 514 global const double *v##_LOOP = pd_value + details->pd_offset[_LOOP]; \ 515 global const double *w##_LOOP = pd_weight + details->pd_offset[_LOOP]; \ 516 int i##_LOOP = (pd_start/details->pd_stride[_LOOP])%n##_LOOP; 517 518 // Jump into the middle of the dispersity loop 519 #define PD_OPEN(_LOOP,_OUTER) \ 520 while (i##_LOOP < n##_LOOP) { \ 521 local_values.vector[p##_LOOP] = v##_LOOP[i##_LOOP]; \ 522 const double weight##_LOOP = w##_LOOP[i##_LOOP] * weight##_OUTER; 523 524 // create the variable "weight#=1.0" where # is the outermost level+1 (=MAX_PD). 525 #define _PD_OUTERMOST_WEIGHT(_n) const double weight##_n = 1.0; 526 #define PD_OUTERMOST_WEIGHT(_n) _PD_OUTERMOST_WEIGHT(_n) 527 528 // Close out the loop 529 #define PD_CLOSE(_LOOP) \ 530 if (step >= pd_stop) break; \ 531 ++i##_LOOP; \ 532 } \ 533 i##_LOOP = 0; 525 534 526 535 // ====== construct the loops ======= … … 537 546 int step = pd_start; 538 547 548 // *** define loops for each of 0, 1, 2, ..., modelinfo.MAX_PD-1 *** 549 539 550 // define looping variables 540 551 #if MAX_PD>4 … … 571 582 PD_OPEN(0,1) 572 583 #endif 573 574 584 575 585 //if (q_index==0) {printf("step:%d of %d, pars:",step,pd_stop); for (int i=0; i < NUM_PARS; i++) printf("p%d=%g ",i, local_values.vector[i]); printf("\n");} … … 672 682 #endif // !USE_OPENCL 673 683 674 // clear the macros in preparation for the next kernel684 // ** clear the macros in preparation for the next kernel ** 675 685 #undef PD_INIT 676 686 #undef PD_OPEN -
sasmodels/modelinfo.py
re3571cb r6aee3ab 30 30 TestCondition = Tuple[ParameterSetUser, TestInput, TestValue] 31 31 32 MAX_PD = 4 #: Maximum number of simultaneously polydisperse parameters 32 # If MAX_PD changes, need to change the loop macros in kernel_iq.c 33 MAX_PD = 5 #: Maximum number of simultaneously polydisperse parameters 33 34 34 35 # assumptions about common parameters exist throughout the code, such as: -
sasmodels/product.py
r1f35235 rce99754 101 101 model_info.composition = ('product', [p_info, s_info]) 102 102 model_info.control = p_info.control 103 model_info.hidden = p_info.hidden 104 if getattr(p_info, 'profile', None) is not None: 105 profile_pars = set(p.id for p in p_info.parameters.kernel_parameters) 106 def profile(**kwargs): 107 # extract the profile args 108 kwargs = dict((k, v) for k, v in kwargs.items() if k in profile_pars) 109 return p_info.profile(**kwargs) 110 else: 111 profile = None 112 model_info.profile = profile 113 model_info.profile_axes = p_info.profile_axes 114 103 115 # TODO: delegate random to p_info, s_info 104 116 #model_info.random = lambda: {} … … 267 279 weight = values[nvalues + call_details.num_weights: nvalues + 2*call_details.num_weights] 268 280 npars = model_info.parameters.npars 269 pairs = [(value[offset:offset+length], weight[offset:offset+length]) 281 # Note: changed from pairs ([v], [w]) to triples (p, [v], [w]), but the 282 # dispersion mesh code doesn't actually care about the nominal parameter 283 # value, p, so set it to None. 284 pairs = [(None, value[offset:offset+length], weight[offset:offset+length]) 270 285 for p, offset, length 271 286 in zip(model_info.parameters.call_parameters[2:2+npars], -
sasmodels/sasview_model.py
ra9bc435 r17db833 205 205 structure_factor._model_info) 206 206 ConstructedModel = make_model_from_info(model_info) 207 return ConstructedModel(form_factor.multiplicity) 207 return ConstructedModel(form_factor.multiplicity) 208 208 209 209 … … 673 673 #call_details.show() 674 674 #print("pairs", pairs) 675 #for k, p in enumerate(self._model_info.parameters.call_parameters): 676 # print(k, p.name, *pairs[k]) 675 677 #print("params", self.params) 676 678 #print("values", values) … … 678 680 result = calculator(call_details, values, cutoff=self.cutoff, 679 681 magnetic=is_magnetic) 682 #print("result", result) 680 683 self._intermediate_results = getattr(calculator, 'results', None) 681 684 calculator.release() … … 761 764 return self.multiplicity, [self.multiplicity], [1.0] 762 765 else: 763 # For hidden parameters use the default value. 766 # For hidden parameters use default values. This sets 767 # scale=1 and background=0 for structure factors 764 768 default = self._model_info.parameters.defaults.get(par.name, np.NaN) 765 return [default], [1.0]769 return default, [default], [1.0] 766 770 elif par.polydisperse: 767 771 value = self.params[par.name] … … 776 780 else: 777 781 value = self.params[par.name] 778 return value, [value if par.relative_pd else 0.0], [1.0]782 return value, [value], [1.0] 779 783 780 784 def test_cylinder(): … … 794 798 Model = _make_standard_model('hardsphere') 795 799 model = Model() 800 value2d = model.evalDistribution([0.1, 0.1]) 801 value1d = model.evalDistribution(np.array([0.1*np.sqrt(2)])) 802 #print("hardsphere", value1d, value2d) 803 if np.isnan(value1d) or np.isnan(value2d): 804 raise ValueError("hardsphere returns nan") 805 806 def test_product(): 807 # type: () -> float 808 """ 809 Test that 2-D hardsphere model runs and doesn't produce NaN. 810 """ 811 S = _make_standard_model('hayter_msa')() 812 P = _make_standard_model('cylinder')() 813 model = MultiplicationModel(P, S) 796 814 value = model.evalDistribution([0.1, 0.1]) 797 815 if np.isnan(value): 798 raise ValueError(" hardspherereturns null")816 raise ValueError("cylinder*hatyer_msa returns null") 799 817 800 818 def test_rpa(): … … 850 868 if __name__ == "__main__": 851 869 print("cylinder(0.1,0.1)=%g"%test_cylinder()) 870 #test_product() 871 #test_structure_factor() 872 #print("rpa:", test_rpa()) 852 873 #test_empty_distribution()
Note: See TracChangeset
for help on using the changeset viewer.