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,135 @@
|
|
|
1
|
+
"""Base class every ensemble in physicskit.rmt implements."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from ..spectrum import Spectrum
|
|
10
|
+
from ..utils.random_state import as_generator
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MatrixEnsemble(ABC):
|
|
14
|
+
"""A distribution over matrices (or, equivalently, over eigenvalue
|
|
15
|
+
tuples). Subclasses implement ``_sample_eigenvalues`` -- eigenvalues,
|
|
16
|
+
not dense matrices, are the primary product, since several ensembles
|
|
17
|
+
(the Gaussian beta-ensembles via the Dumitriu-Edelman tridiagonal
|
|
18
|
+
model) can produce exact-in-distribution eigenvalues far more
|
|
19
|
+
efficiently than forming and diagonalizing a dense matrix.
|
|
20
|
+
|
|
21
|
+
Mirrors the ``scipy.stats`` convention of a distribution object with
|
|
22
|
+
a ``.sample()``/``.rvs()``-style draw method, rather than a bare
|
|
23
|
+
generator function.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
#: Dyson index; set by the subclass (either fixed, e.g. GOE.beta=1,
|
|
27
|
+
#: or passed at construction for continuum-beta ensembles).
|
|
28
|
+
beta: float | None = None
|
|
29
|
+
|
|
30
|
+
def __init__(self, n: int, seed: int | np.random.Generator | None = None) -> None:
|
|
31
|
+
"""
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
n : int
|
|
35
|
+
Matrix dimension.
|
|
36
|
+
seed : int, numpy.random.Generator, or None, optional
|
|
37
|
+
Seed for reproducible sampling. See
|
|
38
|
+
:func:`~physicskit.rmt.utils.random_state.as_generator`.
|
|
39
|
+
"""
|
|
40
|
+
self.n = n
|
|
41
|
+
self.seed = seed
|
|
42
|
+
self._rng = as_generator(seed)
|
|
43
|
+
|
|
44
|
+
@abstractmethod
|
|
45
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
46
|
+
"""Draw one realization's eigenvalues. Must return a 1-D array of
|
|
47
|
+
length ``self.n``.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
rng : numpy.random.Generator
|
|
52
|
+
|
|
53
|
+
Returns
|
|
54
|
+
-------
|
|
55
|
+
numpy.ndarray, shape (n,)
|
|
56
|
+
"""
|
|
57
|
+
raise NotImplementedError # pragma: no cover -- unreachable: ABC blocks
|
|
58
|
+
# instantiating any subclass that doesn't override this abstract method,
|
|
59
|
+
# so this body can never actually run.
|
|
60
|
+
|
|
61
|
+
def _sample_eigenvalues_and_vectors(self, rng: np.random.Generator) -> tuple[np.ndarray, np.ndarray]:
|
|
62
|
+
"""Draw one realization's eigenvalues AND eigenvectors (columns).
|
|
63
|
+
Optional: only ensembles that support eigenvector-level
|
|
64
|
+
statistics (e.g. the inverse participation ratio, see
|
|
65
|
+
``physicskit.rmt.stats.localization``) override this. The default raises
|
|
66
|
+
NotImplementedError.
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
rng : numpy.random.Generator
|
|
71
|
+
|
|
72
|
+
Returns
|
|
73
|
+
-------
|
|
74
|
+
eigenvalues : numpy.ndarray, shape (n,)
|
|
75
|
+
eigenvectors : numpy.ndarray, shape (m, n)
|
|
76
|
+
Column ``i`` is the eigenvector for ``eigenvalues[i]``.
|
|
77
|
+
"""
|
|
78
|
+
raise NotImplementedError(
|
|
79
|
+
f"{type(self).__name__} does not support sample(return_eigenvectors=True) -- no _sample_eigenvalues_and_vectors implementation."
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def sample(self, n_samples: int = 1, return_eigenvectors: bool = False) -> Spectrum:
|
|
83
|
+
"""Draw ``n_samples`` independent realizations.
|
|
84
|
+
|
|
85
|
+
Parameters
|
|
86
|
+
----------
|
|
87
|
+
n_samples : int, optional
|
|
88
|
+
Number of independent realizations to draw. Default 1.
|
|
89
|
+
return_eigenvectors : bool, optional
|
|
90
|
+
If True, also draw eigenvectors and attach them to the
|
|
91
|
+
returned ``Spectrum`` (see ``Spectrum.eigenvectors``).
|
|
92
|
+
Substantially more expensive in time and memory (O(n^2) per
|
|
93
|
+
sample instead of O(n)) and only supported by ensembles that
|
|
94
|
+
implement ``_sample_eigenvalues_and_vectors``; raises
|
|
95
|
+
NotImplementedError otherwise. Default False.
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
Spectrum
|
|
100
|
+
"""
|
|
101
|
+
if return_eigenvectors:
|
|
102
|
+
eig_rows = []
|
|
103
|
+
vec_rows = []
|
|
104
|
+
for _ in range(n_samples):
|
|
105
|
+
eigs, vecs = self._sample_eigenvalues_and_vectors(self._rng)
|
|
106
|
+
eig_rows.append(eigs)
|
|
107
|
+
vec_rows.append(vecs)
|
|
108
|
+
eigenvalues = np.stack(eig_rows)
|
|
109
|
+
eigenvectors: np.ndarray | None = np.stack(vec_rows)
|
|
110
|
+
else:
|
|
111
|
+
rows = [self._sample_eigenvalues(self._rng) for _ in range(n_samples)]
|
|
112
|
+
eigenvalues = np.stack(rows) # dtype (real or complex) inferred automatically;
|
|
113
|
+
# also accommodates ensembles whose eigenvalue count isn't exactly
|
|
114
|
+
# self.n (e.g. GinSE, which returns 2*n genuinely distinct
|
|
115
|
+
# conjugate-paired eigenvalues per sample -- see ensembles/ginibre.py).
|
|
116
|
+
eigenvectors = None
|
|
117
|
+
return Spectrum(
|
|
118
|
+
eigenvalues=eigenvalues,
|
|
119
|
+
n=self.n,
|
|
120
|
+
beta=self.beta,
|
|
121
|
+
ensemble=type(self).__name__,
|
|
122
|
+
scale=self.natural_scale(),
|
|
123
|
+
eigenvectors=eigenvectors,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
def natural_scale(self) -> float:
|
|
127
|
+
"""Factor by which raw eigenvalues should be divided to reach the
|
|
128
|
+
ensemble's standard asymptotic normalization. Default: no rescaling;
|
|
129
|
+
subclasses override where a known theoretical scale applies.
|
|
130
|
+
|
|
131
|
+
Returns
|
|
132
|
+
-------
|
|
133
|
+
float
|
|
134
|
+
"""
|
|
135
|
+
return 1.0
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"""Bogoliubov-de Gennes (BdG) / Altland-Zirnbauer superconductor classes:
|
|
2
|
+
D, C, CI, DIII.
|
|
3
|
+
|
|
4
|
+
These extend Dyson's threefold way (classes A, AI, AII) by adding
|
|
5
|
+
particle-hole (charge-conjugation) symmetry, appropriate to
|
|
6
|
+
non-interacting fermionic Hamiltonians in disordered/chaotic
|
|
7
|
+
superconductors. Together with the threefold way and the three chiral
|
|
8
|
+
classes (AIII, BDI, CII -- QCD-type, realized elsewhere in this package
|
|
9
|
+
via the Wishart/Laguerre singular-value connection), these four complete
|
|
10
|
+
Altland and Zirnbauer's "tenfold way".
|
|
11
|
+
|
|
12
|
+
References
|
|
13
|
+
----------
|
|
14
|
+
A. Altland, M. R. Zirnbauer, "Nonstandard symmetry classes in
|
|
15
|
+
mesoscopic normal-superconducting hybrid structures", Phys. Rev. B 55
|
|
16
|
+
(1997) 1142.
|
|
17
|
+
M. A. Stephanov, J. J. M. Verbaarschot, T. Wettig, "Random Matrices"
|
|
18
|
+
(Wiley Encyclopedia of Electrical and Electronics Engineering, 2005),
|
|
19
|
+
arXiv:hep-ph/0509286 -- the block structure and (alpha, beta) table for
|
|
20
|
+
classes D and C used here.
|
|
21
|
+
M. Stolz, "Fluctuations of Wigner-type random matrices associated with
|
|
22
|
+
symmetric spaces of class DIII and CI", arXiv:1707.03793 -- the
|
|
23
|
+
explicit, unambiguous matrix-space definitions for DIII and CI used
|
|
24
|
+
here (Section 2), stated in purely mathematical terms independent of
|
|
25
|
+
any physics convention.
|
|
26
|
+
|
|
27
|
+
Construction
|
|
28
|
+
------------
|
|
29
|
+
All four classes have the :math:`2N \\times 2N` Hermitian block structure
|
|
30
|
+
|
|
31
|
+
.. math::
|
|
32
|
+
|
|
33
|
+
H = \\begin{pmatrix} A & B \\\\ B^\\dagger & -A^T \\end{pmatrix}
|
|
34
|
+
|
|
35
|
+
(class D, C) or, equivalently in the special case where :math:`B`
|
|
36
|
+
happens to equal its own conjugate transpose (true for the specific
|
|
37
|
+
reality/symmetry combinations used in CI and DIII),
|
|
38
|
+
|
|
39
|
+
.. math::
|
|
40
|
+
|
|
41
|
+
H = \\begin{pmatrix} X_1 & X_2 \\\\ X_2 & -X_1 \\end{pmatrix}
|
|
42
|
+
|
|
43
|
+
(class CI, DIII), where::
|
|
44
|
+
|
|
45
|
+
Class D (beta=2): A complex Hermitian (N x N), B complex antisymmetric.
|
|
46
|
+
Class C (beta=2): A complex Hermitian (N x N), B complex symmetric.
|
|
47
|
+
Class CI (beta=1): X1, X2 real symmetric (N x N) -- H is real symmetric.
|
|
48
|
+
Class DIII (beta=4): X1, X2 purely imaginary skew-symmetric (N x N)
|
|
49
|
+
-- i.e. i times a real antisymmetric matrix,
|
|
50
|
+
which is itself Hermitian.
|
|
51
|
+
|
|
52
|
+
or, in symmetry-constraint form,
|
|
53
|
+
|
|
54
|
+
.. math::
|
|
55
|
+
|
|
56
|
+
\\text{D: } A^\\dagger = A,\\ B^T = -B \\qquad
|
|
57
|
+
\\text{C: } A^\\dagger = A,\\ B^T = B
|
|
58
|
+
|
|
59
|
+
.. math::
|
|
60
|
+
|
|
61
|
+
\\text{CI: } X_1^T = X_1,\\ X_2^T = X_2,\\ X_1, X_2 \\in \\mathbb{R} \\qquad
|
|
62
|
+
\\text{DIII: } X_1^T = -X_1,\\ X_2^T = -X_2,\\ X_1, X_2 \\in i\\mathbb{R}
|
|
63
|
+
|
|
64
|
+
This block structure has a built-in particle-hole (charge-conjugation)
|
|
65
|
+
symmetry
|
|
66
|
+
|
|
67
|
+
.. math::
|
|
68
|
+
|
|
69
|
+
\\mathcal{C} H \\mathcal{C}^{-1} = -H, \\qquad
|
|
70
|
+
\\mathcal{C} = \\tau_x \\mathcal{K}, \\qquad
|
|
71
|
+
\\tau_x = \\begin{pmatrix} 0 & I_N \\\\ I_N & 0 \\end{pmatrix}
|
|
72
|
+
|
|
73
|
+
(:math:`\\mathcal{K}` complex conjugation) that forces the spectrum to be
|
|
74
|
+
symmetric about zero: if :math:`\\lambda` is an eigenvalue, so is
|
|
75
|
+
:math:`-\\lambda`. This is NOT a degeneracy (unlike the Kramers doubling
|
|
76
|
+
in GSE/CSE) -- :math:`\\lambda` and :math:`-\\lambda` are generically
|
|
77
|
+
distinct eigenvalues. Verified during development: all four
|
|
78
|
+
constructions are exactly Hermitian (to machine precision) and exhibit
|
|
79
|
+
this :math:`\\pm\\lambda` pairing to machine precision -- see
|
|
80
|
+
``tests/test_bdg.py``. Going further (validating the exact bulk/edge
|
|
81
|
+
eigenvalue density, which follows Laguerre-type statistics in the
|
|
82
|
+
variable :math:`\\lambda^2` per the :math:`(\\alpha, \\beta)` table in
|
|
83
|
+
Stephanov-Verbaarschot-Wettig) is deferred; only the structural
|
|
84
|
+
properties above are validated here.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
import numpy as np
|
|
88
|
+
|
|
89
|
+
from .base import MatrixEnsemble
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _dense_hermitian(n: int, rng: np.random.Generator, complex_entries: bool) -> np.ndarray:
|
|
93
|
+
if complex_entries:
|
|
94
|
+
x = (rng.standard_normal((n, n)) + 1j * rng.standard_normal((n, n))) / np.sqrt(2.0)
|
|
95
|
+
return (x + x.conj().T) / 2.0
|
|
96
|
+
x = rng.standard_normal((n, n))
|
|
97
|
+
return (x + x.T) / np.sqrt(2.0)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _dense_symmetric(n: int, rng: np.random.Generator, complex_entries: bool) -> np.ndarray:
|
|
101
|
+
if complex_entries:
|
|
102
|
+
x = (rng.standard_normal((n, n)) + 1j * rng.standard_normal((n, n))) / np.sqrt(2.0)
|
|
103
|
+
else:
|
|
104
|
+
x = rng.standard_normal((n, n))
|
|
105
|
+
return (x + x.T) / np.sqrt(2.0)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _dense_antisymmetric(n: int, rng: np.random.Generator, complex_entries: bool) -> np.ndarray:
|
|
109
|
+
if complex_entries:
|
|
110
|
+
x = (rng.standard_normal((n, n)) + 1j * rng.standard_normal((n, n))) / np.sqrt(2.0)
|
|
111
|
+
else:
|
|
112
|
+
x = rng.standard_normal((n, n))
|
|
113
|
+
return (x - x.T) / np.sqrt(2.0)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class BdGClassD(MatrixEnsemble):
|
|
117
|
+
"""Altland-Zirnbauer class D (beta=2).
|
|
118
|
+
|
|
119
|
+
.. math::
|
|
120
|
+
|
|
121
|
+
H = \\begin{pmatrix} A & B \\\\ B^\\dagger & -A^T \\end{pmatrix},
|
|
122
|
+
\\qquad A^\\dagger = A,\\ \\ B^T = -B
|
|
123
|
+
|
|
124
|
+
with :math:`A` complex Hermitian and :math:`B` complex antisymmetric
|
|
125
|
+
(both :math:`N \\times N`). ``n`` is the block size :math:`N`; each
|
|
126
|
+
sample is a :math:`2N \\times 2N` Hermitian matrix with :math:`2N`
|
|
127
|
+
eigenvalues occurring in :math:`\\pm\\lambda` pairs."""
|
|
128
|
+
|
|
129
|
+
beta: float = 2
|
|
130
|
+
|
|
131
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
132
|
+
n = self.n
|
|
133
|
+
a = _dense_hermitian(n, rng, complex_entries=True)
|
|
134
|
+
b = _dense_antisymmetric(n, rng, complex_entries=True)
|
|
135
|
+
h = np.block([[a, b], [b.conj().T, -a.T]])
|
|
136
|
+
h = (h + h.conj().T) / 2.0 # symmetrize away numerical asymmetry
|
|
137
|
+
return np.linalg.eigvalsh(h)
|
|
138
|
+
|
|
139
|
+
def natural_scale(self) -> float:
|
|
140
|
+
return np.sqrt(self.n)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class BdGClassC(MatrixEnsemble):
|
|
144
|
+
"""Altland-Zirnbauer class C (beta=2).
|
|
145
|
+
|
|
146
|
+
.. math::
|
|
147
|
+
|
|
148
|
+
H = \\begin{pmatrix} A & B \\\\ B^\\dagger & -A^T \\end{pmatrix},
|
|
149
|
+
\\qquad A^\\dagger = A,\\ \\ B^T = B
|
|
150
|
+
|
|
151
|
+
with :math:`A` complex Hermitian and :math:`B` complex symmetric
|
|
152
|
+
(both :math:`N \\times N`). ``n`` is the block size :math:`N`; each
|
|
153
|
+
sample is a :math:`2N \\times 2N` Hermitian matrix with :math:`2N`
|
|
154
|
+
eigenvalues occurring in :math:`\\pm\\lambda` pairs."""
|
|
155
|
+
|
|
156
|
+
beta: float = 2
|
|
157
|
+
|
|
158
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
159
|
+
n = self.n
|
|
160
|
+
a = _dense_hermitian(n, rng, complex_entries=True)
|
|
161
|
+
b = _dense_symmetric(n, rng, complex_entries=True)
|
|
162
|
+
h = np.block([[a, b], [b.conj().T, -a.T]])
|
|
163
|
+
h = (h + h.conj().T) / 2.0
|
|
164
|
+
return np.linalg.eigvalsh(h)
|
|
165
|
+
|
|
166
|
+
def natural_scale(self) -> float:
|
|
167
|
+
return np.sqrt(self.n)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class BdGClassCI(MatrixEnsemble):
|
|
171
|
+
"""Altland-Zirnbauer class CI (beta=1).
|
|
172
|
+
|
|
173
|
+
.. math::
|
|
174
|
+
|
|
175
|
+
H = \\begin{pmatrix} X_1 & X_2 \\\\ X_2 & -X_1 \\end{pmatrix},
|
|
176
|
+
\\qquad X_1^T = X_1,\\ \\ X_2^T = X_2,\\ \\ X_1, X_2 \\in \\mathbb{R}^{N \\times N}
|
|
177
|
+
|
|
178
|
+
so :math:`H` is real symmetric (:math:`2N \\times 2N`)."""
|
|
179
|
+
|
|
180
|
+
beta: float = 1
|
|
181
|
+
|
|
182
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
183
|
+
n = self.n
|
|
184
|
+
x1 = _dense_symmetric(n, rng, complex_entries=False)
|
|
185
|
+
x2 = _dense_symmetric(n, rng, complex_entries=False)
|
|
186
|
+
h = np.block([[x1, x2], [x2, -x1]])
|
|
187
|
+
h = (h + h.T) / 2.0
|
|
188
|
+
return np.linalg.eigvalsh(h)
|
|
189
|
+
|
|
190
|
+
def natural_scale(self) -> float:
|
|
191
|
+
return np.sqrt(self.n)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class BdGClassDIII(MatrixEnsemble):
|
|
195
|
+
"""Altland-Zirnbauer class DIII (beta=4).
|
|
196
|
+
|
|
197
|
+
.. math::
|
|
198
|
+
|
|
199
|
+
H = \\begin{pmatrix} X_1 & X_2 \\\\ X_2 & -X_1 \\end{pmatrix},
|
|
200
|
+
\\qquad X_1 = iY_1,\\ X_2 = iY_2,\\ \\ Y_1^T = -Y_1,\\ Y_2^T = -Y_2,\\ \\ Y_1, Y_2 \\in \\mathbb{R}^{N \\times N}
|
|
201
|
+
|
|
202
|
+
i.e. :math:`X_1, X_2` are purely imaginary skew-symmetric
|
|
203
|
+
(:math:`N \\times N`, hence themselves Hermitian). :math:`H` is
|
|
204
|
+
complex Hermitian (:math:`2N \\times 2N`)."""
|
|
205
|
+
|
|
206
|
+
beta: float = 4
|
|
207
|
+
|
|
208
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
209
|
+
n = self.n
|
|
210
|
+
y1 = _dense_antisymmetric(n, rng, complex_entries=False)
|
|
211
|
+
y2 = _dense_antisymmetric(n, rng, complex_entries=False)
|
|
212
|
+
x1, x2 = 1j * y1, 1j * y2
|
|
213
|
+
h = np.block([[x1, x2], [x2, -x1]])
|
|
214
|
+
h = (h + h.conj().T) / 2.0
|
|
215
|
+
return np.linalg.eigvalsh(h)
|
|
216
|
+
|
|
217
|
+
def natural_scale(self) -> float:
|
|
218
|
+
return np.sqrt(self.n)
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"""Chiral ensembles -- chGOE, chGUE, chGSE (Altland-Zirnbauer classes
|
|
2
|
+
BDI, AIII, CII): block off-diagonal Hamiltonians with an anticommuting
|
|
3
|
+
chiral symmetry, the QCD-type ("Dirac operator") random matrix ensembles
|
|
4
|
+
of Verbaarschot and Zahed. Together with the threefold way (A, AI, AII,
|
|
5
|
+
realized in ``physicskit.rmt.ensembles.gaussian``) and the four BdG classes
|
|
6
|
+
(``physicskit.rmt.ensembles.bdg``), these complete Altland-Zirnbauer's "tenfold
|
|
7
|
+
way".
|
|
8
|
+
|
|
9
|
+
References
|
|
10
|
+
----------
|
|
11
|
+
J. J. M. Verbaarschot, I. Zahed, "Spectral density of the QCD Dirac
|
|
12
|
+
operator near zero virtuality", Phys. Rev. Lett. 70 (1993) 3852.
|
|
13
|
+
J. J. M. Verbaarschot, "The spectrum of the QCD Dirac operator and
|
|
14
|
+
chiral random matrix theory", Phys. Rev. Lett. 72 (1994) 2531.
|
|
15
|
+
A. Altland, M. R. Zirnbauer, "Nonstandard symmetry classes in
|
|
16
|
+
mesoscopic normal-superconducting hybrid structures", Phys. Rev. B 55
|
|
17
|
+
(1997) 1142 -- classes BDI, AIII, CII within the tenfold way.
|
|
18
|
+
M. A. Stephanov, J. J. M. Verbaarschot, T. Wettig, "Random Matrices",
|
|
19
|
+
arXiv:hep-ph/0509286 -- the chiral <-> Wishart/Laguerre equivalence
|
|
20
|
+
used here.
|
|
21
|
+
|
|
22
|
+
Construction
|
|
23
|
+
------------
|
|
24
|
+
A chiral Hamiltonian has the block off-diagonal form
|
|
25
|
+
|
|
26
|
+
.. math::
|
|
27
|
+
|
|
28
|
+
H = \\begin{pmatrix} 0 & W \\\\ W^\\dagger & 0 \\end{pmatrix}
|
|
29
|
+
|
|
30
|
+
where :math:`W` is a rectangular :math:`N \\times (N+\\nu)` matrix
|
|
31
|
+
(:math:`\\nu \\geq 0` the topological index -- the number of exact zero
|
|
32
|
+
modes, i.e. the QCD Dirac operator's index), drawn with i.i.d. entries
|
|
33
|
+
from the Dyson symmetry class matching beta: real (beta=1, class BDI,
|
|
34
|
+
chGOE), complex (beta=2, class AIII, chGUE), or quaternionic (beta=4,
|
|
35
|
+
class CII, chGSE). :math:`H` is Hermitian by construction and
|
|
36
|
+
anticommutes with the chiral "gamma_5" operator
|
|
37
|
+
:math:`\\Gamma = \\mathrm{diag}(I_N, -I_{N+\\nu})`:
|
|
38
|
+
|
|
39
|
+
.. math::
|
|
40
|
+
|
|
41
|
+
\\Gamma H \\Gamma = -H
|
|
42
|
+
|
|
43
|
+
-- the defining symmetry of this class (verified directly, to machine
|
|
44
|
+
precision, in ``tests/test_chiral.py``), forcing the spectrum to be
|
|
45
|
+
exactly symmetric about zero -- like BdG's particle-hole symmetry
|
|
46
|
+
(``physicskit.rmt.ensembles.bdg``), but via an ANTIcommuting rather than a
|
|
47
|
+
commuting operator, and via a block off-diagonal rather than a block
|
|
48
|
+
diagonal-plus-symmetric structure.
|
|
49
|
+
|
|
50
|
+
Because
|
|
51
|
+
|
|
52
|
+
.. math::
|
|
53
|
+
|
|
54
|
+
H^2 = \\begin{pmatrix} WW^\\dagger & 0 \\\\ 0 & W^\\dagger W \\end{pmatrix},
|
|
55
|
+
|
|
56
|
+
:math:`H`'s nonzero eigenvalues are exactly :math:`\\pm\\sigma_k`, the
|
|
57
|
+
singular values of :math:`W` -- and :math:`W^\\dagger W` is EXACTLY a
|
|
58
|
+
beta-Wishart/Laguerre matrix (``physicskit.rmt.ensembles.wishart``).
|
|
59
|
+
This is why the chiral ensembles need no new sampling machinery: unlike
|
|
60
|
+
BdG, which needed genuinely new dense constructions, chiral eigenvalues
|
|
61
|
+
are generated here by reusing
|
|
62
|
+
``physicskit.rmt.utils.tridiagonal.sample_laguerre_beta_eigenvalues`` directly
|
|
63
|
+
and taking its square root -- exact in distribution (via the same
|
|
64
|
+
Dumitriu-Edelman generalized-beta mechanism used by
|
|
65
|
+
``HermiteBetaEnsemble``/``LaguerreBetaEnsemble``), without ever forming
|
|
66
|
+
or diagonalizing a dense matrix. This also means that, exactly as
|
|
67
|
+
``HermiteBetaEnsemble``'s GSE (beta=4) returns n eigenvalues (not the 2n
|
|
68
|
+
a dense quaternion embedding would give -- see
|
|
69
|
+
``physicskit.rmt.ensembles.ginibre``'s GinSE for that contrast), the chiral
|
|
70
|
+
ensembles here return ``n`` +-sigma pairs at every beta, including 4 --
|
|
71
|
+
NOT a doubled count from an explicit quaternion embedding.
|
|
72
|
+
|
|
73
|
+
The ``nu`` exact zero eigenvalues (the topological zero modes) are
|
|
74
|
+
appended directly, since W^dagger @ W (an (N+nu) x (N+nu) matrix of rank
|
|
75
|
+
<= N) has exactly ``nu`` zero eigenvalues whenever nu > 0 -- not merely
|
|
76
|
+
small, exactly zero, reflecting the index-theorem structure underlying
|
|
77
|
+
this construction (the same reason a private ``_dense_chiral_hamiltonian``
|
|
78
|
+
helper below, used only for direct structural verification in the test
|
|
79
|
+
suite, checks this on the literal block matrix rather than trusting it
|
|
80
|
+
transitively from the Laguerre connection).
|
|
81
|
+
|
|
82
|
+
Since ``sample_laguerre_beta_eigenvalues`` already returns
|
|
83
|
+
Marchenko-Pastur-normalized eigenvalues (support
|
|
84
|
+
[(1-sqrt(gamma))^2, (1+sqrt(gamma))^2], gamma = n/(n+nu)),
|
|
85
|
+
``natural_scale`` is 1.0 here too (matching
|
|
86
|
+
``LaguerreBetaEnsemble.natural_scale``): the nonzero +-sigma_k already
|
|
87
|
+
lie in [-(1+sqrt(gamma)), -(1-sqrt(gamma))] union
|
|
88
|
+
[(1-sqrt(gamma)), (1+sqrt(gamma))].
|
|
89
|
+
|
|
90
|
+
Two eigenvalue-convention presentations
|
|
91
|
+
----------------------------------------
|
|
92
|
+
``ChiralBetaEnsemble``/``chGOE``/``chGUE``/``chGSE`` present the HERMITIAN
|
|
93
|
+
gamma_5-Hamiltonian :math:`H` (real eigenvalues :math:`\\pm\\sigma_k` and
|
|
94
|
+
:math:`\\nu` exact zeros). The lattice-QCD and chiral-random-matrix-theory
|
|
95
|
+
literature, however, usually works directly with the (anti-Hermitian)
|
|
96
|
+
EUCLIDEAN DIRAC OPERATOR :math:`D`, related to :math:`H` by
|
|
97
|
+
|
|
98
|
+
.. math::
|
|
99
|
+
|
|
100
|
+
D = iH,
|
|
101
|
+
|
|
102
|
+
whose eigenvalues are therefore purely imaginary: :math:`\\pm i\\sigma_k`
|
|
103
|
+
(the nonzero "virtualities") plus :math:`\\nu` exact zero modes.
|
|
104
|
+
``QCDDiracEnsemble``/``QCDDiracGOE``/``QCDDiracGUE``/
|
|
105
|
+
``QCDDiracGSE`` below provide exactly this presentation -- a thin
|
|
106
|
+
wrapper multiplying ``ChiralBetaEnsemble``'s eigenvalues by ``i``, not a
|
|
107
|
+
mathematically distinct construction, provided purely so the eigenvalue
|
|
108
|
+
convention matches what papers in that literature actually plot
|
|
109
|
+
(Im(lambda_n), the Dirac spectral density rho(lambda)) without the
|
|
110
|
+
caller having to remember to do the rotation themselves.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
from __future__ import annotations
|
|
114
|
+
|
|
115
|
+
import numpy as np
|
|
116
|
+
|
|
117
|
+
from ..utils.tridiagonal import sample_laguerre_beta_eigenvalues
|
|
118
|
+
from .base import MatrixEnsemble
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class ChiralBetaEnsemble(MatrixEnsemble):
|
|
122
|
+
"""General beta-chiral ensemble (block off-diagonal, QCD-type Dirac
|
|
123
|
+
operator random matrix).
|
|
124
|
+
|
|
125
|
+
.. math::
|
|
126
|
+
|
|
127
|
+
H = \\begin{pmatrix} 0 & W \\\\ W^\\dagger & 0 \\end{pmatrix},
|
|
128
|
+
\\qquad \\Gamma H \\Gamma = -H,
|
|
129
|
+
\\qquad \\Gamma = \\mathrm{diag}(I_N, -I_{N+\\nu})
|
|
130
|
+
|
|
131
|
+
beta=1, 2, 4 recover chGOE, chGUE, chGSE (Altland-Zirnbauer classes
|
|
132
|
+
BDI, AIII, CII) exactly; any beta > 0 is a valid continuum
|
|
133
|
+
generalization (inherited from the underlying beta-Laguerre
|
|
134
|
+
construction).
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
n : int
|
|
139
|
+
Number of nonzero +-sigma eigenvalue pairs (the smaller block
|
|
140
|
+
dimension N).
|
|
141
|
+
beta : float
|
|
142
|
+
Dyson index.
|
|
143
|
+
nu : int, optional
|
|
144
|
+
Topological index: number of exact zero eigenvalues (default
|
|
145
|
+
0). The larger block dimension is N + nu.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
def __init__(
|
|
149
|
+
self,
|
|
150
|
+
n: int,
|
|
151
|
+
beta: float,
|
|
152
|
+
nu: int = 0,
|
|
153
|
+
seed: int | np.random.Generator | None = None,
|
|
154
|
+
) -> None:
|
|
155
|
+
if beta <= 0:
|
|
156
|
+
raise ValueError(f"beta must be positive, got {beta}")
|
|
157
|
+
if nu < 0:
|
|
158
|
+
raise ValueError(f"nu (topological index) must be >= 0, got {nu}")
|
|
159
|
+
super().__init__(n, seed=seed)
|
|
160
|
+
self.beta: float = float(beta)
|
|
161
|
+
self.nu = nu
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def gamma(self) -> float:
|
|
165
|
+
"""Aspect ratio :math:`\\gamma = n/(n+\\nu)` controlling the
|
|
166
|
+
Marchenko-Pastur-derived support :math:`[(1-\\sqrt{\\gamma})^2,
|
|
167
|
+
(1+\\sqrt{\\gamma})^2]` of the nonzero :math:`\\pm\\sigma` eigenvalues."""
|
|
168
|
+
return self.n / (self.n + self.nu)
|
|
169
|
+
|
|
170
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
171
|
+
m = self.n + self.nu
|
|
172
|
+
squared_singular_values = sample_laguerre_beta_eigenvalues(m, self.n, self.beta, rng)
|
|
173
|
+
sigma = np.sqrt(squared_singular_values)
|
|
174
|
+
zero_modes = np.zeros(self.nu)
|
|
175
|
+
return np.concatenate([-sigma, zero_modes, sigma])
|
|
176
|
+
|
|
177
|
+
def natural_scale(self) -> float:
|
|
178
|
+
return 1.0
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class chGOE(ChiralBetaEnsemble):
|
|
182
|
+
"""Chiral Orthogonal Ensemble (beta=1, Altland-Zirnbauer class BDI).
|
|
183
|
+
|
|
184
|
+
.. math::
|
|
185
|
+
|
|
186
|
+
H = \\begin{pmatrix} 0 & W \\\\ W^T & 0 \\end{pmatrix}, \\qquad W \\in \\mathbb{R}^{N \\times (N+\\nu)}
|
|
187
|
+
|
|
188
|
+
real block off-diagonal Hamiltonian (:math:`W` real)."""
|
|
189
|
+
|
|
190
|
+
def __init__(self, n: int, nu: int = 0, seed: int | np.random.Generator | None = None) -> None:
|
|
191
|
+
super().__init__(n, beta=1, nu=nu, seed=seed)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class chGUE(ChiralBetaEnsemble):
|
|
195
|
+
"""Chiral Unitary Ensemble (beta=2, Altland-Zirnbauer class AIII).
|
|
196
|
+
|
|
197
|
+
.. math::
|
|
198
|
+
|
|
199
|
+
H = \\begin{pmatrix} 0 & W \\\\ W^\\dagger & 0 \\end{pmatrix}, \\qquad W \\in \\mathbb{C}^{N \\times (N+\\nu)}
|
|
200
|
+
|
|
201
|
+
complex block off-diagonal Hamiltonian (:math:`W` complex) -- the
|
|
202
|
+
QCD Dirac operator random matrix ensemble of Verbaarschot-Zahed."""
|
|
203
|
+
|
|
204
|
+
def __init__(self, n: int, nu: int = 0, seed: int | np.random.Generator | None = None) -> None:
|
|
205
|
+
super().__init__(n, beta=2, nu=nu, seed=seed)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class chGSE(ChiralBetaEnsemble):
|
|
209
|
+
"""Chiral Symplectic Ensemble (beta=4, Altland-Zirnbauer class CII).
|
|
210
|
+
|
|
211
|
+
.. math::
|
|
212
|
+
|
|
213
|
+
H = \\begin{pmatrix} 0 & W \\\\ W^\\dagger & 0 \\end{pmatrix}, \\qquad W \\in \\mathbb{H}^{N \\times (N+\\nu)}
|
|
214
|
+
|
|
215
|
+
quaternionic block off-diagonal Hamiltonian (:math:`W` quaternionic)."""
|
|
216
|
+
|
|
217
|
+
def __init__(self, n: int, nu: int = 0, seed: int | np.random.Generator | None = None) -> None:
|
|
218
|
+
super().__init__(n, beta=4, nu=nu, seed=seed)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class QCDDiracEnsemble(ChiralBetaEnsemble):
|
|
222
|
+
"""The QCD Dirac operator
|
|
223
|
+
|
|
224
|
+
.. math::
|
|
225
|
+
|
|
226
|
+
D = iH
|
|
227
|
+
|
|
228
|
+
in the anti-Hermitian convention standard in the lattice-QCD and
|
|
229
|
+
chiral-random-matrix literature (Verbaarschot-Zahed): eigenvalues
|
|
230
|
+
are purely imaginary, :math:`\\pm i\\sigma_k` plus :math:`\\nu` exact
|
|
231
|
+
zero modes, rather than ``ChiralBetaEnsemble``'s real
|
|
232
|
+
:math:`\\pm\\sigma_k` -- see the module docstring section "Two
|
|
233
|
+
eigenvalue-convention presentations". Parameters are identical to
|
|
234
|
+
``ChiralBetaEnsemble``.
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
|
|
238
|
+
return 1j * super()._sample_eigenvalues(rng)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
class QCDDiracGOE(QCDDiracEnsemble):
|
|
242
|
+
"""QCD Dirac operator built on chGOE (beta=1, class BDI): real
|
|
243
|
+
coupling block W, purely imaginary Dirac eigenvalues."""
|
|
244
|
+
|
|
245
|
+
def __init__(self, n: int, nu: int = 0, seed: int | np.random.Generator | None = None) -> None:
|
|
246
|
+
super().__init__(n, beta=1, nu=nu, seed=seed)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class QCDDiracGUE(QCDDiracEnsemble):
|
|
250
|
+
"""QCD Dirac operator built on chGUE (beta=2, class AIII): complex
|
|
251
|
+
coupling block W, purely imaginary Dirac eigenvalues -- the
|
|
252
|
+
Verbaarschot-Zahed QCD Dirac operator ensemble in its standard
|
|
253
|
+
anti-Hermitian presentation."""
|
|
254
|
+
|
|
255
|
+
def __init__(self, n: int, nu: int = 0, seed: int | np.random.Generator | None = None) -> None:
|
|
256
|
+
super().__init__(n, beta=2, nu=nu, seed=seed)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
class QCDDiracGSE(QCDDiracEnsemble):
|
|
260
|
+
"""QCD Dirac operator built on chGSE (beta=4, class CII):
|
|
261
|
+
quaternionic coupling block W, purely imaginary Dirac eigenvalues."""
|
|
262
|
+
|
|
263
|
+
def __init__(self, n: int, nu: int = 0, seed: int | np.random.Generator | None = None) -> None:
|
|
264
|
+
super().__init__(n, beta=4, nu=nu, seed=seed)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def _sample_block(n: int, m: int, rng: np.random.Generator, beta: int) -> np.ndarray:
|
|
268
|
+
"""Rectangular N x M coupling block W matching the Dyson symmetry
|
|
269
|
+
class beta, via an EXPLICIT dense (quaternion-embedded, for beta=4)
|
|
270
|
+
construction. Used only for direct structural verification of the
|
|
271
|
+
chiral-symmetry construction in the test suite -- the efficient
|
|
272
|
+
production sampler above (``ChiralBetaEnsemble._sample_eigenvalues``)
|
|
273
|
+
never forms this matrix; see the module docstring for why."""
|
|
274
|
+
if beta == 1:
|
|
275
|
+
return rng.standard_normal((n, m))
|
|
276
|
+
if beta == 2:
|
|
277
|
+
return (rng.standard_normal((n, m)) + 1j * rng.standard_normal((n, m))) / np.sqrt(2.0)
|
|
278
|
+
if beta == 4:
|
|
279
|
+
a = rng.standard_normal((n, m))
|
|
280
|
+
b = rng.standard_normal((n, m))
|
|
281
|
+
c = rng.standard_normal((n, m))
|
|
282
|
+
d = rng.standard_normal((n, m))
|
|
283
|
+
w = np.zeros((2 * n, 2 * m), dtype=complex)
|
|
284
|
+
w[0::2, 0::2] = a + 1j * b
|
|
285
|
+
w[0::2, 1::2] = c + 1j * d
|
|
286
|
+
w[1::2, 0::2] = -c + 1j * d
|
|
287
|
+
w[1::2, 1::2] = a - 1j * b
|
|
288
|
+
return w / np.sqrt(2.0)
|
|
289
|
+
raise ValueError(f"beta must be 1, 2, or 4, got {beta}")
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def _dense_chiral_hamiltonian(n: int, nu: int, rng: np.random.Generator, beta: int) -> np.ndarray:
|
|
293
|
+
"""Dense block off-diagonal chiral Hamiltonian H = [[0, W], [W^dagger, 0]]
|
|
294
|
+
-- used only for direct structural verification (Hermiticity, exact
|
|
295
|
+
chiral-symmetry anticommutation with Gamma = diag(I, -I), and the
|
|
296
|
+
+-singular-value / exact-zero-mode eigenvalue structure) in the test
|
|
297
|
+
suite. Note beta=4 uses an explicit quaternion embedding here, so its
|
|
298
|
+
block sizes are doubled relative to the (n, n+nu) the fast sampler
|
|
299
|
+
above works with directly -- an independent linear-algebra fact
|
|
300
|
+
about the chiral block structure, not tied to which of the two
|
|
301
|
+
(embedding vs. generalized-beta) conventions is used to realize it.
|
|
302
|
+
"""
|
|
303
|
+
m = n + nu
|
|
304
|
+
w = _sample_block(n, m, rng, beta)
|
|
305
|
+
n_dim, m_dim = w.shape
|
|
306
|
+
top = np.hstack([np.zeros((n_dim, n_dim), dtype=complex), w])
|
|
307
|
+
bottom = np.hstack([w.conj().T, np.zeros((m_dim, m_dim), dtype=complex)])
|
|
308
|
+
return np.vstack([top, bottom])
|