source: sasview/sansmodels/src/sans/models/c_extensions/libmultifunc/librefl.c @ b9765ad

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 b9765ad was b9765ad, checked in by Mathieu Doucet <doucetm@…>, 12 years ago

Re #5 fixing librefl compilation on MSVC

  • 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 cadd(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 csub(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 cmult(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 cdiv(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 cexp(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 csqrt(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 ccos(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 = cmult(b,i);
134        negbi = csub(zero,bi);
135        z = cdiv(cadd(cexp(bi),cexp(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(n_sub, ind, nu)
154        double n_sub,nu, ind;
155{
156  double center, func;
157  if (nu == 0.0)
158                nu = 1e-14;
159        if (n_sub == 0.0)
160                n_sub = 1.0;
161
162
163        //ind = (n_sub-1.0)/2.0-1.0 +ind;
164        center = n_sub/2.0;
165        // transform it so that min(ind) = 0
166        ind -= center;
167        // normalize by max limit
168        ind /= center;
169        // divide by sqrt(2) to get Gaussian func
170        nu /= sqrt(2.0);
171        ind *= nu;
172        // re-scale and normalize it so that max(erf)=1, min(erf)=0
173        func = erf(ind)/erf(nu)/2.0;
174        // shift it by +0.5 in y-direction so that min(erf) = 0
175        func += 0.5;
176
177        return func;
178}
179double linearfunc(n_sub, ind, nu)
180        double n_sub,nu, ind;
181{
182  double bin_size, func;
183        if (n_sub == 0.0)
184                n_sub = 1.0;
185
186        bin_size = 1.0/n_sub;  //size of each sub-layer
187        // rescale
188        ind *= bin_size;
189        func = ind;
190
191        return func;
192}
193// use the right hand side from the center of power func
194double power_r(n_sub, ind, nu)
195        double n_sub, nu, ind;
196{
197  double bin_size,func;
198        if (nu == 0.0)
199                nu = 1e-14;
200        if (n_sub == 0.0)
201                n_sub = 1.0;
202
203        bin_size = 1.0/n_sub;  //size of each sub-layer
204        // rescale
205        ind *= bin_size;
206        func = pow(ind, nu);
207
208        return func;
209}
210// use the left hand side from the center of power func
211double power_l(n_sub, ind, nu)
212        double n_sub, nu, ind;
213{
214  double bin_size, func;
215        if (nu == 0.0)
216                nu = 1e-14;
217        if (n_sub == 0.0)
218                n_sub = 1.0;
219
220        bin_size = 1.0/n_sub;  //size of each sub-layer
221        // rescale
222        ind *= bin_size;
223        func = 1.0-pow((1.0-ind),nu);
224
225        return func;
226}
227// use 1-exp func from x=0 to x=1
228double exp_r(n_sub, ind, nu)
229        double n_sub, nu, ind;
230{
231  double bin_size, func;
232        if (nu == 0.0)
233                nu = 1e-14;
234        if (n_sub == 0.0)
235                n_sub = 1.0;
236
237        bin_size = 1.0/n_sub;  //size of each sub-layer
238        // rescale
239        ind *= bin_size;
240        // modify func so that func(0) =0 and func(max)=1
241        func = 1.0-exp(-nu*ind);
242        // normalize by its max
243        func /= (1.0-exp(-nu));
244
245        return func;
246}
247
248// use the left hand side mirror image of exp func
249double exp_l(n_sub, ind, nu)
250        double n_sub, nu, ind;
251{
252  double bin_size, func;
253        if (nu == 0.0)
254                nu = 1e-14;
255        if (n_sub == 0.0)
256                n_sub = 1.0;
257
258        bin_size = 1.0/n_sub;  //size of each sub-layer
259        // rescale
260        ind *= bin_size;
261        // modify func
262        func = exp(-nu*(1.0-ind))-exp(-nu);
263        // normalize by its max
264        func /= (1.0-exp(-nu));
265
266        return func;
267}
268
269// To select function called
270// At nu = 0 (singular point), call line function
271double intersldfunc(fun_type, n_sub, i, nu, sld_l, sld_r)
272        double n_sub, nu, sld_l, sld_r,i;
273        int fun_type;
274{
275        double sld_i, func;
276        // this condition protects an error from the singular point
277        if (nu == 0.0){
278                nu = 1e-13;
279        }
280        // select func
281        switch(fun_type){
282                case 1 :
283                        func = power_r(n_sub, i, nu);
284                        break;
285                case 2 :
286                        func = power_l(n_sub, i, nu);
287                        break;
288                case 3 :
289                        func = exp_r(n_sub, i, nu);
290                        break;
291                case 4 :
292                        func = exp_l(n_sub, i, nu);
293                        break;
294                case 5 :
295                        func = linearfunc(n_sub, i, nu);
296                        break;
297                default:
298                        func = err_mod_func(n_sub, i, nu);
299                        break;
300        }
301        // compute sld
302        if (sld_r>sld_l){
303                sld_i = (sld_r-sld_l)*func+sld_l; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
304        }
305        else if (sld_r<sld_l){
306                func = 1.0-func;
307                sld_i = (sld_l-sld_r)*func+sld_r; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
308        }
309        else{
310                sld_i = sld_r;
311        }
312        return sld_i;
313}
314
315
316// used by refl.c
317double interfunc(fun_type, n_sub, i, sld_l, sld_r)
318        double n_sub, sld_l, sld_r, i;
319        int fun_type;
320{
321        double sld_i, func;
322        switch(fun_type){
323                case 0 :
324                        func = err_mod_func(n_sub, i, 2.5);
325                        break;
326                default:
327                        func = linearfunc(n_sub, i, 1.0);
328                        break;
329        }
330        if (sld_r>sld_l){
331                sld_i = (sld_r-sld_l)*func+sld_l; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
332        }
333        else if (sld_r<sld_l){
334                func = 1.0-func;
335                sld_i = (sld_l-sld_r)*func+sld_r; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
336        }
337        else{
338                sld_i = sld_r;
339        }
340        return sld_i;
341}
Note: See TracBrowser for help on using the repository browser.