SDDSlib
Loading...
Searching...
No Matches
zeroInterp.c File Reference

Implements the zeroInterp function for finding zeros of a function using successive interpolation. More...

#include <math.h>
#include <stdio.h>
#include "mdb.h"

Go to the source code of this file.

Macros

#define sign(x)
 

Functions

double zeroInterp (double(*fn)(), double value, double x_i, double x_f, double dx, double _zero)
 Finds the zero of a function within a specified interval using successive interpolation.
 

Detailed Description

Implements the zeroInterp function for finding zeros of a function using successive interpolation.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday

Definition in file zeroInterp.c.

Macro Definition Documentation

◆ sign

#define sign ( x)
Value:
((x) > 0 ? 1 : ((x) == 0 ? 0 : -1))

Definition at line 20 of file zeroInterp.c.

Function Documentation

◆ zeroInterp()

double zeroInterp ( double(* fn )(),
double value,
double x_i,
double x_f,
double dx,
double _zero )

Finds the zero of a function within a specified interval using successive interpolation.

This function attempts to find a value x such that fn(x) is approximately equal to the given value. It uses an iterative interpolation method to locate the zero within the interval [x_i, x_f].

Parameters
fnPointer to the function for which the zero is to be found.
valueThe target value to solve for, i.e., find x such that fn(x) = value.
x_iInitial value of the independent variable (start of the interval).
x_fFinal value of the independent variable (end of the interval).
dxStep size to use when searching the interval.
_zeroAcceptable tolerance for the zero, determining when to stop the interpolation.
Returns
The x value where fn(x) is approximately equal to value, or x_f + dx if no zero is found within the interval.

Definition at line 37 of file zeroInterp.c.

44{
45 double xa, xb, xm, x_b;
46 double fa, fb, fm;
47 double f_abs, f_bdd;
48 long s_fa, s_fb, s_fm;
49
50 if (dx > (x_f - x_i))
51 dx = (x_f - x_i) / 2;
52
53 xa = x_i;
54 xb = xa + dx;
55
56 if (xb > x_f)
57 xb = x_f;
58 if (xa == xb)
59 xa = xb - dx;
60
61 fa = (*fn)(xa)-value;
62 s_fa = sign(fa);
63
64 while (xb <= x_f) {
65 fb = (*fn)(xb)-value;
66 s_fb = sign(fb);
67 if (s_fb == s_fa) {
68 fa = fb;
69 xa = xb;
70 s_fa = s_fb;
71 xb = xb + dx;
72 } else {
73 /* function has passed through zero */
74 /* so interpolate to find zero, repeat */
75 f_bdd = 1000 * fabs(fa);
76 xm = xa - fa * (xa - xb) / (fa - fb);
77 fm = (*fn)(xm)-value;
78 s_fm = sign(fm);
79 x_b = xb;
80 do {
81 if (s_fm == 0)
82 return (xm);
83 else if (s_fm != s_fa) {
84 xb = xm;
85 fb = fm;
86 s_fb = s_fm;
87 } else {
88 xa = xm;
89 fa = fm;
90 s_fa = s_fm;
91 }
92 xm = xa - fa * (xa - xb) / (fa - fb);
93 fm = (*fn)(xm)-value;
94 s_fm = sign(fm);
95 f_abs = fabs(fm);
96 } while (f_abs > _zero && f_abs < f_bdd);
97 if (f_abs < _zero)
98 return (xm);
99 /* Function had a tan(x)-like singularity, which
100 * looked like a zero. So step beyond singularity
101 * and continue search.
102 */
103 return (zeroInterp(fn, value, x_b, x_f, dx, _zero));
104 }
105 }
106 return (x_f + dx);
107}
double zeroInterp(double(*fn)(), double value, double x_i, double x_f, double dx, double _zero)
Finds the zero of a function within a specified interval using successive interpolation.
Definition zeroInterp.c:37