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


def fig5_4():
    # global poly interpolation

    ### this requires the subaxis and parseArgs files

    a = -1
    b = 1
    nx = 12
    print(nx)
    xd = np.linspace(a, b, nx)

    # 5th degree poly
    yd4 = np.zeros(nx)
    for iy in range(nx):
        yd4[iy] = (
            (xd[iy] + 0.9)
            * (xd[iy] + 0.1) ** 2
            * (xd[iy] - 0.2)
            * (xd[iy] - 0.8)
        )

    # jump function
    yd1 = np.zeros(nx)
    for iy in range(nx):
        yd1[iy] = (-1) ** (iy + 1) * 0.02
    yd1[4] = 1
    yd1[5] = 1
    yd1[6] = 1
    yd1[7] = 1

    # oscillatory function
    yd2 = np.zeros(nx)
    for iy in range(nx):
        yd2[iy] = (-1) ** (iy + 1)

    # circle function
    yd3 = np.zeros(nx)
    for iy in range(nx):
        yd3[iy] = np.sqrt(1 - xd[iy] ** 2)

    n = 400
    xp = np.linspace(a, b, n)

    print(np.linalg.cond(np.vander(xd), np.inf))

    plt.close("all")
    # get(gcf)
    fig, axes = plt.subplots(2, 2, figsize=(8.8, 4.8))
    fig.subplots_adjust(left=0.09, right=0.98, bottom=0.13, top=0.99, wspace=0.18, hspace=0.18)
    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],
    ])
    for ax in axes.flat:
        ax.set_prop_cycle(cycler(color=co))

    # subplot(2,2,1)

    # global poly
    aa = np.linalg.inv(np.vander(xd)) @ yd1
    yl1 = np.zeros(n)
    for ii in range(n):
        yl1[ii] = aa[nx - 1]
        for ip in range(2, nx + 1):
            yl1[ii] = yl1[ii] + aa[nx - ip] * xp[ii] ** (ip - 1)

    ax = axes[0, 0]
    ax.plot(xd, yd1, "or", markersize=7, linewidth=2)
    ax.plot(xp, yl1, "-b", linewidth=1.4)
    ax.set_xlim(-1.1, 1.1)
    ax.set_ylim(-3, 1.2)
    ax.grid(True)
    ax.set_xlabel("x-axis")
    ax.tick_params(labelsize=12)

    # subplot(2,2,2)

    # global poly
    aa = np.linalg.inv(np.vander(xd)) @ yd2
    yl2 = np.zeros(n)
    for ii in range(n):
        yl2[ii] = aa[nx - 1]
        for ip in range(2, nx + 1):
            yl2[ii] = yl2[ii] + aa[nx - ip] * xp[ii] ** (ip - 1)

    ax = axes[0, 1]
    ax.plot(xd, yd2, "or", markersize=7, linewidth=2)
    ax.plot(xp, yl2, "-b", linewidth=1.4)
    ax.set_xlim(-1.1, 1.1)
    ax.set_ylim(-3, 3)
    ax.grid(True)
    ax.set_xlabel("x-axis")
    ax.set_ylabel("y-axis")
    ax.tick_params(labelsize=12)

    # subplot(2,2,3)

    # global poly
    aa = np.linalg.inv(np.vander(xd)) @ yd3
    yl3 = np.zeros(n)
    for ii in range(n):
        yl3[ii] = aa[nx - 1]
        for ip in range(2, nx + 1):
            yl3[ii] = yl3[ii] + aa[nx - ip] * xp[ii] ** (ip - 1)

    ax = axes[1, 0]
    ax.plot(xd, yd3, "or", markersize=7, linewidth=2)
    ax.plot(xp, yl3, "-b", linewidth=1.4)
    ax.set_xlim(-1.1, 1.1)
    ax.set_ylim(-0.1, 1.1)
    ax.set_yticks([0, 0.5, 1])
    ax.grid(True)
    ax.tick_params(labelsize=12)

    # subplot(2,2,4)

    # global poly
    aa = np.linalg.inv(np.vander(xd)) @ yd4
    yl4 = np.zeros(n)
    for ii in range(n):
        yl4[ii] = aa[nx - 1]
        for ip in range(2, nx + 1):
            yl4[ii] = yl4[ii] + aa[nx - ip] * xp[ii] ** (ip - 1)

    ax = axes[1, 1]
    ax.plot(xd, yd4, "or", markersize=7, linewidth=2)
    ax.plot(xp, yl4, "-b", linewidth=1.4)
    ax.set_xlim(-1.1, 1.1)
    ax.set_ylim(-0.2, 0.4)
    ax.set_yticks([-0.2, 0, 0.2, 0.4])
    ax.grid(True)
    ax.set_ylabel("y-axis")
    ax.tick_params(labelsize=12)

    for ax in axes.flat:
        for label in ax.get_xticklabels() + ax.get_yticklabels():
            label.set_fontweight("bold")
        for spine in ax.spines.values():
            spine.set_visible(True)

    plt.show()


if __name__ == "__main__":
    fig5_4()
