physicskit 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- physicskit/__init__.py +51 -0
- physicskit/astro/__init__.py +66 -0
- physicskit/astro/cosmic_web.py +395 -0
- physicskit/astro/galactic_dynamics.py +137 -0
- physicskit/astro/nbody.py +208 -0
- physicskit/astro/orbital_mechanics.py +220 -0
- physicskit/astro/stellar_dynamo.py +628 -0
- physicskit/astro/stellar_structure.py +198 -0
- physicskit/astro/tests/__init__.py +0 -0
- physicskit/astro/tests/conftest.py +7 -0
- physicskit/astro/tests/test_cosmic_web.py +159 -0
- physicskit/astro/tests/test_galactic_dynamics.py +46 -0
- physicskit/astro/tests/test_nbody.py +81 -0
- physicskit/astro/tests/test_orbital_mechanics.py +73 -0
- physicskit/astro/tests/test_stellar_dynamo.py +198 -0
- physicskit/astro/tests/test_stellar_structure.py +52 -0
- physicskit/astro/tests/test_visualizers.py +159 -0
- physicskit/astro/visualizers.py +628 -0
- physicskit/chaos/__init__.py +55 -0
- physicskit/chaos/core/__init__.py +3 -0
- physicskit/chaos/core/base_system.py +342 -0
- physicskit/chaos/core/integrators.py +40 -0
- physicskit/chaos/exceptions.py +24 -0
- physicskit/chaos/quantum/__init__.py +38 -0
- physicskit/chaos/quantum/billiards.py +274 -0
- physicskit/chaos/quantum/husimi.py +85 -0
- physicskit/chaos/quantum/maps.py +366 -0
- physicskit/chaos/systems/__init__.py +38 -0
- physicskit/chaos/systems/billiards.py +1131 -0
- physicskit/chaos/systems/continuous.py +1276 -0
- physicskit/chaos/systems/maps.py +557 -0
- physicskit/chaos/tests/__init__.py +0 -0
- physicskit/chaos/tests/test_basins.py +76 -0
- physicskit/chaos/tests/test_bifurcation.py +132 -0
- physicskit/chaos/tests/test_billiards.py +115 -0
- physicskit/chaos/tests/test_continuous.py +224 -0
- physicskit/chaos/tests/test_dimension.py +69 -0
- physicskit/chaos/tests/test_divergence.py +90 -0
- physicskit/chaos/tests/test_dynamic_plots.py +269 -0
- physicskit/chaos/tests/test_integrators.py +96 -0
- physicskit/chaos/tests/test_io.py +41 -0
- physicskit/chaos/tests/test_maps.py +110 -0
- physicskit/chaos/tests/test_metrics.py +115 -0
- physicskit/chaos/tests/test_phase_space.py +73 -0
- physicskit/chaos/tests/test_properties.py +116 -0
- physicskit/chaos/tests/test_quantum_billiards.py +94 -0
- physicskit/chaos/tests/test_quantum_maps.py +144 -0
- physicskit/chaos/tests/test_recurrence.py +51 -0
- physicskit/chaos/tests/test_repr_and_api_consistency.py +134 -0
- physicskit/chaos/tests/test_section.py +49 -0
- physicskit/chaos/tests/test_spectral.py +48 -0
- physicskit/chaos/tests/test_streamlit_app.py +45 -0
- physicskit/chaos/tests/test_timeseries.py +131 -0
- physicskit/chaos/tests/test_viewer3d.py +41 -0
- physicskit/chaos/utils/__init__.py +46 -0
- physicskit/chaos/utils/dimension.py +139 -0
- physicskit/chaos/utils/io.py +95 -0
- physicskit/chaos/utils/metrics.py +304 -0
- physicskit/chaos/utils/recurrence.py +122 -0
- physicskit/chaos/utils/spectral.py +69 -0
- physicskit/chaos/utils/timeseries.py +303 -0
- physicskit/chaos/visualizers/__init__.py +85 -0
- physicskit/chaos/visualizers/basins.py +185 -0
- physicskit/chaos/visualizers/bifurcation.py +273 -0
- physicskit/chaos/visualizers/divergence.py +374 -0
- physicskit/chaos/visualizers/dynamic_plots.py +1372 -0
- physicskit/chaos/visualizers/phase_space.py +133 -0
- physicskit/chaos/visualizers/quantum.py +299 -0
- physicskit/chaos/visualizers/recurrence.py +91 -0
- physicskit/chaos/visualizers/section.py +161 -0
- physicskit/chaos/visualizers/theme.py +31 -0
- physicskit/chaos/visualizers/viewer3d.py +82 -0
- physicskit/classical/__init__.py +55 -0
- physicskit/classical/core/__init__.py +17 -0
- physicskit/classical/core/base_system.py +510 -0
- physicskit/classical/core/integrators.py +397 -0
- physicskit/classical/systems/__init__.py +32 -0
- physicskit/classical/systems/chains.py +334 -0
- physicskit/classical/systems/hamiltonian.py +215 -0
- physicskit/classical/systems/lagrangian.py +308 -0
- physicskit/classical/systems/newtonian.py +536 -0
- physicskit/classical/systems/rotations.py +614 -0
- physicskit/classical/tests/__init__.py +0 -0
- physicskit/classical/tests/conftest.py +7 -0
- physicskit/classical/tests/test_base_system.py +113 -0
- physicskit/classical/tests/test_chains.py +84 -0
- physicskit/classical/tests/test_conservation.py +244 -0
- physicskit/classical/tests/test_conservation_utils.py +47 -0
- physicskit/classical/tests/test_hamiltonian.py +44 -0
- physicskit/classical/tests/test_integrators.py +123 -0
- physicskit/classical/tests/test_lagrangian.py +69 -0
- physicskit/classical/tests/test_newtonian.py +45 -0
- physicskit/classical/tests/test_rotations.py +160 -0
- physicskit/classical/tests/test_stepsize.py +149 -0
- physicskit/classical/tests/test_symbolic.py +125 -0
- physicskit/classical/tests/test_visualizers.py +172 -0
- physicskit/classical/utils/__init__.py +20 -0
- physicskit/classical/utils/conservation.py +126 -0
- physicskit/classical/utils/stepsize.py +187 -0
- physicskit/classical/utils/symbolic.py +235 -0
- physicskit/classical/visualizers/__init__.py +25 -0
- physicskit/classical/visualizers/animations.py +508 -0
- physicskit/classical/visualizers/interactive.py +113 -0
- physicskit/classical/visualizers/modal_analysis.py +97 -0
- physicskit/classical/visualizers/phase_space.py +214 -0
- physicskit/condensed/__init__.py +122 -0
- physicskit/condensed/anderson_localization.py +155 -0
- physicskit/condensed/correlated.py +284 -0
- physicskit/condensed/ginzburg_landau.py +220 -0
- physicskit/condensed/landau_levels.py +246 -0
- physicskit/condensed/laughlin.py +229 -0
- physicskit/condensed/models.py +627 -0
- physicskit/condensed/tests/__init__.py +0 -0
- physicskit/condensed/tests/test_condensed.py +518 -0
- physicskit/condensed/tests/test_visualizers.py +87 -0
- physicskit/condensed/tight_binding.py +445 -0
- physicskit/condensed/topological_insulator_3d.py +178 -0
- physicskit/condensed/topology.py +217 -0
- physicskit/condensed/visualizers.py +296 -0
- physicskit/condensed/weyl.py +180 -0
- physicskit/constants.py +184 -0
- physicskit/fields/__init__.py +111 -0
- physicskit/fields/electrodynamics.py +671 -0
- physicskit/fields/quantum_fields.py +510 -0
- physicskit/fields/solitons.py +527 -0
- physicskit/fields/tests/__init__.py +0 -0
- physicskit/fields/tests/conftest.py +7 -0
- physicskit/fields/tests/test_field_animations.py +154 -0
- physicskit/fields/tests/test_fields.py +439 -0
- physicskit/fields/tests/test_visualizers.py +101 -0
- physicskit/fields/visualizers.py +503 -0
- physicskit/fluids/__init__.py +134 -0
- physicskit/fluids/core/__init__.py +23 -0
- physicskit/fluids/core/grid.py +165 -0
- physicskit/fluids/core/timestepping.py +231 -0
- physicskit/fluids/exceptions.py +26 -0
- physicskit/fluids/systems/__init__.py +70 -0
- physicskit/fluids/systems/compressible_flow.py +281 -0
- physicskit/fluids/systems/instabilities.py +343 -0
- physicskit/fluids/systems/navier_stokes.py +221 -0
- physicskit/fluids/systems/potential_flow.py +440 -0
- physicskit/fluids/systems/viscous_flow.py +425 -0
- physicskit/fluids/systems/vortex_dynamics.py +304 -0
- physicskit/fluids/tests/__init__.py +0 -0
- physicskit/fluids/tests/conftest.py +7 -0
- physicskit/fluids/tests/test_compressible_flow.py +66 -0
- physicskit/fluids/tests/test_instabilities.py +115 -0
- physicskit/fluids/tests/test_navier_stokes.py +67 -0
- physicskit/fluids/tests/test_potential_flow.py +92 -0
- physicskit/fluids/tests/test_static_visualizers.py +91 -0
- physicskit/fluids/tests/test_utils.py +100 -0
- physicskit/fluids/tests/test_viscous_flow.py +110 -0
- physicskit/fluids/tests/test_visualizers.py +34 -0
- physicskit/fluids/tests/test_vortex_dynamics.py +88 -0
- physicskit/fluids/utils/__init__.py +18 -0
- physicskit/fluids/utils/dimensionless.py +239 -0
- physicskit/fluids/utils/spectral_analysis.py +142 -0
- physicskit/fluids/visualizers/__init__.py +14 -0
- physicskit/fluids/visualizers/compressible.py +39 -0
- physicskit/fluids/visualizers/flow_fields.py +252 -0
- physicskit/fluids/visualizers/potential_flow.py +51 -0
- physicskit/fluids/visualizers/spectra.py +62 -0
- physicskit/fluids/visualizers/theme.py +38 -0
- physicskit/integrators/__init__.py +52 -0
- physicskit/integrators/adaptive.py +199 -0
- physicskit/integrators/fixed_step.py +360 -0
- physicskit/integrators/tests/__init__.py +0 -0
- physicskit/integrators/tests/test_integrators.py +101 -0
- physicskit/optics/__init__.py +124 -0
- physicskit/optics/_compat.py +5 -0
- physicskit/optics/gaussian.py +382 -0
- physicskit/optics/quantum_optics.py +428 -0
- physicskit/optics/ray.py +469 -0
- physicskit/optics/tests/__init__.py +0 -0
- physicskit/optics/tests/test_diffraction_animation.py +38 -0
- physicskit/optics/tests/test_gaussian.py +170 -0
- physicskit/optics/tests/test_quantum_optics.py +147 -0
- physicskit/optics/tests/test_ray.py +177 -0
- physicskit/optics/tests/test_visualizers.py +58 -0
- physicskit/optics/tests/test_wave.py +146 -0
- physicskit/optics/visualizers.py +264 -0
- physicskit/optics/wave.py +365 -0
- physicskit/particle/__init__.py +152 -0
- physicskit/particle/collider.py +382 -0
- physicskit/particle/confinement.py +125 -0
- physicskit/particle/decays.py +357 -0
- physicskit/particle/electroweak.py +300 -0
- physicskit/particle/kinematics.py +271 -0
- physicskit/particle/neutrinos.py +84 -0
- physicskit/particle/nuclear.py +100 -0
- physicskit/particle/scattering.py +159 -0
- physicskit/particle/tests/__init__.py +0 -0
- physicskit/particle/tests/conftest.py +7 -0
- physicskit/particle/tests/test_collider.py +119 -0
- physicskit/particle/tests/test_confinement.py +42 -0
- physicskit/particle/tests/test_decays.py +112 -0
- physicskit/particle/tests/test_electroweak.py +97 -0
- physicskit/particle/tests/test_kinematics.py +138 -0
- physicskit/particle/tests/test_neutrinos.py +36 -0
- physicskit/particle/tests/test_nuclear.py +45 -0
- physicskit/particle/tests/test_scattering.py +64 -0
- physicskit/particle/tests/test_visualizers.py +214 -0
- physicskit/particle/visualizers/__init__.py +38 -0
- physicskit/particle/visualizers/animations.py +705 -0
- physicskit/particle/visualizers/static.py +101 -0
- physicskit/plasma/__init__.py +176 -0
- physicskit/plasma/acceleration.py +152 -0
- physicskit/plasma/instabilities.py +417 -0
- physicskit/plasma/kinetic.py +588 -0
- physicskit/plasma/mhd.py +463 -0
- physicskit/plasma/single_particle.py +562 -0
- physicskit/plasma/tests/__init__.py +0 -0
- physicskit/plasma/tests/conftest.py +7 -0
- physicskit/plasma/tests/test_new_time_domain_features.py +222 -0
- physicskit/plasma/tests/test_plasma.py +232 -0
- physicskit/plasma/tests/test_visualizers.py +79 -0
- physicskit/plasma/turbulence.py +219 -0
- physicskit/plasma/visualizers.py +868 -0
- physicskit/plasma/waves.py +549 -0
- physicskit/quantum/__init__.py +180 -0
- physicskit/quantum/_compat.py +20 -0
- physicskit/quantum/chapters/__init__.py +0 -0
- physicskit/quantum/chapters/entanglement.py +489 -0
- physicskit/quantum/chapters/harmonic_spin.py +517 -0
- physicskit/quantum/chapters/hydrogen_am.py +292 -0
- physicskit/quantum/chapters/perturbation.py +350 -0
- physicskit/quantum/chapters/potentials.py +997 -0
- physicskit/quantum/chapters/spin.py +306 -0
- physicskit/quantum/chapters/wave_packets.py +541 -0
- physicskit/quantum/core/__init__.py +0 -0
- physicskit/quantum/core/eigensolvers.py +311 -0
- physicskit/quantum/core/operators.py +296 -0
- physicskit/quantum/core/solvers.py +271 -0
- physicskit/quantum/tests/__init__.py +0 -0
- physicskit/quantum/tests/conftest.py +7 -0
- physicskit/quantum/tests/test_animations.py +225 -0
- physicskit/quantum/tests/test_compat.py +43 -0
- physicskit/quantum/tests/test_eigensolvers.py +24 -0
- physicskit/quantum/tests/test_entanglement.py +127 -0
- physicskit/quantum/tests/test_harmonic_spin.py +140 -0
- physicskit/quantum/tests/test_hydrogen_am.py +48 -0
- physicskit/quantum/tests/test_measure.py +110 -0
- physicskit/quantum/tests/test_operators.py +105 -0
- physicskit/quantum/tests/test_perturbation.py +112 -0
- physicskit/quantum/tests/test_physics_checks.py +131 -0
- physicskit/quantum/tests/test_potentials.py +191 -0
- physicskit/quantum/tests/test_solvers.py +70 -0
- physicskit/quantum/tests/test_spin.py +22 -0
- physicskit/quantum/tests/test_unitarity.py +84 -0
- physicskit/quantum/tests/test_wave_packets.py +53 -0
- physicskit/quantum/utils/__init__.py +0 -0
- physicskit/quantum/utils/measure.py +253 -0
- physicskit/quantum/visualizers/__init__.py +0 -0
- physicskit/quantum/visualizers/bloch_sphere.py +205 -0
- physicskit/quantum/visualizers/entanglement.py +58 -0
- physicskit/quantum/visualizers/orbitals.py +187 -0
- physicskit/quantum/visualizers/phase_space.py +179 -0
- physicskit/quantum/visualizers/wavefunctions.py +230 -0
- physicskit/relativity/__init__.py +61 -0
- physicskit/relativity/chapters/__init__.py +33 -0
- physicskit/relativity/chapters/cosmology.py +190 -0
- physicskit/relativity/chapters/gw_merger.py +399 -0
- physicskit/relativity/chapters/kerr.py +371 -0
- physicskit/relativity/chapters/lensing.py +196 -0
- physicskit/relativity/chapters/neutron_star.py +149 -0
- physicskit/relativity/chapters/schwarzschild.py +412 -0
- physicskit/relativity/chapters/timekeeping.py +133 -0
- physicskit/relativity/core/__init__.py +12 -0
- physicskit/relativity/core/geodesics.py +216 -0
- physicskit/relativity/core/kerr_raytracer.py +259 -0
- physicskit/relativity/core/raytracer.py +241 -0
- physicskit/relativity/core/tensors.py +468 -0
- physicskit/relativity/tests/__init__.py +0 -0
- physicskit/relativity/tests/test_conservations.py +54 -0
- physicskit/relativity/tests/test_constants.py +34 -0
- physicskit/relativity/tests/test_cosmology.py +61 -0
- physicskit/relativity/tests/test_gw_merger.py +117 -0
- physicskit/relativity/tests/test_kerr.py +116 -0
- physicskit/relativity/tests/test_kerr_raytracer.py +103 -0
- physicskit/relativity/tests/test_lensing.py +75 -0
- physicskit/relativity/tests/test_neutron_star.py +48 -0
- physicskit/relativity/tests/test_raytracer.py +67 -0
- physicskit/relativity/tests/test_schwarzschild.py +126 -0
- physicskit/relativity/tests/test_shadow_render.py +81 -0
- physicskit/relativity/tests/test_tensors.py +86 -0
- physicskit/relativity/tests/test_timekeeping.py +51 -0
- physicskit/relativity/tests/test_visualizers_misc.py +115 -0
- physicskit/relativity/utils/__init__.py +1 -0
- physicskit/relativity/utils/constants.py +232 -0
- physicskit/relativity/visualizers/__init__.py +46 -0
- physicskit/relativity/visualizers/interactive.py +127 -0
- physicskit/relativity/visualizers/shadow_render.py +367 -0
- physicskit/relativity/visualizers/spacetime_3d.py +92 -0
- physicskit/relativity/visualizers/spacetime_diagrams.py +198 -0
- physicskit/relativity/visualizers/wave_plots.py +185 -0
- physicskit/rmt/__init__.py +8 -0
- physicskit/rmt/ensembles/__init__.py +108 -0
- physicskit/rmt/ensembles/banded.py +114 -0
- physicskit/rmt/ensembles/base.py +135 -0
- physicskit/rmt/ensembles/bdg.py +218 -0
- physicskit/rmt/ensembles/chiral.py +308 -0
- physicskit/rmt/ensembles/circular.py +104 -0
- physicskit/rmt/ensembles/crossover.py +82 -0
- physicskit/rmt/ensembles/density_matrix.py +148 -0
- physicskit/rmt/ensembles/effective_hamiltonian.py +230 -0
- physicskit/rmt/ensembles/embedded.py +207 -0
- physicskit/rmt/ensembles/gaussian.py +153 -0
- physicskit/rmt/ensembles/ginibre.py +110 -0
- physicskit/rmt/ensembles/girko.py +190 -0
- physicskit/rmt/ensembles/graph_laplacian.py +92 -0
- physicskit/rmt/ensembles/haar.py +57 -0
- physicskit/rmt/ensembles/jacobi.py +182 -0
- physicskit/rmt/ensembles/poisson.py +77 -0
- physicskit/rmt/ensembles/polynomial.py +139 -0
- physicskit/rmt/ensembles/pt_symmetric.py +120 -0
- physicskit/rmt/ensembles/single_ring.py +170 -0
- physicskit/rmt/ensembles/sparse.py +95 -0
- physicskit/rmt/ensembles/syk.py +170 -0
- physicskit/rmt/ensembles/truncated_unitary.py +80 -0
- physicskit/rmt/ensembles/universality.py +92 -0
- physicskit/rmt/ensembles/wishart.py +88 -0
- physicskit/rmt/py.typed +0 -0
- physicskit/rmt/spectrum.py +82 -0
- physicskit/rmt/stats/__init__.py +160 -0
- physicskit/rmt/stats/characteristic_polynomial.py +77 -0
- physicskit/rmt/stats/circular_law.py +54 -0
- physicskit/rmt/stats/correlations.py +162 -0
- physicskit/rmt/stats/density.py +70 -0
- physicskit/rmt/stats/entanglement.py +36 -0
- physicskit/rmt/stats/free_probability.py +202 -0
- physicskit/rmt/stats/localization.py +338 -0
- physicskit/rmt/stats/marchenko_pastur.py +55 -0
- physicskit/rmt/stats/pt_symmetric.py +265 -0
- physicskit/rmt/stats/ratios.py +110 -0
- physicskit/rmt/stats/real_ginibre.py +134 -0
- physicskit/rmt/stats/rigidity.py +272 -0
- physicskit/rmt/stats/single_ring.py +95 -0
- physicskit/rmt/stats/spacing.py +150 -0
- physicskit/rmt/stats/tracy_widom.py +175 -0
- physicskit/rmt/stats/truncated_unitary.py +40 -0
- physicskit/rmt/stats/unfolding.py +37 -0
- physicskit/rmt/stats/wachter.py +67 -0
- physicskit/rmt/tests/__init__.py +0 -0
- physicskit/rmt/tests/cache_utils.py +107 -0
- physicskit/rmt/tests/conftest.py +8 -0
- physicskit/rmt/tests/test_banded.py +86 -0
- physicskit/rmt/tests/test_base.py +29 -0
- physicskit/rmt/tests/test_bdg.py +133 -0
- physicskit/rmt/tests/test_characteristic_polynomial.py +50 -0
- physicskit/rmt/tests/test_chiral.py +273 -0
- physicskit/rmt/tests/test_circular.py +225 -0
- physicskit/rmt/tests/test_crossover.py +72 -0
- physicskit/rmt/tests/test_density.py +23 -0
- physicskit/rmt/tests/test_density_matrix.py +181 -0
- physicskit/rmt/tests/test_effective_hamiltonian.py +140 -0
- physicskit/rmt/tests/test_embedded.py +169 -0
- physicskit/rmt/tests/test_free_probability.py +81 -0
- physicskit/rmt/tests/test_gaussian_ensembles.py +22 -0
- physicskit/rmt/tests/test_gaussian_semicircle.py +127 -0
- physicskit/rmt/tests/test_ginibre_circular_law.py +131 -0
- physicskit/rmt/tests/test_girko.py +178 -0
- physicskit/rmt/tests/test_graph_laplacian.py +102 -0
- physicskit/rmt/tests/test_haar.py +118 -0
- physicskit/rmt/tests/test_jacobi_wachter.py +136 -0
- physicskit/rmt/tests/test_localization.py +240 -0
- physicskit/rmt/tests/test_poisson.py +149 -0
- physicskit/rmt/tests/test_polynomial.py +107 -0
- physicskit/rmt/tests/test_pt_symmetric.py +178 -0
- physicskit/rmt/tests/test_random_state.py +19 -0
- physicskit/rmt/tests/test_real_ginibre.py +112 -0
- physicskit/rmt/tests/test_rigidity_universality.py +167 -0
- physicskit/rmt/tests/test_single_ring.py +132 -0
- physicskit/rmt/tests/test_spacing_and_ratios.py +122 -0
- physicskit/rmt/tests/test_sparse.py +71 -0
- physicskit/rmt/tests/test_spectrum.py +27 -0
- physicskit/rmt/tests/test_syk.py +136 -0
- physicskit/rmt/tests/test_tracy_widom.py +113 -0
- physicskit/rmt/tests/test_tridiagonal.py +41 -0
- physicskit/rmt/tests/test_truncated_unitary.py +80 -0
- physicskit/rmt/tests/test_validation_base.py +25 -0
- physicskit/rmt/tests/test_validation_misc.py +67 -0
- physicskit/rmt/tests/test_wishart_marchenko_pastur.py +120 -0
- physicskit/rmt/utils/__init__.py +0 -0
- physicskit/rmt/utils/haar.py +128 -0
- physicskit/rmt/utils/random_state.py +24 -0
- physicskit/rmt/utils/tridiagonal.py +167 -0
- physicskit/rmt/validation/__init__.py +36 -0
- physicskit/rmt/validation/base.py +126 -0
- physicskit/rmt/validation/circular_law.py +80 -0
- physicskit/rmt/validation/marchenko_pastur.py +53 -0
- physicskit/rmt/validation/ratio_distribution.py +53 -0
- physicskit/rmt/validation/real_ginibre.py +60 -0
- physicskit/rmt/validation/sine_kernel.py +57 -0
- physicskit/rmt/validation/single_ring.py +68 -0
- physicskit/rmt/validation/tracy_widom.py +89 -0
- physicskit/rmt/validation/universality.py +100 -0
- physicskit/rmt/validation/wachter.py +52 -0
- physicskit/rmt/validation/wigner_semicircle.py +40 -0
- physicskit/rmt/validation/wigner_surmise.py +58 -0
- physicskit/semiclassical/__init__.py +94 -0
- physicskit/semiclassical/_compat.py +5 -0
- physicskit/semiclassical/core/__init__.py +41 -0
- physicskit/semiclassical/core/gutzwiller.py +215 -0
- physicskit/semiclassical/core/path_integral.py +594 -0
- physicskit/semiclassical/core/propagators.py +579 -0
- physicskit/semiclassical/core/wkb.py +308 -0
- physicskit/semiclassical/systems/__init__.py +13 -0
- physicskit/semiclassical/systems/scarring.py +278 -0
- physicskit/semiclassical/tests/__init__.py +0 -0
- physicskit/semiclassical/tests/test_gutzwiller.py +35 -0
- physicskit/semiclassical/tests/test_path_integral.py +194 -0
- physicskit/semiclassical/tests/test_propagators.py +82 -0
- physicskit/semiclassical/tests/test_scarring.py +43 -0
- physicskit/semiclassical/tests/test_visualizers.py +89 -0
- physicskit/semiclassical/tests/test_wkb.py +30 -0
- physicskit/semiclassical/visualizers/__init__.py +17 -0
- physicskit/semiclassical/visualizers/gutzwiller.py +55 -0
- physicskit/semiclassical/visualizers/path_integral.py +195 -0
- physicskit/semiclassical/visualizers/propagators.py +89 -0
- physicskit/semiclassical/visualizers/scarring.py +146 -0
- physicskit/semiclassical/visualizers/wkb.py +55 -0
- physicskit/statphys/__init__.py +80 -0
- physicskit/statphys/chapters/__init__.py +43 -0
- physicskit/statphys/chapters/ehrenfest_urn.py +112 -0
- physicskit/statphys/chapters/ising_lattice.py +431 -0
- physicskit/statphys/chapters/kpz_growth.py +129 -0
- physicskit/statphys/chapters/molecular_dynamics.py +258 -0
- physicskit/statphys/chapters/nonequilibrium_work.py +146 -0
- physicskit/statphys/chapters/percolation.py +305 -0
- physicskit/statphys/chapters/random_walk.py +142 -0
- physicskit/statphys/chapters/renormalization.py +148 -0
- physicskit/statphys/chapters/sandpile.py +109 -0
- physicskit/statphys/chapters/spin_glass.py +275 -0
- physicskit/statphys/core/__init__.py +10 -0
- physicskit/statphys/core/kpz_engine.py +53 -0
- physicskit/statphys/core/md_engine.py +157 -0
- physicskit/statphys/core/monte_carlo.py +462 -0
- physicskit/statphys/core/random_walk_engine.py +68 -0
- physicskit/statphys/core/sandpile_engine.py +52 -0
- physicskit/statphys/tests/__init__.py +0 -0
- physicskit/statphys/tests/test_dynamics.py +66 -0
- physicskit/statphys/tests/test_ehrenfest_urn.py +44 -0
- physicskit/statphys/tests/test_finite_size_scaling.py +62 -0
- physicskit/statphys/tests/test_interactive.py +33 -0
- physicskit/statphys/tests/test_ising.py +68 -0
- physicskit/statphys/tests/test_kpz.py +55 -0
- physicskit/statphys/tests/test_landau_theory.py +49 -0
- physicskit/statphys/tests/test_md_engine.py +31 -0
- physicskit/statphys/tests/test_molecular_dynamics.py +72 -0
- physicskit/statphys/tests/test_nonequilibrium_work.py +33 -0
- physicskit/statphys/tests/test_partition_function.py +26 -0
- physicskit/statphys/tests/test_percolation.py +116 -0
- physicskit/statphys/tests/test_potts_model.py +46 -0
- physicskit/statphys/tests/test_random_walk.py +50 -0
- physicskit/statphys/tests/test_renormalization.py +44 -0
- physicskit/statphys/tests/test_sandpile.py +44 -0
- physicskit/statphys/tests/test_spin_glass.py +73 -0
- physicskit/statphys/tests/test_thermodynamics.py +121 -0
- physicskit/statphys/tests/test_xy_model.py +45 -0
- physicskit/statphys/utils/__init__.py +1 -0
- physicskit/statphys/utils/dynamics.py +100 -0
- physicskit/statphys/utils/finite_size_scaling.py +171 -0
- physicskit/statphys/utils/landau_theory.py +151 -0
- physicskit/statphys/utils/partition_function.py +109 -0
- physicskit/statphys/utils/thermodynamics.py +356 -0
- physicskit/statphys/visualizers/__init__.py +87 -0
- physicskit/statphys/visualizers/interactive.py +161 -0
- physicskit/statphys/visualizers/jarzynski_render.py +44 -0
- physicskit/statphys/visualizers/kpz_render.py +65 -0
- physicskit/statphys/visualizers/lattice_render.py +212 -0
- physicskit/statphys/visualizers/particle_render.py +121 -0
- physicskit/statphys/visualizers/random_walk_render.py +106 -0
- physicskit/statphys/visualizers/rg_render.py +45 -0
- physicskit/statphys/visualizers/sandpile_render.py +65 -0
- physicskit/statphys/visualizers/spin_glass_render.py +40 -0
- physicskit/statphys/visualizers/urn_render.py +38 -0
- physicskit/statphys/visualizers/vortex_render.py +84 -0
- physicskit/tests/__init__.py +0 -0
- physicskit/tests/test_constants.py +38 -0
- physicskit-0.1.0.dist-info/METADATA +196 -0
- physicskit-0.1.0.dist-info/RECORD +484 -0
- physicskit-0.1.0.dist-info/WHEEL +5 -0
- physicskit-0.1.0.dist-info/licenses/LICENSE +21 -0
- physicskit-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
r"""Matrix Numerov eigensolver for the time-independent Schrodinger equation.
|
|
2
|
+
|
|
3
|
+
Solves
|
|
4
|
+
|
|
5
|
+
.. math::
|
|
6
|
+
|
|
7
|
+
-\frac{\hbar^2}{2m}\,\psi''(x) + V(x)\,\psi(x) = E\,\psi(x)
|
|
8
|
+
|
|
9
|
+
on a uniform grid with :math:`\psi = 0` at the domain boundary, using the
|
|
10
|
+
generalized-eigenvalue formulation of the Numerov method (Pillai, Goglio &
|
|
11
|
+
Walker, *Am. J. Phys.* **80**, 1017 (2012)).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
from numba import njit
|
|
20
|
+
from scipy.linalg import eigh
|
|
21
|
+
from scipy.sparse import diags
|
|
22
|
+
|
|
23
|
+
from .._compat import trapz
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"EigenResult",
|
|
27
|
+
"NumerovSolver",
|
|
28
|
+
"infinite_well",
|
|
29
|
+
"finite_well",
|
|
30
|
+
"asymmetric_step_well",
|
|
31
|
+
"linear_gravitational_well",
|
|
32
|
+
"double_well",
|
|
33
|
+
"harmonic_well",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@njit(cache=True)
|
|
38
|
+
def _tridiag_arrays(V: np.ndarray, h: float, hbar: float, m: float):
|
|
39
|
+
n = V.shape[0]
|
|
40
|
+
a_main = np.empty(n)
|
|
41
|
+
a_off = np.empty(n - 1)
|
|
42
|
+
b_main = np.empty(n)
|
|
43
|
+
b_off = np.empty(n - 1)
|
|
44
|
+
|
|
45
|
+
kin = hbar**2 / (2.0 * m * h * h)
|
|
46
|
+
for i in range(n):
|
|
47
|
+
a_main[i] = 2.0 * kin + (10.0 / 12.0) * V[i]
|
|
48
|
+
b_main[i] = 10.0 / 12.0
|
|
49
|
+
for i in range(n - 1):
|
|
50
|
+
a_off[i] = -kin + (1.0 / 12.0) * 0.5 * (V[i] + V[i + 1])
|
|
51
|
+
b_off[i] = 1.0 / 12.0
|
|
52
|
+
return a_main, a_off, b_main, b_off
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass
|
|
56
|
+
class EigenResult:
|
|
57
|
+
"""Container for the output of :meth:`NumerovSolver.solve`."""
|
|
58
|
+
|
|
59
|
+
x: np.ndarray
|
|
60
|
+
"""numpy.ndarray: The spatial grid the wavefunctions are sampled on."""
|
|
61
|
+
|
|
62
|
+
energies: np.ndarray
|
|
63
|
+
r"""numpy.ndarray: Eigenenergies :math:`E_n`, ascending, shape ``(n_states,)``."""
|
|
64
|
+
|
|
65
|
+
wavefunctions: np.ndarray
|
|
66
|
+
r"""numpy.ndarray: Normalized eigenfunctions :math:`\psi_n(x)`, shape
|
|
67
|
+
``(n_states, len(x))``, with :math:`\int \lvert\psi_n\rvert^2\,dx = 1`
|
|
68
|
+
and :math:`\psi_n(x[0]) = \psi_n(x[-1]) = 0`."""
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class NumerovSolver:
|
|
72
|
+
r"""Bound-state solver for an arbitrary 1D potential :math:`V(x)` on a fixed grid.
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
x : array_like
|
|
77
|
+
Uniform spatial grid. The wavefunction is forced to vanish at
|
|
78
|
+
``x[0]`` and ``x[-1]`` (hard walls), so the domain should extend
|
|
79
|
+
well into the classically forbidden region for soft potentials.
|
|
80
|
+
V : callable or array_like
|
|
81
|
+
Potential energy, either a function ``V(x)`` or a precomputed array
|
|
82
|
+
matching ``x``.
|
|
83
|
+
hbar : float, default=1.0
|
|
84
|
+
Value of :math:`\hbar` to use.
|
|
85
|
+
m : float, default=1.0
|
|
86
|
+
Particle mass.
|
|
87
|
+
|
|
88
|
+
Notes
|
|
89
|
+
-----
|
|
90
|
+
The Numerov finite-difference relation for :math:`\psi'' = f\psi` is
|
|
91
|
+
recast as the generalized eigenvalue problem
|
|
92
|
+
|
|
93
|
+
.. math::
|
|
94
|
+
|
|
95
|
+
\hat A \boldsymbol\psi = E \hat B \boldsymbol\psi, \qquad
|
|
96
|
+
\hat A = -\frac{\hbar^2}{2m h^2}\hat T + \hat B\,\mathrm{diag}(V),
|
|
97
|
+
|
|
98
|
+
where :math:`\hat T` and :math:`\hat B` are the tridiagonal matrices
|
|
99
|
+
:math:`\mathrm{tridiag}(1,-2,1)` and :math:`\mathrm{tridiag}(1,10,1)/12`
|
|
100
|
+
and :math:`h` is the grid spacing. Validated against the analytic
|
|
101
|
+
infinite-well and harmonic-oscillator spectra to four decimal places.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
def __init__(self, x: np.ndarray, V, hbar: float = 1.0, m: float = 1.0):
|
|
105
|
+
self.x = np.asarray(x, dtype=float)
|
|
106
|
+
h = self.x[1] - self.x[0]
|
|
107
|
+
if not np.allclose(np.diff(self.x), h, rtol=1e-8):
|
|
108
|
+
raise ValueError("NumerovSolver requires a uniform grid.")
|
|
109
|
+
self.h = h
|
|
110
|
+
self.hbar = hbar
|
|
111
|
+
self.m = m
|
|
112
|
+
self.V_full = np.asarray(V(self.x) if callable(V) else V, dtype=float)
|
|
113
|
+
|
|
114
|
+
def solve(self, n_states: int = 6) -> EigenResult:
|
|
115
|
+
"""Compute the lowest bound states.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
n_states : int, default=6
|
|
120
|
+
Number of lowest-energy eigenstates to return. Must be smaller
|
|
121
|
+
than the number of interior grid points.
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
EigenResult
|
|
126
|
+
The energies and normalized wavefunctions.
|
|
127
|
+
|
|
128
|
+
Raises
|
|
129
|
+
------
|
|
130
|
+
ValueError
|
|
131
|
+
If ``n_states`` is not smaller than the number of interior grid
|
|
132
|
+
points.
|
|
133
|
+
"""
|
|
134
|
+
# Interior points only; psi vanishes at the two boundary points.
|
|
135
|
+
V_int = self.V_full[1:-1]
|
|
136
|
+
n = V_int.shape[0]
|
|
137
|
+
if n_states >= n:
|
|
138
|
+
raise ValueError("n_states must be smaller than the number of interior grid points.")
|
|
139
|
+
|
|
140
|
+
a_main, a_off, b_main, b_off = _tridiag_arrays(V_int, self.h, self.hbar, self.m)
|
|
141
|
+
|
|
142
|
+
A = diags([a_off, a_main, a_off], offsets=[-1, 0, 1]).toarray()
|
|
143
|
+
B = diags([b_off, b_main, b_off], offsets=[-1, 0, 1]).toarray()
|
|
144
|
+
|
|
145
|
+
eigvals, eigvecs = eigh(A, B)
|
|
146
|
+
|
|
147
|
+
energies = eigvals[:n_states]
|
|
148
|
+
psis = np.zeros((n_states, self.x.shape[0]))
|
|
149
|
+
for k in range(n_states):
|
|
150
|
+
psi_int = eigvecs[:, k]
|
|
151
|
+
psi = np.zeros(self.x.shape[0])
|
|
152
|
+
psi[1:-1] = psi_int
|
|
153
|
+
norm = np.sqrt(trapz(psi**2, self.x))
|
|
154
|
+
psis[k] = psi / norm
|
|
155
|
+
|
|
156
|
+
return EigenResult(x=self.x, energies=energies, wavefunctions=psis)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# --- Convenience potential builders ---------------------------------------
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def infinite_well():
|
|
163
|
+
r"""The infinite square well: :math:`V(x) = 0` inside the domain.
|
|
164
|
+
|
|
165
|
+
The grid boundaries passed to :class:`NumerovSolver` act as the
|
|
166
|
+
infinite walls, since the wavefunction is forced to vanish there.
|
|
167
|
+
|
|
168
|
+
Returns
|
|
169
|
+
-------
|
|
170
|
+
callable
|
|
171
|
+
A function ``V(x)`` returning zeros the same shape as ``x``.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
def V(x):
|
|
175
|
+
return np.zeros_like(x)
|
|
176
|
+
|
|
177
|
+
return V
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def finite_well(V0: float, width: float):
|
|
181
|
+
r"""A finite square well,
|
|
182
|
+
|
|
183
|
+
.. math::
|
|
184
|
+
|
|
185
|
+
V(x) = \begin{cases} 0 & \lvert x\rvert \le \text{width}/2 \\
|
|
186
|
+
V_0 & \text{otherwise} \end{cases}.
|
|
187
|
+
|
|
188
|
+
Parameters
|
|
189
|
+
----------
|
|
190
|
+
V0 : float
|
|
191
|
+
Height of the barrier outside the well.
|
|
192
|
+
width : float
|
|
193
|
+
Full width of the well (zero-potential region).
|
|
194
|
+
|
|
195
|
+
Returns
|
|
196
|
+
-------
|
|
197
|
+
callable
|
|
198
|
+
A function ``V(x)``.
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
def V(x):
|
|
202
|
+
return np.where(np.abs(x) <= width / 2, 0.0, V0)
|
|
203
|
+
|
|
204
|
+
return V
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def asymmetric_step_well(width: float, V_left: float, V_right: float):
|
|
208
|
+
r"""A well of unequal left/right wall heights,
|
|
209
|
+
|
|
210
|
+
.. math::
|
|
211
|
+
|
|
212
|
+
V(x) = \begin{cases}
|
|
213
|
+
V_\text{left} & x < -\text{width}/2 \\
|
|
214
|
+
0 & \lvert x\rvert \le \text{width}/2 \\
|
|
215
|
+
V_\text{right} & x > \text{width}/2
|
|
216
|
+
\end{cases}.
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
width : float
|
|
221
|
+
Full width of the zero-potential region.
|
|
222
|
+
V_left : float
|
|
223
|
+
Wall height on the left side.
|
|
224
|
+
V_right : float
|
|
225
|
+
Wall height on the right side.
|
|
226
|
+
|
|
227
|
+
Returns
|
|
228
|
+
-------
|
|
229
|
+
callable
|
|
230
|
+
A function ``V(x)``.
|
|
231
|
+
"""
|
|
232
|
+
|
|
233
|
+
def V(x):
|
|
234
|
+
out = np.zeros_like(x)
|
|
235
|
+
out[x < -width / 2] = V_left
|
|
236
|
+
out[x > width / 2] = V_right
|
|
237
|
+
return out
|
|
238
|
+
|
|
239
|
+
return V
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def linear_gravitational_well(alpha: float):
|
|
243
|
+
r"""The V-shaped 'quantum bouncer' well, :math:`V(x) = \alpha \lvert x\rvert`.
|
|
244
|
+
|
|
245
|
+
A particle in this potential is the quantum analogue of a ball bouncing
|
|
246
|
+
under uniform gravity (:math:`\alpha = mg` on the half-line); its
|
|
247
|
+
eigenstates are Airy functions (see :func:`physicskit.quantum.chapters.potentials.airy_bouncer_energies`).
|
|
248
|
+
|
|
249
|
+
Parameters
|
|
250
|
+
----------
|
|
251
|
+
alpha : float
|
|
252
|
+
Slope of the linear potential (e.g. :math:`mg` for gravity).
|
|
253
|
+
|
|
254
|
+
Returns
|
|
255
|
+
-------
|
|
256
|
+
callable
|
|
257
|
+
A function ``V(x)``.
|
|
258
|
+
"""
|
|
259
|
+
|
|
260
|
+
def V(x):
|
|
261
|
+
return alpha * np.abs(x)
|
|
262
|
+
|
|
263
|
+
return V
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def double_well(lam: float, a: float):
|
|
267
|
+
r"""The symmetric quartic double well, :math:`V(x) = \lambda (x^2 - a^2)^2`.
|
|
268
|
+
|
|
269
|
+
Has minima at :math:`x = \pm a`, each of depth 0, separated by a barrier
|
|
270
|
+
of height :math:`\lambda a^4` at :math:`x=0`.
|
|
271
|
+
|
|
272
|
+
Parameters
|
|
273
|
+
----------
|
|
274
|
+
lam : float
|
|
275
|
+
Overall strength :math:`\lambda` of the quartic potential.
|
|
276
|
+
a : float
|
|
277
|
+
Half-separation of the two minima.
|
|
278
|
+
|
|
279
|
+
Returns
|
|
280
|
+
-------
|
|
281
|
+
callable
|
|
282
|
+
A function ``V(x)``.
|
|
283
|
+
"""
|
|
284
|
+
|
|
285
|
+
def V(x):
|
|
286
|
+
return lam * (x**2 - a**2) ** 2
|
|
287
|
+
|
|
288
|
+
return V
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def harmonic_well(m: float = 1.0, omega: float = 1.0):
|
|
292
|
+
r"""The quantum harmonic oscillator potential,
|
|
293
|
+
:math:`V(x) = \tfrac{1}{2} m \omega^2 x^2`.
|
|
294
|
+
|
|
295
|
+
Parameters
|
|
296
|
+
----------
|
|
297
|
+
m : float, default=1.0
|
|
298
|
+
Particle mass.
|
|
299
|
+
omega : float, default=1.0
|
|
300
|
+
Angular frequency :math:`\omega`.
|
|
301
|
+
|
|
302
|
+
Returns
|
|
303
|
+
-------
|
|
304
|
+
callable
|
|
305
|
+
A function ``V(x)``.
|
|
306
|
+
"""
|
|
307
|
+
|
|
308
|
+
def V(x):
|
|
309
|
+
return 0.5 * m * omega**2 * x**2
|
|
310
|
+
|
|
311
|
+
return V
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
r"""Dirac algebra helpers: Pauli matrices, spin/ladder operators, commutators.
|
|
2
|
+
|
|
3
|
+
Conventions follow Cohen-Tannoudji, Diu & Laloe, with :math:`\hbar = 1`
|
|
4
|
+
unless a function explicitly takes ``hbar`` as a parameter.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"sigma_x",
|
|
13
|
+
"sigma_y",
|
|
14
|
+
"sigma_z",
|
|
15
|
+
"identity2",
|
|
16
|
+
"PAULI",
|
|
17
|
+
"spin_operator",
|
|
18
|
+
"annihilation_operator",
|
|
19
|
+
"creation_operator",
|
|
20
|
+
"number_operator",
|
|
21
|
+
"position_operator",
|
|
22
|
+
"momentum_operator",
|
|
23
|
+
"commutator",
|
|
24
|
+
"anticommutator",
|
|
25
|
+
"expectation",
|
|
26
|
+
"is_hermitian",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
# --- Pauli matrices -------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
sigma_x = np.array([[0, 1], [1, 0]], dtype=complex)
|
|
32
|
+
r"""The Pauli matrix :math:`\sigma_x = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}`."""
|
|
33
|
+
|
|
34
|
+
sigma_y = np.array([[0, -1j], [1j, 0]], dtype=complex)
|
|
35
|
+
r"""The Pauli matrix :math:`\sigma_y = \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix}`."""
|
|
36
|
+
|
|
37
|
+
sigma_z = np.array([[1, 0], [0, -1]], dtype=complex)
|
|
38
|
+
r"""The Pauli matrix :math:`\sigma_z = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}`."""
|
|
39
|
+
|
|
40
|
+
identity2 = np.eye(2, dtype=complex)
|
|
41
|
+
"""The :math:`2\\times 2` identity matrix."""
|
|
42
|
+
|
|
43
|
+
PAULI = {"x": sigma_x, "y": sigma_y, "z": sigma_z, "i": identity2}
|
|
44
|
+
"""Dict mapping ``'x'``, ``'y'``, ``'z'``, ``'i'`` to the corresponding matrix."""
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def spin_operator(axis: str, s: float = 0.5, hbar: float = 1.0) -> np.ndarray:
|
|
48
|
+
r"""Angular-momentum operator :math:`\hat S_\text{axis}` for spin quantum number ``s``.
|
|
49
|
+
|
|
50
|
+
For :math:`s=1/2` this reduces to :math:`(\hbar/2)\,\sigma_\text{axis}`. For
|
|
51
|
+
general :math:`s`, the :math:`(2s+1)`-dimensional matrix representation is
|
|
52
|
+
built from the ladder operators
|
|
53
|
+
|
|
54
|
+
.. math::
|
|
55
|
+
|
|
56
|
+
\hat S_\pm \lvert s, m\rangle
|
|
57
|
+
= \hbar\sqrt{s(s+1) - m(m\pm 1)}\, \lvert s, m\pm 1\rangle,
|
|
58
|
+
|
|
59
|
+
with :math:`\hat S_x = (\hat S_+ + \hat S_-)/2` and
|
|
60
|
+
:math:`\hat S_y = (\hat S_+ - \hat S_-)/2i`.
|
|
61
|
+
|
|
62
|
+
Parameters
|
|
63
|
+
----------
|
|
64
|
+
axis : {'x', 'y', 'z', '+', '-'}
|
|
65
|
+
Which component (or ladder operator) to return.
|
|
66
|
+
s : float, default=0.5
|
|
67
|
+
Spin quantum number (may be integer or half-integer).
|
|
68
|
+
hbar : float, default=1.0
|
|
69
|
+
Value of :math:`\hbar` to use.
|
|
70
|
+
|
|
71
|
+
Returns
|
|
72
|
+
-------
|
|
73
|
+
numpy.ndarray
|
|
74
|
+
The :math:`(2s+1)\times(2s+1)` operator matrix, in the
|
|
75
|
+
:math:`\lvert s, m\rangle` basis ordered :math:`m = s, s-1, \dots, -s`.
|
|
76
|
+
|
|
77
|
+
Raises
|
|
78
|
+
------
|
|
79
|
+
ValueError
|
|
80
|
+
If ``axis`` is not one of ``'x'``, ``'y'``, ``'z'``, ``'+'``, ``'-'``.
|
|
81
|
+
"""
|
|
82
|
+
dim = int(round(2 * s + 1))
|
|
83
|
+
m_values = np.array([s - k for k in range(dim)]) # m = s, s-1, ..., -s
|
|
84
|
+
|
|
85
|
+
if axis == "z":
|
|
86
|
+
return hbar * np.diag(m_values).astype(complex)
|
|
87
|
+
|
|
88
|
+
s_plus = np.zeros((dim, dim), dtype=complex)
|
|
89
|
+
for k in range(dim - 1):
|
|
90
|
+
m = m_values[k + 1]
|
|
91
|
+
coeff = hbar * np.sqrt(s * (s + 1) - m * (m + 1))
|
|
92
|
+
s_plus[k, k + 1] = coeff
|
|
93
|
+
s_minus = s_plus.conj().T
|
|
94
|
+
|
|
95
|
+
if axis == "+":
|
|
96
|
+
return s_plus
|
|
97
|
+
if axis == "-":
|
|
98
|
+
return s_minus
|
|
99
|
+
if axis == "x":
|
|
100
|
+
return 0.5 * (s_plus + s_minus)
|
|
101
|
+
if axis == "y":
|
|
102
|
+
return (s_plus - s_minus) / (2j)
|
|
103
|
+
raise ValueError(f"Unknown axis {axis!r}; expected 'x', 'y', 'z', '+' or '-'.")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# --- Harmonic-oscillator ladder operators (truncated Fock basis) ---------
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def annihilation_operator(n_max: int) -> np.ndarray:
|
|
110
|
+
r"""Lowering operator :math:`\hat a` in a truncated Fock basis.
|
|
111
|
+
|
|
112
|
+
Acts as :math:`\hat a \lvert n\rangle = \sqrt{n}\,\lvert n-1\rangle` on the
|
|
113
|
+
truncated basis :math:`\{\lvert 0\rangle, \dots, \lvert n_\text{max}-1\rangle\}`.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
n_max : int
|
|
118
|
+
Dimension of the truncated Fock space.
|
|
119
|
+
|
|
120
|
+
Returns
|
|
121
|
+
-------
|
|
122
|
+
numpy.ndarray
|
|
123
|
+
The :math:`n_\text{max}\times n_\text{max}` matrix representation of
|
|
124
|
+
:math:`\hat a`.
|
|
125
|
+
"""
|
|
126
|
+
a = np.zeros((n_max, n_max), dtype=complex)
|
|
127
|
+
for n in range(1, n_max):
|
|
128
|
+
a[n - 1, n] = np.sqrt(n)
|
|
129
|
+
return a
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def creation_operator(n_max: int) -> np.ndarray:
|
|
133
|
+
r"""Raising operator :math:`\hat a^\dagger`, the Hermitian conjugate of
|
|
134
|
+
:func:`annihilation_operator`.
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
n_max : int
|
|
139
|
+
Dimension of the truncated Fock space.
|
|
140
|
+
|
|
141
|
+
Returns
|
|
142
|
+
-------
|
|
143
|
+
numpy.ndarray
|
|
144
|
+
The :math:`n_\text{max}\times n_\text{max}` matrix representation of
|
|
145
|
+
:math:`\hat a^\dagger`.
|
|
146
|
+
"""
|
|
147
|
+
return annihilation_operator(n_max).conj().T
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def number_operator(n_max: int) -> np.ndarray:
|
|
151
|
+
r"""Number operator :math:`\hat N = \hat a^\dagger \hat a`, diagonal with
|
|
152
|
+
eigenvalues :math:`0, 1, \dots, n_\text{max}-1`.
|
|
153
|
+
|
|
154
|
+
Parameters
|
|
155
|
+
----------
|
|
156
|
+
n_max : int
|
|
157
|
+
Dimension of the truncated Fock space.
|
|
158
|
+
|
|
159
|
+
Returns
|
|
160
|
+
-------
|
|
161
|
+
numpy.ndarray
|
|
162
|
+
The :math:`n_\text{max}\times n_\text{max}` matrix representation of
|
|
163
|
+
:math:`\hat N`.
|
|
164
|
+
"""
|
|
165
|
+
a = annihilation_operator(n_max)
|
|
166
|
+
return a.conj().T @ a
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def position_operator(n_max: int, m: float = 1.0, omega: float = 1.0, hbar: float = 1.0) -> np.ndarray:
|
|
170
|
+
r"""Harmonic-oscillator position operator in the truncated Fock basis,
|
|
171
|
+
|
|
172
|
+
.. math::
|
|
173
|
+
|
|
174
|
+
\hat x = \sqrt{\frac{\hbar}{2 m \omega}} \left(\hat a + \hat a^\dagger\right).
|
|
175
|
+
|
|
176
|
+
Parameters
|
|
177
|
+
----------
|
|
178
|
+
n_max : int
|
|
179
|
+
Dimension of the truncated Fock space.
|
|
180
|
+
m : float, default=1.0
|
|
181
|
+
Particle mass.
|
|
182
|
+
omega : float, default=1.0
|
|
183
|
+
Angular frequency of the oscillator.
|
|
184
|
+
hbar : float, default=1.0
|
|
185
|
+
Value of :math:`\hbar` to use.
|
|
186
|
+
|
|
187
|
+
Returns
|
|
188
|
+
-------
|
|
189
|
+
numpy.ndarray
|
|
190
|
+
The :math:`n_\text{max}\times n_\text{max}` matrix representation of
|
|
191
|
+
:math:`\hat x`.
|
|
192
|
+
"""
|
|
193
|
+
a = annihilation_operator(n_max)
|
|
194
|
+
return np.sqrt(hbar / (2 * m * omega)) * (a + a.conj().T)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def momentum_operator(n_max: int, m: float = 1.0, omega: float = 1.0, hbar: float = 1.0) -> np.ndarray:
|
|
198
|
+
r"""Harmonic-oscillator momentum operator in the truncated Fock basis,
|
|
199
|
+
|
|
200
|
+
.. math::
|
|
201
|
+
|
|
202
|
+
\hat p = i\sqrt{\frac{\hbar m \omega}{2}} \left(\hat a^\dagger - \hat a\right).
|
|
203
|
+
|
|
204
|
+
Parameters
|
|
205
|
+
----------
|
|
206
|
+
n_max : int
|
|
207
|
+
Dimension of the truncated Fock space.
|
|
208
|
+
m : float, default=1.0
|
|
209
|
+
Particle mass.
|
|
210
|
+
omega : float, default=1.0
|
|
211
|
+
Angular frequency of the oscillator.
|
|
212
|
+
hbar : float, default=1.0
|
|
213
|
+
Value of :math:`\hbar` to use.
|
|
214
|
+
|
|
215
|
+
Returns
|
|
216
|
+
-------
|
|
217
|
+
numpy.ndarray
|
|
218
|
+
The :math:`n_\text{max}\times n_\text{max}` matrix representation of
|
|
219
|
+
:math:`\hat p`.
|
|
220
|
+
"""
|
|
221
|
+
a = annihilation_operator(n_max)
|
|
222
|
+
return 1j * np.sqrt(hbar * m * omega / 2) * (a.conj().T - a)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# --- Algebra utilities ------------------------------------------------------
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def commutator(A: np.ndarray, B: np.ndarray) -> np.ndarray:
|
|
229
|
+
r"""The commutator :math:`[\hat A, \hat B] = \hat A \hat B - \hat B \hat A`.
|
|
230
|
+
|
|
231
|
+
Parameters
|
|
232
|
+
----------
|
|
233
|
+
A, B : numpy.ndarray
|
|
234
|
+
Square matrices of matching shape.
|
|
235
|
+
|
|
236
|
+
Returns
|
|
237
|
+
-------
|
|
238
|
+
numpy.ndarray
|
|
239
|
+
:math:`\hat A \hat B - \hat B \hat A`.
|
|
240
|
+
"""
|
|
241
|
+
return A @ B - B @ A
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def anticommutator(A: np.ndarray, B: np.ndarray) -> np.ndarray:
|
|
245
|
+
r"""The anticommutator :math:`\{\hat A, \hat B\} = \hat A \hat B + \hat B \hat A`.
|
|
246
|
+
|
|
247
|
+
Parameters
|
|
248
|
+
----------
|
|
249
|
+
A, B : numpy.ndarray
|
|
250
|
+
Square matrices of matching shape.
|
|
251
|
+
|
|
252
|
+
Returns
|
|
253
|
+
-------
|
|
254
|
+
numpy.ndarray
|
|
255
|
+
:math:`\hat A \hat B + \hat B \hat A`.
|
|
256
|
+
"""
|
|
257
|
+
return A @ B + B @ A
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def expectation(operator: np.ndarray, state: np.ndarray) -> complex:
|
|
261
|
+
r"""Expectation value :math:`\langle\psi\rvert \hat A \lvert\psi\rangle` of
|
|
262
|
+
an operator in a discrete-basis state vector.
|
|
263
|
+
|
|
264
|
+
Parameters
|
|
265
|
+
----------
|
|
266
|
+
operator : numpy.ndarray
|
|
267
|
+
The operator matrix :math:`\hat A`.
|
|
268
|
+
state : numpy.ndarray
|
|
269
|
+
The (not necessarily normalized) state vector :math:`\lvert\psi\rangle`;
|
|
270
|
+
flattened if not already 1D.
|
|
271
|
+
|
|
272
|
+
Returns
|
|
273
|
+
-------
|
|
274
|
+
complex
|
|
275
|
+
:math:`\langle\psi\rvert \hat A \lvert\psi\rangle`.
|
|
276
|
+
"""
|
|
277
|
+
state = np.asarray(state).reshape(-1)
|
|
278
|
+
return complex(np.vdot(state, operator @ state))
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def is_hermitian(A: np.ndarray, atol: float = 1e-10) -> bool:
|
|
282
|
+
r"""Check whether a matrix is Hermitian, :math:`\hat A = \hat A^\dagger`.
|
|
283
|
+
|
|
284
|
+
Parameters
|
|
285
|
+
----------
|
|
286
|
+
A : numpy.ndarray
|
|
287
|
+
The matrix to test.
|
|
288
|
+
atol : float, default=1e-10
|
|
289
|
+
Absolute tolerance passed to :func:`numpy.allclose`.
|
|
290
|
+
|
|
291
|
+
Returns
|
|
292
|
+
-------
|
|
293
|
+
bool
|
|
294
|
+
``True`` if ``A`` equals its conjugate transpose within ``atol``.
|
|
295
|
+
"""
|
|
296
|
+
return np.allclose(A, A.conj().T, atol=atol)
|