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,104 @@
|
|
|
1
|
+
"""Circular ensembles -- COE, CUE, CSE.
|
|
2
|
+
|
|
3
|
+
References
|
|
4
|
+
----------
|
|
5
|
+
F. J. Dyson, "Statistical Theory of the Energy Levels of Complex Systems
|
|
6
|
+
I-III", J. Math. Phys. 3 (1962) 140, 157, 166 -- the original
|
|
7
|
+
circular-ensemble classification, and the source of Dyson's beta=1,2,4
|
|
8
|
+
threefold way.
|
|
9
|
+
F. Mezzadri, Notices Amer. Math. Soc. 54 (2007) 592 -- the Haar-random
|
|
10
|
+
sampling recipe used here.
|
|
11
|
+
|
|
12
|
+
Important construction note (this is easy to get wrong): COE and CSE
|
|
13
|
+
are NOT simply "eigenvalues of a Haar-random matrix from O(n) / Sp(n)".
|
|
14
|
+
A real orthogonal matrix's eigenvalues are either +-1 or complex-conjugate
|
|
15
|
+
pairs -- not the generic unit-circle structure a circular ensemble
|
|
16
|
+
requires. Dyson's actual constructions::
|
|
17
|
+
|
|
18
|
+
CUE: eigenvalues of U, U Haar-random from U(n).
|
|
19
|
+
COE: eigenvalues of U = V^T V, V Haar-random from U(n) -- a
|
|
20
|
+
*symmetric* unitary matrix, built from a unitary building block.
|
|
21
|
+
CSE: eigenvalues of U = V^R V, V Haar-random from U(2n), where
|
|
22
|
+
V^R = Z V^T Z^{-1} is the symplectic dual (Z the symplectic
|
|
23
|
+
form). U is self-dual unitary; its 2n eigenvalues come in n
|
|
24
|
+
doubly-degenerate pairs, of which n distinct values are the CSE
|
|
25
|
+
eigenvalues.
|
|
26
|
+
|
|
27
|
+
All three were verified during development by checking their unfolded
|
|
28
|
+
level-spacing statistics against the already-validated (generalized)
|
|
29
|
+
Wigner surmise at the matching beta -- see ``tests/test_circular.py``.
|
|
30
|
+
This is a meaningful cross-family check: spacing statistics are
|
|
31
|
+
universal in beta across the Gaussian and circular families, so
|
|
32
|
+
agreement here is independent evidence the constructions are correct,
|
|
33
|
+
not just that "some points ended up on a circle".
|
|
34
|
+
|
|
35
|
+
Eigenvalue representation: ``Spectrum.eigenvalues`` for these ensembles
|
|
36
|
+
holds the eigenvalue *phases* theta in [0, 2*pi), not the complex
|
|
37
|
+
eigenvalues e^{i*theta} themselves -- this keeps the rest of the
|
|
38
|
+
(real-array-based) stats machinery directly usable. ``natural_scale`` is
|
|
39
|
+
set to 2*pi/n, so ``Spectrum.rescaled`` is already fully unfolded with
|
|
40
|
+
exactly unit mean spacing -- exactly, not just asymptotically, since
|
|
41
|
+
Haar measure is exactly rotation-invariant at any finite n. This is a
|
|
42
|
+
structural simplification relative to the Gaussian/Wishart ensembles,
|
|
43
|
+
which only have unit mean spacing after unfolding against their
|
|
44
|
+
(asymptotic) limiting density.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
import numpy as np
|
|
48
|
+
|
|
49
|
+
from ..utils.haar import haar_unitary, symplectic_form
|
|
50
|
+
from .base import MatrixEnsemble
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class COE(MatrixEnsemble):
|
|
54
|
+
"""Circular Orthogonal Ensemble (beta=1)."""
|
|
55
|
+
|
|
56
|
+
beta: float = 1
|
|
57
|
+
|
|
58
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
59
|
+
v = haar_unitary(self.n, rng)
|
|
60
|
+
u = v.T @ v # symmetric unitary
|
|
61
|
+
eigs = np.linalg.eigvals(u)
|
|
62
|
+
return np.sort(np.angle(eigs) % (2.0 * np.pi))
|
|
63
|
+
|
|
64
|
+
def natural_scale(self) -> float:
|
|
65
|
+
return 2.0 * np.pi / self.n
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class CUE(MatrixEnsemble):
|
|
69
|
+
"""Circular Unitary Ensemble (beta=2)."""
|
|
70
|
+
|
|
71
|
+
beta: float = 2
|
|
72
|
+
|
|
73
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
74
|
+
u = haar_unitary(self.n, rng)
|
|
75
|
+
eigs = np.linalg.eigvals(u)
|
|
76
|
+
return np.sort(np.angle(eigs) % (2.0 * np.pi))
|
|
77
|
+
|
|
78
|
+
def natural_scale(self) -> float:
|
|
79
|
+
return 2.0 * np.pi / self.n
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class CSE(MatrixEnsemble):
|
|
83
|
+
"""Circular Symplectic Ensemble (beta=4).
|
|
84
|
+
|
|
85
|
+
``n`` here is the number of *distinct* CSE eigenvalues; internally a
|
|
86
|
+
Haar-random matrix of size 2n is used (each eigenvalue of the dual
|
|
87
|
+
construction is doubly degenerate).
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
beta: float = 4
|
|
91
|
+
|
|
92
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
93
|
+
n2 = 2 * self.n
|
|
94
|
+
v = haar_unitary(n2, rng)
|
|
95
|
+
z = symplectic_form(n2)
|
|
96
|
+
v_dual = (-z) @ v.T @ z # Z^{-1} = -Z since Z^2 = -I
|
|
97
|
+
u = v_dual @ v
|
|
98
|
+
eigs = np.linalg.eigvals(u)
|
|
99
|
+
theta = np.sort(np.angle(eigs) % (2.0 * np.pi))
|
|
100
|
+
# Degenerate pairs are adjacent after sorting; keep one of each.
|
|
101
|
+
return theta[0::2]
|
|
102
|
+
|
|
103
|
+
def natural_scale(self) -> float:
|
|
104
|
+
return 2.0 * np.pi / self.n
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""The Pandey-Mehta GOE-GUE crossover ensemble: a continuous
|
|
2
|
+
symmetry-breaking deformation interpolating between time-reversal-
|
|
3
|
+
symmetric (GOE, beta=1) and time-reversal-broken (GUE, beta=2) level
|
|
4
|
+
statistics.
|
|
5
|
+
|
|
6
|
+
References
|
|
7
|
+
----------
|
|
8
|
+
A. Pandey, M. L. Mehta, "Gaussian ensembles of random Hermitian
|
|
9
|
+
matrices intermediate between orthogonal and unitary ones", Commun.
|
|
10
|
+
Math. Phys. 87 (1982) 449.
|
|
11
|
+
F. J. Dyson, "A Brownian-motion model for the eigenvalues of a random
|
|
12
|
+
matrix", J. Math. Phys. 3 (1962) 1191 -- the same crossover realized as
|
|
13
|
+
a continuous-time stochastic (Dyson Brownian motion) process; the
|
|
14
|
+
static construction here is the same family at one fixed "time".
|
|
15
|
+
|
|
16
|
+
Construction: H(lambda) = A + i*lambda*B, for A an independent real
|
|
17
|
+
symmetric (GOE-type) matrix and B an independent real ANTIsymmetric
|
|
18
|
+
matrix (so i*B is Hermitian: (i*B)^dagger = -i*B^dagger = -i*(-B) =
|
|
19
|
+
i*B). H is Hermitian for any real lambda. lambda=0 recovers GOE exactly
|
|
20
|
+
(H = A); as lambda grows, the added antisymmetric-times-i piece breaks
|
|
21
|
+
time-reversal symmetry, and level statistics cross over toward GUE.
|
|
22
|
+
|
|
23
|
+
Verified numerically during development (see
|
|
24
|
+
``tests/test_crossover.py``): the raw eigenvalue spread grows as
|
|
25
|
+
``sqrt(n*(1+lambda^2))`` (each off-diagonal entry's variance is
|
|
26
|
+
Var(A_ij) + lambda^2*Var(B_ij) = 1 + lambda^2, by independence),
|
|
27
|
+
confirmed by checking the empirical eigenvalue standard deviation
|
|
28
|
+
against this formula at several (n, lambda) pairs before using it as
|
|
29
|
+
``natural_scale``. The consecutive-spacing-ratio statistic
|
|
30
|
+
(``physicskit.rmt.stats.ratios.ratio_statistics``, no unfolding needed) was
|
|
31
|
+
checked against both the GOE and GUE surmises across a lambda sweep at
|
|
32
|
+
n=400: KS distance to the GOE surmise is smallest at lambda=0 (0.013)
|
|
33
|
+
and grows monotonically; KS distance to the GUE surmise is smallest by
|
|
34
|
+
lambda~0.1 (0.012) -- a genuine, verified crossover, with the
|
|
35
|
+
half-way point falling at a small lambda (roughly 0.03-0.05 at n=400),
|
|
36
|
+
consistent with the well-known finite-size scaling of this crossover
|
|
37
|
+
(the transition lambda shrinks like 1/sqrt(n) as n grows) -- that
|
|
38
|
+
specific scaling law itself is not derived or asserted exactly here.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
from __future__ import annotations
|
|
42
|
+
|
|
43
|
+
import numpy as np
|
|
44
|
+
|
|
45
|
+
from .base import MatrixEnsemble
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class GOEGUECrossoverEnsemble(MatrixEnsemble):
|
|
49
|
+
"""Pandey-Mehta GOE-GUE crossover ensemble (see module docstring):
|
|
50
|
+
H = A + i*lambda*B, A real symmetric, B real antisymmetric.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
n : int
|
|
55
|
+
Matrix dimension.
|
|
56
|
+
lam : float
|
|
57
|
+
Symmetry-breaking (time-reversal-breaking) crossover parameter.
|
|
58
|
+
lam=0 recovers GOE exactly; lam -> infinity approaches GUE-like
|
|
59
|
+
statistics (at a lam scale that shrinks with n -- see module
|
|
60
|
+
docstring).
|
|
61
|
+
seed : int, numpy.random.Generator, or None, optional
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(self, n: int, lam: float, seed: int | np.random.Generator | None = None) -> None:
|
|
65
|
+
if lam < 0:
|
|
66
|
+
raise ValueError(f"lam must be >= 0, got {lam}")
|
|
67
|
+
super().__init__(n, seed=seed)
|
|
68
|
+
self.lam = float(lam)
|
|
69
|
+
|
|
70
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
71
|
+
n = self.n
|
|
72
|
+
x = rng.standard_normal((n, n))
|
|
73
|
+
a = (x + x.T) / np.sqrt(2.0)
|
|
74
|
+
y = rng.standard_normal((n, n))
|
|
75
|
+
b = (y - y.T) / np.sqrt(2.0)
|
|
76
|
+
h = a + 1j * self.lam * b
|
|
77
|
+
return np.linalg.eigvalsh(h)
|
|
78
|
+
|
|
79
|
+
def natural_scale(self) -> float:
|
|
80
|
+
# Verified numerically (see module docstring): raw eigenvalue
|
|
81
|
+
# spread grows as sqrt(n*(1+lambda^2)).
|
|
82
|
+
return np.sqrt(self.n * (1.0 + self.lam**2))
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""Random quantum state (density matrix) ensembles: the induced measure
|
|
2
|
+
(Hilbert-Schmidt as its special case) and the Bures-Hall measure.
|
|
3
|
+
|
|
4
|
+
References
|
|
5
|
+
----------
|
|
6
|
+
K. Zyczkowski, H.-J. Sommers, "Induced measures in the space of mixed
|
|
7
|
+
quantum states", J. Phys. A 34 (2001) 7111 -- the induced-measure
|
|
8
|
+
construction, its joint eigenvalue density, and the mean-purity formula
|
|
9
|
+
used for validation here.
|
|
10
|
+
D. N. Page, "Average entropy of a subsystem", Phys. Rev. Lett. 71
|
|
11
|
+
(1993) 1291 -- the exact average-entanglement-entropy formula (the
|
|
12
|
+
"Page curve"), realized directly by this ensemble at general k -- see
|
|
13
|
+
below.
|
|
14
|
+
K. Zyczkowski, K. A. Penson, I. Nechita, B. Collins, "Generating random
|
|
15
|
+
density matrices", J. Math. Phys. 52 (2011) 062201 -- survey covering
|
|
16
|
+
both measures used here.
|
|
17
|
+
V. Osipov, H.-J. Sommers, K. Zyczkowski, "Random Bures mixed states and
|
|
18
|
+
the distribution of their purity", J. Phys. A 43 (2010) 055302 -- the
|
|
19
|
+
Bures-Hall construction and joint eigenvalue density.
|
|
20
|
+
J. Hall, "Random quantum correlations and density operator
|
|
21
|
+
distributions", Phys. Lett. A 242 (1998) 123 -- the original Bures-Hall
|
|
22
|
+
measure.
|
|
23
|
+
|
|
24
|
+
Induced measure (and its Hilbert-Schmidt special case)
|
|
25
|
+
--------------------------------------------------------
|
|
26
|
+
A Haar-random pure state on C^n (x) C^k (n <= k WLOG), traced out over
|
|
27
|
+
the k-dimensional second factor, gives a reduced density matrix on the
|
|
28
|
+
n-dimensional first factor distributed EXACTLY as
|
|
29
|
+
|
|
30
|
+
rho = A @ A^dagger / Tr(A @ A^dagger)
|
|
31
|
+
|
|
32
|
+
for A an n x k complex Ginibre matrix -- the "induced measure" with
|
|
33
|
+
environment dimension k (Zyczkowski-Sommers 2001). k=n is the
|
|
34
|
+
Hilbert-Schmidt measure (the flat/uniform measure induced by the
|
|
35
|
+
natural volume element on the space of density matrices);
|
|
36
|
+
k -> infinity concentrates rho near the maximally mixed state I/n; k=1
|
|
37
|
+
forces A to be a single column, so A @ A^dagger is rank 1 and rho is
|
|
38
|
+
exactly a Haar-random PURE state (a rank-1 projector).
|
|
39
|
+
|
|
40
|
+
This SAME construction is, with no modification, exactly the standard
|
|
41
|
+
matrix model used to study the "Page curve": since A n x k IS the
|
|
42
|
+
(unnormalized) reduced density matrix of a random bipartite pure state
|
|
43
|
+
on C^n (x) C^k, ``InducedMeasureEnsemble(n, k)`` directly generates that
|
|
44
|
+
bipartite ensemble too -- ``physicskit.rmt.stats.entanglement`` provides the
|
|
45
|
+
matching von Neumann entropy calculation and Page's (1993) exact average
|
|
46
|
+
-- see ``tests/test_density_matrix.py`` for the verification (both the
|
|
47
|
+
mean-purity formula (n+k)/(n*k+1) and Page's average-entropy formula
|
|
48
|
+
were checked directly against Monte Carlo, at several (n, k) pairs,
|
|
49
|
+
before being trusted here).
|
|
50
|
+
|
|
51
|
+
Bures-Hall measure
|
|
52
|
+
-------------------
|
|
53
|
+
A genuinely different, non-Hilbert-Schmidt measure on density matrices,
|
|
54
|
+
induced by the Bures (fidelity) metric rather than the flat
|
|
55
|
+
Hilbert-Schmidt one. Realized here as
|
|
56
|
+
|
|
57
|
+
rho = (I + U) @ G @ G^dagger @ (I + U)^dagger / Tr(...)
|
|
58
|
+
|
|
59
|
+
for G an independent n x n complex Ginibre matrix and U an independent
|
|
60
|
+
Haar-random unitary (Osipov-Sommers-Zyczkowski 2010). This construction
|
|
61
|
+
was verified directly here (not assumed from a remembered formula, given
|
|
62
|
+
how easy this measure is to get subtly wrong) by comparing Monte Carlo
|
|
63
|
+
samples against the EXACT joint eigenvalue density
|
|
64
|
+
|
|
65
|
+
P(lambda) ~ prod_{i<j} (lambda_i-lambda_j)^2 / (lambda_i+lambda_j)
|
|
66
|
+
* prod_i lambda_i^(-1/2), sum_i lambda_i = 1
|
|
67
|
+
|
|
68
|
+
at n=2 (closed-form 1-D marginal, checked via a KS test) and n=3
|
|
69
|
+
(2-D numerical integration over the simplex, checked via mean purity) --
|
|
70
|
+
both matched to within Monte Carlo noise; see ``tests/test_density_matrix.py``.
|
|
71
|
+
|
|
72
|
+
Unlike the induced measure (whose joint density is a pure Vandermonde
|
|
73
|
+
power ``|Delta(lambda)|^2``, exactly the classical Dyson beta=2 form, so
|
|
74
|
+
``beta=2`` is used below), the Bures-Hall joint density has the EXTRA
|
|
75
|
+
prod 1/(lambda_i+lambda_j) factor -- not one of Dyson's classical
|
|
76
|
+
beta-ensembles, so ``beta`` is left ``None`` for it.
|
|
77
|
+
|
|
78
|
+
All three ensembles return eigenvalues already in the natural [0, 1]
|
|
79
|
+
range, summing to 1 (a genuine probability distribution) --
|
|
80
|
+
``natural_scale`` is 1.0 throughout, no rescaling needed.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
from __future__ import annotations
|
|
84
|
+
|
|
85
|
+
import numpy as np
|
|
86
|
+
|
|
87
|
+
from ..utils.haar import haar_unitary
|
|
88
|
+
from .base import MatrixEnsemble
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class InducedMeasureEnsemble(MatrixEnsemble):
|
|
92
|
+
"""Induced-measure random density matrix: rho = A @ A^dagger / Tr(...)
|
|
93
|
+
for an n x k complex Ginibre matrix A.
|
|
94
|
+
|
|
95
|
+
Parameters
|
|
96
|
+
----------
|
|
97
|
+
n : int
|
|
98
|
+
Dimension of the density matrix (the traced-IN subsystem).
|
|
99
|
+
k : int, optional
|
|
100
|
+
Environment/other-subsystem dimension (default: n, the
|
|
101
|
+
Hilbert-Schmidt measure). k=1 gives Haar-random pure states.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
beta: float = 2
|
|
105
|
+
|
|
106
|
+
def __init__(self, n: int, k: int | None = None, seed: int | np.random.Generator | None = None) -> None:
|
|
107
|
+
k = n if k is None else k
|
|
108
|
+
if k < 1:
|
|
109
|
+
raise ValueError(f"k must be >= 1, got {k}")
|
|
110
|
+
super().__init__(n, seed=seed)
|
|
111
|
+
self.k = k
|
|
112
|
+
|
|
113
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
114
|
+
a = (rng.standard_normal((self.n, self.k)) + 1j * rng.standard_normal((self.n, self.k))) / np.sqrt(2.0)
|
|
115
|
+
rho = a @ a.conj().T
|
|
116
|
+
rho = rho / np.trace(rho).real
|
|
117
|
+
rho = (rho + rho.conj().T) / 2.0
|
|
118
|
+
return np.linalg.eigvalsh(rho)
|
|
119
|
+
|
|
120
|
+
def natural_scale(self) -> float:
|
|
121
|
+
return 1.0
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class HilbertSchmidtEnsemble(InducedMeasureEnsemble):
|
|
125
|
+
"""Hilbert-Schmidt random density matrix: the k=n special case of
|
|
126
|
+
:class:`InducedMeasureEnsemble` (the flat/uniform measure on the
|
|
127
|
+
space of n x n density matrices)."""
|
|
128
|
+
|
|
129
|
+
def __init__(self, n: int, seed: int | np.random.Generator | None = None) -> None:
|
|
130
|
+
super().__init__(n, k=n, seed=seed)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class BuresHallEnsemble(MatrixEnsemble):
|
|
134
|
+
"""Bures-Hall random density matrix (see module docstring)."""
|
|
135
|
+
|
|
136
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
137
|
+
n = self.n
|
|
138
|
+
g = (rng.standard_normal((n, n)) + 1j * rng.standard_normal((n, n))) / np.sqrt(2.0)
|
|
139
|
+
w = g @ g.conj().T
|
|
140
|
+
u = haar_unitary(n, rng)
|
|
141
|
+
ip = np.eye(n) + u
|
|
142
|
+
rho = ip @ w @ ip.conj().T
|
|
143
|
+
rho = rho / np.trace(rho).real
|
|
144
|
+
rho = (rho + rho.conj().T) / 2.0
|
|
145
|
+
return np.linalg.eigvalsh(rho)
|
|
146
|
+
|
|
147
|
+
def natural_scale(self) -> float:
|
|
148
|
+
return 1.0
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"""Non-Hermitian effective Hamiltonians for open quantum systems (Feshbach
|
|
2
|
+
projection / chaotic-scattering resonance ensembles).
|
|
3
|
+
|
|
4
|
+
References
|
|
5
|
+
----------
|
|
6
|
+
V.V. Sokolov, V.G. Zelevinsky, "Dynamics and statistics of unstable
|
|
7
|
+
quantum states", Nucl. Phys. A 504 (1989) 562.
|
|
8
|
+
Y.V. Fyodorov, H.-J. Sommers, "Statistics of resonance poles, phase
|
|
9
|
+
shifts and time delays in quantum chaotic scattering: Random matrix
|
|
10
|
+
approach for systems with broken time-reversal invariance", J. Math.
|
|
11
|
+
Phys. 38 (1997) 1918.
|
|
12
|
+
Y.V. Fyodorov, D.V. Savin, H.-J. Sommers, "Scattering, reflection and
|
|
13
|
+
impedance of waves in chaotic and disordered systems with absorption",
|
|
14
|
+
J. Phys. A 38 (2005) 10731 (review).
|
|
15
|
+
|
|
16
|
+
Physical picture
|
|
17
|
+
-----------------
|
|
18
|
+
A quantum system with N internal levels, coupled to M open decay/
|
|
19
|
+
scattering channels, is no longer described by a Hermitian Hamiltonian
|
|
20
|
+
once the continuum is eliminated via a Feshbach projection: the
|
|
21
|
+
resulting effective Hamiltonian is
|
|
22
|
+
|
|
23
|
+
H_eff = H - (i / 2) * coupling**2 * V @ V^dagger
|
|
24
|
+
|
|
25
|
+
where H (N x N) is drawn from the closed-system ensemble (GOE/GUE/GSE)
|
|
26
|
+
and V (N x M) collects the amplitudes coupling each internal level to
|
|
27
|
+
each open channel, drawn from the matching Dyson symmetry class.
|
|
28
|
+
Complex eigenvalues E_k - i*Gamma_k/2 of H_eff are resonance poles:
|
|
29
|
+
Re(E_k) are resonance positions, Gamma_k >= 0 are widths (decay rates).
|
|
30
|
+
beta = 1, 2, 4 fixes both H's and V's symmetry class together
|
|
31
|
+
(time-reversal-invariant / broken / self-dual), so this is the direct
|
|
32
|
+
non-Hermitian analogue of GOE/GUE/GSE, not an unrelated construction --
|
|
33
|
+
see :class:`EffGOE`, :class:`EffGUE`, :class:`EffGSE`.
|
|
34
|
+
|
|
35
|
+
``m`` (number of open channels) controls the openness of the system::
|
|
36
|
+
|
|
37
|
+
m=0: recovers the parent Hermitian ensemble exactly
|
|
38
|
+
(H_eff = H, eigenvalues real to machine precision).
|
|
39
|
+
m << n: weak-coupling/isolated-resonance regime.
|
|
40
|
+
m ~ n or m >> n: strong-coupling/overlapping-resonance regime --
|
|
41
|
+
"resonance trapping", where a few short-lived
|
|
42
|
+
states absorb most of the total decay width and
|
|
43
|
+
n-m long-lived states remain.
|
|
44
|
+
|
|
45
|
+
Causality (widths are never negative): for ANY complex vector x with
|
|
46
|
+
H_eff @ x = lam * x,
|
|
47
|
+
|
|
48
|
+
lam = (x^dagger @ H @ x - (i/2) * x^dagger @ Gamma @ x) / (x^dagger @ x)
|
|
49
|
+
|
|
50
|
+
where Gamma = coupling**2 * V @ V^dagger. x^dagger @ H @ x and
|
|
51
|
+
x^dagger @ x are real (H Hermitian), and x^dagger @ Gamma @ x is real
|
|
52
|
+
and >= 0 (Gamma Hermitian positive semi-definite), so
|
|
53
|
+
Im(lam) = -(x^dagger @ Gamma @ x) / (2 * x^dagger @ x) <= 0 always --
|
|
54
|
+
this holds for every eigenvalue of every realization, not just on
|
|
55
|
+
average, regardless of beta, n, or m. See ``tests/test_effective_hamiltonian.py``.
|
|
56
|
+
|
|
57
|
+
beta=4 (:class:`EffGSE`) construction note: both H and V are built from
|
|
58
|
+
2x2 quaternion blocks (the same embedding as :class:`~physicskit.rmt.ensembles.ginibre.GinSE`),
|
|
59
|
+
so H is quaternionic self-dual Hermitian and Gamma = V @ V^dagger is
|
|
60
|
+
quaternionic self-dual Hermitian PSD (the quaternion embedding is an
|
|
61
|
+
algebra homomorphism, so products and adjoints of embedded matrices stay
|
|
62
|
+
embedded). H_eff = H - (i/2)*Gamma is therefore a sum of two self-dual
|
|
63
|
+
matrices and, verified numerically during development (to ~1e-14,
|
|
64
|
+
machine precision -- see the test suite), its 2n eigenvalues retain
|
|
65
|
+
Kramers' exact two-fold degeneracy even though H_eff itself is not
|
|
66
|
+
Hermitian -- the same true degeneracy GSE itself has, unlike
|
|
67
|
+
:class:`~physicskit.rmt.ensembles.ginibre.GinSE`'s *distinct* conjugate pairs.
|
|
68
|
+
Only the n distinct values are returned (one representative per
|
|
69
|
+
degenerate pair), mirroring :class:`~physicskit.rmt.ensembles.circular.CSE`.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
from __future__ import annotations
|
|
73
|
+
|
|
74
|
+
import numpy as np
|
|
75
|
+
|
|
76
|
+
from .base import MatrixEnsemble
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _quaternion_block_embedding(rows: int, cols: int, rng: np.random.Generator) -> np.ndarray:
|
|
80
|
+
"""N x M quaternion matrix, embedded as a 2N x 2M complex matrix via
|
|
81
|
+
the standard quaternion-to-2x2-complex-block map (same convention as
|
|
82
|
+
``physicskit.rmt.ensembles.ginibre.GinSE``)."""
|
|
83
|
+
a = rng.standard_normal((rows, cols))
|
|
84
|
+
b = rng.standard_normal((rows, cols))
|
|
85
|
+
c = rng.standard_normal((rows, cols))
|
|
86
|
+
d = rng.standard_normal((rows, cols))
|
|
87
|
+
m = np.zeros((2 * rows, 2 * cols), dtype=complex)
|
|
88
|
+
m[0::2, 0::2] = a + 1j * b
|
|
89
|
+
m[0::2, 1::2] = c + 1j * d
|
|
90
|
+
m[1::2, 0::2] = -c + 1j * d
|
|
91
|
+
m[1::2, 1::2] = a - 1j * b
|
|
92
|
+
return m
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _sample_hamiltonian(n: int, rng: np.random.Generator, beta: float) -> np.ndarray:
|
|
96
|
+
"""Dense closed-system Hamiltonian H for the given Dyson index."""
|
|
97
|
+
if beta == 1:
|
|
98
|
+
x = rng.standard_normal((n, n))
|
|
99
|
+
return (x + x.T) / np.sqrt(2.0)
|
|
100
|
+
if beta == 2:
|
|
101
|
+
x = (rng.standard_normal((n, n)) + 1j * rng.standard_normal((n, n))) / np.sqrt(2.0)
|
|
102
|
+
return (x + x.conj().T) / 2.0
|
|
103
|
+
if beta == 4:
|
|
104
|
+
m = _quaternion_block_embedding(n, n, rng)
|
|
105
|
+
return (m + m.conj().T) / 2.0 # quaternionic self-dual Hermitian
|
|
106
|
+
raise ValueError(f"beta must be 1, 2, or 4, got {beta}")
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _sample_coupling(n: int, m: int, rng: np.random.Generator, beta: float) -> np.ndarray:
|
|
110
|
+
"""Dense N x M (or, for beta=4, 2N x 2M) coupling matrix V."""
|
|
111
|
+
if beta == 1:
|
|
112
|
+
return rng.standard_normal((n, m))
|
|
113
|
+
if beta == 2:
|
|
114
|
+
return (rng.standard_normal((n, m)) + 1j * rng.standard_normal((n, m))) / np.sqrt(2.0)
|
|
115
|
+
if beta == 4:
|
|
116
|
+
return _quaternion_block_embedding(n, m, rng) / np.sqrt(2.0)
|
|
117
|
+
raise ValueError(f"beta must be 1, 2, or 4, got {beta}")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class EffectiveHamiltonianEnsemble(MatrixEnsemble):
|
|
121
|
+
"""Non-Hermitian effective Hamiltonian H_eff = H - (i/2) * coupling**2 * V @ V^dagger.
|
|
122
|
+
|
|
123
|
+
Use the named subclasses (:class:`EffGOE`, :class:`EffGUE`,
|
|
124
|
+
:class:`EffGSE`) for the classical beta=1,2,4 cases.
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
n : int
|
|
129
|
+
Dimension of the closed system (number of resonances).
|
|
130
|
+
m : int
|
|
131
|
+
Number of open decay/scattering channels (m=0 recovers the
|
|
132
|
+
parent Hermitian ensemble exactly).
|
|
133
|
+
beta : {1, 2, 4}
|
|
134
|
+
Dyson index shared by the parent Hamiltonian H and the coupling
|
|
135
|
+
matrix V.
|
|
136
|
+
coupling : float, optional
|
|
137
|
+
Overall coupling strength scaling V (default 1.0); larger values
|
|
138
|
+
drive the system from the isolated-resonance regime towards
|
|
139
|
+
resonance trapping without changing beta or the number of
|
|
140
|
+
channels m.
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
def __init__(
|
|
144
|
+
self,
|
|
145
|
+
n: int,
|
|
146
|
+
m: int,
|
|
147
|
+
beta: int,
|
|
148
|
+
coupling: float = 1.0,
|
|
149
|
+
seed: int | np.random.Generator | None = None,
|
|
150
|
+
) -> None:
|
|
151
|
+
if beta not in (1, 2, 4):
|
|
152
|
+
raise ValueError(f"beta must be 1, 2, or 4, got {beta}")
|
|
153
|
+
if m < 0:
|
|
154
|
+
raise ValueError(f"m (number of open channels) must be >= 0, got {m}")
|
|
155
|
+
super().__init__(n, seed=seed)
|
|
156
|
+
self.m = m
|
|
157
|
+
self.beta: float = beta
|
|
158
|
+
self.coupling = float(coupling)
|
|
159
|
+
|
|
160
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
161
|
+
n, m, beta = self.n, self.m, self.beta
|
|
162
|
+
h = _sample_hamiltonian(n, rng, beta)
|
|
163
|
+
if m > 0:
|
|
164
|
+
v = self.coupling * _sample_coupling(n, m, rng, beta)
|
|
165
|
+
gamma = v @ v.conj().T
|
|
166
|
+
else:
|
|
167
|
+
gamma = np.zeros_like(h)
|
|
168
|
+
h_eff = h - 0.5j * gamma
|
|
169
|
+
eigs = np.linalg.eigvals(h_eff)
|
|
170
|
+
if beta == 4:
|
|
171
|
+
# Exact Kramers double degeneracy (see module docstring) --
|
|
172
|
+
# keep one representative per pair, as CSE does.
|
|
173
|
+
order = np.lexsort((eigs.imag, eigs.real))
|
|
174
|
+
eigs = eigs[order][0::2]
|
|
175
|
+
return eigs.astype(complex)
|
|
176
|
+
|
|
177
|
+
def natural_scale(self) -> float:
|
|
178
|
+
# Re(eigenvalues) inherit the parent Hermitian ensemble's level
|
|
179
|
+
# scale (exactly, at m=0; approximately for weak-to-moderate
|
|
180
|
+
# coupling) -- see HermiteBetaEnsemble.natural_scale. Widths
|
|
181
|
+
# (Im part) have no comparably universal n-independent scale --
|
|
182
|
+
# they depend on m and coupling as well as n -- so this factor
|
|
183
|
+
# should be treated as a Re-axis convenience, not a full
|
|
184
|
+
# normalization of the complex plane.
|
|
185
|
+
return np.sqrt(self.n * self.beta)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class EffGOE(EffectiveHamiltonianEnsemble):
|
|
189
|
+
"""Effective Hamiltonian built on GOE (beta=1): time-reversal
|
|
190
|
+
invariant closed system, real coupling to the open channels."""
|
|
191
|
+
|
|
192
|
+
def __init__(
|
|
193
|
+
self,
|
|
194
|
+
n: int,
|
|
195
|
+
m: int,
|
|
196
|
+
coupling: float = 1.0,
|
|
197
|
+
seed: int | np.random.Generator | None = None,
|
|
198
|
+
) -> None:
|
|
199
|
+
super().__init__(n, m, beta=1, coupling=coupling, seed=seed)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class EffGUE(EffectiveHamiltonianEnsemble):
|
|
203
|
+
"""Effective Hamiltonian built on GUE (beta=2): broken time-reversal
|
|
204
|
+
symmetry, complex coupling to the open channels."""
|
|
205
|
+
|
|
206
|
+
def __init__(
|
|
207
|
+
self,
|
|
208
|
+
n: int,
|
|
209
|
+
m: int,
|
|
210
|
+
coupling: float = 1.0,
|
|
211
|
+
seed: int | np.random.Generator | None = None,
|
|
212
|
+
) -> None:
|
|
213
|
+
super().__init__(n, m, beta=2, coupling=coupling, seed=seed)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class EffGSE(EffectiveHamiltonianEnsemble):
|
|
217
|
+
"""Effective Hamiltonian built on GSE (beta=4): self-dual
|
|
218
|
+
(Kramers-degenerate) closed system, quaternionic coupling to the
|
|
219
|
+
open channels. ``n`` is the quaternionic dimension; each sample
|
|
220
|
+
produces n distinct complex resonances (each an exact Kramers pair
|
|
221
|
+
internally -- see module docstring)."""
|
|
222
|
+
|
|
223
|
+
def __init__(
|
|
224
|
+
self,
|
|
225
|
+
n: int,
|
|
226
|
+
m: int,
|
|
227
|
+
coupling: float = 1.0,
|
|
228
|
+
seed: int | np.random.Generator | None = None,
|
|
229
|
+
) -> None:
|
|
230
|
+
super().__init__(n, m, beta=4, coupling=coupling, seed=seed)
|