Test time complexity vs. linear chain size¶

In [ ]:
import numpy as np
import matplotlib.pyplot as plt
from fuNEGF.models import LinearChain
import timeit
from scipy.optimize import curve_fit

Define static parameters¶

In [ ]:
# static parameters
eps_0 = 0
t = 1
a = 1

Time complexity of model construction and $T(E)$ calculation for a clean system¶

In [ ]:
N_all = np.arange(1, 20, 2)
times_constr_only_all = []
times_constr_and_transmission_all = []

fig, ax = plt.subplots(1, 1, figsize=(3.5, 3))

for N in N_all:

    def time_constr():
        chain = LinearChain(N, eps_0, t, a, plot_dispersion=False)

    chain = LinearChain(N, eps_0, t, a, plot_dispersion=False)

    def time_transmission_calculation():
        chain.plot_transmission(ax=ax)

    t_constr_only = timeit.timeit(lambda: time_constr(), number=100)
    t_constr_and_transmission = timeit.timeit(
        lambda: time_transmission_calculation(), number=30
    )

    times_constr_only_all.append(t_constr_only)
    times_constr_and_transmission_all.append(t_constr_and_transmission)
plt.close()


def fit_power_law_and_plot(N_all, times_all, ax, title, color=None, marker=None):
    # fit data with a power law
    def power_law(x, a, b, c):
        return a + b * np.power(x, c)

    N_all = np.array(N_all)
    times_all = np.array(times_all)
    p0 = [0, 0.01, 1]
    p = curve_fit(power_law, N_all, times_all, p0=p0)[0]

    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(3.5, 3))
    if color is None:
        color = "lightblue"
    if marker is None:
        marker = "o"
    ax.plot(N_all, times_all, "-", color=color, marker=marker)
    ax.plot(
        N_all,
        power_law(N_all, *p),
        "k--",
        label=f"$t(N) = {p[0]:.2g} + {p[1]:.2g}"
        + r" \cdot N^{"
        + f"{p[2]:.2f}"
        + r"} $",
    )
    ax.set_xlabel(r"$N$", fontsize=11)
    ax.set_ylabel("Time (s)", fontsize=11)
    ax.legend(
        title=r"scaling $\mathcal{O}(" + f"{p[2]:.3g}" + r")$",
        loc="upper left",
        fontsize=9,
    )
    # legend title bold
    ax.get_legend().get_title().set_fontweight("bold")
    ax.axhline(0, color="black", lw=0.5)
    ax.axvline(0, color="black", lw=0.5)
    if title is None:
        title = (
            r"Time complexity of size-$N$ " + "\n" + r"linear chain $T(E)$ calculation"
        )
    ax.set_title(title, fontsize=11)
    plt.tight_layout()


fig, axes = plt.subplots(1, 2, figsize=(7.0, 3))
plt.suptitle("Time complexity of size-$N$ linear chain calculation", fontsize=12)
fit_power_law_and_plot(
    N_all,
    times_constr_only_all,
    ax=axes[0],
    color="C0",
    marker="o",
    title="Hamiltonian construction",
)
fit_power_law_and_plot(
    N_all,
    times_constr_and_transmission_all,
    ax=axes[1],
    color="C1",
    marker="o",
    title=r"$T(E)$ calculation",
)
axes[1].set_ylabel("")
plt.tight_layout()
plt.show()
No description has been provided for this image
  • Hamiltonian construction $\mathcal{O}(N)$
  • $T(E)$ calculation $\mathcal{O}(N^2)$
    • $\mathcal{O}(N^{\approx 2})$ correponds to matrix multiplication
      • "As of January 2024, the best bound on the asymptotic complexity of a matrix multiplication algorithm is O(n2.371552)." (wiki)
      • "numpy is "incredibly fast" in matrix multiplication, using a highly optimized BLAS (Basic Linear Algebra Subprograms) implementation"