source: sasview/sansmodels/src/sans/models/c_models/parameters.cpp @ 5dc2818

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 5dc2818 was 34c2649, checked in by Mathieu Doucet <doucetm@…>, 13 years ago

Re #4 Fixed warnings

  • Property mode set to 100644
File size: 11.5 KB
RevLine 
[fca6936]1/**
2        This software was developed by the University of Tennessee as part of the
3        Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4        project funded by the US National Science Foundation.
5
6        If you use DANSE applications to do scientific research that leads to
7        publication, we ask that you acknowledge the use of the software with the
8        following sentence:
9
10        "This work benefited from DANSE software developed under NSF award DMR-0520547."
11
12        copyright 2008, University of Tennessee
13 */
14#include "parameters.hh"
15#include <stdio.h>
16#include <math.h>
17using namespace std;
18
19/**
20 * TODO: normalize all dispersion weight lists
21 */
22
23
24/**
[836fe6e]25 * Weight points
[fca6936]26 */
27WeightPoint :: WeightPoint() {
28        value = 0.0;
29        weight = 0.0;
30}
31
32WeightPoint :: WeightPoint(double v, double w) {
33        value = v;
34        weight = w;
35}
36
37/**
[836fe6e]38 * Dispersion models
[fca6936]39 */
40DispersionModel :: DispersionModel() {
41        npts  = 1;
42        width = 0.0;
43};
44
45void DispersionModel :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
46        visitor->dispersion_to_dict(from, to);
47}
48void DispersionModel :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
49        visitor->dispersion_from_dict(from, to);
50}
51void DispersionModel :: operator() (void *param, vector<WeightPoint> &weights){
52        // Check against zero width
53        if (width<=0) {
54                width = 0.0;
55                npts  = 1;
56        }
57
58        Parameter* par = (Parameter*)param;
59        double value = (*par)();
[59b9b675]60        double sig;
[fca6936]61        if (npts<2) {
62                weights.insert(weights.end(), WeightPoint(value, 1.0));
63        } else {
64                for(int i=0; i<npts; i++) {
65
[59b9b675]66                        if ((*par).has_min==false){
67                                // width = sigma for angles
68                                sig = width;
69                        }
70                        else{
71                                //width = polydispersity (=sigma/value) for length
72                                sig = width * value;
73                        }
74                        double val = value + sig * (1.0*double(i)/double(npts-1) - 0.5);
[fca6936]75                        if ( ((*par).has_min==false || val>(*par).min)
76                          && ((*par).has_max==false || val<(*par).max)  )
77                                weights.insert(weights.end(), WeightPoint(val, 1.0));
78                }
79        }
80}
81
82/**
83 * Method to set the weights
84 * Not implemented for this class
85 */
86void DispersionModel :: set_weights(int npoints, double* values, double* weights){}
87
88/**
[836fe6e]89 * Gaussian dispersion
[fca6936]90 */
91
92GaussianDispersion :: GaussianDispersion() {
[a5e14410]93        npts  = 100;
[fca6936]94        width = 0.0;
[a5e14410]95        nsigmas = 10;
[fca6936]96};
97
98void GaussianDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
99        visitor->gaussian_to_dict(from, to);
100}
101void GaussianDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
102        visitor->gaussian_from_dict(from, to);
103}
104
105double gaussian_weight(double mean, double sigma, double x) {
106        double vary, expo_value;
107    vary = x-mean;
[8dc02d8b]108    expo_value = -vary*vary/(2.0*sigma*sigma);
[fca6936]109    //return 1.0;
110    return exp(expo_value);
111}
112
113/**
114 * Gaussian dispersion
115 * @param mean: mean value of the Gaussian
116 * @param sigma: standard deviation of the Gaussian
117 * @param x: value at which the Gaussian is evaluated
118 * @return: value of the Gaussian
119 */
120void GaussianDispersion :: operator() (void *param, vector<WeightPoint> &weights){
121        // Check against zero width
122        if (width<=0) {
123                width = 0.0;
124                npts  = 1;
[a5e14410]125                nsigmas = 10;
[fca6936]126        }
127
128        Parameter* par = (Parameter*)param;
129        double value = (*par)();
[59b9b675]130        double sig;
[fca6936]131        if (npts<2) {
132                weights.insert(weights.end(), WeightPoint(value, 1.0));
133        } else {
134                for(int i=0; i<npts; i++) {
[59b9b675]135                        if ((*par).has_min==false){
136                                // width = sigma for angles
137                                sig = width;
138                        }
139                        else{
140                                //width = polydispersity (=sigma/value) for length
141                                sig = width * value;
142                        }
[fcd8a80e]143                        // We cover n(nsigmas) times sigmas on each side of the mean
[59b9b675]144                        double val = value + sig * (2.0*nsigmas*double(i)/double(npts-1) - nsigmas);
[fca6936]145                        if ( ((*par).has_min==false || val>(*par).min)
146                          && ((*par).has_max==false || val<(*par).max)  ) {
[59b9b675]147                                double _w = gaussian_weight(value, sig, val);
[fca6936]148                                weights.insert(weights.end(), WeightPoint(val, _w));
149                        }
150                }
151        }
152}
153
[eba9885]154
155/**
[8dc02d8b]156 * Flat dispersion
157 */
158
159RectangleDispersion :: RectangleDispersion() {
[a5e14410]160        npts  = 100;
[8dc02d8b]161        width = 0.0;
[0ad5703]162        nsigmas = 1.73205;
[8dc02d8b]163};
164
165void RectangleDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
166        visitor->rectangle_to_dict(from, to);
167}
168void RectangleDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
169        visitor->rectangle_from_dict(from, to);
170}
171
172double rectangle_weight(double mean, double sigma, double x) {
[0ad5703]173    double wid = fabs(sigma) * sqrt(3.0);
174    if (x>= (mean-wid) && x<=(mean+wid)){
[8dc02d8b]175        return 1.0;
176    }
177    else{
178        return 0.0;
179    }
180}
181
182/**
183 * Flat dispersion
184 * @param mean: mean value
185 * @param sigma: half width of top hat function
186 * @param x: value at which the Flat is evaluated
187 * @return: value of the Flat
188 */
189void RectangleDispersion :: operator() (void *param, vector<WeightPoint> &weights){
190        // Check against zero width
191        if (width<=0) {
192                width = 0.0;
193                npts  = 1;
[0ad5703]194                nsigmas = 1.73205;
[8dc02d8b]195        }
196
197        Parameter* par = (Parameter*)param;
198        double value = (*par)();
[59b9b675]199        double sig;
[8dc02d8b]200        if (npts<2) {
201                weights.insert(weights.end(), WeightPoint(value, 1.0));
202        } else {
203                for(int i=0; i<npts; i++) {
[59b9b675]204                        if ((*par).has_min==false){
205                                // width = sigma for angles
206                                sig = width;
207                        }
208                        else{
209                                //width = polydispersity (=sigma/value) for length
210                                sig = width * value;
211                        }
[8dc02d8b]212                        // We cover n(nsigmas) times sigmas on each side of the mean
[59b9b675]213                        double val = value + sig * (2.0*nsigmas*double(i)/double(npts-1) - nsigmas);
[8dc02d8b]214                        if ( ((*par).has_min==false || val>(*par).min)
215                          && ((*par).has_max==false || val<(*par).max)  ) {
[59b9b675]216                                double _w = rectangle_weight(value, sig, val);
[8dc02d8b]217                                weights.insert(weights.end(), WeightPoint(val, _w));
218                        }
219                }
220        }
221}
222
223
224/**
[eba9885]225 * LogNormal dispersion
226 */
227
228LogNormalDispersion :: LogNormalDispersion() {
[a5e14410]229        npts  = 100;
[eba9885]230        width = 0.0;
[a5e14410]231        nsigmas = 10.0;
[eba9885]232};
233
234void LogNormalDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
235        visitor->lognormal_to_dict(from, to);
236}
237void LogNormalDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
238        visitor->lognormal_from_dict(from, to);
239}
240
241double lognormal_weight(double mean, double sigma, double x) {
[c5607fa]242
[1d78e4b]243        double sigma2 = pow(sigma, 2.0);
[a5e14410]244        return 1.0/(x*sigma) * exp( -pow((log(x) - mean), 2.0) / (2.0*sigma2));
[c5607fa]245
[eba9885]246}
247
248/**
249 * Lognormal dispersion
250 * @param mean: mean value of the LogNormal
251 * @param sigma: standard deviation of the LogNormal
252 * @param x: value at which the LogNormal is evaluated
253 * @return: value of the LogNormal
254 */
255void LogNormalDispersion :: operator() (void *param, vector<WeightPoint> &weights){
256        // Check against zero width
257        if (width<=0) {
258                width = 0.0;
259                npts  = 1;
[a5e14410]260                nsigmas = 10.0;
[eba9885]261        }
262
263        Parameter* par = (Parameter*)param;
264        double value = (*par)();
[59b9b675]265        double sig;
[eba9885]266        if (npts<2) {
267                weights.insert(weights.end(), WeightPoint(value, 1.0));
268        } else {
269                for(int i=0; i<npts; i++) {
[0ad5703]270                        // Note that the definition of sigma is different from Gaussian
[59b9b675]271                        if ((*par).has_min==false){
[0ad5703]272                                // sig  for angles
[a5e14410]273                                sig = width;
[59b9b675]274                        }
275                        else{
[0ad5703]276                                // by lognormal definition, PD is same as sigma
[a5e14410]277                                sig = width * value;
[59b9b675]278                        }
[a5e14410]279                       
[eba9885]280                        // We cover n(nsigmas) times sigmas on each side of the mean
[a5e14410]281                        //constant bin in real space
[59b9b675]282                        double val = value + sig * (2.0*nsigmas*double(i)/double(npts-1) - nsigmas);
[a5e14410]283                        // sigma in the lognormal function is in ln(R) space, thus needs converting
284                        sig = fabs(sig/value); 
[eba9885]285                        if ( ((*par).has_min==false || val>(*par).min)
286                          && ((*par).has_max==false || val<(*par).max)  ) {
[a5e14410]287                                double _w = lognormal_weight(log(value), sig, val);
[eba9885]288                                weights.insert(weights.end(), WeightPoint(val, _w));
[a5e14410]289                                //printf("%g \t %g\n",val,_w);
290
[eba9885]291                        }
292                }
293        }
294}
295
296
297
298/**
299 * Schulz dispersion
300 */
301
302SchulzDispersion :: SchulzDispersion() {
[a5e14410]303        npts  = 100;
[eba9885]304        width = 0.0;
[a5e14410]305        nsigmas = 10.0;
[eba9885]306};
307
308void SchulzDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
309        visitor->schulz_to_dict(from, to);
310}
311void SchulzDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
312        visitor->schulz_from_dict(from, to);
313}
314
315double schulz_weight(double mean, double sigma, double x) {
[1d78e4b]316    double z = pow(mean/ sigma, 2.0)-1.0;
[eba9885]317        double R= x/mean;
[1d78e4b]318        double zz= z+1.0;
[c5607fa]319        double expo;
320        expo = zz*log(zz)+z*log(R)-R*zz-log(mean)-lgamma(zz);
321        return  exp(expo);
[eba9885]322}
323
324/**
325 * Schulz dispersion
326 * @param mean: mean value of the Schulz
327 * @param sigma: standard deviation of the Schulz
328 * @param x: value at which the Schulz is evaluated
329 * @return: value of the Schulz
330 */
331void SchulzDispersion :: operator() (void *param, vector<WeightPoint> &weights){
332        // Check against zero width
333        if (width<=0) {
334                width = 0.0;
335                npts  = 1;
[a5e14410]336                nsigmas = 10.0;
[eba9885]337        }
338
339        Parameter* par = (Parameter*)param;
340        double value = (*par)();
[59b9b675]341        double sig;
[eba9885]342        if (npts<2) {
343                weights.insert(weights.end(), WeightPoint(value, 1.0));
344        } else {
345                for(int i=0; i<npts; i++) {
[59b9b675]346                        if ((*par).has_min==false){
347                                // width = sigma for angles
348                                sig = width;
349                        }
350                        else{
351                                //width = polydispersity (=sigma/value) for length
352                                sig = width * value;
353                        }
[eba9885]354                        // We cover n(nsigmas) times sigmas on each side of the mean
[59b9b675]355                        double val = value + sig * (2.0*nsigmas*double(i)/double(npts-1) - nsigmas);
[eba9885]356
357                        if ( ((*par).has_min==false || val>(*par).min)
358                          && ((*par).has_max==false || val<(*par).max)  ) {
[59b9b675]359                                double _w = schulz_weight(value, sig, val);
[eba9885]360                                weights.insert(weights.end(), WeightPoint(val, _w));
361                        }
362                }
363        }
364}
365
366
367
368
[fca6936]369/**
370 * Array dispersion based on input arrays
371 */
372
373void ArrayDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
374        visitor->array_to_dict(from, to);
375}
376void ArrayDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
377        visitor->array_from_dict(from, to);
378}
379
380/**
381 * Method to get the weights
382 */
383void ArrayDispersion :: operator() (void *param, vector<WeightPoint> &weights) {
384        Parameter* par = (Parameter*)param;
385        double value = (*par)();
386
[07da749]387        if (npts<2) {
388                weights.insert(weights.end(), WeightPoint(value, 1.0));
389        } else {
[fca6936]390                for(int i=0; i<npts; i++) {
[0fff338f]391                        double val = _values[i]; //+ value;  //ToDo: Talk to Paul and put back the 'value'.
[59b9b675]392
[0fff338f]393                        if ( ((*par).has_min==false || val>(*par).min)
394                          && ((*par).has_max==false || val<(*par).max)  )
395                                weights.insert(weights.end(), WeightPoint(val, _weights[i]));
[fca6936]396                }
[07da749]397        }
[fca6936]398}
399/**
400 * Method to set the weights
401 */
402void ArrayDispersion :: set_weights(int npoints, double* values, double* weights){
403        npts = npoints;
404        _values = values;
405        _weights = weights;
406}
407
408
409/**
[836fe6e]410 * Parameters
[fca6936]411 */
412Parameter :: Parameter() {
413        value = 0;
414        min   = 0.0;
415        max   = 0.0;
416        has_min = false;
417        has_max = false;
418        has_dispersion = false;
419        dispersion = new GaussianDispersion();
420}
421
422Parameter :: Parameter(double _value) {
423        value = _value;
424        min   = 0.0;
425        max   = 0.0;
426        has_min = false;
427        has_max = false;
428        has_dispersion = false;
429        dispersion = new GaussianDispersion();
430}
431
432Parameter :: Parameter(double _value, bool disp) {
433        value = _value;
434        min   = 0.0;
435        max   = 0.0;
436        has_min = false;
437        has_max = false;
438        has_dispersion = disp;
439        dispersion = new GaussianDispersion();
440}
441
442void Parameter :: get_weights(vector<WeightPoint> &weights) {
443        (*dispersion)((void*)this, weights);
444}
445
446void Parameter :: set_min(double value) {
447        has_min = true;
448        min = value;
449}
450
451void Parameter :: set_max(double value) {
452        has_max = true;
453        max = value;
454}
455
456double Parameter :: operator()() {
457        return value;
458}
459
460double Parameter :: operator=(double _value){
461        value = _value;
[34c2649]462        return value;
[fca6936]463}
Note: See TracBrowser for help on using the repository browser.