"""Literal Python conversion of cores.m."""

from time import perf_counter

import numpy as np
from scipy.linalg import lu


def cores(n_values=None, nr_values=None, random_seed=None):
    # LU timing code

    ### For one core values start MATLAB using the command:
    ### /Applications/MATLAB_R2022a.app/bin/matlab -singleCompThread
    ###
    ### For Python, set the BLAS thread variables before starting Python, for example:
    ### OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 VECLIB_MAXIMUM_THREADS=1 python cores.py

    rng = np.random.default_rng(random_seed)
    L, U = lu(rng.random((10, 10)), permute_l=True)

    # n=np.array([100, 500])
    # nr=np.array([30, 30])

    if n_values is None:
        n = np.array([100, 500, 1000, 2000, 4000, 8000, 16000, 32000], dtype=int)
    else:
        n = np.asarray(n_values, dtype=int)
    if nr_values is None:
        if n_values is None:
            nr = np.array([30, 30, 20, 20, 10, 10, 5, 5], dtype=int)
        else:
            nr = np.ones(len(n), dtype=int)
    else:
        nr = np.asarray(nr_values, dtype=int)

    if len(n) != len(nr):
        raise ValueError("n_values and nr_values must have the same length")

    TN = len(n)
    t = np.zeros(TN)
    t2 = np.zeros(TN)

    for in_ in range(TN):
        # nr=30-3*(in-1)
        # nr=20-2*(in-1)
        # nr=9-in
        a = rng.random((n[in_], n[in_]))
        tim = 0
        tim2 = np.inf
        for ir in range(nr[in_]):
            # a=rand(n(in),n(in))
            tic = perf_counter()
            L, U = lu(a, permute_l=True)
            toc2 = perf_counter() - tic
            tim = tim + toc2
            if tim2 > toc2:
                tim2 = toc2
        t[in_] = tim / nr[in_]
        t2[in_] = tim2

    print("\n n = [ " + "   ".join("%i" % value for value in n) + "]")
    print("\n t = [ " + "   ".join("%6.2e" % value for value in t) + " ]")
    print("\n t = [ " + "   ".join("%6.2e" % value for value in t2) + " ]\n")

    # print('\n n = [ %i   %i ]' % tuple(n))
    # print('\n t = [ %6.2e   %6.2e ]' % tuple(t))

    # 10 core values (2022a):
    #  n = [ 100   500   1000   2000   4000   8000   16000   32000]
    #  t = [ 5.93e-05   1.46e-03   7.34e-03   2.39e-02   1.54e-01   9.35e-01   7.04e+00   4.78e+01 ]

    # single core values (2022a):
    #  n = [ 100   500   1000   2000   4000   8000   16000   32000]
    #  t = [ 4.71e-05   2.20e-03   1.43e-02   1.34e-01   8.61e-01   4.27e+00   3.09e+01   2.32e+02 ]

    return n, t, t2


if __name__ == "__main__":
    cores()
