"""Literal Python conversion of fig8_14.m."""

import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import minimize


def E(v):
    nd = 6
    xd = np.zeros(nd)
    yd = np.zeros(nd)
    xd[0] = 0.1; xd[1] = 0.5; xd[2] = 1; xd[3] = 2; xd[4] = 5; xd[5] = 10
    yd[0] = 0.5; yd[1] = 1.8; yd[2] = 3.4; yd[3] = 6.1; yd[4] = 8.7; yd[5] = 11.1
    s = 0
    for i in range(nd):
        s = s + (v[0] * xd[i] / (v[1] + xd[i]) - yd[i]) ** 2
    return s


def fig8_14():
    #  data for regression
    nd = 6
    xd = np.zeros(nd)
    yd = np.zeros(nd)
    xd[0] = 0.1; xd[1] = 0.5; xd[2] = 1; xd[3] = 2; xd[4] = 5; xd[5] = 10
    yd[0] = 0.5; yd[1] = 1.8; yd[2] = 3.4; yd[3] = 6.1; yd[4] = 8.7; yd[5] = 11.1

    ######  find the min for original using nonlinear regression
    v2 = 1; v1 = 14 * v2
    result = minimize(
        E,
        [v1, v2],
        method="Nelder-Mead",
        options={"maxfev": 1_000_000, "maxiter": 1_000_000, "xatol": 1e-6},
    )
    sol = result.x
    v1 = sol[0]
    v2 = sol[1]
    print(f"v1 = {v1}")
    print(f"v2 = {v2}")
    x = np.linspace(0, 10, 100)
    y = np.zeros(100)
    for i in range(100):
        y[i] = v1 * x[i] / (v2 + x[i])

    ######  find min using linear regression (non relative error)
    A = 0; B = 0; R1 = 0; R2 = 0
    XD = np.zeros(nd)
    YD = np.zeros(nd)
    for i in range(nd):
        XD[i] = 1 / xd[i]
        YD[i] = 1 / yd[i]
        A = A + XD[i] ** 2
        B = B + XD[i]
        R1 = R1 + YD[i]
        R2 = R2 + XD[i] * YD[i]
    V1 = (A * R1 - B * R2) / (nd * A - B ** 2)
    V2 = (-B * R1 + nd * R2) / (nd * A - B ** 2)
    vv1 = 1 / V1
    vv2 = vv1 * V2
    print(f"vv1 = {vv1}")
    print(f"vv2 = {vv2}")
    yy = np.zeros(100)
    for i in range(100):
        yy[i] = vv1 * x[i] / (vv2 + x[i])
    # compute error magnifying factor at x=10
    gy = vv1 * xd[nd - 1] / (vv2 + xd[nd - 1]) - yd[nd - 1]
    G = V1 + V2 * XD[nd - 1]
    GY = G - YD[nd - 1]
    YG = YD[nd - 1] * G
    factor = 1 / YG
    print(f"gy = {gy}")
    print(f"GY = {GY}")
    print(f"YG = {YG}")
    print(f"factor = {factor}")

    ######  find min using linear regression (relative error)
    AA = 0; BB = 0; DD = 0; RR1 = 0; RR2 = 0
    for i in range(nd):
        AA = AA + XD[i] ** 2 / YD[i] ** 2
        BB = BB + XD[i] / YD[i] ** 2
        DD = DD + 1 / YD[i] ** 2
        RR1 = RR1 + 1 / YD[i]
        RR2 = RR2 + XD[i] / YD[i]
    VV1 = (AA * RR1 - BB * RR2) / (DD * AA - BB ** 2)
    VV2 = (-BB * RR1 + DD * RR2) / (DD * AA - BB ** 2)
    vvv1 = 1 / VV1
    vvv2 = vvv1 * VV2
    print(f"vvv1 = {vvv1}")
    print(f"vvv2 = {vvv2}")
    yyy = np.zeros(100)
    for i in range(100):
        yyy[i] = vvv1 * x[i] / (vvv2 + x[i])

    plt.close("all")
    # get(gcf)
    # MATLAB Position [25 1115 658 230], scaled to fit the plot window.
    fig, ax = plt.subplots(figsize=(6.58, 3.0), layout="constrained")
    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(color=co)

    # ax.plot(x,y,'--k',linewidth=3)
    ax.plot(x, yyy, "r", linewidth=1.6)
    ax.plot(xd, yd, ".b", markersize=30)
    ax.axis([0, 10, 0, 12])
    ax.set_yticks([0, 3, 6, 9, 12])
    ax.set_frame_on(True)
    ax.grid(True)
    ax.set_xlabel("x-axis", fontsize=14, fontweight="bold")
    ax.set_ylabel("y-axis", fontsize=14, fontweight="bold")
    ax.tick_params(labelsize=14)
    for label in ax.get_xticklabels() + ax.get_yticklabels():
        label.set_fontweight("bold")

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


if __name__ == "__main__":
    fig8_14()
