import numpy as np
import matplotlib.pyplot as plt
from cycler import cycler


def table2_2():
    #  included figure 2.4

    #  Input:
    # a = left endpoint of interval
    # b = right endpoint of interval
    # tol = tolerance for stopping bisection method
    # f(x) This is at end of file

    a = -1.5
    b = 2.5

    mid = 0.5 * (a + b)
    tol = 10 ** (-6)
    err = 10 * tol
    sol = 2.1

    # bisection procedure
    it = 0
    E = []
    ER = []
    print("\n RIE = relative iterative error \n")
    print(" k \t\t x_k  \t \t Error \t\t RIE ")
    while err > tol:
        old = mid
        fmid = f(mid)
        if f(a) * fmid < 0:
            b = mid
        elif f(b) * fmid < 0:
            a = mid
        else:
            break
        mid = 0.5 * (a + b)
        it = it + 1
        err = abs((mid - old) / mid)
        E.append(abs(mid - sol))
        ER.append(err)
        print(f" {it:d} \t {mid:19.15f} \t {E[it - 1]:5.1e} \t {err:5.1e}")
        # print(f'\\, {it:d} \\, & \\,\\, {mid:19.15f} \\,\\, & \\,\\, {E[it-1]:5.1e} \\,\\, & \\,\\, {err:5.1e} \\\\\\hline')
    print()

    plt.close("all")
    # get(gcf)
    fig, ax = plt.subplots(
        figsize=(658 / 100, 230 / 100), dpi=100, constrained_layout=True
    )
    co = [
        (0, 0, 1),
        (0, 0.5, 0),
        (1, 0, 0),
        (0, 0.75, 0.75),
        (0.75, 0, 0.75),
        (0.75, 0.75, 0),
        (0.25, 0.25, 0.25),
    ]
    plt.rcParams["axes.prop_cycle"] = cycler(color=co)

    # plot error
    steps = np.arange(1, it + 1)
    ax.semilogy(steps, E, "--or", linewidth=1.6, markersize=7)
    ax.semilogy(steps, ER, "--ob", linewidth=1.6, markersize=7)
    legend = ax.legend(
        [" Error", " Relative Iterative Error"],
        loc="upper right",
        fontsize=12,
        prop={"weight": "bold", "size": 12},
    )
    ax.axis([0, 20, 1e-7, 1])
    ax.set_yticks([1e-6, 1e-3, 1])
    ax.set_xlabel("Iteration Step")
    ax.set_ylabel("Error")
    ax.grid(True)
    for spine in ax.spines.values():
        spine.set_visible(True)
    ax.tick_params(labelsize=12)
    for label in ax.get_xticklabels() + ax.get_yticklabels():
        label.set_fontweight("bold")
    ax.xaxis.label.set_fontsize(12)
    ax.yaxis.label.set_fontsize(12)
    ax.xaxis.label.set_fontweight("bold")
    ax.yaxis.label.set_fontweight("bold")

    # fig.savefig('/Users/mark/Desktop/exam21.eps')
    plt.show()


def f(x):
    g = (x - 0.1) * (x - 2.1) * (x + 1.1)
    # g=exp(-x)-(2+x);
    return g


if __name__ == "__main__":
    table2_2()
