SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
qromb.c File Reference

Detailed Description

Performs numerical integration using Romberg's method.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
H. Shang, R. Soliday

Definition in file qromb.c.

#include "mdb.h"

Go to the source code of this file.

Functions

double qromb (double(*func)(), long maxe, double a, double b, double eps)
 Computes the definite integral of a function using Romberg's method.
 

Function Documentation

◆ qromb()

double qromb ( double(* func )(),
long maxe,
double a,
double b,
double eps )

Computes the definite integral of a function using Romberg's method.

Estimates the integral of the function func over the interval $ [a, b] $ using Romberg's numerical integration technique, which applies Richardson extrapolation to the trapezoidal rule to achieve higher accuracy.

Parameters
funcPointer to the function to integrate. The function should accept a single double argument and return a double.
maxeMaximum number of extrapolation steps to perform.
aLower limit of integration.
bUpper limit of integration.
epsDesired accuracy (error tolerance) for the integral approximation.
Returns
The estimated value of the integral. Returns 0 if the maximum number of steps is exceeded without achieving the desired accuracy.

Definition at line 34 of file qromb.c.

37 {
38 double T, R, BB, S, H, S1, S0, err, result;
39 static long MAXE = 0;
40 static double *RM = NULL;
41 long K, K1, N, N0, N1, KK, KKK, K0, J, L, K2;
42
43 T = (b - a) * (func(a) + func(b)) * .5; /* initial trapzoid rule */
44 if (RM == NULL || maxe > MAXE) {
45 if (RM)
46 free(RM);
47 RM = malloc(sizeof(*RM) * (maxe + 2));
48 MAXE = maxe;
49 }
50 RM[1] = (b - a) * func((a + b) * 0.5);
51 N = 2;
52 R = 4.0;
53
54 for (K = 1; K <= maxe; K++) {
55 BB = (R * 0.5 - 1.0) / (R - 1.0);
56 /*improved trapzoid value */
57 T = RM[1] + BB * (T - RM[1]);
58 /* double number of subdivision of a and b */
59 N = 2 * N;
60 S = 0;
61 H = (b - a) / (N * 1.0);
62 /* calculate rectangle value */
63 if (N <= 32) {
64 N0 = N1 = N;
65 } else if (N <= 512) {
66 N0 = 32;
67 N1 = N;
68 } else {
69 N0 = 32;
70 N1 = 512;
71 }
72 for (K2 = 1; K2 <= N; K2 += 512) {
73 S1 = 0.0;
74 KK = K2 + N1 - 1;
75 for (K1 = K2; K1 <= KK; K1 += 32) {
76 S0 = 0.0;
77 KKK = K1 + N0 - 1;
78 for (K0 = K1; K0 <= KKK; K0 += 2)
79 S0 += func(a + K0 * H);
80 S1 += S0;
81 }
82 S += S1;
83 }
84 RM[K + 1] = 2.0 * H * S;
85 /* end of calculate rectangle value */
86 R = 4.0;
87 for (J = 1; J <= K; J++) {
88 L = K + 1 - J;
89 RM[L] = RM[L + 1] + (RM[L + 1] - RM[L]) / (R - 1.0);
90 R = 4.0 * R;
91 }
92 err = fabs(T - RM[1]) * 0.5;
93 if (err <= eps) {
94 K = 0;
95 result = (T + RM[1]) * 0.5;
96 N = N + 1;
97 return result;
98 }
99 }
100 fprintf(stderr, "too many qrom steps\n");
101 return 0;
102}