From dd51a4928aadb4e94a0556e1dffe11ef01d39985 Mon Sep 17 00:00:00 2001 From: someone <154041471+Garvity@users.noreply.github.com> Date: Mon, 6 Oct 2025 07:09:01 +0530 Subject: [PATCH 1/7] [feat] Add classical and quantum Hamiltonian functions with examples --- physics/hamiltonian.py | 158 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 physics/hamiltonian.py diff --git a/physics/hamiltonian.py b/physics/hamiltonian.py new file mode 100644 index 000000000000..f841ae1f2f3a --- /dev/null +++ b/physics/hamiltonian.py @@ -0,0 +1,158 @@ +""" +Hamiltonian functions for classical and quantum mechanics. + +This module provides two educational, minimal implementations: + +- classical_hamiltonian(m, p, V): Computes H = T + V for a particle/system, where + T = p^2 / (2 m) is the kinetic energy expressed in terms of momentum p, and V is + the potential energy (can be a scalar or an array broadcastable to p). + +- quantum_hamiltonian_1d(m, hbar, V, dx): Builds the 1D Hamiltonian matrix for a + particle in a potential V using second-order central finite differences for the + kinetic energy operator: T = - (hbar^2 / 2m) d^2/dx^2 with Dirichlet boundaries. + +These functions are intended for learners to quickly prototype and simulate basic +physical systems. + +References +---------- +- Classical Hamiltonian mechanics: https://en.wikipedia.org/wiki/Hamiltonian_mechanics +- Discrete 1D Schrödinger operator: https://en.wikipedia.org/wiki/Finite_difference_method +""" + +from __future__ import annotations + +from typing import Any + +import numpy as np + + +def classical_hamiltonian(m: float, p: Any, V: Any) -> Any: + """ + Classical Hamiltonian H = T + V with T = p^2 / (2 m). + + The function supports scalars or array-like inputs for momentum ``p`` and + potential energy ``V``; NumPy broadcasting rules apply. If inputs are scalars, + a float is returned; otherwise a NumPy array is returned. + + Parameters + ---------- + m : float + Mass (must be positive). + p : array-like or scalar + Canonical momentum. + V : array-like or scalar + Potential energy evaluated for the corresponding configuration. + + Returns + ------- + float | np.ndarray + The Hamiltonian value(s) H = p^2/(2m) + V. + + Examples + -------- + Free particle with p = 3 kg·m/s and m = 2 kg (V = 0): + >>> classical_hamiltonian(2.0, 3.0, 0.0) + 2.25 + + Harmonic oscillator snapshot with vectorized p and V: + >>> m = 1.0 + >>> p = np.array([0.0, 1.0, 2.0]) + >>> V = np.array([0.5, 0.5, 0.5]) # e.g., 1/2 k x^2 at three positions + >>> classical_hamiltonian(m, p, V).tolist() + [0.5, 1.0, 2.5] + """ + if m <= 0: + raise ValueError("Mass m must be positive.") + + p_arr = np.asarray(p) + V_arr = np.asarray(V) + + T = (p_arr * p_arr) / (2.0 * m) + H = T + V_arr + + # Preserve scalar type when both inputs are scalar + if np.isscalar(p) and np.isscalar(V): + return float(H) + return H + + +def quantum_hamiltonian_1d(m: float, hbar: float, V: Any, dx: float) -> np.ndarray: + """ + Construct the 1D quantum Hamiltonian matrix using finite differences. + + Discretizes the kinetic operator with second-order central differences and + Dirichlet boundary conditions (wavefunction assumed zero beyond endpoints): + + H = - (hbar^2 / 2m) d^2/dx^2 + V + + On a uniform grid with spacing ``dx`` and N sites, the Laplacian is + approximated by the tridiagonal matrix with main diagonal ``-2`` and + off-diagonals ``+1``. The resulting kinetic term has main diagonal + ``(hbar^2)/(m*dx^2)`` and off-diagonals ``-(hbar^2)/(2*m*dx^2)``. + + Parameters + ---------- + m : float + Particle mass (must be positive). + hbar : float + Reduced Planck constant (can be set to 1.0 in natural units). + V : array-like shape (N,) + Potential energy values on the grid. Defines the matrix size. + dx : float + Grid spacing (must be positive). + + Returns + ------- + np.ndarray shape (N, N) + The Hermitian Hamiltonian matrix. + + Examples + -------- + Free particle (V=0) on a small grid: main diagonal = 1/dx^2, off = -1/(2*dx^2) in units m=hbar=1. + >>> N, dx = 5, 0.1 + >>> H = quantum_hamiltonian_1d(m=1.0, hbar=1.0, V=np.zeros(N), dx=dx) + >>> float(H[0, 0]) + 99.99999999999999 + >>> float(H[0, 1]) + -49.99999999999999 + + Add a harmonic-like site potential to the diagonal: + >>> x = dx * (np.arange(N) - (N-1)/2) + >>> V = 0.5 * x**2 # k=m=omega=1 for illustration + >>> H2 = quantum_hamiltonian_1d(1.0, 1.0, V, dx) + >>> np.allclose(np.diag(H2) - np.diag(H), V) + True + """ + if m <= 0: + raise ValueError("Mass m must be positive.") + if dx <= 0: + raise ValueError("Grid spacing dx must be positive.") + + V_arr = np.asarray(V, dtype=float) + if V_arr.ndim != 1: + raise ValueError("V must be a 1D array-like of potential values.") + + N = V_arr.size + if N == 0: + raise ValueError("V must contain at least one grid point.") + + coeff_main = (hbar * hbar) / (m * dx * dx) + coeff_off = -0.5 * (hbar * hbar) / (m * dx * dx) + + # Build tridiagonal kinetic matrix + H = np.zeros((N, N), dtype=float) + np.fill_diagonal(H, coeff_main) + idx = np.arange(N - 1) + H[idx, idx + 1] = coeff_off + H[idx + 1, idx] = coeff_off + + # Add the potential on the diagonal + H[np.arange(N), np.arange(N)] += V_arr + return H + + +if __name__ == "__main__": + import doctest + + doctest.testmod(verbose=True) From 7372169c26d713bdff4549d740ba9097676a4368 Mon Sep 17 00:00:00 2001 From: someone <154041471+Garvity@users.noreply.github.com> Date: Mon, 6 Oct 2025 18:03:44 +0530 Subject: [PATCH 2/7] fix case --- physics/hamiltonian.py | 60 +++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/physics/hamiltonian.py b/physics/hamiltonian.py index f841ae1f2f3a..cf52a0fa55fa 100644 --- a/physics/hamiltonian.py +++ b/physics/hamiltonian.py @@ -3,12 +3,12 @@ This module provides two educational, minimal implementations: -- classical_hamiltonian(m, p, V): Computes H = T + V for a particle/system, where - T = p^2 / (2 m) is the kinetic energy expressed in terms of momentum p, and V is +- classical_hamiltonian(m, p, v): Computes H = T + v for a particle/system, where + T = p^2 / (2 m) is the kinetic energy expressed in terms of momentum p, and v is the potential energy (can be a scalar or an array broadcastable to p). -- quantum_hamiltonian_1d(m, hbar, V, dx): Builds the 1D Hamiltonian matrix for a - particle in a potential V using second-order central finite differences for the +- quantum_hamiltonian_1d(m, hbar, v, dx): Builds the 1D Hamiltonian matrix for a + particle in a potential v using second-order central finite differences for the kinetic energy operator: T = - (hbar^2 / 2m) d^2/dx^2 with Dirichlet boundaries. These functions are intended for learners to quickly prototype and simulate basic @@ -27,12 +27,12 @@ import numpy as np -def classical_hamiltonian(m: float, p: Any, V: Any) -> Any: +def classical_hamiltonian(m: float, p: Any, v: Any) -> Any: """ - Classical Hamiltonian H = T + V with T = p^2 / (2 m). + Classical Hamiltonian H = T + v with T = p^2 / (2 m). The function supports scalars or array-like inputs for momentum ``p`` and - potential energy ``V``; NumPy broadcasting rules apply. If inputs are scalars, + potential energy ``v``; NumPy broadcasting rules apply. If inputs are scalars, a float is returned; otherwise a NumPy array is returned. Parameters @@ -41,50 +41,50 @@ def classical_hamiltonian(m: float, p: Any, V: Any) -> Any: Mass (must be positive). p : array-like or scalar Canonical momentum. - V : array-like or scalar + v : array-like or scalar Potential energy evaluated for the corresponding configuration. Returns ------- float | np.ndarray - The Hamiltonian value(s) H = p^2/(2m) + V. + The Hamiltonian value(s) H = p^2/(2m) + v. Examples -------- - Free particle with p = 3 kg·m/s and m = 2 kg (V = 0): + Free particle with p = 3 kg·m/s and m = 2 kg (v = 0): >>> classical_hamiltonian(2.0, 3.0, 0.0) 2.25 - Harmonic oscillator snapshot with vectorized p and V: + Harmonic oscillator snapshot with vectorized p and v: >>> m = 1.0 >>> p = np.array([0.0, 1.0, 2.0]) - >>> V = np.array([0.5, 0.5, 0.5]) # e.g., 1/2 k x^2 at three positions - >>> classical_hamiltonian(m, p, V).tolist() + >>> v = np.array([0.5, 0.5, 0.5]) # e.g., 1/2 k x^2 at three positions + >>> classical_hamiltonian(m, p, v).tolist() [0.5, 1.0, 2.5] """ if m <= 0: raise ValueError("Mass m must be positive.") p_arr = np.asarray(p) - V_arr = np.asarray(V) + v_arr = np.asarray(v) T = (p_arr * p_arr) / (2.0 * m) - H = T + V_arr + H = T + v_arr # Preserve scalar type when both inputs are scalar - if np.isscalar(p) and np.isscalar(V): + if np.isscalar(p) and np.isscalar(v): return float(H) return H -def quantum_hamiltonian_1d(m: float, hbar: float, V: Any, dx: float) -> np.ndarray: +def quantum_hamiltonian_1d(m: float, hbar: float, v: Any, dx: float) -> np.ndarray: """ Construct the 1D quantum Hamiltonian matrix using finite differences. Discretizes the kinetic operator with second-order central differences and Dirichlet boundary conditions (wavefunction assumed zero beyond endpoints): - H = - (hbar^2 / 2m) d^2/dx^2 + V + H = - (hbar^2 / 2m) d^2/dx^2 + v On a uniform grid with spacing ``dx`` and N sites, the Laplacian is approximated by the tridiagonal matrix with main diagonal ``-2`` and @@ -97,7 +97,7 @@ def quantum_hamiltonian_1d(m: float, hbar: float, V: Any, dx: float) -> np.ndarr Particle mass (must be positive). hbar : float Reduced Planck constant (can be set to 1.0 in natural units). - V : array-like shape (N,) + v : array-like shape (N,) Potential energy values on the grid. Defines the matrix size. dx : float Grid spacing (must be positive). @@ -109,9 +109,9 @@ def quantum_hamiltonian_1d(m: float, hbar: float, V: Any, dx: float) -> np.ndarr Examples -------- - Free particle (V=0) on a small grid: main diagonal = 1/dx^2, off = -1/(2*dx^2) in units m=hbar=1. + Free particle (v=0) on a small grid: main diagonal = 1/dx^2, off = -1/(2*dx^2) in units m=hbar=1. >>> N, dx = 5, 0.1 - >>> H = quantum_hamiltonian_1d(m=1.0, hbar=1.0, V=np.zeros(N), dx=dx) + >>> H = quantum_hamiltonian_1d(m=1.0, hbar=1.0, v=np.zeros(N), dx=dx) >>> float(H[0, 0]) 99.99999999999999 >>> float(H[0, 1]) @@ -119,9 +119,9 @@ def quantum_hamiltonian_1d(m: float, hbar: float, V: Any, dx: float) -> np.ndarr Add a harmonic-like site potential to the diagonal: >>> x = dx * (np.arange(N) - (N-1)/2) - >>> V = 0.5 * x**2 # k=m=omega=1 for illustration - >>> H2 = quantum_hamiltonian_1d(1.0, 1.0, V, dx) - >>> np.allclose(np.diag(H2) - np.diag(H), V) + >>> v = 0.5 * x**2 # k=m=omega=1 for illustration + >>> H2 = quantum_hamiltonian_1d(1.0, 1.0, v, dx) + >>> np.allclose(np.diag(H2) - np.diag(H), v) True """ if m <= 0: @@ -129,13 +129,13 @@ def quantum_hamiltonian_1d(m: float, hbar: float, V: Any, dx: float) -> np.ndarr if dx <= 0: raise ValueError("Grid spacing dx must be positive.") - V_arr = np.asarray(V, dtype=float) - if V_arr.ndim != 1: - raise ValueError("V must be a 1D array-like of potential values.") + v_arr = np.asarray(v, dtype=float) + if v_arr.ndim != 1: + raise ValueError("v must be a 1D array-like of potential values.") - N = V_arr.size + N = v_arr.size if N == 0: - raise ValueError("V must contain at least one grid point.") + raise ValueError("v must contain at least one grid point.") coeff_main = (hbar * hbar) / (m * dx * dx) coeff_off = -0.5 * (hbar * hbar) / (m * dx * dx) @@ -148,7 +148,7 @@ def quantum_hamiltonian_1d(m: float, hbar: float, V: Any, dx: float) -> np.ndarr H[idx + 1, idx] = coeff_off # Add the potential on the diagonal - H[np.arange(N), np.arange(N)] += V_arr + H[np.arange(N), np.arange(N)] += v_arr return H From 1465a1a6ed2385e2c405d168ac903e7ba94d5a34 Mon Sep 17 00:00:00 2001 From: someone <154041471+Garvity@users.noreply.github.com> Date: Mon, 6 Oct 2025 18:10:23 +0530 Subject: [PATCH 3/7] update --- physics/hamiltonian.py | 98 +++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/physics/hamiltonian.py b/physics/hamiltonian.py index cf52a0fa55fa..882cb11ff228 100644 --- a/physics/hamiltonian.py +++ b/physics/hamiltonian.py @@ -3,12 +3,12 @@ This module provides two educational, minimal implementations: -- classical_hamiltonian(m, p, v): Computes H = T + v for a particle/system, where - T = p^2 / (2 m) is the kinetic energy expressed in terms of momentum p, and v is +- classical_hamiltonian(mass, momentum, potential_energy): Computes H = T + V for a particle/system, where + T = p^2 / (2 m) is the kinetic energy expressed in terms of momentum p, and V is the potential energy (can be a scalar or an array broadcastable to p). -- quantum_hamiltonian_1d(m, hbar, v, dx): Builds the 1D Hamiltonian matrix for a - particle in a potential v using second-order central finite differences for the +- quantum_hamiltonian_1d(mass, hbar, potential_energy, dx): Builds the 1D Hamiltonian matrix for a + particle in a potential V using second-order central finite differences for the kinetic energy operator: T = - (hbar^2 / 2m) d^2/dx^2 with Dirichlet boundaries. These functions are intended for learners to quickly prototype and simulate basic @@ -27,9 +27,9 @@ import numpy as np -def classical_hamiltonian(m: float, p: Any, v: Any) -> Any: +def classical_hamiltonian(mass: float, momentum: Any, potential_energy: Any) -> Any: """ - Classical Hamiltonian H = T + v with T = p^2 / (2 m). + Classical Hamiltonian H = T + V with T = p^2 / (2 m). The function supports scalars or array-like inputs for momentum ``p`` and potential energy ``v``; NumPy broadcasting rules apply. If inputs are scalars, @@ -37,17 +37,17 @@ def classical_hamiltonian(m: float, p: Any, v: Any) -> Any: Parameters ---------- - m : float + mass : float Mass (must be positive). - p : array-like or scalar + momentum : array-like or scalar Canonical momentum. - v : array-like or scalar + potential_energy : array-like or scalar Potential energy evaluated for the corresponding configuration. Returns ------- float | np.ndarray - The Hamiltonian value(s) H = p^2/(2m) + v. + The Hamiltonian value(s) H = p^2/(2m) + V. Examples -------- @@ -56,35 +56,35 @@ def classical_hamiltonian(m: float, p: Any, v: Any) -> Any: 2.25 Harmonic oscillator snapshot with vectorized p and v: - >>> m = 1.0 - >>> p = np.array([0.0, 1.0, 2.0]) - >>> v = np.array([0.5, 0.5, 0.5]) # e.g., 1/2 k x^2 at three positions - >>> classical_hamiltonian(m, p, v).tolist() + >>> mass = 1.0 + >>> momentum = np.array([0.0, 1.0, 2.0]) + >>> potential_energy = np.array([0.5, 0.5, 0.5]) # e.g., 1/2 k x^2 at three positions + >>> classical_hamiltonian(mass, momentum, potential_energy).tolist() [0.5, 1.0, 2.5] """ - if m <= 0: + if mass <= 0: raise ValueError("Mass m must be positive.") - p_arr = np.asarray(p) - v_arr = np.asarray(v) + p = np.asarray(momentum) + v = np.asarray(potential_energy) - T = (p_arr * p_arr) / (2.0 * m) - H = T + v_arr + t = (p * p) / (2.0 * mass) + h = t + v # Preserve scalar type when both inputs are scalar - if np.isscalar(p) and np.isscalar(v): - return float(H) - return H + if np.isscalar(momentum) and np.isscalar(potential_energy): + return float(h) + return h -def quantum_hamiltonian_1d(m: float, hbar: float, v: Any, dx: float) -> np.ndarray: +def quantum_hamiltonian_1d(mass: float, hbar: float, potential_energy: Any, dx: float) -> np.ndarray: """ Construct the 1D quantum Hamiltonian matrix using finite differences. Discretizes the kinetic operator with second-order central differences and Dirichlet boundary conditions (wavefunction assumed zero beyond endpoints): - H = - (hbar^2 / 2m) d^2/dx^2 + v + H = - (hbar^2 / 2m) d^2/dx^2 + V On a uniform grid with spacing ``dx`` and N sites, the Laplacian is approximated by the tridiagonal matrix with main diagonal ``-2`` and @@ -93,63 +93,63 @@ def quantum_hamiltonian_1d(m: float, hbar: float, v: Any, dx: float) -> np.ndarr Parameters ---------- - m : float + mass : float Particle mass (must be positive). hbar : float Reduced Planck constant (can be set to 1.0 in natural units). - v : array-like shape (N,) + potential_energy : array-like shape (N,) Potential energy values on the grid. Defines the matrix size. dx : float Grid spacing (must be positive). Returns ------- - np.ndarray shape (N, N) + np.ndarray shape (n, n) The Hermitian Hamiltonian matrix. Examples -------- Free particle (v=0) on a small grid: main diagonal = 1/dx^2, off = -1/(2*dx^2) in units m=hbar=1. - >>> N, dx = 5, 0.1 - >>> H = quantum_hamiltonian_1d(m=1.0, hbar=1.0, v=np.zeros(N), dx=dx) - >>> float(H[0, 0]) + >>> n, dx = 5, 0.1 + >>> h = quantum_hamiltonian_1d(mass=1.0, hbar=1.0, potential_energy=np.zeros(n), dx=dx) + >>> float(h[0, 0]) 99.99999999999999 - >>> float(H[0, 1]) + >>> float(h[0, 1]) -49.99999999999999 Add a harmonic-like site potential to the diagonal: - >>> x = dx * (np.arange(N) - (N-1)/2) - >>> v = 0.5 * x**2 # k=m=omega=1 for illustration - >>> H2 = quantum_hamiltonian_1d(1.0, 1.0, v, dx) - >>> np.allclose(np.diag(H2) - np.diag(H), v) + >>> x = dx * (np.arange(n) - (n-1)/2) + >>> potential_energy = 0.5 * x**2 # k=m=omega=1 for illustration + >>> h2 = quantum_hamiltonian_1d(1.0, 1.0, potential_energy, dx) + >>> np.allclose(np.diag(h2) - np.diag(h), potential_energy) True """ - if m <= 0: + if mass <= 0: raise ValueError("Mass m must be positive.") if dx <= 0: raise ValueError("Grid spacing dx must be positive.") - v_arr = np.asarray(v, dtype=float) - if v_arr.ndim != 1: + v = np.asarray(potential_energy, dtype=float) + if v.ndim != 1: raise ValueError("v must be a 1D array-like of potential values.") - N = v_arr.size - if N == 0: + n = v.size + if n == 0: raise ValueError("v must contain at least one grid point.") - coeff_main = (hbar * hbar) / (m * dx * dx) - coeff_off = -0.5 * (hbar * hbar) / (m * dx * dx) + coeff_main = (hbar * hbar) / (mass * dx * dx) + coeff_off = -0.5 * (hbar * hbar) / (mass * dx * dx) # Build tridiagonal kinetic matrix - H = np.zeros((N, N), dtype=float) - np.fill_diagonal(H, coeff_main) - idx = np.arange(N - 1) - H[idx, idx + 1] = coeff_off - H[idx + 1, idx] = coeff_off + h = np.zeros((n, n), dtype=float) + np.fill_diagonal(h, coeff_main) + idx = np.arange(n - 1) + h[idx, idx + 1] = coeff_off + h[idx + 1, idx] = coeff_off # Add the potential on the diagonal - H[np.arange(N), np.arange(N)] += v_arr - return H + h[np.arange(n), np.arange(n)] += v + return h if __name__ == "__main__": From 5738494d821b72d2966963db377f19dfaf8795ce Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 12:40:53 +0000 Subject: [PATCH 4/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- physics/hamiltonian.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/physics/hamiltonian.py b/physics/hamiltonian.py index 882cb11ff228..d7e61cf220ef 100644 --- a/physics/hamiltonian.py +++ b/physics/hamiltonian.py @@ -77,7 +77,9 @@ def classical_hamiltonian(mass: float, momentum: Any, potential_energy: Any) -> return h -def quantum_hamiltonian_1d(mass: float, hbar: float, potential_energy: Any, dx: float) -> np.ndarray: +def quantum_hamiltonian_1d( + mass: float, hbar: float, potential_energy: Any, dx: float +) -> np.ndarray: """ Construct the 1D quantum Hamiltonian matrix using finite differences. From 10a5b2545ded2dd7aeeddf2140a6029490d792de Mon Sep 17 00:00:00 2001 From: someone <154041471+Garvity@users.noreply.github.com> Date: Mon, 6 Oct 2025 18:33:31 +0530 Subject: [PATCH 5/7] update1 --- physics/hamiltonian.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/physics/hamiltonian.py b/physics/hamiltonian.py index d7e61cf220ef..7b394ef1d437 100644 --- a/physics/hamiltonian.py +++ b/physics/hamiltonian.py @@ -1,5 +1,5 @@ """ -Hamiltonian functions for classical and quantum mechanics. +Hamiltonian functions for classical and quantum mechanics. This module provides two educational, minimal implementations: From f3f45a58330a7ea005512800cbdfb6bfc77c906b Mon Sep 17 00:00:00 2001 From: someone <154041471+Garvity@users.noreply.github.com> Date: Mon, 6 Oct 2025 21:03:13 +0530 Subject: [PATCH 6/7] updated --- physics/hamiltonian.py | 63 +++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/physics/hamiltonian.py b/physics/hamiltonian.py index 7b394ef1d437..f97da5ddf059 100644 --- a/physics/hamiltonian.py +++ b/physics/hamiltonian.py @@ -1,38 +1,40 @@ """ -Hamiltonian functions for classical and quantum mechanics. +Hamiltonian functions for classical and quantum mechanics. This module provides two educational, minimal implementations: -- classical_hamiltonian(mass, momentum, potential_energy): Computes H = T + V for a particle/system, where - T = p^2 / (2 m) is the kinetic energy expressed in terms of momentum p, and V is - the potential energy (can be a scalar or an array broadcastable to p). +- ham_c(mass, momentum, potential_energy): + Computes H = T + V, where T = p^2/(2m), and V is the potential (scalar or array). -- quantum_hamiltonian_1d(mass, hbar, potential_energy, dx): Builds the 1D Hamiltonian matrix for a - particle in a potential V using second-order central finite differences for the - kinetic energy operator: T = - (hbar^2 / 2m) d^2/dx^2 with Dirichlet boundaries. +- ham_1d(mass, hbar, potential_energy, dx): + Builds the 1D Hamiltonian using second-order central differences for the kinetic + operator: T = - (hbar^2 / 2m) d^2/dx^2 with Dirichlet boundaries. -These functions are intended for learners to quickly prototype and simulate basic -physical systems. +These functions help learners quickly prototype and simulate basic physical systems. References ---------- -- Classical Hamiltonian mechanics: https://en.wikipedia.org/wiki/Hamiltonian_mechanics -- Discrete 1D Schrödinger operator: https://en.wikipedia.org/wiki/Finite_difference_method +- Classical Hamiltonian mechanics: + https://en.wikipedia.org/wiki/Hamiltonian_mechanics +- Discrete 1D Schrödinger operator: + https://en.wikipedia.org/wiki/Finite_difference_method """ -from __future__ import annotations - from typing import Any import numpy as np -def classical_hamiltonian(mass: float, momentum: Any, potential_energy: Any) -> Any: +def ham_c( + mass: float, + momentum: Any, + potential_energy: Any, +) -> Any: """ Classical Hamiltonian H = T + V with T = p^2 / (2 m). The function supports scalars or array-like inputs for momentum ``p`` and - potential energy ``v``; NumPy broadcasting rules apply. If inputs are scalars, + potential energy ``v``. NumPy broadcasting rules apply. If inputs are scalars, a float is returned; otherwise a NumPy array is returned. Parameters @@ -47,19 +49,19 @@ def classical_hamiltonian(mass: float, momentum: Any, potential_energy: Any) -> Returns ------- float | np.ndarray - The Hamiltonian value(s) H = p^2/(2m) + V. + The Hamiltonian value(s) H = p^2/(2m) + V. Examples -------- Free particle with p = 3 kg·m/s and m = 2 kg (v = 0): - >>> classical_hamiltonian(2.0, 3.0, 0.0) + >>> ham_c(2.0, 3.0, 0.0) 2.25 Harmonic oscillator snapshot with vectorized p and v: >>> mass = 1.0 >>> momentum = np.array([0.0, 1.0, 2.0]) - >>> potential_energy = np.array([0.5, 0.5, 0.5]) # e.g., 1/2 k x^2 at three positions - >>> classical_hamiltonian(mass, momentum, potential_energy).tolist() + >>> potential_energy = np.array([0.5, 0.5, 0.5]) # e.g., 1/2 k x^2 at positions + >>> ham_c(mass, momentum, potential_energy).tolist() [0.5, 1.0, 2.5] """ if mass <= 0: @@ -77,8 +79,12 @@ def classical_hamiltonian(mass: float, momentum: Any, potential_energy: Any) -> return h -def quantum_hamiltonian_1d( - mass: float, hbar: float, potential_energy: Any, dx: float + +def ham_1d( + mass: float, + hbar: float, + potential_energy: Any, + dx: float, ) -> np.ndarray: """ Construct the 1D quantum Hamiltonian matrix using finite differences. @@ -89,7 +95,7 @@ def quantum_hamiltonian_1d( H = - (hbar^2 / 2m) d^2/dx^2 + V On a uniform grid with spacing ``dx`` and N sites, the Laplacian is - approximated by the tridiagonal matrix with main diagonal ``-2`` and + approximated by a tridiagonal matrix with main diagonal ``-2`` and off-diagonals ``+1``. The resulting kinetic term has main diagonal ``(hbar^2)/(m*dx^2)`` and off-diagonals ``-(hbar^2)/(2*m*dx^2)``. @@ -111,9 +117,12 @@ def quantum_hamiltonian_1d( Examples -------- - Free particle (v=0) on a small grid: main diagonal = 1/dx^2, off = -1/(2*dx^2) in units m=hbar=1. + Free particle (v=0) on a small grid: main diagonal = 1/dx^2, off = -1/(2*dx^2) + in units m=hbar=1. >>> n, dx = 5, 0.1 - >>> h = quantum_hamiltonian_1d(mass=1.0, hbar=1.0, potential_energy=np.zeros(n), dx=dx) + >>> h = ham_1d( + ... mass=1.0, hbar=1.0, potential_energy=np.zeros(n), dx=dx + ... ) >>> float(h[0, 0]) 99.99999999999999 >>> float(h[0, 1]) @@ -122,7 +131,7 @@ def quantum_hamiltonian_1d( Add a harmonic-like site potential to the diagonal: >>> x = dx * (np.arange(n) - (n-1)/2) >>> potential_energy = 0.5 * x**2 # k=m=omega=1 for illustration - >>> h2 = quantum_hamiltonian_1d(1.0, 1.0, potential_energy, dx) + >>> h2 = ham_1d(1.0, 1.0, potential_energy, dx) >>> np.allclose(np.diag(h2) - np.diag(h), potential_energy) True """ @@ -158,3 +167,7 @@ def quantum_hamiltonian_1d( import doctest doctest.testmod(verbose=True) + +# Backward-compatible aliases +classical_hamiltonian = ham_c +quantum_hamiltonian_1d = ham_1d From c7a7dc72aa88e3dd392397219fdc69fbedaa33f1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 15:33:41 +0000 Subject: [PATCH 7/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- physics/hamiltonian.py | 1 - 1 file changed, 1 deletion(-) diff --git a/physics/hamiltonian.py b/physics/hamiltonian.py index f97da5ddf059..3717be98ac01 100644 --- a/physics/hamiltonian.py +++ b/physics/hamiltonian.py @@ -79,7 +79,6 @@ def ham_c( return h - def ham_1d( mass: float, hbar: float,