/*
* MuellersMethod.c (c) Sunday, July 21, 2024 by
* James Pate Williams, Jr. BA, BS, MSwE, PhD
* Translated from the FORTRAN 77 source code
* found in "Elementary Numerical Analysis: An
* Algorithmic Approach" by S. D. Conte and Carl
* de Boor Originally coded in FORTRAN IV in 1982 then
* into C# in March 2015 Finished Tuesday,
* July 23, 2024 The complex division method is
* from "A Numerical Library in C for Scientists
* and Engineers" by H. T. Lau Chapter 1
*/
#include <complex.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
//#define DEBUG
static _Lcomplex HornersMethod(_Lcomplex coeff[], _Lcomplex z, int degree) {
int i = 0;
_Lcomplex c = coeff[degree];
for (i = degree; i >= 1; i--) {
_Lcomplex product = _LCmulcc(c, z);
c._Val[0] = product._Val[0] + coeff[i - 1]._Val[0];
c._Val[1] = product._Val[1] + coeff[i - 1]._Val[1];
}
#ifdef DEBUG
_Lcomplex sum = { 0 };
for (i = 0; i <= degree; i++) {
_Lcomplex term =
_LCmulcc(cpowl(z, _LCbuild(i, 0.0)), coeff[i]);
sum._Val[0] += term._Val[0];
sum._Val[1] += term._Val[1];
}
long double delta = fabsl(cabsl(c) - cabsl(sum));
if (delta > 1.0e-12)
exit(-5);
#endif
return c;
}
static void comdiv(
long double xr, long double xi,
long double yr, long double yi,
long double* zr, long double* zi)
{
long double h, d;
if (fabs(yi) < fabs(yr)) {
if (yi == 0.0) {
*zr = xr / yr;
*zi = xi / yr;
}
else {
h = yi / yr;
d = h * yi + yr;
*zr = (xr + h * xi) / d;
*zi = (xi - h * xr) / d;
}
}
else {
h = yr / yi;
d = h * yr + yi;
*zr = (xr * h + xi) / d;
*zi = (xi * h - xr) / d;
}
}
#ifdef DEBUG
static _Lcomplex MyComplexDivide(_Lcomplex numer, _Lcomplex denom) {
long double norm2 =
denom._Val[0] * denom._Val[0] +
denom._Val[1] * denom._Val[1];
_Lcomplex result = { 0 };
result._Val[0] = (
numer._Val[0] * denom._Val[0] +
numer._Val[1] * denom._Val[1]) / norm2;
result._Val[1] = (
numer._Val[1] * denom._Val[0] -
numer._Val[0] * denom._Val[1]) / norm2;
return result;
}
#endif
static _Lcomplex ComplexDivide(_Lcomplex numer, _Lcomplex denom) {
_Lcomplex result = { 0 };
comdiv(
numer._Val[0], numer._Val[1],
denom._Val[0], denom._Val[1],
&result._Val[0], &result._Val[1]);
#ifdef DEBUG
_Lcomplex myResult = MyComplexDivide(numer, denom);
long double delta = fabsl(cabsl(result) - cabsl(myResult));
if (delta > 1.0e-12)
exit(-6);
#endif
return result;
}
static int Deflate(
_Lcomplex coeff[], _Lcomplex zero,
_Lcomplex* fzero, _Lcomplex* fzrdfl,
_Lcomplex zeros[], int i, int* count,
int degree) {
_Lcomplex denom = { 0 };
(*count)++;
*fzero = HornersMethod(coeff, zero, degree);
*fzrdfl = *fzero;
if (i < 1)
return 0;
for (int j = 1; j <= i; j++) {
denom._Val[0] = zero._Val[0] - zeros[j - 1]._Val[0];
denom._Val[1] = zero._Val[1] - zeros[j - 1]._Val[1];
if (cabsl(denom) == 0.0) {
zeros[i] = _LCmulcr(zero, 1.001);
return 1;
}
else
*fzrdfl = ComplexDivide(*fzrdfl, denom);
}
return 0;
}
static void Mueller(
_Lcomplex coeff[], _Lcomplex zeros[],
double epsilon1, double epsilon2,
int degree, int fnreal, int maxIts, int n, int nPrev) {
double eps1 = max(epsilon1, 1.0e-12);
double eps2 = max(epsilon2, 1.0e-20);
int count = 0, i = 0;
_Lcomplex c = { 0 };
_Lcomplex denom = { 0 };
_Lcomplex divdf1 = { 0 };
_Lcomplex divdf2 = { 0 };
_Lcomplex divdf1p = { 0 };
_Lcomplex fzero = { 0 };
_Lcomplex fzr = { 0 };
_Lcomplex fzdfl = { 0 };
_Lcomplex fzrdfl = { 0 };
_Lcomplex fzrprv = { 0 };
_Lcomplex four = _LCbuild(4.0, 0.0);
_Lcomplex h = { 0 };
_Lcomplex hprev = { 0 };
_Lcomplex sqr = { 0 };
_Lcomplex zero = { 0 };
_Lcomplex p5 = _LCbuild(0.5, 0.0);
_Lcomplex zeropp5 = { 0 };
_Lcomplex zeromp5 = { 0 };
_Lcomplex diff = { 0 };
_Lcomplex tadd = { 0 };
_Lcomplex tmul = { 0 };
_Lcomplex umul = { 0 };
_Lcomplex vmul = { 0 };
for (i = nPrev; i < n; i++) {
count = 0;
Label1:
zero = zeros[i];
h = p5;
zeropp5._Val[0] = zero._Val[0] + p5._Val[0];
zeropp5._Val[1] = zero._Val[1] + p5._Val[1];
if (Deflate(
coeff, zeropp5, &fzr, &divdf1p,
zeros, i, &count, degree))
goto Label1;
zeromp5._Val[0] = zero._Val[0] - p5._Val[0];
zeromp5._Val[1] = zero._Val[1] - p5._Val[1];
if (Deflate(
coeff, zeromp5, &fzr, &fzrprv,
zeros, i, &count, degree))
goto Label1;
hprev._Val[0] = -1.0;
hprev._Val[1] = 0.0;
diff._Val[0] = fzrprv._Val[0] - divdf1p._Val[0];
diff._Val[1] = fzrprv._Val[1] - divdf1p._Val[1];
if (cabsl(hprev) == 0)
exit(-2);
divdf1p = ComplexDivide(diff, hprev);
if (Deflate(
coeff, zero, &fzr, &fzrdfl,
zeros, i, &count, degree))
goto Label1;
Label2:
diff._Val[0] = fzrdfl._Val[0] - fzrprv._Val[0];
diff._Val[1] = fzrdfl._Val[1] - fzrprv._Val[1];
if (cabsl(h) == 0)
exit(-3);
divdf1 = ComplexDivide(diff, h);
diff._Val[0] = divdf1._Val[0] - divdf1p._Val[0];
diff._Val[1] = divdf1._Val[1] - divdf1p._Val[1];
tadd._Val[0] = h._Val[0] + hprev._Val[0];
tadd._Val[1] = h._Val[1] + hprev._Val[1];
if (cabsl(tadd) == 0)
exit(-3);
divdf2 = ComplexDivide(diff, tadd);
hprev = h;
divdf1p = divdf1;
tmul = _LCmulcc(h, divdf2);
c._Val[0] = divdf1._Val[0] + tmul._Val[0];
c._Val[1] = divdf1._Val[1] + tmul._Val[1];
tmul = _LCmulcc(c, c);
umul = _LCmulcc(four, fzrdfl);
vmul = _LCmulcc(umul, divdf2);
sqr._Val[0] = tmul._Val[0] - vmul._Val[0];
sqr._Val[1] = tmul._Val[1] - vmul._Val[1];
if (fnreal && sqr._Val[0] < 0.0)
{
sqr._Val[0] = 0.0;
sqr._Val[1] = 0.0;
}
sqr = csqrtl(sqr);
if ((c._Val[0] * sqr._Val[0] + c._Val[1] * sqr._Val[1]) < 0.0) {
denom._Val[0] = c._Val[0] - sqr._Val[0];
denom._Val[1] = c._Val[1] - sqr._Val[1];
}
else {
denom._Val[0] = c._Val[0] + sqr._Val[0];
denom._Val[1] = c._Val[1] + sqr._Val[1];
}
if (cabsl(denom) <= 0.0)
{
denom._Val[0] = 1.0;
denom._Val[1] = 0.0;
}
if (cabsl(denom) == 0)
exit(-4);
tmul = _LCmulcr(fzrdfl, -2.0);
h = ComplexDivide(tmul, denom);
fzrprv = fzrdfl;
zero._Val[0] = zero._Val[0] + h._Val[0];
zero._Val[1] = zero._Val[1] + h._Val[1];
if (count > maxIts)
goto Label4;
Label3:
if (Deflate(
coeff, zero, &fzr, &fzrdfl,
zeros, i, &count, degree))
goto Label1;
if (cabsl(h) < eps1 * cabsl(zero))
goto Label4;
if (max(cabsl(fzr), cabsl(fzdfl)) < eps2)
goto Label4;
if (cabsl(fzrdfl) >= 10.0 * cabsl(fzrprv)) {
h = _LCmulcr(h, 0.5);
zero._Val[0] = zero._Val[0] - h._Val[0];
zero._Val[1] = zero._Val[1] - h._Val[1];
goto Label3;
}
else
goto Label2;
Label4:
zeros[i] = zero;
}
}
int main(void)
{
double epsilon1 = 1.0e-15;
double epsilon2 = 1.0e-15;
int degree = 0, fnreal = 0, i = 0, maxIts = 1000;
int n = 0, nPrev = 0;
while (1) {
_Lcomplex* coeff = NULL;
_Lcomplex* zeros = NULL;
printf_s("Degree (0 to quit) = ");
scanf_s("%d", °ree);
if (degree == 0)
break;
n = degree;
coeff = calloc(degree + 1, sizeof(_Lcomplex));
if (coeff == NULL)
exit(-1);
zeros = calloc(n, sizeof(_Lcomplex));
if (zeros == NULL)
exit(-1);
for (i = degree; i >= 0; i--) {
printf_s("coefficient[%d].real = ", i);
scanf_s("%Lf", &coeff[i]._Val[0]);
printf_s("coefficient[%d].imag = ", i);
scanf_s("%Lf", &coeff[i]._Val[1]);
}
Mueller(
coeff, zeros, epsilon1,
epsilon2, degree, fnreal,
maxIts, n, nPrev);
printf_s("\n");
for (i = 0; i < degree; i++) {
printf_s("zero[%d].real = %17.10e\t", i, zeros[i]._Val[0]);
printf_s("zero[%d].imag = %17.10e\n", i, zeros[i]._Val[1]);
}
printf_s("\n");
for (i = 0; i < degree; i++) {
_Lcomplex func = HornersMethod(coeff, zeros[i], degree);
printf_s("func[%d].real = %17.10e\t", i, func._Val[0]);
printf_s("func[%d].imag = %17.10e\n", i, func._Val[1]);
}
printf_s("\n");
free(coeff);
free(zeros);
}
return 0;
}
Category: Root Finding Algorithms
Blog Entry (c) Wednesday, July 30, 2025, by James Pate Williams, Jr. Four Root Finding Algorithms and C Source
function exp(-x) - sin(0.5 * pi * x)
The interval found by bisection is:
a = +0.4435735341 b = +0.4435735341
bisection # iterations = 50
The root by regula falsi:
x = +0.4435735341 f(x) = -0.0000000000
regula falsi # iterations = 8
The root by the secant method:
x = +0.4435735341 f(x) = +0.0000000000
secant method # iterations = 9
The root by Newton's Method:
x = +0.4435735341 f(x) = -0.0000000000
Newton's Method # iterations = 6
D:\roots\x64\Release\roots.exe (process 28152) exited with code 0 (0x0).
Press any key to close this window . . .
#include <math.h>
#include <stdio.h>
typedef double real;
static real f(real x)
{
double pi2 = 2.0 * atan(1.0);
return(exp(-x) - sin(pi2 * x));
}
static real g(real x)
{
double pi2 = 2.0 * atan(1.0);
return(-exp(-x) - pi2 * cos(pi2 * x));
}
static int bisection(
real(*f)(real), real* a, real* b, real xtol, int* flag)
{
real error, fa, fm, xm;
int n = 0;
fa = (*f)(*a);
if (fa * (*f)(*b) > 0.0)
{
*flag = -1;
return(n);
}
error = fabsl(*b - *a);
while (error > xtol)
{
n++;
error *= 0.5;
if (error <= xtol)
{
*flag = 0;
return(n);
}
xm = 0.5 * (*a + *b);
if (xm + error == xm)
{
*flag = 1;
return(n);
}
fm = (*f)(xm);
if (fa * fm > 0.0)
{
*a = xm;
fa = fm;
}
else
*b = xm;
}
*flag = 2;
return(n);
}
static int regula(
real (*f)(real), real a, real b, real xtol,
real ftol, int ntol, real* w, int* flag)
{
int n = 0;
real fa, fb, fw, signfa, prvsfw;
fa = f(a);
if (fa >= 0.0) signfa = +1.0; else signfa = -1.0;
fb = f(b);
if (signfa * fb >= 0.0)
{
*flag = -1;
return n;
}
*w = a;
fw = fa;
for (n = 0; n <= ntol; n++)
{
if (fabs(a - b) <= xtol)
{
*flag = 0;
return n;
}
if (fabs(fw) <= ftol)
{
*flag = 1;
return n;
}
*w = (fa * b - fb * a) / (fa - fb);
if (fw >= 0.0) prvsfw = +1.0; else prvsfw = -1.0;
fw = f(*w);
if (signfa * fw > 0.0)
{
a = *w;
fa = fw;
if (fw * prvsfw > 0.0) fb = 0.5 * fb;
}
else
{
b = *w;
fb = fw;
if (fw * prvsfw > 0.0) fa = 0.5 * fa;
}
}
*flag = 2;
return n;
}
static int secantMethod(
real(*f)(real), real xtol, real ftol,
int ntol, real xm1, real x0, real* w)
{
real fm1 = f(xm1), f0 = f(x0);
real df = fabs(fm1 - f0), f1 = 0.0;
real dx = fabs(xm1 - x0), x1 = 0.0;
int n = 0;
while (n < ntol && df > ftol && dx > xtol)
{
x1 = (f0 * xm1 - fm1 * x0) / (f0 - fm1);
f1 = f(x1);
df = fabs(f(x1) - f0);
dx = fabs(x1 - x0);
fm1 = f0;
f0 = f1;
xm1 = x0;
x0 = x1;
n++;
}
*w = x1;
return n;
}
static int NewtonsMethod(
real(*f)(real), real(*g)(real),
real xtol, real ftol, int ntol,
real* w)
{
// f is the function
// g is the function's derivative
// xtol is root's tolerance
// ftol is the function's tolerance
// ntol is the maximum # of iterations
real f1 = 0.0, g1 = 0.0, x0 = *w, x1 = 0.0;
real f0 = f(x0), g0 = g(x0);
real deltaX = DBL_MAX, deltaF = DBL_MAX;
int n = 0;
while (n < ntol && deltaX > xtol && deltaF > ftol)
{
x1 = x0 - f0 / g0;
f1 = f(x1);
g1 = g(x1);
deltaX = fabs(x1 - x0);
deltaF = fabs(f1 - f0);
f0 = f1;
g0 = g1;
x0 = x1;
n++;
}
*w = x1;
return n;
}
int main(void)
{
int flag = 0, ntol = 0;
real a0 = 0, b0 = 0, ftol = 0, w1 = 0, w2 = 1.0;
real a1 = 0, b1 = 0, w3 = 0, xtol = 0;
a0 = 0.0;
b0 = 1.0;
ntol = 128;
ftol = 1.0e-15;
xtol = 1.0e-15;
int its1 = bisection(f, &a0, &b0, xtol, &flag);
a1 = 0.0;
b1 = 1.0;
int its2 = regula(f, a1, b1, xtol, ftol, ntol, &w1, &flag);
int its3 = secantMethod(f, ftol, xtol, ntol, 0.0, 1.0, &w2);
int its4 = NewtonsMethod(f, g, xtol, ftol, ntol, &w3);
printf("function exp(-x) - sin(0.5 * pi * x)\n");
printf("The interval found by bisection is:\n");
printf("a = %+13.10lf b = %+13.10lf\n", a0, b0);
printf("bisection # iterations = %ld\n", its1);
printf("The root by regula falsi:\n");
printf("x = %+13.10lf f(x) = %+13.10lf\n", w1, f(w1));
printf("regula falsi # iterations = %ld\n", its2);
printf("The root by the secant method:\n");
printf("x = %+13.10lf f(x) = %+13.10lf\n", w2, f(w2));
printf("secant method # iterations = %ld\n", its3);
printf("The root by Newton's Method:\n");
printf("x = %+13.10lf f(x) = %+13.10lf\n", w2, f(w3));
printf("Newton's Method # iterations = %ld\n", its4);
return(0);
}
Blog Entry (c) Monday, January 2025, by James Pate Williams, Jr. nth Roots of a Real Number Using the Newton-Raphson Method Win32 C/C++ App
Blog Entry (c) Saturday August 31, 2024, by James Pate Williams, Jr. An Elementary School Problem Found Online
Solve for a real root of the equation
f(x)=log6l(5+x)+log6l(x)=0
First we test our log6l(x) function
log6l(12) = 1.386853
log6l(36) = 2.000000
x = 0.1925824036
f = 0.0000000000
Blog Entry Friday, June 14, 2024 (c) James Pate Williams, Jr.
For the last week or so I have been working my way through Chapter 3 The Solution of Nonlinear Equations found in the textbook “Numerical Analysis: An Algorithmic Approach” by S. D. Conte and Carl de Boor. I also used some C source code from “A Numerical Library in C for Scientists and Engineers” by H. T. Lau, PhD. I implemented twenty examples and exercises from the previously mentioned chapter.
Root Finding Algorithms by James Pate Williams, BA, BS, MSwE, PhD
We designed and implemented a C# application that uses the following root finding algorithms:
- Bisection Method
- Brent’s Method
- Newton’s Method
- Regula Falsi
https://en.wikipedia.org/wiki/Bisection_method
https://en.wikipedia.org/wiki/Brent%27s_method
https://en.wikipedia.org/wiki/Newton%27s_method
https://en.wikipedia.org/wiki/False_position_method

















The source code files are displayed below as Word files:
