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

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 ab6098f was 43c0a8e, checked in by Mathieu Doucet <doucetm@…>, 17 years ago

Add a couple of figures of merit

  • Property mode set to 100644
File size: 5.1 KB
Line 
1#include <math.h>
2#include "invertor.h"
3#include <memory.h>
4#include <stdio.h>
5#include <stdlib.h>
6
7double pi = 3.1416;
8
9/**
10 * Deallocate memory
11 */
12void invertor_dealloc(Invertor_params *pars) {
13        free(pars->x);
14        free(pars->y);
15        free(pars->err);
16}
17
18void invertor_init(Invertor_params *pars) {
19        pars->d_max = 180;
20        pars->q_min = -1.0;
21        pars->q_max = -1.0;
22}
23
24
25/**
26 * P(r) of a sphere, for test purposes
27 *
28 * @param R: radius of the sphere
29 * @param r: distance, in the same units as the radius
30 * @return: P(r)
31 */
32double pr_sphere(double R, double r) {
33    if (r <= 2.0*R) {
34        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 );
35    } else {
36        return 0.0;
37    }
38}
39
40/**
41 * Orthogonal functions:
42 * B(r) = 2r sin(pi*nr/d)
43 *
44 */
45double ortho(double d_max, int n, double r) {
46        return 2.0*r*sin(pi*n*r/d_max);
47}
48
49/**
50 * Fourier transform of the nth orthogonal function
51 *
52 */
53double ortho_transformed(double d_max, int n, double q) {
54        return 8.0*pow(pi, 2.0)/q * d_max * n * pow(-1.0, n+1)
55                *sin(q*d_max) / ( pow(pi*n, 2.0) - pow(q*d_max, 2.0) );
56}
57
58/**
59 * First derivative in of the orthogonal function dB(r)/dr
60 *
61 */
62double ortho_derived(double d_max, int n, double r) {
63    return 2.0*sin(pi*n*r/d_max) + 2.0*r*cos(pi*n*r/d_max);
64}
65
66/**
67 * Scattering intensity calculated from the expansion.
68 */
69double iq(double *pars, double d_max, int n_c, double q) {
70    double sum = 0.0;
71        int i;
72    for (i=0; i<n_c; i++) {
73        sum += pars[i] * ortho_transformed(d_max, i+1, q);
74    }
75    return sum;
76}
77
78/**
79 * P(r) calculated from the expansion.
80 */
81double pr(double *pars, double d_max, int n_c, double r) {
82    double sum = 0.0; 
83        int i;
84    for (i=0; i<n_c; i++) {
85        sum += pars[i] * ortho(d_max, i+1, r);
86    }
87    return sum;
88}
89
90/**
91 * P(r) calculated from the expansion, with errors
92 */
93void pr_err(double *pars, double *err, double d_max, int n_c, 
94                double r, double *pr_value, double *pr_value_err) {
95    double sum = 0.0; 
96    double sum_err = 0.0;
97    double func_value;
98        int i;
99    for (i=0; i<n_c; i++) {
100        func_value = ortho(d_max, i+1, r);
101        sum += pars[i] * func_value;
102        //sum_err += err[i]*err[i]*func_value*func_value;
103        sum_err += err[i*n_c+i]*func_value*func_value;
104    }
105    *pr_value = sum;
106    if (sum_err>0) {
107        *pr_value_err = sqrt(sum_err);
108    } else {
109        *pr_value_err = sum;
110    }
111} 
112
113/**
114 * dP(r)/dr calculated from the expansion.
115 */
116double dprdr(double *pars, double d_max, int n_c, double r) {
117    double sum = 0.0; 
118        int i; 
119    for (i=0; i<n_c; i++) {
120        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));
121    }
122    return sum;
123}
124
125/**
126 * regularization term calculated from the expansion.
127 */
128double reg_term(double *pars, double d_max, int n_c, int nslice) {
129    double sum = 0.0; 
130    double r;
131    double deriv;
132        int i;
133    for (i=0; i<nslice; i++) {
134        r = d_max/(1.0*nslice)*i;
135        deriv = dprdr(pars, d_max, n_c, r);
136        sum += deriv*deriv;
137    }
138    return sum/(1.0*nslice)*d_max;
139}
140
141/**
142 * regularization term calculated from the expansion.
143 */
144double int_p2(double *pars, double d_max, int n_c, int nslice) {
145    double sum = 0.0; 
146    double r; 
147    double value;
148        int i;
149    for (i=0; i<nslice; i++) {
150        r = d_max/(1.0*nslice)*i;
151        value = pr(pars, d_max, n_c, r);
152        sum += value*value;
153    }
154    return sum/(1.0*nslice)*d_max;
155}
156
157/**
158 * Get the number of P(r) peaks.
159 */
160int npeaks(double *pars, double d_max, int n_c, int nslice) {
161    double r; 
162    double value;
163        int i;
164        double previous = 0.0;
165        double slope    = 0.0;
166        int count = 0;
167    for (i=0; i<nslice; i++) {
168        r = d_max/(1.0*nslice)*i;
169        value = pr(pars, d_max, n_c, r);
170        if (previous<=value){
171                //if (slope<0) count += 1;
172                slope = 1;
173        } else {
174                //printf("slope -1");
175                if (slope>0) count += 1;
176                slope = -1;
177        }
178        previous = value;
179    }
180    return count;
181}
182
183/**
184 * Get the fraction of the integral of P(r) over the whole range
185 * of r that is above zero.
186 * A valid P(r) is define as being positive for all r.
187 */
188double positive_integral(double *pars, double d_max, int n_c, int nslice) {
189    double r; 
190    double value;
191        int i;
192        double sum_pos = 0.0;
193        double sum = 0.0;
194       
195    for (i=0; i<nslice; i++) {
196        r = d_max/(1.0*nslice)*i;
197        value = pr(pars, d_max, n_c, r);
198        if (value>0.0) sum_pos += value;
199        sum += value;
200    }
201    return sum_pos/sum;
202}
203
204/**
205 * Get the fraction of the integral of P(r) over the whole range
206 * of r that is at least one sigma above zero.
207 */
208double positive_errors(double *pars, double *err, double d_max, int n_c, int nslice) {
209    double r; 
210    double value;
211        int i; 
212        double sum_pos = 0.0;
213        double sum = 0.0;
214        double pr_val;
215        double pr_val_err;
216       
217    for (i=0; i<nslice; i++) {
218        r = d_max/(1.0*nslice)*i;
219        pr_err(pars, err, d_max, n_c, r, &pr_val, &pr_val_err);
220        if (pr_val>pr_val_err) sum_pos += pr_val;
221        sum += pr_val;
222       
223
224    }
225    return sum_pos/sum;
226}
Note: See TracBrowser for help on using the repository browser.