source: sasview/sansmodels/src/c_models/librefl.c @ 7887723

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 7887723 was 1b758b3, checked in by Mathieu Doucet <doucetm@…>, 13 years ago

clean up warnings

  • Property mode set to 100644
File size: 6.2 KB
Line 
1// The original code, of which work was not DANSE funded,
2// was provided by J. Cho.
3// And modified to fit sansmodels/sansview: JC
4
5#include <math.h>
6#include "libmultifunc/librefl.h"
7#include <stdio.h>
8#include <stdlib.h>
9#if defined(_MSC_VER)
10#include "winFuncs.h"
11#endif
12
13complex cassign(real, imag)
14        double real, imag;
15{
16        complex x;
17        x.re = real;
18        x.im = imag;
19        return x;
20}
21
22
23complex cplx_add(x,y)
24        complex x,y;
25{
26        complex z;
27        z.re = x.re + y.re;
28        z.im = x.im + y.im;
29        return z;
30}
31
32complex rcmult(x,y)
33        double x;
34    complex y;
35{
36        complex z;
37        z.re = x*y.re;
38        z.im = x*y.im;
39        return z;
40}
41
42complex cplx_sub(x,y)
43        complex x,y;
44{
45        complex z;
46        z.re = x.re - y.re;
47        z.im = x.im - y.im;
48        return z;
49}
50
51
52complex cplx_mult(x,y)
53        complex x,y;
54{
55        complex z;
56        z.re = x.re*y.re - x.im*y.im;
57        z.im = x.re*y.im + x.im*y.re;
58        return z;
59}
60
61complex cplx_div(x,y)
62        complex x,y;
63{
64        complex z;
65        z.re = (x.re*y.re + x.im*y.im)/(y.re*y.re + y.im*y.im);
66        z.im = (x.im*y.re - x.re*y.im)/(y.re*y.re + y.im*y.im);
67        return z;
68}
69
70complex cplx_exp(b)
71        complex b;
72{
73        complex z;
74        double br,bi;
75        br=b.re;
76        bi=b.im;
77        z.re = exp(br)*cos(bi);
78        z.im = exp(br)*sin(bi);
79        return z;
80}
81
82
83complex cplx_sqrt(z)    //see Schaum`s Math Handbook p. 22, 6.6 and 6.10
84        complex z;
85{
86        complex c;
87        double zr,zi,x,y,r,w;
88
89        zr=z.re;
90        zi=z.im;
91
92        if (zr==0.0 && zi==0.0)
93        {
94    c.re=0.0;
95        c.im=0.0;
96    return c;
97        }
98        else
99        {
100                x=fabs(zr);
101                y=fabs(zi);
102                if (x>y)
103                {
104                        r=y/x;
105                        w=sqrt(x)*sqrt(0.5*(1.0+sqrt(1.0+r*r)));
106                }
107                else
108                {
109                        r=x/y;
110                        w=sqrt(y)*sqrt(0.5*(r+sqrt(1.0+r*r)));
111                }
112                if (zr >=0.0)
113                {
114                        c.re=w;
115                        c.im=zi/(2.0*w);
116                }
117                else
118                {
119                        c.im=(zi >= 0) ? w : -w;
120                        c.re=zi/(2.0*c.im);
121                }
122                return c;
123        }
124}
125
126complex cplx_cos(b)
127        complex b;
128{
129        complex zero,two,z,i,bi,negbi;
130        zero = cassign(0.0,0.0);
131        two = cassign(2.0,0.0);
132        i = cassign(0.0,1.0);
133        bi = cplx_mult(b,i);
134        negbi = cplx_sub(zero,bi);
135        z = cplx_div(cplx_add(cplx_exp(bi),cplx_exp(negbi)),two);
136        return z;
137}
138
139// normalized and modified erf
140//   |
141// 1 +                __  - - - -
142//   |             _
143//       |            _
144//   |        __
145// 0 + - - -
146//   |-------------+------------+--
147//   0           center       n_sub    --->
148//                                     ind
149//
150// n_sub = total no. of bins(or sublayers)
151// ind = x position: 0 to max
152// nu = max x to integration
153double err_mod_func(double n_sub, double ind, double nu)
154{
155  double center, func;
156  if (nu == 0.0)
157                nu = 1e-14;
158        if (n_sub == 0.0)
159                n_sub = 1.0;
160
161
162        //ind = (n_sub-1.0)/2.0-1.0 +ind;
163        center = n_sub/2.0;
164        // transform it so that min(ind) = 0
165        ind -= center;
166        // normalize by max limit
167        ind /= center;
168        // divide by sqrt(2) to get Gaussian func
169        nu /= sqrt(2.0);
170        ind *= nu;
171        // re-scale and normalize it so that max(erf)=1, min(erf)=0
172        func = erf(ind)/erf(nu)/2.0;
173        // shift it by +0.5 in y-direction so that min(erf) = 0
174        func += 0.5;
175
176        return func;
177}
178double linearfunc(double n_sub, double ind, double nu)
179{
180  double bin_size, func;
181        if (n_sub == 0.0)
182                n_sub = 1.0;
183
184        bin_size = 1.0/n_sub;  //size of each sub-layer
185        // rescale
186        ind *= bin_size;
187        func = ind;
188
189        return func;
190}
191// use the right hand side from the center of power func
192double power_r(double n_sub, double ind, double nu)
193{
194  double bin_size,func;
195        if (nu == 0.0)
196                nu = 1e-14;
197        if (n_sub == 0.0)
198                n_sub = 1.0;
199
200        bin_size = 1.0/n_sub;  //size of each sub-layer
201        // rescale
202        ind *= bin_size;
203        func = pow(ind, nu);
204
205        return func;
206}
207// use the left hand side from the center of power func
208double power_l(double n_sub, double ind, double nu)
209{
210  double bin_size, func;
211        if (nu == 0.0)
212                nu = 1e-14;
213        if (n_sub == 0.0)
214                n_sub = 1.0;
215
216        bin_size = 1.0/n_sub;  //size of each sub-layer
217        // rescale
218        ind *= bin_size;
219        func = 1.0-pow((1.0-ind),nu);
220
221        return func;
222}
223// use 1-exp func from x=0 to x=1
224double exp_r(double n_sub, double ind, double nu)
225{
226  double bin_size, func;
227        if (nu == 0.0)
228                nu = 1e-14;
229        if (n_sub == 0.0)
230                n_sub = 1.0;
231
232        bin_size = 1.0/n_sub;  //size of each sub-layer
233        // rescale
234        ind *= bin_size;
235        // modify func so that func(0) =0 and func(max)=1
236        func = 1.0-exp(-nu*ind);
237        // normalize by its max
238        func /= (1.0-exp(-nu));
239
240        return func;
241}
242
243// use the left hand side mirror image of exp func
244double exp_l(double n_sub, double ind, double nu)
245{
246  double bin_size, func;
247        if (nu == 0.0)
248                nu = 1e-14;
249        if (n_sub == 0.0)
250                n_sub = 1.0;
251
252        bin_size = 1.0/n_sub;  //size of each sub-layer
253        // rescale
254        ind *= bin_size;
255        // modify func
256        func = exp(-nu*(1.0-ind))-exp(-nu);
257        // normalize by its max
258        func /= (1.0-exp(-nu));
259
260        return func;
261}
262
263// To select function called
264// At nu = 0 (singular point), call line function
265double intersldfunc(int fun_type, double n_sub, double i, double nu, double sld_l, double sld_r)
266{
267        double sld_i, func;
268        // this condition protects an error from the singular point
269        if (nu == 0.0){
270                nu = 1e-13;
271        }
272        // select func
273        switch(fun_type){
274                case 1 :
275                        func = power_r(n_sub, i, nu);
276                        break;
277                case 2 :
278                        func = power_l(n_sub, i, nu);
279                        break;
280                case 3 :
281                        func = exp_r(n_sub, i, nu);
282                        break;
283                case 4 :
284                        func = exp_l(n_sub, i, nu);
285                        break;
286                case 5 :
287                        func = linearfunc(n_sub, i, nu);
288                        break;
289                default:
290                        func = err_mod_func(n_sub, i, nu);
291                        break;
292        }
293        // compute sld
294        if (sld_r>sld_l){
295                sld_i = (sld_r-sld_l)*func+sld_l; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
296        }
297        else if (sld_r<sld_l){
298                func = 1.0-func;
299                sld_i = (sld_l-sld_r)*func+sld_r; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
300        }
301        else{
302                sld_i = sld_r;
303        }
304        return sld_i;
305}
306
307
308// used by refl.c
309double interfunc(int fun_type, double n_sub, double i, double sld_l, double sld_r)
310{
311        double sld_i, func;
312        switch(fun_type){
313                case 0 :
314                        func = err_mod_func(n_sub, i, 2.5);
315                        break;
316                default:
317                        func = linearfunc(n_sub, i, 1.0);
318                        break;
319        }
320        if (sld_r>sld_l){
321                sld_i = (sld_r-sld_l)*func+sld_l; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
322        }
323        else if (sld_r<sld_l){
324                func = 1.0-func;
325                sld_i = (sld_l-sld_r)*func+sld_r; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
326        }
327        else{
328                sld_i = sld_r;
329        }
330        return sld_i;
331}
Note: See TracBrowser for help on using the repository browser.