"""Literal Python conversion of fig3_4B.m."""

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


def _set_bold_ticks(ax, fontsize):
    ax.tick_params(labelsize=fontsize)
    for label in ax.get_xticklabels() + ax.get_yticklabels():
        label.set_fontweight("bold")


def fig3_4B():
    A = np.zeros((2, 2))
    A[0, 0] = 1
    A[0, 1] = -1
    A[1, 0] = -1
    A[1, 1] = 2
    k_inf = np.linalg.cond(A, np.inf)
    k_2 = np.linalg.cond(A, 2)
    print("k_inf =", k_inf)
    print("k_2 =", k_2)

    plt.close("all")
    # get(gcf)
    # MATLAB Position [26 909 867 436], scaled to fit the plot window.
    fig, axes = plt.subplots(1, 3, figsize=(11.0, 5.4))
    # subaxis spacing is represented by subplots_adjust.
    fig.subplots_adjust(top=0.97, bottom=0.16, right=0.98, left=0.07, wspace=0.22)
    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:
        ax.set_prop_cycle(cycler(color=co.tolist()))

    nt = 200
    th = np.linspace(0, 2 * np.pi, nt)
    x0 = np.zeros(nt)
    y0 = np.zeros(nt)
    for it in range(nt):
        x0[it] = np.cos(th[it])
        y0[it] = np.sin(th[it])

    # left ellipse
    ax = axes[0]

    A[1, 1] = 1.5
    AA = np.linalg.inv(A)
    k_inf = np.linalg.cond(A, np.inf)
    k_2 = np.linalg.cond(A, 2)
    print("k_inf =", k_inf)
    print("k_2 =", k_2)
    x1 = np.zeros(nt)
    y1 = np.zeros(nt)
    for it in range(nt):
        x1[it] = AA[0, 0] * x0[it] + AA[0, 1] * y0[it]
        y1[it] = AA[1, 0] * x0[it] + AA[1, 1] * y0[it]
    ax.plot(x1, y1, "b", linewidth=1.8)
    ax.set_aspect("equal", adjustable="box")
    ax.set_frame_on(True)
    ax.grid(True)
    ax.set_xlabel("x_1-axis", fontsize=17, fontweight="bold")
    ax.set_ylabel("x_2-axis", fontsize=17, fontweight="bold")
    xM = round(np.linalg.norm(x1, np.inf) - 0.5)
    yM = round(np.linalg.norm(y1, np.inf) + 0.5)
    print("xM =", xM)
    print("yM =", yM)
    ax.set_yticks([-yM, 0, yM], labels=["-3r", "0", "3r"])
    ax.set_xticks([-xM, 0, xM], labels=["-3r", "0", "3r"])
    xs = ax.get_xlim()
    ax.plot([xs[0], xs[1]], [0, 0], "k", linewidth=0.3)
    ys = ax.get_ylim()
    ax.plot([0, 0], [ys[0], ys[1]], "k", linewidth=0.3)
    say2 = r"$\kappa_\infty = 12$"
    say = "d = 1.5"
    yy = ax.get_ylim()
    xA = xM / 12
    yA = yy[0] * 0.8
    ax.text(xA, yA, say2, fontsize=18, fontweight="bold")
    ax.text(xA, yA * 0.8, say, fontsize=18, fontweight="bold")
    _set_bold_ticks(ax, 17)

    # fig.savefig('/Users/mark/Desktop/n1.eps')

    # middle ellipse
    ax = axes[1]
    A[1, 1] = 1.1
    AA = np.linalg.inv(A)
    k_inf = np.linalg.cond(A, np.inf)
    k_2 = np.linalg.cond(A, 2)
    print("k_inf =", k_inf)
    print("k_2 =", k_2)
    for it in range(nt):
        x1[it] = AA[0, 0] * x0[it] + AA[0, 1] * y0[it]
        y1[it] = AA[1, 0] * x0[it] + AA[1, 1] * y0[it]
    ax.plot(x1, y1, "b", linewidth=1.8)
    ax.set_aspect("equal", adjustable="box")
    xM = round(np.linalg.norm(x1, np.inf) - 0.5)
    yM = round(np.linalg.norm(y1, np.inf) + 0.5)
    ax.set_yticks([-yM, 0, yM], labels=["-15r", "0", "15r"])
    ax.set_xlim([-15, 15])
    xs = ax.get_xlim()
    ax.plot([xs[0], xs[1]], [0, 0], "k", linewidth=0.3)
    ys = ax.get_ylim()
    ax.plot([0, 0], [ys[0], ys[1]], "k", linewidth=0.3)
    ax.set_xticks([-15, 0, 15], labels=["-15r", "0", "15r"])
    ax.set_frame_on(True)
    ax.grid(True)
    ax.set_xlabel("x_1-axis", fontsize=17, fontweight="bold")
    say2 = r"$\kappa_\infty = 44$"
    say = "d = 1.1"
    yy = ax.get_ylim()
    xA = xM / 12
    yA = yy[0] * 0.8
    ax.text(xA, yA, say2, fontsize=18, fontweight="bold")
    ax.text(xA, yA * 0.8, say, fontsize=18, fontweight="bold")
    _set_bold_ticks(ax, 17)

    # fig.savefig('/Users/mark/Desktop/n2.eps')

    # right ellipse
    ax = axes[2]
    A[1, 1] = 1 + 1 / 20
    AA = np.linalg.inv(A)
    k_inf = np.linalg.cond(A, np.inf)
    k_2 = np.linalg.cond(A, 2)
    print("k_inf =", k_inf)
    print("k_2 =", k_2)
    for it in range(nt):
        x1[it] = AA[0, 0] * x0[it] + AA[0, 1] * y0[it]
        y1[it] = AA[1, 0] * x0[it] + AA[1, 1] * y0[it]
    ax.plot(x1, y1, "b", linewidth=1.8)
    ax.set_aspect("equal", adjustable="box")
    ax.set_frame_on(True)
    ax.grid(True)
    ax.set_xlabel("x_1-axis", fontsize=17, fontweight="bold")
    xM = round(np.linalg.norm(x1, np.inf) - 0.5)
    yM = round(np.linalg.norm(y1, np.inf) + 0.5)
    xs = ax.get_xlim()
    ax.plot([xs[0], xs[1]], [0, 0], "k", linewidth=0.3)
    ys = ax.get_ylim()
    ax.plot([0, 0], [ys[0], ys[1]], "k", linewidth=0.3)
    ax.set_yticks([-30, 0, 30], labels=["-30r", "0", "30r"])
    ax.set_xlim([-30, 30])
    ax.set_xticks([-30, 0, 30], labels=["-30r", "0", "30r"])
    say2 = r"$\kappa_\infty = 82$"
    say = "d = 1.05"
    yy = ax.get_ylim()
    xA = xM / 12
    yA = yy[0] * 0.8
    ax.text(xA, yA, say2, fontsize=18, fontweight="bold")
    ax.text(xA, yA * 0.8, say, fontsize=18, fontweight="bold")
    _set_bold_ticks(ax, 17)

    plt.show()
    return fig, axes

    # fig.savefig('/Users/mark/Desktop/nn.eps')
    # fig.savefig('/Users/holmes/Desktop/nn.eps')


if __name__ == "__main__":
    fig3_4B()
