SDDSlib
Loading...
Searching...
No Matches
GillMillerIntegration.c
Go to the documentation of this file.
1/**
2 * @file GillMillerIntegration.c
3 * @brief Provides the Gill-Miller integration method for numerical integration of functions.
4 *
5 * This file contains the implementation of the Gill-Miller integration algorithm,
6 * which integrates a function f(x) provided as arrays of x and f values.
7 * Based on P. E. Gill and G. F. Miller, The Computer Journal, Vol 15, No. 1, 80-83, 1972.
8 *
9 * @copyright
10 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
11 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
12 *
13 * @license
14 * This file is distributed under the terms of the Software License Agreement
15 * found in the file LICENSE included with this distribution.
16 *
17 * @author M. Borland, R. Soliday, N. Kuklev
18 */
19
20#include "mdb.h"
21
22/**
23 * @brief Performs numerical integration using the Gill-Miller method.
24 *
25 * This function integrates a set of data points representing a function f(x) using
26 * the Gill-Miller integration technique. The integration is performed based on the
27 * algorithm described by P. E. Gill and G. F. Miller in their 1972 publication.
28 *
29 * @param integral Pointer to an array where the computed integral values will be stored.
30 * @param error Pointer to an array where the estimated errors of the integral will be stored.
31 * This parameter can be NULL if error estimates are not required.
32 * @param f Pointer to an array of y-values representing the function f(x) to be integrated.
33 * @param x Pointer to an array of x-values corresponding to the function f(x).
34 * @param n The number of data points in the arrays x and f. Must be greater than 1.
35 *
36 * @return
37 * - 0 on successful integration.
38 * - 1 if any of the pointers integral, f, or x are NULL.
39 * - 2 if the number of data points n is less than or equal to 1.
40 * - 3 to 8 for various numerical errors encountered during the integration process.
41 */
42int GillMillerIntegration(double *integral, double *error,
43 double *f, double *x, long n) {
44 double e, de1, de2;
45 double h1 = 0, h2 = 0, h3 = 0, h4, r1, r2, r3, r4, d1 = 0, d2 = 0, d3 = 0, c, s, integ, dinteg1, dinteg2;
46 long i, k;
47
48 if (!integral || !f || !x)
49 return 1;
50 if (n <= 1)
51 return 2;
52
53 integ = e = s = c = r4 = 0;
54 n -= 1; /* for consistency with GM paper */
55
56 integral[0] = 0;
57 if (error)
58 error[0] = 0;
59
60 k = n - 1;
61 dinteg2 = 0;
62 de2 = 0;
63
64 for (i = 2; i <= k; i++) {
65 dinteg1 = 0;
66 if (i == 2) {
67 h2 = x[i - 1] - x[i - 2];
68 if (h2 == 0)
69 return 3;
70 d3 = (f[i - 1] - f[i - 2]) / h2;
71 h3 = x[i] - x[i - 1];
72 d1 = (f[i] - f[i - 1]) / h3;
73 h1 = h2 + h3;
74 if (h1 == 0)
75 return 4;
76 d2 = (d1 - d3) / h1;
77 h4 = x[i + 1] - x[i];
78 r1 = (f[i + 1] - f[i]) / h4;
79 if ((h4 + h3) == 0)
80 return 5;
81 r2 = (r1 - d1) / (h4 + h3);
82 h1 = h1 + h4;
83 if (h1 == 0)
84 return 6;
85 r3 = (r2 - d2) / h1;
86 integ = h2 * (f[0] + h2 * (d3 / 2.0 - h2 * (d2 / 6 - (h2 + 2 * h3) * r3 / 12)));
87 s = -ipow3(h2) * (h2 * (3 * h2 + 5 * h4) + 10 * h3 * h1) / 60.0;
88 integral[i - 1] = integ;
89 if (error)
90 error[i - 1] = 0;
91 } else {
92 h4 = x[i + 1] - x[i];
93 if (h4 == 0)
94 return 7;
95 r1 = (f[i + 1] - f[i]) / h4;
96 r4 = h4 + h3;
97 if (r4 == 0)
98 return 8;
99 r2 = (r1 - d1) / r4;
100 r4 = r4 + h2;
101 if (r4 == 0)
102 return 8;
103 r3 = (r2 - d2) / r4;
104 r4 = r4 + h1;
105 if (r4 == 0)
106 return 8;
107 r4 = (r3 - d3) / r4;
108 }
109
110 dinteg1 = h3 * ((f[i] + f[i - 1]) / 2 - h3 * h3 * (d2 + r2 + (h2 - h4) * r3) / 12.0);
111 c = ipow3(h3) * (2 * h3 * h3 + 5 * (h3 * (h4 + h2) + 2 * h4 * h2)) / 120;
112 de1 = (c + s) * r4;
113 s = (i == 2 ? 2 * c + s : c);
114
115 if (i == 2)
116 integral[i] = integ + dinteg1 + e + de1;
117 else
118 integral[i] = integ + dinteg2 + e + de2;
119 integ += dinteg1;
120
121 if (error) {
122 if (i == 2)
123 error[i] = e + de1;
124 else
125 error[i] = e + de2;
126 }
127 e += de1;
128
129 dinteg2 = h4 * (f[i + 1] - h4 * (r1 / 2 + h4 * (r2 / 6 + (2 * h3 + h4) * r3 / 12)));
130 de2 = s * r4 - ipow3(h4) * r4 * (h4 * (3 * h4 + 5 * h2) + 10 * h3 * (h2 + h3 + h4)) / 60;
131
132 if (i == k) {
133 integ += dinteg2;
134 e += de2;
135 } else {
136 h1 = h2;
137 h2 = h3;
138 h3 = h4;
139 d1 = r1;
140 d2 = r2;
141 d3 = r3;
142 }
143 }
144
145 integral[i] = integ + e;
146 if (error)
147 error[i] = e;
148
149 return 0;
150}
int GillMillerIntegration(double *integral, double *error, double *f, double *x, long n)
Performs numerical integration using the Gill-Miller method.