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,541 @@
|
|
|
1
|
+
r"""Non-stationary wave dynamics: free dispersion, the twin-slit experiment,
|
|
2
|
+
and quantum revivals in the infinite square well.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
from numba import njit
|
|
11
|
+
|
|
12
|
+
from .._compat import trapz
|
|
13
|
+
from ..core.solvers import SplitOperatorSolver2D
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"free_gaussian_wavepacket",
|
|
17
|
+
"GaussianDispersion",
|
|
18
|
+
"TwinSlit",
|
|
19
|
+
"QuantumRevival",
|
|
20
|
+
"double_slit_potential",
|
|
21
|
+
"propagate_double_slit",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def free_gaussian_wavepacket(x: np.ndarray, x0: float, sigma0: float, k0: float) -> np.ndarray:
|
|
26
|
+
r"""A minimum-uncertainty Gaussian wavepacket at :math:`t=0`.
|
|
27
|
+
|
|
28
|
+
.. math::
|
|
29
|
+
|
|
30
|
+
\psi(x,0) = (2\pi\sigma_0^2)^{-1/4}\,
|
|
31
|
+
\exp\!\left[-\frac{(x-x_0)^2}{4\sigma_0^2}\right] e^{ik_0 x}.
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
x : numpy.ndarray
|
|
36
|
+
Positions to evaluate at.
|
|
37
|
+
x0 : float
|
|
38
|
+
Center of the packet.
|
|
39
|
+
sigma0 : float
|
|
40
|
+
Initial width (:math:`\Delta x = \sigma_0`).
|
|
41
|
+
k0 : float
|
|
42
|
+
Central wavenumber.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
numpy.ndarray
|
|
47
|
+
"""
|
|
48
|
+
norm = (2 * np.pi * sigma0**2) ** (-0.25)
|
|
49
|
+
return norm * np.exp(-((x - x0) ** 2) / (4 * sigma0**2)) * np.exp(1j * k0 * x)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass
|
|
53
|
+
class GaussianDispersion:
|
|
54
|
+
r"""Free-particle spreading of a Gaussian wavepacket.
|
|
55
|
+
|
|
56
|
+
The exact analytic solution of the free-particle Schrodinger equation
|
|
57
|
+
for a Gaussian initial condition; used to benchmark the FFT
|
|
58
|
+
split-operator propagator.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
x0 : float, default=0.0
|
|
63
|
+
Initial center of the packet.
|
|
64
|
+
sigma0 : float, default=1.0
|
|
65
|
+
Initial width.
|
|
66
|
+
k0 : float, default=5.0
|
|
67
|
+
Central wavenumber.
|
|
68
|
+
hbar : float, default=1.0
|
|
69
|
+
Value of :math:`\hbar` to use.
|
|
70
|
+
m : float, default=1.0
|
|
71
|
+
Particle mass.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
x0: float = 0.0
|
|
75
|
+
sigma0: float = 1.0
|
|
76
|
+
k0: float = 5.0
|
|
77
|
+
hbar: float = 1.0
|
|
78
|
+
m: float = 1.0
|
|
79
|
+
|
|
80
|
+
def width(self, t: np.ndarray) -> np.ndarray:
|
|
81
|
+
r"""The spreading width :math:`\sigma(t)`.
|
|
82
|
+
|
|
83
|
+
.. math::
|
|
84
|
+
|
|
85
|
+
\sigma(t) = \sigma_0\sqrt{1 + \left(\frac{\hbar t}{2m\sigma_0^2}\right)^2}.
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
t : numpy.ndarray
|
|
90
|
+
|
|
91
|
+
Returns
|
|
92
|
+
-------
|
|
93
|
+
numpy.ndarray
|
|
94
|
+
"""
|
|
95
|
+
t = np.asarray(t)
|
|
96
|
+
return self.sigma0 * np.sqrt(1 + (self.hbar * t / (2 * self.m * self.sigma0**2)) ** 2)
|
|
97
|
+
|
|
98
|
+
def center(self, t: np.ndarray) -> np.ndarray:
|
|
99
|
+
r"""The ballistic center :math:`x_0 + (\hbar k_0/m)\,t`.
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
t : numpy.ndarray
|
|
104
|
+
|
|
105
|
+
Returns
|
|
106
|
+
-------
|
|
107
|
+
numpy.ndarray
|
|
108
|
+
"""
|
|
109
|
+
return self.x0 + (self.hbar * self.k0 / self.m) * np.asarray(t)
|
|
110
|
+
|
|
111
|
+
def psi(self, x: np.ndarray, t: float) -> np.ndarray:
|
|
112
|
+
"""The exact free-particle wavefunction :math:`\\psi(x,t)`.
|
|
113
|
+
|
|
114
|
+
Parameters
|
|
115
|
+
----------
|
|
116
|
+
x : numpy.ndarray
|
|
117
|
+
Positions to evaluate at.
|
|
118
|
+
t : float
|
|
119
|
+
Time.
|
|
120
|
+
|
|
121
|
+
Returns
|
|
122
|
+
-------
|
|
123
|
+
numpy.ndarray
|
|
124
|
+
Complex-valued.
|
|
125
|
+
"""
|
|
126
|
+
m, hbar, sigma0, k0, x0 = self.m, self.hbar, self.sigma0, self.k0, self.x0
|
|
127
|
+
a = sigma0**2 + 1j * hbar * t / (2 * m)
|
|
128
|
+
norm = (2 * np.pi * sigma0**2) ** (-0.25) * np.sqrt(sigma0**2 / a)
|
|
129
|
+
envelope = np.exp(-((x - x0 - hbar * k0 * t / m) ** 2) / (4 * a))
|
|
130
|
+
plane = np.exp(1j * k0 * (x - x0) - 1j * hbar * k0**2 * t / (2 * m))
|
|
131
|
+
return norm * envelope * plane
|
|
132
|
+
|
|
133
|
+
def density(self, x: np.ndarray, t: float) -> np.ndarray:
|
|
134
|
+
r"""The probability density :math:`\lvert\psi(x,t)\rvert^2`.
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
x : numpy.ndarray
|
|
139
|
+
Positions to evaluate at.
|
|
140
|
+
t : float
|
|
141
|
+
Time.
|
|
142
|
+
|
|
143
|
+
Returns
|
|
144
|
+
-------
|
|
145
|
+
numpy.ndarray
|
|
146
|
+
"""
|
|
147
|
+
return np.abs(self.psi(x, t)) ** 2
|
|
148
|
+
|
|
149
|
+
def trajectory(self, x: np.ndarray, t_values: np.ndarray) -> np.ndarray:
|
|
150
|
+
r"""Stack of :math:`\psi(x,t)` snapshots over a time grid.
|
|
151
|
+
|
|
152
|
+
Shaped for :func:`~physicskit.quantum.visualizers.wavefunctions.animate_density`.
|
|
153
|
+
|
|
154
|
+
Parameters
|
|
155
|
+
----------
|
|
156
|
+
x : numpy.ndarray
|
|
157
|
+
Positions to evaluate at.
|
|
158
|
+
t_values : numpy.ndarray
|
|
159
|
+
Times to evaluate at.
|
|
160
|
+
|
|
161
|
+
Returns
|
|
162
|
+
-------
|
|
163
|
+
numpy.ndarray
|
|
164
|
+
Complex-valued, shape ``(len(t_values), len(x))``.
|
|
165
|
+
"""
|
|
166
|
+
return np.array([self.psi(x, t) for t in t_values])
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
@dataclass
|
|
170
|
+
class TwinSlit:
|
|
171
|
+
r"""Young's double-slit for a massive particle.
|
|
172
|
+
|
|
173
|
+
Built from two coherent Gaussian point sources at the slit plane,
|
|
174
|
+
propagated freely to a downstream screen -- the quantum interference
|
|
175
|
+
pattern is the same :math:`\lvert\psi_1+\psi_2\rvert^2` mechanism as
|
|
176
|
+
light, now for massive-particle probability amplitude.
|
|
177
|
+
|
|
178
|
+
Parameters
|
|
179
|
+
----------
|
|
180
|
+
slit_separation : float, default=4.0
|
|
181
|
+
Distance between the two slits.
|
|
182
|
+
slit_width : float, default=0.4
|
|
183
|
+
Width of each slit (sets the Gaussian source envelope).
|
|
184
|
+
k0 : float, default=10.0
|
|
185
|
+
Central wavenumber of the incident beam.
|
|
186
|
+
hbar : float, default=1.0
|
|
187
|
+
Value of :math:`\hbar` to use.
|
|
188
|
+
m : float, default=1.0
|
|
189
|
+
Particle mass.
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
slit_separation: float = 4.0
|
|
193
|
+
slit_width: float = 0.4
|
|
194
|
+
k0: float = 10.0
|
|
195
|
+
hbar: float = 1.0
|
|
196
|
+
m: float = 1.0
|
|
197
|
+
|
|
198
|
+
def amplitude(self, x: np.ndarray, screen_distance: float, t: float | None = None) -> np.ndarray:
|
|
199
|
+
r"""Fraunhofer-style amplitude on a screen at distance :math:`L`.
|
|
200
|
+
|
|
201
|
+
Sums the two slit contributions with their propagation phase
|
|
202
|
+
:math:`kL + kx^2/2L` (paraxial/Fresnel approximation), :math:`x`
|
|
203
|
+
measured along the screen.
|
|
204
|
+
|
|
205
|
+
Parameters
|
|
206
|
+
----------
|
|
207
|
+
x : numpy.ndarray
|
|
208
|
+
Screen positions.
|
|
209
|
+
screen_distance : float
|
|
210
|
+
Distance :math:`L` from the slit plane to the screen.
|
|
211
|
+
t : float or None, optional
|
|
212
|
+
Unused; retained for API symmetry with time-dependent amplitudes.
|
|
213
|
+
|
|
214
|
+
Returns
|
|
215
|
+
-------
|
|
216
|
+
numpy.ndarray
|
|
217
|
+
Complex-valued amplitude.
|
|
218
|
+
"""
|
|
219
|
+
k = self.k0
|
|
220
|
+
L = screen_distance
|
|
221
|
+
d = self.slit_separation
|
|
222
|
+
w = self.slit_width
|
|
223
|
+
|
|
224
|
+
def slit_amp(y0):
|
|
225
|
+
# each slit acts as a Gaussian source of width w
|
|
226
|
+
r = np.sqrt(L**2 + (x - y0) ** 2)
|
|
227
|
+
phase = k * r
|
|
228
|
+
sinc_envelope = np.exp(-((x - y0) ** 2) * (w**2) / (4 * L**2 + 1e-12))
|
|
229
|
+
return sinc_envelope * np.exp(1j * phase) / np.sqrt(r)
|
|
230
|
+
|
|
231
|
+
return slit_amp(d / 2) + slit_amp(-d / 2)
|
|
232
|
+
|
|
233
|
+
def intensity(self, x: np.ndarray, screen_distance: float) -> np.ndarray:
|
|
234
|
+
r"""Normalized interference intensity :math:`\lvert\psi_1+\psi_2\rvert^2`.
|
|
235
|
+
|
|
236
|
+
Parameters
|
|
237
|
+
----------
|
|
238
|
+
x : numpy.ndarray
|
|
239
|
+
Screen positions.
|
|
240
|
+
screen_distance : float
|
|
241
|
+
Distance from the slit plane to the screen.
|
|
242
|
+
|
|
243
|
+
Returns
|
|
244
|
+
-------
|
|
245
|
+
numpy.ndarray
|
|
246
|
+
Normalized so that :math:`\int I\,dx = 1`.
|
|
247
|
+
"""
|
|
248
|
+
amp = self.amplitude(x, screen_distance)
|
|
249
|
+
I = np.abs(amp) ** 2
|
|
250
|
+
return I / trapz(I, x)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def double_slit_potential(
|
|
254
|
+
X: np.ndarray,
|
|
255
|
+
Y: np.ndarray,
|
|
256
|
+
wall_x: float = 0.0,
|
|
257
|
+
wall_thickness: float = 0.5,
|
|
258
|
+
slit_separation: float = 3.0,
|
|
259
|
+
slit_width: float = 0.8,
|
|
260
|
+
wall_height: float = 400.0,
|
|
261
|
+
) -> np.ndarray:
|
|
262
|
+
r"""An opaque wall at :math:`x=\text{wall\_x}` pierced by two gaps.
|
|
263
|
+
|
|
264
|
+
:math:`V=\text{wall\_height}` inside the wall slab except within two
|
|
265
|
+
strips of width ``slit_width`` centered at
|
|
266
|
+
:math:`y = \pm\text{slit\_separation}/2`, where :math:`V=0`.
|
|
267
|
+
|
|
268
|
+
Parameters
|
|
269
|
+
----------
|
|
270
|
+
X, Y : numpy.ndarray
|
|
271
|
+
Coordinate meshgrid (e.g. ``SplitOperatorSolver2D.X/.Y``).
|
|
272
|
+
wall_x : float, default=0.0
|
|
273
|
+
Position of the wall along :math:`x`.
|
|
274
|
+
wall_thickness : float, default=0.5
|
|
275
|
+
Thickness of the wall along :math:`x`.
|
|
276
|
+
slit_separation : float, default=3.0
|
|
277
|
+
Center-to-center distance between the two slits.
|
|
278
|
+
slit_width : float, default=0.8
|
|
279
|
+
Width of each slit (gap in the wall).
|
|
280
|
+
wall_height : float, default=400.0
|
|
281
|
+
Potential inside the opaque part of the wall.
|
|
282
|
+
|
|
283
|
+
Returns
|
|
284
|
+
-------
|
|
285
|
+
numpy.ndarray
|
|
286
|
+
:math:`V(x,y)` on the grid.
|
|
287
|
+
"""
|
|
288
|
+
in_wall = np.abs(X - wall_x) <= wall_thickness / 2
|
|
289
|
+
in_slit = (np.abs(Y - slit_separation / 2) <= slit_width / 2) | (np.abs(Y + slit_separation / 2) <= slit_width / 2)
|
|
290
|
+
return np.where(in_wall & ~in_slit, wall_height, 0.0)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def propagate_double_slit(
|
|
294
|
+
x: np.ndarray,
|
|
295
|
+
y: np.ndarray,
|
|
296
|
+
x0: float = -8.0,
|
|
297
|
+
k0: float = 8.0,
|
|
298
|
+
sigma_x: float = 0.7,
|
|
299
|
+
sigma_y: float = 4.0,
|
|
300
|
+
wall_x: float = 0.0,
|
|
301
|
+
wall_thickness: float = 0.5,
|
|
302
|
+
slit_separation: float = 3.0,
|
|
303
|
+
slit_width: float = 0.8,
|
|
304
|
+
wall_height: float = 400.0,
|
|
305
|
+
hbar: float = 1.0,
|
|
306
|
+
m: float = 1.0,
|
|
307
|
+
dt: float = 1e-4,
|
|
308
|
+
n_steps: int = 4000,
|
|
309
|
+
save_every: int = 40,
|
|
310
|
+
):
|
|
311
|
+
r"""Propagate a wavepacket through :func:`double_slit_potential`.
|
|
312
|
+
|
|
313
|
+
A genuinely time-propagated double-slit: a Gaussian packet, elongated
|
|
314
|
+
along :math:`y` (to illuminate both slits coherently) and moving along
|
|
315
|
+
:math:`+x` with wavenumber ``k0``, is evolved with
|
|
316
|
+
:class:`~physicskit.quantum.core.solvers.SplitOperatorSolver2D` through the
|
|
317
|
+
two-slit wall, producing the interference pattern building up downstream
|
|
318
|
+
from genuine wave dynamics rather than the far-field Fraunhofer formula
|
|
319
|
+
(:class:`TwinSlit`).
|
|
320
|
+
|
|
321
|
+
Parameters
|
|
322
|
+
----------
|
|
323
|
+
x, y : numpy.ndarray
|
|
324
|
+
Uniform spatial grids.
|
|
325
|
+
x0 : float, default=-8.0
|
|
326
|
+
Initial center of the packet along :math:`x` (should sit well
|
|
327
|
+
upstream of ``wall_x``).
|
|
328
|
+
k0 : float, default=8.0
|
|
329
|
+
Central wavenumber along :math:`x`.
|
|
330
|
+
sigma_x, sigma_y : float, default=0.7, 4.0
|
|
331
|
+
Initial packet widths (``sigma_y`` should span both slits).
|
|
332
|
+
wall_x, wall_thickness, slit_separation, slit_width, wall_height : float
|
|
333
|
+
Passed to :func:`double_slit_potential`.
|
|
334
|
+
hbar, m, dt : float
|
|
335
|
+
Propagation parameters, passed to
|
|
336
|
+
:class:`~physicskit.quantum.core.solvers.SplitOperatorSolver2D`.
|
|
337
|
+
n_steps : int, default=4000
|
|
338
|
+
Total number of time steps.
|
|
339
|
+
save_every : int, default=40
|
|
340
|
+
Save a snapshot every this many steps.
|
|
341
|
+
|
|
342
|
+
Returns
|
|
343
|
+
-------
|
|
344
|
+
X, Y : numpy.ndarray
|
|
345
|
+
The coordinate meshgrid.
|
|
346
|
+
frames : numpy.ndarray
|
|
347
|
+
Complex wavefunction snapshots, shape ``(n_saved, len(x), len(y))``.
|
|
348
|
+
times : numpy.ndarray
|
|
349
|
+
The time of each snapshot.
|
|
350
|
+
"""
|
|
351
|
+
|
|
352
|
+
def V(xx, yy):
|
|
353
|
+
return double_slit_potential(xx, yy, wall_x, wall_thickness, slit_separation, slit_width, wall_height)
|
|
354
|
+
|
|
355
|
+
solver = SplitOperatorSolver2D(x, y, V, hbar=hbar, m=m, dt=dt)
|
|
356
|
+
X, Y = solver.X, solver.Y
|
|
357
|
+
psi0 = np.exp(-((X - x0) ** 2) / (4 * sigma_x**2) - Y**2 / (4 * sigma_y**2)) * np.exp(1j * k0 * X)
|
|
358
|
+
frames, times = solver.propagate(psi0.astype(complex), n_steps, save_every=save_every)
|
|
359
|
+
return X, Y, frames, times
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
@njit(cache=True)
|
|
363
|
+
def _revival_sum(coeffs_re, coeffs_im, sin_table, n_values, energies_over_hbar, t):
|
|
364
|
+
"""Sum_n c_n phi_n(x) exp(-i E_n t/hbar) evaluated on the box eigenbasis,
|
|
365
|
+
vectorized manually for numba (coeffs and sin_table are precomputed)."""
|
|
366
|
+
n_states, n_x = sin_table.shape
|
|
367
|
+
out_re = np.zeros(n_x)
|
|
368
|
+
out_im = np.zeros(n_x)
|
|
369
|
+
for k in range(n_states):
|
|
370
|
+
phase = -energies_over_hbar[k] * t
|
|
371
|
+
cos_p = np.cos(phase)
|
|
372
|
+
sin_p = np.sin(phase)
|
|
373
|
+
# (c_re + i c_im)(cos_p + i sin_p) = (c_re cos_p - c_im sin_p) + i(c_re sin_p + c_im cos_p)
|
|
374
|
+
a = coeffs_re[k] * cos_p - coeffs_im[k] * sin_p
|
|
375
|
+
b = coeffs_re[k] * sin_p + coeffs_im[k] * cos_p
|
|
376
|
+
for j in range(n_x):
|
|
377
|
+
s = sin_table[k, j]
|
|
378
|
+
out_re[j] += a * s
|
|
379
|
+
out_im[j] += b * s
|
|
380
|
+
return out_re, out_im
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
@dataclass
|
|
384
|
+
class QuantumRevival:
|
|
385
|
+
r"""A localized wavepacket in an infinite square well of width :math:`L`.
|
|
386
|
+
|
|
387
|
+
Because :math:`E_n = n^2\pi^2\hbar^2/(2mL^2)` is quadratic in :math:`n`,
|
|
388
|
+
the packet disperses into apparent chaos yet exactly reassembles into
|
|
389
|
+
replicas of :math:`\psi(x,0)` at fractional multiples of the revival time
|
|
390
|
+
|
|
391
|
+
.. math::
|
|
392
|
+
|
|
393
|
+
t_\text{rev} = \frac{4mL^2}{\pi\hbar}
|
|
394
|
+
|
|
395
|
+
(since :math:`E_n = n^2\cdot(\hbar\cdot 2\pi/t_\text{rev})/2`), with a
|
|
396
|
+
mirror-image replica at :math:`t_\text{rev}/2`, and reduced-scale
|
|
397
|
+
"fractional revivals" (clones/anti-clones) at rational fractions
|
|
398
|
+
:math:`t_\text{rev}\cdot(p/q)`.
|
|
399
|
+
|
|
400
|
+
Parameters
|
|
401
|
+
----------
|
|
402
|
+
L : float, default=1.0
|
|
403
|
+
Well width.
|
|
404
|
+
hbar : float, default=1.0
|
|
405
|
+
Value of :math:`\hbar` to use.
|
|
406
|
+
m : float, default=1.0
|
|
407
|
+
Particle mass.
|
|
408
|
+
n_max : int, default=400
|
|
409
|
+
Number of box eigenstates used in the expansion.
|
|
410
|
+
"""
|
|
411
|
+
|
|
412
|
+
L: float = 1.0
|
|
413
|
+
hbar: float = 1.0
|
|
414
|
+
m: float = 1.0
|
|
415
|
+
n_max: int = 400
|
|
416
|
+
|
|
417
|
+
def energy(self, n: np.ndarray) -> np.ndarray:
|
|
418
|
+
r"""Box eigenenergy :math:`E_n = n^2\pi^2\hbar^2/(2mL^2)`.
|
|
419
|
+
|
|
420
|
+
Parameters
|
|
421
|
+
----------
|
|
422
|
+
n : numpy.ndarray
|
|
423
|
+
|
|
424
|
+
Returns
|
|
425
|
+
-------
|
|
426
|
+
numpy.ndarray
|
|
427
|
+
"""
|
|
428
|
+
return (n**2 * np.pi**2 * self.hbar**2) / (2 * self.m * self.L**2)
|
|
429
|
+
|
|
430
|
+
@property
|
|
431
|
+
def revival_time(self) -> float:
|
|
432
|
+
r"""float: The revival time :math:`t_\text{rev} = 4mL^2/(\pi\hbar)`."""
|
|
433
|
+
return 4 * self.m * self.L**2 / (np.pi * self.hbar)
|
|
434
|
+
|
|
435
|
+
def eigenbasis_coefficients(self, psi0_func, n_grid: int = 4000) -> np.ndarray:
|
|
436
|
+
r"""Box-eigenbasis expansion coefficients of an initial state.
|
|
437
|
+
|
|
438
|
+
.. math::
|
|
439
|
+
|
|
440
|
+
c_n = \langle\phi_n\rvert\psi_0\rangle, \qquad
|
|
441
|
+
\phi_n(x) = \sqrt{2/L}\,\sin(n\pi x/L).
|
|
442
|
+
|
|
443
|
+
Parameters
|
|
444
|
+
----------
|
|
445
|
+
psi0_func : callable
|
|
446
|
+
Function ``psi0_func(x) -> array`` giving the initial state.
|
|
447
|
+
n_grid : int, default=4000
|
|
448
|
+
Number of quadrature points used to evaluate the overlap integral.
|
|
449
|
+
|
|
450
|
+
Returns
|
|
451
|
+
-------
|
|
452
|
+
numpy.ndarray
|
|
453
|
+
Coefficients :math:`c_n`, shape ``(n_max,)``.
|
|
454
|
+
"""
|
|
455
|
+
x = np.linspace(0, self.L, n_grid)
|
|
456
|
+
psi0 = psi0_func(x)
|
|
457
|
+
n = np.arange(1, self.n_max + 1)
|
|
458
|
+
sin_table = np.sqrt(2.0 / self.L) * np.sin(np.outer(n, np.pi * x / self.L))
|
|
459
|
+
c = trapz(sin_table * psi0[None, :], x, axis=1)
|
|
460
|
+
return c
|
|
461
|
+
|
|
462
|
+
def wavefunction(self, x: np.ndarray, t: float, coeffs: np.ndarray) -> np.ndarray:
|
|
463
|
+
r"""Evaluate the evolved state :math:`\psi(x,t) = \sum_n c_n \phi_n(x)
|
|
464
|
+
e^{-iE_n t/\hbar}`.
|
|
465
|
+
|
|
466
|
+
Parameters
|
|
467
|
+
----------
|
|
468
|
+
x : numpy.ndarray
|
|
469
|
+
Positions to evaluate at.
|
|
470
|
+
t : float
|
|
471
|
+
Time.
|
|
472
|
+
coeffs : numpy.ndarray
|
|
473
|
+
Expansion coefficients from :meth:`eigenbasis_coefficients`.
|
|
474
|
+
|
|
475
|
+
Returns
|
|
476
|
+
-------
|
|
477
|
+
numpy.ndarray
|
|
478
|
+
Complex-valued :math:`\psi(x,t)`.
|
|
479
|
+
"""
|
|
480
|
+
n = np.arange(1, self.n_max + 1)
|
|
481
|
+
sin_table = np.sqrt(2.0 / self.L) * np.sin(np.outer(n, np.pi * x / self.L))
|
|
482
|
+
energies_over_hbar = self.energy(n) / self.hbar
|
|
483
|
+
out_re, out_im = _revival_sum(
|
|
484
|
+
np.ascontiguousarray(coeffs.real),
|
|
485
|
+
np.ascontiguousarray(coeffs.imag),
|
|
486
|
+
np.ascontiguousarray(sin_table),
|
|
487
|
+
n,
|
|
488
|
+
energies_over_hbar,
|
|
489
|
+
t,
|
|
490
|
+
)
|
|
491
|
+
return out_re + 1j * out_im
|
|
492
|
+
|
|
493
|
+
def gaussian_initial_state(self, x0: float, sigma: float):
|
|
494
|
+
"""Build a normalized Gaussian initial-state function for the box.
|
|
495
|
+
|
|
496
|
+
Parameters
|
|
497
|
+
----------
|
|
498
|
+
x0 : float
|
|
499
|
+
Center of the packet (should lie well inside ``(0, L)``).
|
|
500
|
+
sigma : float
|
|
501
|
+
Width of the packet.
|
|
502
|
+
|
|
503
|
+
Returns
|
|
504
|
+
-------
|
|
505
|
+
callable
|
|
506
|
+
A function ``psi0(x) -> array`` (zero outside ``[0, L]``).
|
|
507
|
+
"""
|
|
508
|
+
|
|
509
|
+
def psi0(x):
|
|
510
|
+
packet = np.exp(-((x - x0) ** 2) / (4 * sigma**2))
|
|
511
|
+
packet[x <= 0] = 0.0
|
|
512
|
+
packet[x >= self.L] = 0.0
|
|
513
|
+
norm = np.sqrt(trapz(np.abs(packet) ** 2, np.linspace(0, self.L, x.shape[0])))
|
|
514
|
+
return packet / norm
|
|
515
|
+
|
|
516
|
+
return psi0
|
|
517
|
+
|
|
518
|
+
def fidelity_to_initial(self, x: np.ndarray, t: float, coeffs: np.ndarray, psi0: np.ndarray) -> float:
|
|
519
|
+
r"""Fidelity :math:`\lvert\langle\psi_0\rvert\psi(t)\rangle\rvert^2`
|
|
520
|
+
of the evolved state to the initial state.
|
|
521
|
+
|
|
522
|
+
Approaches 1 at (fractional) revival times.
|
|
523
|
+
|
|
524
|
+
Parameters
|
|
525
|
+
----------
|
|
526
|
+
x : numpy.ndarray
|
|
527
|
+
Positions to evaluate at.
|
|
528
|
+
t : float
|
|
529
|
+
Time.
|
|
530
|
+
coeffs : numpy.ndarray
|
|
531
|
+
Expansion coefficients from :meth:`eigenbasis_coefficients`.
|
|
532
|
+
psi0 : numpy.ndarray
|
|
533
|
+
The initial state sampled on ``x``.
|
|
534
|
+
|
|
535
|
+
Returns
|
|
536
|
+
-------
|
|
537
|
+
float
|
|
538
|
+
"""
|
|
539
|
+
psi_t = self.wavefunction(x, t, coeffs)
|
|
540
|
+
overlap = trapz(np.conj(psi0) * psi_t, x)
|
|
541
|
+
return float(np.abs(overlap) ** 2)
|
|
File without changes
|