Blog Entry © Sunday, March 22, 2026, by James Pate Williams, Jr. Mueller’s Method

/*
* 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", &degree);

		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;
}

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:

  1. Bisection Method
  2. Brent’s Method
  3. Newton’s Method
  4. 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

rfa f 1

rfa f 2

bs 0bs 1br 1nm 1rf 1bs 2br 2nm 2rf 2bs 3br 3nm 3rf 3nm 0rf 0

The source code files are displayed below as Word files:

BisectionMethod – Copy

BrentsMethod – Copy.cs

MainForm – Copy.cs

NewtonsMethod – Copy.cs

RegulaFalsi – Copy.cs