|
| 1 | +""" |
| 2 | +Functions to calculate the Hamiltonian in both classical and quantum mechanics. |
| 3 | +
|
| 4 | +Overview: |
| 5 | + The Hamiltonian represents the total energy of a system. |
| 6 | +
|
| 7 | + - In classical mechanics, it is the sum of kinetic and potential energies. |
| 8 | +
|
| 9 | + - In quantum mechanics, it becomes an operator acting on the wavefunction ψ(x), describing how the system evolves in time. |
| 10 | +
|
| 11 | +This module includes: |
| 12 | + - classical_hamiltonian(): return total energy for given mass, momentum, and potential. |
| 13 | + - quantum_hamiltonian_1d(): Builds a 1D Hamiltonian matrix for numerical quantum systems. |
| 14 | +""" |
| 15 | + |
| 16 | +import numpy as np |
| 17 | + |
| 18 | + |
| 19 | +def classical_hamiltonian(mass: float, momentum: float, potential_energy: float) -> float: |
| 20 | + """ |
| 21 | + Calculate the classical Hamiltonian (total energy) of a particle. |
| 22 | +
|
| 23 | + The Hamiltonian(H) represents the total energy of the system: |
| 24 | + H = (momentum² / (2 × mass)) + potential_energy |
| 25 | +
|
| 26 | + Parameters: |
| 27 | + mass (float): Mass of the particle (must be positive). |
| 28 | + momentum (float): Linear momentum of the particle. |
| 29 | + potential_energy (float): Potential energy of the particle. |
| 30 | +
|
| 31 | + Returns: |
| 32 | + float: Total energy (Hamiltonian) of the particle. |
| 33 | +
|
| 34 | + Examples: |
| 35 | + >>> classical_hamiltonian(1.0, 2.0, 5.0) |
| 36 | + 7.0 |
| 37 | + >>> classical_hamiltonian(2.0, 3.0, 1.0) |
| 38 | + 3.25 |
| 39 | + >>> classical_hamiltonian(1.0, 0.0, 10.0) |
| 40 | + 10.0 |
| 41 | + >>> classical_hamiltonian(1.0, 2.0, 0.0) |
| 42 | + 2.0 |
| 43 | + """ |
| 44 | + if mass <= 0: |
| 45 | + raise ValueError("Mass must be a positive value.") |
| 46 | + return (momentum ** 2) / (2 * mass) + potential_energy |
| 47 | + |
| 48 | + |
| 49 | +def quantum_hamiltonian_1d( |
| 50 | + mass: float, |
| 51 | + hbar: float, |
| 52 | + potential_energy_array: np.ndarray, |
| 53 | + grid_spacing: float, |
| 54 | + round_to: int | None = None |
| 55 | +) -> np.ndarray: |
| 56 | + """ |
| 57 | + Construct the 1-D quantum Hamiltonian matrix for a particle in given potential. |
| 58 | +
|
| 59 | + Description: |
| 60 | + In quantum mechanics, the Hamiltonian (H) represents the total energy |
| 61 | + of a particle, combining both kinetic and potential energy components. |
| 62 | + For a particle of mass m in one spatial dimension, it is defined as: |
| 63 | +
|
| 64 | + H = - (ħ² / 2m) * (d²/dx²) + V(x) |
| 65 | +
|
| 66 | + - The first term is the kinetic energy operator. |
| 67 | + - The second term is the potential energy V(x). |
| 68 | +
|
| 69 | + Using the *finite difference method*, the second derivative is approximated by: |
| 70 | + d²ψ/dx² ≈ (ψ[i+1] - 2ψ[i] + ψ[i-1]) / (Δx²) |
| 71 | +
|
| 72 | + This turns the continuous operator into a discrete matrix. |
| 73 | +
|
| 74 | + Formula: |
| 75 | + H[i, i] = (ħ² / (m × Δx²)) + V[i] |
| 76 | + H[i, i±1] = - (ħ² / (2m × Δx²)) |
| 77 | +
|
| 78 | + Parameters: |
| 79 | + mass (float): Mass of the particle. (must be positive) |
| 80 | + hbar (float): Reduced Planck constant. (must be positive) |
| 81 | + potential_energy_array (np.ndarray): Potential energy values V(x) at each grid point. |
| 82 | + grid_spacing (float): Distance between consecutive grid points Δx. (must be positive) |
| 83 | + round_to (int | None): Number of decimal places to round the matrix to. |
| 84 | + If None (default), no rounding is applied. |
| 85 | +
|
| 86 | + Returns: |
| 87 | + np.ndarray: The discrete Hamiltonian matrix representing the total energy operator. |
| 88 | +
|
| 89 | + Examples: |
| 90 | + >>> import numpy as np |
| 91 | + >>> potential = np.array([0.0, 0.0, 0.0]) |
| 92 | + >>> quantum_hamiltonian_1d(1.0, 1.0, potential, 1.0) |
| 93 | + array([[ 1. , -0.5, 0. ], |
| 94 | + [-0.5, 1. , -0.5], |
| 95 | + [ 0. , -0.5, 1. ]]) |
| 96 | + >>> potential = np.array([1.0, 2.0, 3.0]) |
| 97 | + >>> quantum_hamiltonian_1d(2.0, 1.0, potential, 0.5) |
| 98 | + array([[ 3., -1., 0.], |
| 99 | + [-1., 4., -1.], |
| 100 | + [ 0., -1., 5.]]) |
| 101 | + """ |
| 102 | + if any(val <= 0 for val in (mass, hbar, grid_spacing)): |
| 103 | + raise ValueError("mass, hbar, and grid_spacing must be positive values.") |
| 104 | + |
| 105 | + num_points = len(potential_energy_array) |
| 106 | + kinetic_prefactor = hbar**2 / (2 * mass * grid_spacing**2) |
| 107 | + |
| 108 | + diagonal = np.full(num_points, 2) |
| 109 | + off_diagonal = np.ones(num_points - 1) |
| 110 | + |
| 111 | + kinetic_matrix = kinetic_prefactor * ( |
| 112 | + np.diag(diagonal) |
| 113 | + - np.diag(off_diagonal, 1) |
| 114 | + - np.diag(off_diagonal, -1) |
| 115 | + ) |
| 116 | + |
| 117 | + potential_matrix = np.diag(potential_energy_array) |
| 118 | + total_hamiltonian = kinetic_matrix + potential_matrix |
| 119 | + |
| 120 | + if round_to is not None: |
| 121 | + total_hamiltonian = np.round(total_hamiltonian, round_to) |
| 122 | + |
| 123 | + return total_hamiltonian |
| 124 | + |
| 125 | +if __name__ == "__main__": |
| 126 | + import doctest |
| 127 | + |
| 128 | + doctest.testmod(verbose=True) |
0 commit comments