source: sasview/pr_inversion/c_extensions/invertor.c @ edce46e

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 edce46e was 2d06beb, checked in by Mathieu Doucet <doucetm@…>, 17 years ago

Use simple least-square fit

  • Property mode set to 100644
File size: 2.9 KB
Line 
1#include <math.h>
2#include "invertor.h"
3
4double pi = 3.1416;
5
6/**
7 * Deallocate memory
8 */
9void invertor_dealloc(Invertor_params *pars) {
10        free(pars->x);
11        free(pars->y);
12        free(pars->err);
13}
14
15void invertor_init(Invertor_params *pars) {
16        pars->d_max = 180;
17}
18
19
20/**
21 * P(r) of a sphere, for test purposes
22 *
23 * @param R: radius of the sphere
24 * @param r: distance, in the same units as the radius
25 * @return: P(r)
26 */
27double pr_sphere(double R, double r) {
28    if (r <= 2.0*R) {
29        return 12.0* pow(0.5*r/R, 2.0) * pow(1.0-0.5*r/R, 2.0) * ( 2.0 + 0.5*r/R );
30    } else {
31        return 0.0;
32    }
33}
34
35/**
36 * Orthogonal functions:
37 * B(r) = 2r sin(pi*nr/d)
38 *
39 */
40double ortho(double d_max, int n, double r) {
41        return 2.0*r*sin(pi*n*r/d_max);
42}
43
44/**
45 * Fourier transform of the nth orthogonal function
46 *
47 */
48double ortho_transformed(double d_max, int n, double q) {
49        return 8.0*pow(pi, 2.0)/q * d_max * n * pow(-1.0, n+1)
50                *sin(q*d_max) / ( pow(pi*n, 2.0) - pow(q*d_max, 2.0) );
51}
52
53/**
54 * First derivative in of the orthogonal function dB(r)/dr
55 *
56 */
57double ortho_derived(double d_max, int n, double r) {
58    return 2.0*sin(pi*n*r/d_max) + 2.0*r*cos(pi*n*r/d_max);
59}
60
61/**
62 * Scattering intensity calculated from the expansion.
63 */
64double iq(double *pars, double d_max, int n_c, double q) {
65    double sum = 0.0;
66        int i;
67    for (i=0; i<n_c; i++) {
68        sum += pars[i] * ortho_transformed(d_max, i+1, q);
69    }
70    return sum;
71}
72
73/**
74 * P(r) calculated from the expansion.
75 */
76double pr(double *pars, double d_max, int n_c, double r) {
77    double sum = 0.0; 
78        int i;
79    for (i=0; i<n_c; i++) {
80        sum += pars[i] * ortho(d_max, i+1, r);
81    }
82    return sum;
83}
84
85/**
86 * P(r) calculated from the expansion, with errors
87 */
88void pr_err(double *pars, double *err, double d_max, int n_c, 
89                double r, double *pr_value, double *pr_value_err) {
90    double sum = 0.0; 
91    double sum_err = 0.0;
92    double func_value;
93        int i;
94    for (i=0; i<n_c; i++) {
95        func_value = ortho(d_max, i+1, r);
96        sum += pars[i] * func_value;
97        sum_err += err[i]*err[i]*func_value*func_value;
98    }
99    *pr_value = sum;
100    if (sum_err>0) {
101        *pr_value_err = sqrt(sum_err);
102    } else {
103        *pr_value_err = sum;
104    }
105} 
106
107/**
108 * dP(r)/dr calculated from the expansion.
109 */
110double dprdr(double *pars, double d_max, int n_c, double r) {
111    double sum = 0.0; 
112        int i;
113    for (i=0; i<n_c; i++) {
114        sum += pars[i] * 2.0*(sin(pi*(i+1)*r/d_max) + pi*(i+1)*r/d_max * cos(pi*(i+1)*r/d_max));
115    }
116    return sum;
117}
118
119/**
120 * regularization term calculated from the expansion.
121 */
122double reg_term(double *pars, double d_max, int n_c) {
123    double sum = 0.0; 
124    double r;
125    double deriv;
126        int i;
127    for (i=0; i<25; i++) {
128        r = d_max/25.0*i;
129        deriv = dprdr(pars, d_max, n_c, r);
130        sum += deriv*deriv;
131    }
132    return sum/25.0*d_max;
133}
134
Note: See TracBrowser for help on using the repository browser.