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()
- 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"
- $\mathcal{O}(N^{\approx 2})$ correponds to matrix multiplication