#include "nrutil.h" #include "rtmuller.h" #include float rtmuller(float (*func)(float), float x1, float x2, float xacc) { int j; float fh, fl, fm, fnew, s, xl, r, x3, x0, x_prev, x_curr, x_next; float d0, d1, d2, a, b, c; x0 = x1; x_prev = x2; x_curr = (x0 + x_prev) / 2.0; if (x_prev == x_curr) x_curr += xacc; if (x0 == x_curr) x0 -= xacc; for (j = 1; j <= 200; j++) { d0 = func(x0); d1 = func(x_prev); d2 = func(x_curr); float h1 = x_prev - x0; float h2 = x_curr - x_prev; float delta1 = (d1 - d0) / h1; float delta2 = (d2 - d1) / h2; a = (delta2 - delta1) / (h2 + h1); b = a * h2 + delta2; c = d2; float disc = b * b - 4 * a * c; if (disc < 0) nrerror("Muller's method: complex roots encountered"); float denom1 = b + sqrt(disc); float denom2 = b - sqrt(disc); if (fabs(denom1) < fabs(denom2)) { x_next = x_curr - (2 * c) / denom2; } else { x_next = x_curr - (2 * c) / denom1; } if (fabs(x_next - x_curr) < xacc) return x_next; x0 = x_prev; x_prev = x_curr; x_curr = x_next; } nrerror("Too many iterations in rtmuller"); return 0.0; }