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


def fig5_23():
    a = 0
    b = 3
    nx = 100
    x = np.linspace(a, b, nx)

    f = np.zeros(nx)
    f2 = np.zeros(nx)
    f4 = np.zeros(nx)
    for ix in range(nx):
        f[ix] = np.exp(np.sin(x[ix])) / (5 + x[ix])
        f2[ix] = d2f(x[ix])
        f4[ix] = d4f(x[ix])

    m2 = np.max(np.abs(f2))
    m4 = np.max(np.abs(f4))
    f2 = 1.9 * f2 / m2
    f4 = 2.9 * f4 / m4

    plt.close("all")
    # get(gcf)
    fig, ax = plt.subplots(figsize=(9.0, 3.2))
    fig.subplots_adjust(left=0.05, right=0.98, bottom=0.22, top=0.97)
    co = np.array([
        [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],
    ])
    ax.set_prop_cycle(cycler(color=co))

    ax.plot(x, f2, "--b", linewidth=1.5)
    ax.plot(x, f4, "r", linewidth=1.5)
    # ax.set_yticks([0, 200, 400, 600])
    # ax.set_xticks([0, 0.1, 0.2, 0.3, 0.4])
    ax.set_xlim(0, 3)
    ax.set_ylim(-2, 3)
    ax.grid(True)
    ax.set_xlabel("x-axis")
    # ax.set_ylabel("y-axis")
    ax.tick_params(labelsize=14)
    for label in ax.get_xticklabels() + ax.get_yticklabels():
        label.set_fontweight("bold")
    ax.legend(
        [r" $f^{\prime\prime}$", r" $f^{\prime\prime\prime\prime}$"],
        loc="upper right",
        prop={"size": 14, "weight": "bold"},
    )
    for spine in ax.spines.values():
        spine.set_visible(True)
    plt.show()

    # plt.savefig('/Users/mark/Desktop/hwex2.eps')


def d2f(x):
    z = (
        -4 * np.sin(2 * x) * np.exp(np.sin(2 * x)) / (4 + x)
        + 4 * np.cos(2 * x) ** 2 * np.exp(np.sin(2 * x)) / (4 + x)
        - 4 * np.cos(2 * x) * np.exp(np.sin(2 * x)) / (4 + x) ** 2
        + 2 * np.exp(np.sin(2 * x)) / (4 + x) ** 3
    )
    return z


def d4f(x):
    z = (
        16 * np.sin(2 * x) * np.exp(np.sin(2 * x)) / (4 + x)
        - 64 * np.cos(2 * x) ** 2 * np.exp(np.sin(2 * x)) / (4 + x)
        + 32 * np.cos(2 * x) * np.exp(np.sin(2 * x)) / (4 + x) ** 2
        + 48 * np.sin(2 * x) ** 2 * np.exp(np.sin(2 * x)) / (4 + x)
        - 96 * np.sin(2 * x) * np.cos(2 * x) ** 2 * np.exp(np.sin(2 * x)) / (4 + x)
        + 96 * np.sin(2 * x) * np.cos(2 * x) * np.exp(np.sin(2 * x)) / (4 + x) ** 2
        - 48 * np.sin(2 * x) * np.exp(np.sin(2 * x)) / (4 + x) ** 3
        + 16 * np.cos(2 * x) ** 4 * np.exp(np.sin(2 * x)) / (4 + x)
        - 32 * np.cos(2 * x) ** 3 * np.exp(np.sin(2 * x)) / (4 + x) ** 2
        + 48 * np.cos(2 * x) ** 2 * np.exp(np.sin(2 * x)) / (4 + x) ** 3
        - 48 * np.cos(2 * x) * np.exp(np.sin(2 * x)) / (4 + x) ** 4
        + 24 * np.exp(np.sin(2 * x)) / (4 + x) ** 5
    )
    return z


if __name__ == "__main__":
    fig5_23()
