source: sasview/sansmodels/src/sans/models/c_models/parameters.cpp @ 8dc02d8b

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 8dc02d8b was 8dc02d8b, checked in by Jae Cho <jhjcho@…>, 13 years ago

added rectangular function for poly-dispersion

  • Property mode set to 100644
File size: 10.3 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*double(i)/double(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  = 21;
86        width = 0.0;
87        nsigmas = 3.0;
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.0*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.0;
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*double(i)/double(npts-1) - nsigmas);
129                        if ( ((*par).has_min==false || val>(*par).min)
130                          && ((*par).has_max==false || val<(*par).max)  ) {
131                                double _w = gaussian_weight(value, width, val);
132                                weights.insert(weights.end(), WeightPoint(val, _w));
133                        }
134                }
135        }
136}
137
138
139/**
140 * Flat dispersion
141 */
142
143RectangleDispersion :: RectangleDispersion() {
144        npts  = 21;
145        width = 0.0;
146        nsigmas = 1.0;
147};
148
149void RectangleDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
150        visitor->rectangle_to_dict(from, to);
151}
152void RectangleDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
153        visitor->rectangle_from_dict(from, to);
154}
155
156double rectangle_weight(double mean, double sigma, double x) {
157        double vary, expo_value;
158    double sig = fabs(sigma);
159    if (x>= (mean-sig) && x<(mean+sig)){
160        return 1.0;
161    }
162    else{
163        return 0.0;
164    }
165}
166
167/**
168 * Flat dispersion
169 * @param mean: mean value
170 * @param sigma: half width of top hat function
171 * @param x: value at which the Flat is evaluated
172 * @return: value of the Flat
173 */
174void RectangleDispersion :: operator() (void *param, vector<WeightPoint> &weights){
175        // Check against zero width
176        if (width<=0) {
177                width = 0.0;
178                npts  = 1;
179                nsigmas = 1.0;
180        }
181
182        Parameter* par = (Parameter*)param;
183        double value = (*par)();
184
185        if (npts<2) {
186                weights.insert(weights.end(), WeightPoint(value, 1.0));
187        } else {
188                for(int i=0; i<npts; i++) {
189                        // We cover n(nsigmas) times sigmas on each side of the mean
190                        double val = value + width * (2.0*nsigmas*double(i)/double(npts-1) - nsigmas);
191                        if ( ((*par).has_min==false || val>(*par).min)
192                          && ((*par).has_max==false || val<(*par).max)  ) {
193                                double _w = rectangle_weight(value, width, val);
194                                weights.insert(weights.end(), WeightPoint(val, _w));
195                        }
196                }
197        }
198}
199
200
201/**
202 * LogNormal dispersion
203 */
204
205LogNormalDispersion :: LogNormalDispersion() {
206        npts  = 21;
207        width = 0.0;
208        nsigmas = 3.0;
209};
210
211void LogNormalDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
212        visitor->lognormal_to_dict(from, to);
213}
214void LogNormalDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
215        visitor->lognormal_from_dict(from, to);
216}
217
218double lognormal_weight(double mean, double sigma, double x) {
219
220        double sigma2 = pow(sigma, 2.0);
221        return 1.0/(x*sigma2) * exp( -pow((log(x) -mean), 2.0) / (2.0*sigma2));
222
223}
224
225/**
226 * Lognormal dispersion
227 * @param mean: mean value of the LogNormal
228 * @param sigma: standard deviation of the LogNormal
229 * @param x: value at which the LogNormal is evaluated
230 * @return: value of the LogNormal
231 */
232void LogNormalDispersion :: operator() (void *param, vector<WeightPoint> &weights){
233        // Check against zero width
234        if (width<=0) {
235                width = 0.0;
236                npts  = 1;
237                nsigmas = 3.0;
238        }
239
240        Parameter* par = (Parameter*)param;
241        double value = (*par)();
242
243        if (npts<2) {
244                weights.insert(weights.end(), WeightPoint(value, 1.0));
245        } else {
246                for(int i=0; i<npts; i++) {
247                        // We cover n(nsigmas) times sigmas on each side of the mean
248                        double val = value + width * (2.0*nsigmas*double(i)/double(npts-1) - nsigmas);
249
250                        if ( ((*par).has_min==false || val>(*par).min)
251                          && ((*par).has_max==false || val<(*par).max)  ) {
252                                double _w = lognormal_weight(value, width, val);
253                                weights.insert(weights.end(), WeightPoint(val, _w));
254                        }
255                }
256        }
257}
258
259
260
261/**
262 * Schulz dispersion
263 */
264
265SchulzDispersion :: SchulzDispersion() {
266        npts  = 21;
267        width = 0.0;
268        nsigmas = 3.0;
269};
270
271void SchulzDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
272        visitor->schulz_to_dict(from, to);
273}
274void SchulzDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
275        visitor->schulz_from_dict(from, to);
276}
277
278double schulz_weight(double mean, double sigma, double x) {
279        double vary, expo_value;
280    double z = pow(mean/ sigma, 2.0)-1.0;
281        double R= x/mean;
282        double zz= z+1.0;
283        double expo;
284        expo = zz*log(zz)+z*log(R)-R*zz-log(mean)-lgamma(zz);
285        return  exp(expo);
286}
287
288/**
289 * Schulz dispersion
290 * @param mean: mean value of the Schulz
291 * @param sigma: standard deviation of the Schulz
292 * @param x: value at which the Schulz is evaluated
293 * @return: value of the Schulz
294 */
295void SchulzDispersion :: operator() (void *param, vector<WeightPoint> &weights){
296        // Check against zero width
297        if (width<=0) {
298                width = 0.0;
299                npts  = 1;
300                nsigmas = 3.0;
301        }
302
303        Parameter* par = (Parameter*)param;
304        double value = (*par)();
305
306        if (npts<2) {
307                weights.insert(weights.end(), WeightPoint(value, 1.0));
308        } else {
309                for(int i=0; i<npts; i++) {
310                        // We cover n(nsigmas) times sigmas on each side of the mean
311                        double val = value + width * (2.0*nsigmas*double(i)/double(npts-1) - nsigmas);
312
313                        if ( ((*par).has_min==false || val>(*par).min)
314                          && ((*par).has_max==false || val<(*par).max)  ) {
315                                double _w = schulz_weight(value, width, val);
316                                weights.insert(weights.end(), WeightPoint(val, _w));
317                        }
318                }
319        }
320}
321
322
323
324
325/**
326 * Array dispersion based on input arrays
327 */
328
329void ArrayDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
330        visitor->array_to_dict(from, to);
331}
332void ArrayDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
333        visitor->array_from_dict(from, to);
334}
335
336/**
337 * Method to get the weights
338 */
339void ArrayDispersion :: operator() (void *param, vector<WeightPoint> &weights) {
340        Parameter* par = (Parameter*)param;
341        double value = (*par)();
342
343        if (npts<2) {
344                weights.insert(weights.end(), WeightPoint(value, 1.0));
345        } else {
346                for(int i=0; i<npts; i++) {
347                        double val = _values[i]; //+ value;  //ToDo: Talk to Paul and put back the 'value'.
348                        if ( ((*par).has_min==false || val>(*par).min)
349                          && ((*par).has_max==false || val<(*par).max)  )
350                                weights.insert(weights.end(), WeightPoint(val, _weights[i]));
351                }
352        }
353}
354/**
355 * Method to set the weights
356 */
357void ArrayDispersion :: set_weights(int npoints, double* values, double* weights){
358        npts = npoints;
359        _values = values;
360        _weights = weights;
361}
362
363
364/**
365 * Parameters
366 */
367Parameter :: Parameter() {
368        value = 0;
369        min   = 0.0;
370        max   = 0.0;
371        has_min = false;
372        has_max = false;
373        has_dispersion = false;
374        dispersion = new GaussianDispersion();
375}
376
377Parameter :: Parameter(double _value) {
378        value = _value;
379        min   = 0.0;
380        max   = 0.0;
381        has_min = false;
382        has_max = false;
383        has_dispersion = false;
384        dispersion = new GaussianDispersion();
385}
386
387Parameter :: Parameter(double _value, bool disp) {
388        value = _value;
389        min   = 0.0;
390        max   = 0.0;
391        has_min = false;
392        has_max = false;
393        has_dispersion = disp;
394        dispersion = new GaussianDispersion();
395}
396
397void Parameter :: get_weights(vector<WeightPoint> &weights) {
398        (*dispersion)((void*)this, weights);
399}
400
401void Parameter :: set_min(double value) {
402        has_min = true;
403        min = value;
404}
405
406void Parameter :: set_max(double value) {
407        has_max = true;
408        max = value;
409}
410
411double Parameter :: operator()() {
412        return value;
413}
414
415double Parameter :: operator=(double _value){
416        value = _value;
417}
Note: See TracBrowser for help on using the repository browser.