#include "nrutil.h"

#include "muller.h"
#include <math.h>

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