source: sasview/sansmodels/src/sans/models/c_models/parameters.cpp @ 885857e

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 885857e was c5607fa, checked in by Jae Cho <jhjcho@…>, 15 years ago

Trick applied to the formula of Schulz func to fix having many singularities near small sigmas

  • Property mode set to 100644
File size: 8.6 KB
Line 
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/**
25 * Weight points
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/**
38 * Dispersion models
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)();
60
61        if (npts<2) {
62                weights.insert(weights.end(), WeightPoint(value, 1.0));
63        } else {
64                for(int i=0; i<npts; i++) {
65                        double val = value + width * (1.0*i/float(npts-1) - 0.5);
66
67                        if ( ((*par).has_min==false || val>(*par).min)
68                          && ((*par).has_max==false || val<(*par).max)  )
69                                weights.insert(weights.end(), WeightPoint(val, 1.0));
70                }
71        }
72}
73
74/**
75 * Method to set the weights
76 * Not implemented for this class
77 */
78void DispersionModel :: set_weights(int npoints, double* values, double* weights){}
79
80/**
81 * Gaussian dispersion
82 */
83
84GaussianDispersion :: GaussianDispersion() {
85        npts  = 1;
86        width = 0.0;
87        nsigmas = 2;
88};
89
90void GaussianDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
91        visitor->gaussian_to_dict(from, to);
92}
93void GaussianDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
94        visitor->gaussian_from_dict(from, to);
95}
96
97double gaussian_weight(double mean, double sigma, double x) {
98        double vary, expo_value;
99    vary = x-mean;
100    expo_value = -vary*vary/(2*sigma*sigma);
101    //return 1.0;
102    return exp(expo_value);
103}
104
105/**
106 * Gaussian dispersion
107 * @param mean: mean value of the Gaussian
108 * @param sigma: standard deviation of the Gaussian
109 * @param x: value at which the Gaussian is evaluated
110 * @return: value of the Gaussian
111 */
112void GaussianDispersion :: operator() (void *param, vector<WeightPoint> &weights){
113        // Check against zero width
114        if (width<=0) {
115                width = 0.0;
116                npts  = 1;
117                nsigmas = 3;
118        }
119
120        Parameter* par = (Parameter*)param;
121        double value = (*par)();
122
123        if (npts<2) {
124                weights.insert(weights.end(), WeightPoint(value, 1.0));
125        } else {
126                for(int i=0; i<npts; i++) {
127                        // We cover n(nsigmas) times sigmas on each side of the mean
128                        double val = value + width * (2.0*nsigmas*i/float(npts-1) - nsigmas);
129
130                        if ( ((*par).has_min==false || val>(*par).min)
131                          && ((*par).has_max==false || val<(*par).max)  ) {
132                                double _w = gaussian_weight(value, width, val);
133                                weights.insert(weights.end(), WeightPoint(val, _w));
134                        }
135                }
136        }
137}
138
139
140/**
141 * LogNormal dispersion
142 */
143
144LogNormalDispersion :: LogNormalDispersion() {
145        npts  = 1;
146        width = 0.0;
147        nsigmas = 2;
148};
149
150void LogNormalDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
151        visitor->lognormal_to_dict(from, to);
152}
153void LogNormalDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
154        visitor->lognormal_from_dict(from, to);
155}
156
157double lognormal_weight(double mean, double sigma, double x) {
158
159        double sigma2 = pow(sigma, 2);
160        return 1/(x*sigma2) * exp( -pow((log(x) -mean), 2) / (2*sigma2));
161
162}
163
164/**
165 * Lognormal dispersion
166 * @param mean: mean value of the LogNormal
167 * @param sigma: standard deviation of the LogNormal
168 * @param x: value at which the LogNormal is evaluated
169 * @return: value of the LogNormal
170 */
171void LogNormalDispersion :: operator() (void *param, vector<WeightPoint> &weights){
172        // Check against zero width
173        if (width<=0) {
174                width = 0.0;
175                npts  = 1;
176                nsigmas = 3;
177        }
178
179        Parameter* par = (Parameter*)param;
180        double value = (*par)();
181
182        if (npts<2) {
183                weights.insert(weights.end(), WeightPoint(value, 1.0));
184        } else {
185                for(int i=0; i<npts; i++) {
186                        // We cover n(nsigmas) times sigmas on each side of the mean
187                        double val = value + width * (2.0*nsigmas*i/float(npts-1) - nsigmas);
188
189                        if ( ((*par).has_min==false || val>(*par).min)
190                          && ((*par).has_max==false || val<(*par).max)  ) {
191                                double _w = lognormal_weight(value, width, val);
192                                weights.insert(weights.end(), WeightPoint(val, _w));
193                        }
194                }
195        }
196}
197
198
199
200/**
201 * Schulz dispersion
202 */
203
204SchulzDispersion :: SchulzDispersion() {
205        npts  = 1;
206        width = 0.0;
207        nsigmas = 2;
208};
209
210void SchulzDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
211        visitor->schulz_to_dict(from, to);
212}
213void SchulzDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
214        visitor->schulz_from_dict(from, to);
215}
216
217double schulz_weight(double mean, double sigma, double x) {
218        double vary, expo_value;
219    double z = pow(mean/ sigma, 2)-1;
220        double R= x/mean;
221        double zz= z+1;
222        double expo;
223        expo = zz*log(zz)+z*log(R)-R*zz-log(mean)-lgamma(zz);
224        return  exp(expo);
225}
226
227/**
228 * Schulz dispersion
229 * @param mean: mean value of the Schulz
230 * @param sigma: standard deviation of the Schulz
231 * @param x: value at which the Schulz is evaluated
232 * @return: value of the Schulz
233 */
234void SchulzDispersion :: operator() (void *param, vector<WeightPoint> &weights){
235        // Check against zero width
236        if (width<=0) {
237                width = 0.0;
238                npts  = 1;
239                nsigmas = 3;
240        }
241
242        Parameter* par = (Parameter*)param;
243        double value = (*par)();
244
245        if (npts<2) {
246                weights.insert(weights.end(), WeightPoint(value, 1.0));
247        } else {
248                for(int i=0; i<npts; i++) {
249                        // We cover n(nsigmas) times sigmas on each side of the mean
250                        double val = value + width * (2.0*nsigmas*i/float(npts-1) - nsigmas);
251
252                        if ( ((*par).has_min==false || val>(*par).min)
253                          && ((*par).has_max==false || val<(*par).max)  ) {
254                                double _w = schulz_weight(value, width, val);
255                                weights.insert(weights.end(), WeightPoint(val, _w));
256                        }
257                }
258        }
259}
260
261
262
263
264/**
265 * Array dispersion based on input arrays
266 */
267
268void ArrayDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
269        visitor->array_to_dict(from, to);
270}
271void ArrayDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
272        visitor->array_from_dict(from, to);
273}
274
275/**
276 * Method to get the weights
277 */
278void ArrayDispersion :: operator() (void *param, vector<WeightPoint> &weights) {
279        Parameter* par = (Parameter*)param;
280        double value = (*par)();
281
282        if (npts<2) {
283                weights.insert(weights.end(), WeightPoint(value, 1.0));
284        } else {
285                for(int i=0; i<npts; i++) {
286                        if ( ((*par).has_min==false || _values[i]>(*par).min)
287                          && ((*par).has_max==false || _values[i]<(*par).max)  )
288                                weights.insert(weights.end(), WeightPoint(_values[i], _weights[i]));
289                }
290        }
291}
292/**
293 * Method to set the weights
294 */
295void ArrayDispersion :: set_weights(int npoints, double* values, double* weights){
296        npts = npoints;
297        _values = values;
298        _weights = weights;
299}
300
301
302/**
303 * Parameters
304 */
305Parameter :: Parameter() {
306        value = 0;
307        min   = 0.0;
308        max   = 0.0;
309        has_min = false;
310        has_max = false;
311        has_dispersion = false;
312        dispersion = new GaussianDispersion();
313}
314
315Parameter :: Parameter(double _value) {
316        value = _value;
317        min   = 0.0;
318        max   = 0.0;
319        has_min = false;
320        has_max = false;
321        has_dispersion = false;
322        dispersion = new GaussianDispersion();
323}
324
325Parameter :: Parameter(double _value, bool disp) {
326        value = _value;
327        min   = 0.0;
328        max   = 0.0;
329        has_min = false;
330        has_max = false;
331        has_dispersion = disp;
332        dispersion = new GaussianDispersion();
333}
334
335void Parameter :: get_weights(vector<WeightPoint> &weights) {
336        (*dispersion)((void*)this, weights);
337}
338
339void Parameter :: set_min(double value) {
340        has_min = true;
341        min = value;
342}
343
344void Parameter :: set_max(double value) {
345        has_max = true;
346        max = value;
347}
348
349double Parameter :: operator()() {
350        return value;
351}
352
353double Parameter :: operator=(double _value){
354        value = _value;
355}
Note: See TracBrowser for help on using the repository browser.