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,274 @@
|
|
|
1
|
+
"""Quantum billiards: eigenvalues and eigenfunctions of physicskit.chaos's classical billiard shapes.
|
|
2
|
+
|
|
3
|
+
Solves the Dirichlet Helmholtz (quantum-particle-in-a-box) eigenproblem
|
|
4
|
+
``-laplacian(psi) = k^2 * psi`` (``psi = 0`` on the boundary) inside any
|
|
5
|
+
:class:`~physicskit.chaos.core.base_system.BilliardSystem` shape physicskit.chaos ships,
|
|
6
|
+
using a straightforward five-point finite-difference discretization -- lower
|
|
7
|
+
accuracy than a dedicated boundary-integral eigensolver, but simple, robust,
|
|
8
|
+
and shape-agnostic, since it only needs each billiard's existing
|
|
9
|
+
:meth:`~physicskit.chaos.core.base_system.BilliardSystem.boundary_polyline` to know
|
|
10
|
+
which grid points are inside.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
import scipy.sparse
|
|
17
|
+
import scipy.sparse.linalg
|
|
18
|
+
from numpy.typing import NDArray
|
|
19
|
+
|
|
20
|
+
from physicskit.chaos.core.base_system import BilliardSystem, get_init_params
|
|
21
|
+
from physicskit.chaos.exceptions import InvalidParameterError
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _split_loops(polyline: NDArray[np.float64]) -> list[NDArray[np.float64]]:
|
|
25
|
+
"""Split a NaN-separated boundary polyline into its closed-loop components."""
|
|
26
|
+
nan_rows = np.flatnonzero(np.isnan(polyline[:, 0])).tolist() + [polyline.shape[0]]
|
|
27
|
+
loops = []
|
|
28
|
+
start = 0
|
|
29
|
+
for end in nan_rows:
|
|
30
|
+
loop = polyline[start:end]
|
|
31
|
+
if loop.shape[0] >= 3:
|
|
32
|
+
loops.append(loop)
|
|
33
|
+
start = end + 1
|
|
34
|
+
return loops
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _ray_cast(loop: NDArray[np.float64], x: NDArray[np.float64], y: NDArray[np.float64]) -> NDArray[np.bool_]:
|
|
38
|
+
"""Even-odd ray-casting point-in-polygon test, vectorized over query points."""
|
|
39
|
+
inside = np.zeros(x.shape, dtype=bool)
|
|
40
|
+
x1, y1 = loop[-1]
|
|
41
|
+
for x2, y2 in loop:
|
|
42
|
+
crosses = (y1 > y) != (y2 > y)
|
|
43
|
+
with np.errstate(divide="ignore", invalid="ignore"):
|
|
44
|
+
x_intersect = (x2 - x1) * (y - y1) / (y2 - y1) + x1
|
|
45
|
+
inside ^= crosses & (x < x_intersect)
|
|
46
|
+
x1, y1 = x2, y2
|
|
47
|
+
return inside
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def points_in_billiard(billiard: BilliardSystem, points: NDArray[np.float64]) -> NDArray[np.bool_]:
|
|
51
|
+
"""Test which of `points` lie inside a billiard's boundary.
|
|
52
|
+
|
|
53
|
+
Applies the even-odd fill rule across every closed component of the
|
|
54
|
+
billiard's :meth:`~physicskit.chaos.core.base_system.BilliardSystem.boundary_polyline`,
|
|
55
|
+
so shapes with an excised interior scatterer (e.g.
|
|
56
|
+
:class:`~physicskit.chaos.systems.billiards.SinaiBilliard`) are handled correctly
|
|
57
|
+
regardless of each component's winding direction.
|
|
58
|
+
|
|
59
|
+
Parameters
|
|
60
|
+
----------
|
|
61
|
+
billiard : BilliardSystem
|
|
62
|
+
Billiard whose boundary defines the domain.
|
|
63
|
+
points : ndarray of float, shape (n, 2)
|
|
64
|
+
Query points.
|
|
65
|
+
|
|
66
|
+
Returns
|
|
67
|
+
-------
|
|
68
|
+
ndarray of bool, shape (n,)
|
|
69
|
+
Whether each point lies inside the billiard.
|
|
70
|
+
"""
|
|
71
|
+
loops = _split_loops(billiard.boundary_polyline())
|
|
72
|
+
x, y = points[:, 0], points[:, 1]
|
|
73
|
+
inside = np.zeros(x.shape, dtype=bool)
|
|
74
|
+
for loop in loops:
|
|
75
|
+
inside ^= _ray_cast(loop, x, y)
|
|
76
|
+
return inside
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class QuantumBilliard:
|
|
80
|
+
"""Dirichlet Helmholtz eigenstates of a billiard: "particle in a box" quantum chaos.
|
|
81
|
+
|
|
82
|
+
A quantum particle confined to a chaotic billiard is one of the two
|
|
83
|
+
textbook playgrounds of quantum chaos (alongside quantized maps like
|
|
84
|
+
:class:`~physicskit.chaos.quantum.maps.QuantumKickedRotor`): its energy
|
|
85
|
+
eigenvalues ``E_n = k_n^2`` (in units where ``hbar^2 / 2m = 1``) obey
|
|
86
|
+
Weyl's law on average (see :meth:`weyl_counting_function`) but fluctuate
|
|
87
|
+
around it in a way that reflects the underlying classical dynamics, and
|
|
88
|
+
its eigenfunctions can "scar" -- show anomalously enhanced density -- on
|
|
89
|
+
unstable classical periodic orbits.
|
|
90
|
+
|
|
91
|
+
Built directly from any :class:`~physicskit.chaos.core.base_system.BilliardSystem`
|
|
92
|
+
already in physicskit.chaos (no shape-specific code needed): a regular grid is
|
|
93
|
+
laid over the shape's bounding box, points inside the boundary (via
|
|
94
|
+
:func:`points_in_billiard`) become unknowns of a standard five-point
|
|
95
|
+
finite-difference Laplacian, and the lowest eigenpairs of the resulting
|
|
96
|
+
sparse, symmetric positive-definite matrix are found by shift-invert
|
|
97
|
+
Lanczos iteration.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
billiard : BilliardSystem
|
|
102
|
+
The billiard shape to quantize.
|
|
103
|
+
resolution : int, default 150
|
|
104
|
+
Number of grid points along the longer side of the billiard's
|
|
105
|
+
bounding box; the grid spacing (and hence both the accuracy and the
|
|
106
|
+
cost of solving for eigenstates) scales with this.
|
|
107
|
+
|
|
108
|
+
Attributes
|
|
109
|
+
----------
|
|
110
|
+
billiard : BilliardSystem
|
|
111
|
+
The billiard shape.
|
|
112
|
+
resolution : int
|
|
113
|
+
Grid resolution.
|
|
114
|
+
|
|
115
|
+
Raises
|
|
116
|
+
------
|
|
117
|
+
InvalidParameterError
|
|
118
|
+
If `resolution` is smaller than 10.
|
|
119
|
+
|
|
120
|
+
Notes
|
|
121
|
+
-----
|
|
122
|
+
Finite differences converge slowly (error ``O(h^2)``) and, being defined
|
|
123
|
+
on a Cartesian grid, represent curved or slanted boundaries only
|
|
124
|
+
approximately; treat eigenvalues as accurate to a few percent at the
|
|
125
|
+
default `resolution`; increase `resolution` for tighter results, at
|
|
126
|
+
roughly quadratic cost in memory and eigensolver runtime.
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
def __init__(self, billiard: BilliardSystem, resolution: int = 150):
|
|
130
|
+
if resolution < 10:
|
|
131
|
+
raise InvalidParameterError("resolution must be at least 10")
|
|
132
|
+
self.billiard = billiard
|
|
133
|
+
self.resolution = int(resolution)
|
|
134
|
+
self._build_grid()
|
|
135
|
+
|
|
136
|
+
def _build_grid(self) -> None:
|
|
137
|
+
polyline = self.billiard.boundary_polyline()
|
|
138
|
+
finite = polyline[~np.isnan(polyline[:, 0])]
|
|
139
|
+
xmin, xmax = finite[:, 0].min(), finite[:, 0].max()
|
|
140
|
+
ymin, ymax = finite[:, 1].min(), finite[:, 1].max()
|
|
141
|
+
|
|
142
|
+
h = max(xmax - xmin, ymax - ymin) / self.resolution
|
|
143
|
+
nx = int(np.ceil((xmax - xmin) / h)) + 3
|
|
144
|
+
ny = int(np.ceil((ymax - ymin) / h)) + 3
|
|
145
|
+
xs = (xmin - h) + h * np.arange(nx)
|
|
146
|
+
ys = (ymin - h) + h * np.arange(ny)
|
|
147
|
+
|
|
148
|
+
x_grid, y_grid = np.meshgrid(xs, ys, indexing="ij")
|
|
149
|
+
points = np.column_stack([x_grid.ravel(), y_grid.ravel()])
|
|
150
|
+
inside = points_in_billiard(self.billiard, points).reshape(x_grid.shape)
|
|
151
|
+
|
|
152
|
+
self._h = h
|
|
153
|
+
self._xs, self._ys = xs, ys
|
|
154
|
+
self._x_grid, self._y_grid = x_grid, y_grid
|
|
155
|
+
self._inside = inside
|
|
156
|
+
|
|
157
|
+
def eigenstates(self, n_states: int = 6) -> tuple[NDArray[np.float64], NDArray[np.float64]]:
|
|
158
|
+
"""Solve for the lowest `n_states` Dirichlet eigenpairs.
|
|
159
|
+
|
|
160
|
+
Parameters
|
|
161
|
+
----------
|
|
162
|
+
n_states : int, default 6
|
|
163
|
+
Number of lowest eigenstates to compute.
|
|
164
|
+
|
|
165
|
+
Returns
|
|
166
|
+
-------
|
|
167
|
+
eigenvalues : ndarray of float, shape (n_states,)
|
|
168
|
+
Eigenvalues ``k_n^2``, ascending.
|
|
169
|
+
eigenfunctions : ndarray of float, shape (n_states, nx, ny)
|
|
170
|
+
Eigenfunctions on the grid returned by :meth:`grid`, each
|
|
171
|
+
normalized to a peak absolute value of 1; grid points outside
|
|
172
|
+
the billiard are ``nan`` (so ``plt.imshow``/``pcolormesh`` leave
|
|
173
|
+
them blank).
|
|
174
|
+
"""
|
|
175
|
+
inside = self._inside
|
|
176
|
+
nx, ny = inside.shape
|
|
177
|
+
index = -np.ones((nx, ny), dtype=np.int64)
|
|
178
|
+
interior_ij = np.argwhere(inside)
|
|
179
|
+
index[inside] = np.arange(interior_ij.shape[0])
|
|
180
|
+
n_interior = interior_ij.shape[0]
|
|
181
|
+
h2 = self._h**2
|
|
182
|
+
|
|
183
|
+
rows: list[int] = []
|
|
184
|
+
cols: list[int] = []
|
|
185
|
+
data: list[float] = []
|
|
186
|
+
for k, (i, j) in enumerate(interior_ij):
|
|
187
|
+
rows.append(k)
|
|
188
|
+
cols.append(k)
|
|
189
|
+
data.append(4.0 / h2)
|
|
190
|
+
for di, dj in ((1, 0), (-1, 0), (0, 1), (0, -1)):
|
|
191
|
+
ni, nj = i + di, j + dj
|
|
192
|
+
if 0 <= ni < nx and 0 <= nj < ny and inside[ni, nj]:
|
|
193
|
+
rows.append(k)
|
|
194
|
+
cols.append(int(index[ni, nj]))
|
|
195
|
+
data.append(-1.0 / h2)
|
|
196
|
+
|
|
197
|
+
laplacian = scipy.sparse.csr_matrix((data, (rows, cols)), shape=(n_interior, n_interior))
|
|
198
|
+
eigenvalues, eigenvectors = scipy.sparse.linalg.eigsh(laplacian, k=n_states, sigma=0.0, which="LM")
|
|
199
|
+
order = np.argsort(eigenvalues)
|
|
200
|
+
eigenvalues = eigenvalues[order]
|
|
201
|
+
eigenvectors = eigenvectors[:, order]
|
|
202
|
+
|
|
203
|
+
eigenfunctions = np.full((n_states, nx, ny), np.nan)
|
|
204
|
+
for m in range(n_states):
|
|
205
|
+
full = np.full((nx, ny), np.nan)
|
|
206
|
+
full[inside] = eigenvectors[:, m]
|
|
207
|
+
full /= np.nanmax(np.abs(full))
|
|
208
|
+
eigenfunctions[m] = full
|
|
209
|
+
return eigenvalues, eigenfunctions
|
|
210
|
+
|
|
211
|
+
def wavenumbers(self, n_states: int = 6) -> NDArray[np.float64]:
|
|
212
|
+
"""Wavenumbers ``k_n = sqrt(eigenvalue)`` of the lowest `n_states` states.
|
|
213
|
+
|
|
214
|
+
Parameters
|
|
215
|
+
----------
|
|
216
|
+
n_states : int, default 6
|
|
217
|
+
Number of lowest eigenstates to compute.
|
|
218
|
+
|
|
219
|
+
Returns
|
|
220
|
+
-------
|
|
221
|
+
ndarray of float, shape (n_states,)
|
|
222
|
+
Wavenumbers, ascending.
|
|
223
|
+
"""
|
|
224
|
+
eigenvalues, _ = self.eigenstates(n_states)
|
|
225
|
+
return np.sqrt(eigenvalues)
|
|
226
|
+
|
|
227
|
+
def grid(self) -> tuple[NDArray[np.float64], NDArray[np.float64]]:
|
|
228
|
+
"""The Cartesian grid eigenfunctions are returned on.
|
|
229
|
+
|
|
230
|
+
Returns
|
|
231
|
+
-------
|
|
232
|
+
X, Y : ndarray of float, shape (nx, ny)
|
|
233
|
+
Grid coordinates (as from ``np.meshgrid(..., indexing="ij")``).
|
|
234
|
+
"""
|
|
235
|
+
return self._x_grid, self._y_grid
|
|
236
|
+
|
|
237
|
+
def area(self) -> float:
|
|
238
|
+
"""Interior area, estimated by counting grid points inside the boundary.
|
|
239
|
+
|
|
240
|
+
Returns
|
|
241
|
+
-------
|
|
242
|
+
float
|
|
243
|
+
Approximate billiard area.
|
|
244
|
+
"""
|
|
245
|
+
return float(np.sum(self._inside)) * self._h**2
|
|
246
|
+
|
|
247
|
+
def weyl_counting_function(self, k: NDArray[np.float64] | float) -> NDArray[np.float64] | float:
|
|
248
|
+
"""Weyl's law: the average number of eigenvalues below wavenumber `k`.
|
|
249
|
+
|
|
250
|
+
``N(k) ~ Area * k^2 / (4*pi) - Perimeter * k / (4*pi)``, the leading
|
|
251
|
+
area term plus the first-order (Dirichlet) boundary correction. Real
|
|
252
|
+
billiards' actual eigenvalue counts fluctuate around this smooth
|
|
253
|
+
curve; how they fluctuate (level "rigidity") is a hallmark of
|
|
254
|
+
whether the classical billiard is integrable or chaotic -- exactly
|
|
255
|
+
the kind of spectral statistic ``physicskit.rmt`` is built to quantify, using
|
|
256
|
+
:meth:`wavenumbers` as its input.
|
|
257
|
+
|
|
258
|
+
Parameters
|
|
259
|
+
----------
|
|
260
|
+
k : float or array_like of float
|
|
261
|
+
Wavenumber(s) at which to evaluate the counting function.
|
|
262
|
+
|
|
263
|
+
Returns
|
|
264
|
+
-------
|
|
265
|
+
float or ndarray of float
|
|
266
|
+
Expected (smoothed) number of eigenvalues below `k`.
|
|
267
|
+
"""
|
|
268
|
+
area = self.area()
|
|
269
|
+
perimeter = self.billiard.perimeter()
|
|
270
|
+
return area * k**2 / (4.0 * np.pi) - perimeter * k / (4.0 * np.pi)
|
|
271
|
+
|
|
272
|
+
def __repr__(self) -> str:
|
|
273
|
+
parts = [f"{name}={value!r}" for name, value in get_init_params(self).items()]
|
|
274
|
+
return f"{type(self).__name__}({', '.join(parts)})"
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""The Husimi (coherent-state) phase-space representation of a state on a torus.
|
|
2
|
+
|
|
3
|
+
Shared by :class:`~physicskit.chaos.quantum.maps.QuantumKickedRotor` and
|
|
4
|
+
:class:`~physicskit.chaos.quantum.maps.QuantumBakersMap`, whose Hilbert spaces are both
|
|
5
|
+
built on a position basis evenly spaced around a periodic ``[0, q_period)``
|
|
6
|
+
domain -- the Husimi construction below only depends on that shared structure,
|
|
7
|
+
not on which map produced the state.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
from numpy.typing import NDArray
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def husimi_function(
|
|
17
|
+
psi: NDArray[np.complexfloating],
|
|
18
|
+
hbar: float,
|
|
19
|
+
q_period: float,
|
|
20
|
+
resolution: int = 80,
|
|
21
|
+
n_wraps: int = 3,
|
|
22
|
+
) -> tuple[NDArray[np.float64], NDArray[np.float64], NDArray[np.float64]]:
|
|
23
|
+
"""Husimi (coherent-state overlap) phase-space distribution of a state.
|
|
24
|
+
|
|
25
|
+
The Husimi function ``Q(q0, p0) = |<q0, p0|psi>|^2`` is the state's
|
|
26
|
+
overlap with minimum-uncertainty coherent states centered at every point
|
|
27
|
+
``(q0, p0)`` of phase space -- the standard way to see a quantum state
|
|
28
|
+
"on top of" classical phase space (e.g. a classical Poincare section or
|
|
29
|
+
a classical map's orbits), since it is everywhere non-negative and
|
|
30
|
+
smoothly spread out, unlike the (generally negative-valued) Wigner
|
|
31
|
+
function.
|
|
32
|
+
|
|
33
|
+
Both :class:`~physicskit.chaos.quantum.maps.QuantumKickedRotor` and
|
|
34
|
+
:class:`~physicskit.chaos.quantum.maps.QuantumBakersMap` live on a position
|
|
35
|
+
basis of `N` points evenly spaced around a periodic domain
|
|
36
|
+
``[0, q_period)`` (``q_period = 2*pi`` for the kicked rotor's angle,
|
|
37
|
+
``q_period = 1`` for the baker's map's unit interval); the coherent
|
|
38
|
+
states used here are periodized Gaussians of width ``sqrt(hbar *
|
|
39
|
+
q_period / (2*pi))`` on that same domain, so this one function serves
|
|
40
|
+
both.
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
psi : ndarray of complex, shape (N,)
|
|
45
|
+
State vector in the position representation (`N` basis points
|
|
46
|
+
evenly spaced over ``[0, q_period)``); need not be normalized.
|
|
47
|
+
hbar : float
|
|
48
|
+
Effective Planck constant of the underlying quantum map.
|
|
49
|
+
q_period : float
|
|
50
|
+
Length of the (periodic) position and momentum domain, e.g.
|
|
51
|
+
``2*pi`` for the kicked rotor or ``1.0`` for the baker's map.
|
|
52
|
+
resolution : int, default 80
|
|
53
|
+
Number of grid points along each of the ``q`` and ``p`` axes.
|
|
54
|
+
n_wraps : int, default 3
|
|
55
|
+
Number of periodic images summed on each side to periodize the
|
|
56
|
+
coherent state around the torus; 3 is already accurate to
|
|
57
|
+
essentially machine precision for the Gaussian widths used here.
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
Q0, P0 : ndarray of float, shape (resolution, resolution)
|
|
62
|
+
Phase-space grid (as from ``np.meshgrid(..., indexing="ij")``).
|
|
63
|
+
husimi : ndarray of float, shape (resolution, resolution)
|
|
64
|
+
The Husimi distribution, normalized to a peak value of 1 (this is a
|
|
65
|
+
relative-intensity plotting convenience, not a probability density
|
|
66
|
+
normalized to unit integral).
|
|
67
|
+
"""
|
|
68
|
+
psi = np.asarray(psi, dtype=np.complex128)
|
|
69
|
+
n = psi.shape[0]
|
|
70
|
+
q_j = np.arange(n) * (q_period / n)
|
|
71
|
+
sigma2 = hbar * q_period / (2.0 * np.pi)
|
|
72
|
+
|
|
73
|
+
q0 = np.linspace(0.0, q_period, resolution, endpoint=False)
|
|
74
|
+
p0 = np.linspace(0.0, q_period, resolution, endpoint=False)
|
|
75
|
+
Q0, P0 = np.meshgrid(q0, p0, indexing="ij")
|
|
76
|
+
|
|
77
|
+
overlap = np.zeros(Q0.shape, dtype=np.complex128)
|
|
78
|
+
for m in range(-n_wraps, n_wraps + 1):
|
|
79
|
+
dq = q_j[None, None, :] - Q0[:, :, None] - m * q_period
|
|
80
|
+
coherent = np.exp(-(dq**2) / (2.0 * sigma2)) * np.exp(1j * P0[:, :, None] * dq / hbar)
|
|
81
|
+
overlap += np.tensordot(np.conj(coherent), psi, axes=([2], [0]))
|
|
82
|
+
|
|
83
|
+
husimi = np.abs(overlap) ** 2
|
|
84
|
+
husimi /= husimi.max()
|
|
85
|
+
return Q0, P0, husimi
|