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,152 @@
|
|
|
1
|
+
"""physicskit.particle: relativistic kinematics, decays, scattering, and nuclear physics.
|
|
2
|
+
|
|
3
|
+
Works throughout in natural units with :math:`c=1` (:mod:`~physicskit.particle.nuclear`
|
|
4
|
+
specifically uses MeV, the standard convention for its formulas).
|
|
5
|
+
|
|
6
|
+
- :mod:`physicskit.particle.kinematics` -- four-vectors, Lorentz boosts,
|
|
7
|
+
invariant mass, rapidity, and center-of-momentum frames.
|
|
8
|
+
- :mod:`physicskit.particle.decays` -- two-body decay kinematics,
|
|
9
|
+
radioactive decay chains (the Bateman equations), and the muon's
|
|
10
|
+
three-body Michel-spectrum decay.
|
|
11
|
+
- :mod:`physicskit.particle.scattering` -- Mandelstam kinematics and
|
|
12
|
+
Rutherford scattering.
|
|
13
|
+
- :mod:`physicskit.particle.nuclear` -- the semi-empirical mass formula
|
|
14
|
+
and nuclear reaction Q-values.
|
|
15
|
+
- :mod:`physicskit.particle.collider` -- toy branching cascades
|
|
16
|
+
(particle showers, parton showers) and a schematic detector geometry.
|
|
17
|
+
- :mod:`physicskit.particle.confinement` -- toy quark confinement and
|
|
18
|
+
QCD string breaking.
|
|
19
|
+
- :mod:`physicskit.particle.electroweak` -- toy classical symmetry
|
|
20
|
+
breaking (Higgs mechanism), leading-order QED annihilation, and
|
|
21
|
+
neutral-meson CP violation.
|
|
22
|
+
- :mod:`physicskit.particle.neutrinos` -- two-flavor vacuum neutrino oscillations.
|
|
23
|
+
- :mod:`physicskit.particle.visualizers` -- decay-chain and
|
|
24
|
+
differential-cross-section plots, plus animations of all of the above.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from physicskit.particle.collider import (
|
|
28
|
+
ShowerParticle,
|
|
29
|
+
charged_track_points,
|
|
30
|
+
cluster_into_jets,
|
|
31
|
+
flatten_shower,
|
|
32
|
+
parton_shower,
|
|
33
|
+
shower_leaves,
|
|
34
|
+
simple_shower,
|
|
35
|
+
)
|
|
36
|
+
from physicskit.particle.confinement import string_break_chain, string_tension_energy
|
|
37
|
+
from physicskit.particle.decays import (
|
|
38
|
+
activity,
|
|
39
|
+
bateman_decay_chain,
|
|
40
|
+
decay_constant,
|
|
41
|
+
half_life,
|
|
42
|
+
michel_spectrum,
|
|
43
|
+
muon_decay_event,
|
|
44
|
+
radioactive_decay_number,
|
|
45
|
+
sample_michel_electron_energies,
|
|
46
|
+
two_body_decay,
|
|
47
|
+
two_body_decay_momentum,
|
|
48
|
+
)
|
|
49
|
+
from physicskit.particle.electroweak import (
|
|
50
|
+
cp_asymmetry,
|
|
51
|
+
higgs_field_rollover,
|
|
52
|
+
higgs_potential,
|
|
53
|
+
higgs_vev,
|
|
54
|
+
meson_decay_rates_cp_eigenstate,
|
|
55
|
+
qed_dsigma_domega_mumu,
|
|
56
|
+
qed_total_cross_section_mumu,
|
|
57
|
+
)
|
|
58
|
+
from physicskit.particle.kinematics import FourVector, boost, boost_generic, boost_to_com, invariant_mass, rapidity
|
|
59
|
+
from physicskit.particle.neutrinos import oscillation_probability, survival_probability
|
|
60
|
+
from physicskit.particle.nuclear import binding_energy_per_nucleon, q_value, semf_binding_energy
|
|
61
|
+
from physicskit.particle.scattering import (
|
|
62
|
+
ALPHA_FS,
|
|
63
|
+
impact_parameter,
|
|
64
|
+
mandelstam_s,
|
|
65
|
+
mandelstam_t,
|
|
66
|
+
mandelstam_u,
|
|
67
|
+
rutherford_dsigma_domega,
|
|
68
|
+
)
|
|
69
|
+
from physicskit.particle.visualizers import (
|
|
70
|
+
animate_cp_asymmetry,
|
|
71
|
+
animate_decay_chain_bars,
|
|
72
|
+
animate_detector_event,
|
|
73
|
+
animate_higgs_rollover,
|
|
74
|
+
animate_michel_histogram,
|
|
75
|
+
animate_neutrino_oscillation,
|
|
76
|
+
animate_particle_cascade,
|
|
77
|
+
animate_parton_shower,
|
|
78
|
+
animate_qed_angular_distribution,
|
|
79
|
+
animate_string_breaking,
|
|
80
|
+
plot_decay_chain,
|
|
81
|
+
plot_differential_cross_section,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
__version__ = "0.1.0"
|
|
85
|
+
|
|
86
|
+
__all__ = [
|
|
87
|
+
"__version__",
|
|
88
|
+
# kinematics
|
|
89
|
+
"FourVector",
|
|
90
|
+
"boost",
|
|
91
|
+
"boost_generic",
|
|
92
|
+
"invariant_mass",
|
|
93
|
+
"rapidity",
|
|
94
|
+
"boost_to_com",
|
|
95
|
+
# decays
|
|
96
|
+
"two_body_decay_momentum",
|
|
97
|
+
"two_body_decay",
|
|
98
|
+
"decay_constant",
|
|
99
|
+
"half_life",
|
|
100
|
+
"radioactive_decay_number",
|
|
101
|
+
"activity",
|
|
102
|
+
"bateman_decay_chain",
|
|
103
|
+
"michel_spectrum",
|
|
104
|
+
"sample_michel_electron_energies",
|
|
105
|
+
"muon_decay_event",
|
|
106
|
+
# scattering
|
|
107
|
+
"ALPHA_FS",
|
|
108
|
+
"mandelstam_s",
|
|
109
|
+
"mandelstam_t",
|
|
110
|
+
"mandelstam_u",
|
|
111
|
+
"rutherford_dsigma_domega",
|
|
112
|
+
"impact_parameter",
|
|
113
|
+
# nuclear
|
|
114
|
+
"semf_binding_energy",
|
|
115
|
+
"binding_energy_per_nucleon",
|
|
116
|
+
"q_value",
|
|
117
|
+
# collider
|
|
118
|
+
"ShowerParticle",
|
|
119
|
+
"simple_shower",
|
|
120
|
+
"parton_shower",
|
|
121
|
+
"flatten_shower",
|
|
122
|
+
"shower_leaves",
|
|
123
|
+
"cluster_into_jets",
|
|
124
|
+
"charged_track_points",
|
|
125
|
+
# confinement
|
|
126
|
+
"string_tension_energy",
|
|
127
|
+
"string_break_chain",
|
|
128
|
+
# electroweak
|
|
129
|
+
"higgs_potential",
|
|
130
|
+
"higgs_vev",
|
|
131
|
+
"higgs_field_rollover",
|
|
132
|
+
"qed_dsigma_domega_mumu",
|
|
133
|
+
"qed_total_cross_section_mumu",
|
|
134
|
+
"meson_decay_rates_cp_eigenstate",
|
|
135
|
+
"cp_asymmetry",
|
|
136
|
+
# neutrinos
|
|
137
|
+
"oscillation_probability",
|
|
138
|
+
"survival_probability",
|
|
139
|
+
# visualizers
|
|
140
|
+
"plot_decay_chain",
|
|
141
|
+
"plot_differential_cross_section",
|
|
142
|
+
"animate_particle_cascade",
|
|
143
|
+
"animate_parton_shower",
|
|
144
|
+
"animate_detector_event",
|
|
145
|
+
"animate_string_breaking",
|
|
146
|
+
"animate_higgs_rollover",
|
|
147
|
+
"animate_decay_chain_bars",
|
|
148
|
+
"animate_neutrino_oscillation",
|
|
149
|
+
"animate_qed_angular_distribution",
|
|
150
|
+
"animate_michel_histogram",
|
|
151
|
+
"animate_cp_asymmetry",
|
|
152
|
+
]
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
r"""Toy branching cascades (particle showers, parton showers) and a
|
|
2
|
+
schematic detector geometry for displaying their final states.
|
|
3
|
+
|
|
4
|
+
Uses the same natural-unit convention (:math:`\hbar=c=1`) as
|
|
5
|
+
:mod:`physicskit.particle.kinematics`.
|
|
6
|
+
|
|
7
|
+
- :class:`ShowerParticle` -- a node of a branching-cascade tree.
|
|
8
|
+
- :func:`simple_shower` -- a generic toy branching cascade (particle
|
|
9
|
+
collision -> shower).
|
|
10
|
+
- :func:`parton_shower` -- a DGLAP-flavored toy branching cascade with
|
|
11
|
+
quark/gluon flavor bookkeeping.
|
|
12
|
+
- :func:`flatten_shower`, :func:`shower_leaves` -- tree-traversal helpers.
|
|
13
|
+
- :func:`cluster_into_jets` -- group final-state momenta into jets by angle.
|
|
14
|
+
- :func:`charged_track_points` -- a charged (or neutral) particle's 2D
|
|
15
|
+
trajectory in a uniform axial magnetic field, for a schematic detector
|
|
16
|
+
event display.
|
|
17
|
+
|
|
18
|
+
**Shared branching model** (:func:`simple_shower` and
|
|
19
|
+
:func:`parton_shower`): each particle carries a "virtuality" mass (its
|
|
20
|
+
:class:`~physicskit.particle.kinematics.FourVector` invariant mass,
|
|
21
|
+
standing in for how far off its true mass shell it is); a branching is
|
|
22
|
+
computed as an *exact* two-body decay (reusing
|
|
23
|
+
:func:`~physicskit.particle.decays.two_body_decay`) in the parent's own
|
|
24
|
+
rest frame with an isotropically sampled angle, then boosted back to the
|
|
25
|
+
lab frame with :func:`~physicskit.particle.kinematics.boost_generic` --
|
|
26
|
+
so energy-momentum is conserved at every vertex to machine precision,
|
|
27
|
+
for free, by reusing already-tested kinematics building blocks. Daughter
|
|
28
|
+
virtualities shrink by a fixed fraction each generation, and branching
|
|
29
|
+
stops once either the energy or the virtuality falls below a cutoff
|
|
30
|
+
(the shower's "hadronization scale"). This is a deliberately simplified
|
|
31
|
+
stand-in for a real fragmentation function / DGLAP splitting kernel
|
|
32
|
+
(which would sample an energy-sharing fraction ``z`` and an evolution
|
|
33
|
+
variable from Sudakov form factors) -- but the isotropic rest-frame
|
|
34
|
+
angle, combined with the boost back to the lab frame, still produces a
|
|
35
|
+
genuinely collimated, energy-ordered cascade (small opening angles for
|
|
36
|
+
high-energy branches), a real physical consequence of the boost rather
|
|
37
|
+
than something imposed by hand.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
from __future__ import annotations
|
|
41
|
+
|
|
42
|
+
from dataclasses import dataclass, field
|
|
43
|
+
from typing import Optional
|
|
44
|
+
|
|
45
|
+
import numpy as np
|
|
46
|
+
|
|
47
|
+
from physicskit.particle.decays import two_body_decay
|
|
48
|
+
from physicskit.particle.kinematics import FourVector, boost_generic
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
"ShowerParticle",
|
|
52
|
+
"simple_shower",
|
|
53
|
+
"parton_shower",
|
|
54
|
+
"flatten_shower",
|
|
55
|
+
"shower_leaves",
|
|
56
|
+
"cluster_into_jets",
|
|
57
|
+
"charged_track_points",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass
|
|
62
|
+
class ShowerParticle:
|
|
63
|
+
"""One node of a branching-cascade tree.
|
|
64
|
+
|
|
65
|
+
Attributes
|
|
66
|
+
----------
|
|
67
|
+
four_vector : FourVector
|
|
68
|
+
This particle's lab-frame four-momentum.
|
|
69
|
+
generation : int
|
|
70
|
+
Branching depth (0 for the initial/primary particle).
|
|
71
|
+
flavor : str, default=""
|
|
72
|
+
Parton flavor label (``"q"``, ``"qbar"``, ``"g"``); unused (left
|
|
73
|
+
empty) by :func:`simple_shower`.
|
|
74
|
+
parent : ShowerParticle, optional
|
|
75
|
+
The particle this one was produced from (``None`` for the root).
|
|
76
|
+
children : list of ShowerParticle
|
|
77
|
+
The two daughters, if this particle branched further (empty for
|
|
78
|
+
a final-state / leaf particle).
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
four_vector: FourVector
|
|
82
|
+
generation: int
|
|
83
|
+
flavor: str = ""
|
|
84
|
+
parent: Optional[ShowerParticle] = None
|
|
85
|
+
children: list = field(default_factory=list)
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def is_leaf(self):
|
|
89
|
+
"""Whether this particle is final-state (did not branch further)."""
|
|
90
|
+
return len(self.children) == 0
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _split_isotropic(parent_four_vector, m1, m2, rng):
|
|
94
|
+
"""Exact two-body split of ``parent_four_vector`` (in its own rest frame,
|
|
95
|
+
isotropic angle), boosted back to the lab frame."""
|
|
96
|
+
cos_theta = rng.uniform(-1.0, 1.0)
|
|
97
|
+
phi = rng.uniform(0.0, 2.0 * np.pi)
|
|
98
|
+
p1_rest, p2_rest = two_body_decay(parent_four_vector.mass, m1, m2, cos_theta, phi)
|
|
99
|
+
beta_vec = parent_four_vector.p_vec / parent_four_vector.E
|
|
100
|
+
return boost_generic(p1_rest, beta_vec), boost_generic(p2_rest, beta_vec)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _build_shower(E0, m0_fraction, daughter_fraction, E_threshold, max_generations, rng, flavor_rule=None, flavor0=""):
|
|
104
|
+
m0 = m0_fraction * E0
|
|
105
|
+
p0 = FourVector(E0, 0.0, 0.0, float(np.sqrt(max(E0**2 - m0**2, 0.0))))
|
|
106
|
+
root = ShowerParticle(p0, generation=0, flavor=flavor0)
|
|
107
|
+
|
|
108
|
+
def branch(node):
|
|
109
|
+
if node.generation >= max_generations or node.four_vector.E < E_threshold or node.four_vector.mass < 1e-9:
|
|
110
|
+
return
|
|
111
|
+
m_parent = node.four_vector.mass
|
|
112
|
+
m1 = m2 = daughter_fraction * m_parent
|
|
113
|
+
if m1 + m2 >= m_parent:
|
|
114
|
+
return
|
|
115
|
+
p1, p2 = _split_isotropic(node.four_vector, m1, m2, rng)
|
|
116
|
+
f1, f2 = flavor_rule(node.flavor, rng) if flavor_rule is not None else ("", "")
|
|
117
|
+
c1 = ShowerParticle(p1, node.generation + 1, flavor=f1, parent=node)
|
|
118
|
+
c2 = ShowerParticle(p2, node.generation + 1, flavor=f2, parent=node)
|
|
119
|
+
node.children = [c1, c2]
|
|
120
|
+
branch(c1)
|
|
121
|
+
branch(c2)
|
|
122
|
+
|
|
123
|
+
branch(root)
|
|
124
|
+
return root
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def simple_shower(E0, m0_fraction=0.3, daughter_fraction=0.42, E_threshold=1.0, max_generations=8, rng=None):
|
|
128
|
+
r"""A toy branching cascade: a single high-energy particle splitting
|
|
129
|
+
repeatedly until its descendants fall below an energy threshold.
|
|
130
|
+
|
|
131
|
+
Each split is an exact 1-to-2 branching (see the module docstring
|
|
132
|
+
for the shared construction); the initial particle is given a toy
|
|
133
|
+
"virtuality" :math:`m_0=` ``m0_fraction`` :math:`{}\times E_0`
|
|
134
|
+
representing how far off-shell it is when it enters the cascade,
|
|
135
|
+
and each generation's daughters inherit a virtuality shrunk by
|
|
136
|
+
``daughter_fraction`` (< 0.5, so it always halves-or-better,
|
|
137
|
+
guaranteeing the branching stays kinematically allowed).
|
|
138
|
+
|
|
139
|
+
Parameters
|
|
140
|
+
----------
|
|
141
|
+
E0 : float
|
|
142
|
+
Energy of the initial incident particle (along the beam/z axis).
|
|
143
|
+
m0_fraction : float, default=0.3
|
|
144
|
+
Initial virtuality as a fraction of ``E0``.
|
|
145
|
+
daughter_fraction : float, default=0.42
|
|
146
|
+
Fraction of the parent's virtuality inherited by each daughter.
|
|
147
|
+
E_threshold : float, default=1.0
|
|
148
|
+
Energy below which a particle is treated as final-state (stops branching).
|
|
149
|
+
max_generations : int, default=8
|
|
150
|
+
Hard cap on branching depth (safety net against numerical edge cases).
|
|
151
|
+
rng : numpy.random.Generator, optional
|
|
152
|
+
Random number generator; a fresh default one is used if omitted.
|
|
153
|
+
|
|
154
|
+
Returns
|
|
155
|
+
-------
|
|
156
|
+
ShowerParticle
|
|
157
|
+
The root of the cascade tree (the initial particle; its
|
|
158
|
+
descendants are reached via ``.children``).
|
|
159
|
+
|
|
160
|
+
Examples
|
|
161
|
+
--------
|
|
162
|
+
>>> import numpy as np
|
|
163
|
+
>>> root = simple_shower(100.0, E_threshold=5.0, rng=np.random.default_rng(0))
|
|
164
|
+
>>> leaves = shower_leaves(root)
|
|
165
|
+
>>> from physicskit.particle.kinematics import invariant_mass
|
|
166
|
+
>>> bool(abs(invariant_mass([leaf.four_vector for leaf in leaves]) - root.four_vector.mass) < 1e-6)
|
|
167
|
+
True
|
|
168
|
+
"""
|
|
169
|
+
rng = np.random.default_rng() if rng is None else rng
|
|
170
|
+
return _build_shower(E0, m0_fraction, daughter_fraction, E_threshold, max_generations, rng)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def parton_shower(E0, flavor0="q", m0_fraction=0.3, daughter_fraction=0.42, E_threshold=1.0, gluon_splitting_prob=0.2, max_generations=10, rng=None):
|
|
174
|
+
r"""A toy DGLAP-flavored parton shower: quarks radiate gluons, gluons
|
|
175
|
+
split into gluon pairs or quark-antiquark pairs.
|
|
176
|
+
|
|
177
|
+
Uses the same exact-two-body-split-and-boost construction as
|
|
178
|
+
:func:`simple_shower` (see the module docstring), with a simplified
|
|
179
|
+
flavor rule standing in for the DGLAP splitting functions
|
|
180
|
+
:math:`P_{qq},P_{gg},P_{qg}`:
|
|
181
|
+
|
|
182
|
+
- a quark or antiquark always radiates a gluon (``q -> q g``,
|
|
183
|
+
``qbar -> qbar g``), the only flavor-conserving 1-to-2 splitting
|
|
184
|
+
available to it;
|
|
185
|
+
- a gluon splits into two gluons with probability
|
|
186
|
+
``1-gluon_splitting_prob`` (``g -> g g``) or into a quark-antiquark
|
|
187
|
+
pair with probability ``gluon_splitting_prob`` (``g -> q qbar``).
|
|
188
|
+
|
|
189
|
+
Parameters
|
|
190
|
+
----------
|
|
191
|
+
E0 : float
|
|
192
|
+
Energy of the initial parton.
|
|
193
|
+
flavor0 : str, default="q"
|
|
194
|
+
Flavor of the initial parton (``"q"``, ``"qbar"``, or ``"g"``).
|
|
195
|
+
m0_fraction, daughter_fraction, E_threshold, max_generations, rng
|
|
196
|
+
See :func:`simple_shower`.
|
|
197
|
+
gluon_splitting_prob : float, default=0.2
|
|
198
|
+
Probability that a gluon branching produces a quark-antiquark
|
|
199
|
+
pair rather than two gluons.
|
|
200
|
+
|
|
201
|
+
Returns
|
|
202
|
+
-------
|
|
203
|
+
ShowerParticle
|
|
204
|
+
The root of the shower tree.
|
|
205
|
+
|
|
206
|
+
Examples
|
|
207
|
+
--------
|
|
208
|
+
>>> import numpy as np
|
|
209
|
+
>>> root = parton_shower(100.0, E_threshold=5.0, rng=np.random.default_rng(0))
|
|
210
|
+
>>> leaves = shower_leaves(root)
|
|
211
|
+
>>> from physicskit.particle.kinematics import invariant_mass
|
|
212
|
+
>>> bool(abs(invariant_mass([leaf.four_vector for leaf in leaves]) - root.four_vector.mass) < 1e-6)
|
|
213
|
+
True
|
|
214
|
+
"""
|
|
215
|
+
rng = np.random.default_rng() if rng is None else rng
|
|
216
|
+
|
|
217
|
+
def flavor_rule(flavor, rng):
|
|
218
|
+
if flavor == "g":
|
|
219
|
+
if rng.uniform() < gluon_splitting_prob:
|
|
220
|
+
return "q", "qbar"
|
|
221
|
+
return "g", "g"
|
|
222
|
+
return flavor, "g"
|
|
223
|
+
|
|
224
|
+
return _build_shower(E0, m0_fraction, daughter_fraction, E_threshold, max_generations, rng, flavor_rule=flavor_rule, flavor0=flavor0)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def flatten_shower(root):
|
|
228
|
+
"""All nodes of a shower tree (root included), in no particular order.
|
|
229
|
+
|
|
230
|
+
Parameters
|
|
231
|
+
----------
|
|
232
|
+
root : ShowerParticle
|
|
233
|
+
|
|
234
|
+
Returns
|
|
235
|
+
-------
|
|
236
|
+
list of ShowerParticle
|
|
237
|
+
"""
|
|
238
|
+
out = []
|
|
239
|
+
stack = [root]
|
|
240
|
+
while stack:
|
|
241
|
+
node = stack.pop()
|
|
242
|
+
out.append(node)
|
|
243
|
+
stack.extend(node.children)
|
|
244
|
+
return out
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def shower_leaves(root):
|
|
248
|
+
"""The final-state (non-branching) particles of a shower tree.
|
|
249
|
+
|
|
250
|
+
Parameters
|
|
251
|
+
----------
|
|
252
|
+
root : ShowerParticle
|
|
253
|
+
|
|
254
|
+
Returns
|
|
255
|
+
-------
|
|
256
|
+
list of ShowerParticle
|
|
257
|
+
"""
|
|
258
|
+
return [node for node in flatten_shower(root) if node.is_leaf]
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def cluster_into_jets(leaves, n_jets=2, n_iter=25, seed=0):
|
|
262
|
+
"""Group final-state shower particles into jets by momentum direction.
|
|
263
|
+
|
|
264
|
+
A minimal, dependency-free k-means clustering on the unit momentum
|
|
265
|
+
directions (i.e. by angular proximity) -- a schematic stand-in for a
|
|
266
|
+
real sequential jet algorithm (:math:`k_T`, anti-:math:`k_T`, ...),
|
|
267
|
+
adequate for visually grouping a toy shower's final state into a
|
|
268
|
+
couple of back-to-back jet cones.
|
|
269
|
+
|
|
270
|
+
Parameters
|
|
271
|
+
----------
|
|
272
|
+
leaves : sequence of ShowerParticle
|
|
273
|
+
Final-state particles, e.g. from :func:`shower_leaves`.
|
|
274
|
+
n_jets : int, default=2
|
|
275
|
+
Number of jets to form (capped at ``len(leaves)``).
|
|
276
|
+
n_iter : int, default=25
|
|
277
|
+
Number of k-means (Lloyd) iterations.
|
|
278
|
+
seed : int, default=0
|
|
279
|
+
Seed for the deterministic random initialization.
|
|
280
|
+
|
|
281
|
+
Returns
|
|
282
|
+
-------
|
|
283
|
+
list of list of ShowerParticle
|
|
284
|
+
One list of member particles per jet.
|
|
285
|
+
|
|
286
|
+
Examples
|
|
287
|
+
--------
|
|
288
|
+
>>> import numpy as np
|
|
289
|
+
>>> root = parton_shower(100.0, E_threshold=5.0, rng=np.random.default_rng(0))
|
|
290
|
+
>>> jets = cluster_into_jets(shower_leaves(root), n_jets=2)
|
|
291
|
+
>>> len(jets) == 2
|
|
292
|
+
True
|
|
293
|
+
"""
|
|
294
|
+
directions = np.array([[leaf.four_vector.px, leaf.four_vector.py, leaf.four_vector.pz] for leaf in leaves])
|
|
295
|
+
norm = np.linalg.norm(directions, axis=1, keepdims=True)
|
|
296
|
+
norm[norm == 0.0] = 1.0
|
|
297
|
+
unit = directions / norm
|
|
298
|
+
n_jets = min(n_jets, len(leaves))
|
|
299
|
+
rng = np.random.default_rng(seed)
|
|
300
|
+
centers = unit[rng.choice(len(unit), size=n_jets, replace=False)].copy()
|
|
301
|
+
labels = np.zeros(len(unit), dtype=int)
|
|
302
|
+
for _ in range(n_iter):
|
|
303
|
+
labels = np.argmax(unit @ centers.T, axis=1)
|
|
304
|
+
for k in range(n_jets):
|
|
305
|
+
members = unit[labels == k]
|
|
306
|
+
if len(members) > 0:
|
|
307
|
+
c = members.mean(axis=0)
|
|
308
|
+
c_norm = np.linalg.norm(c)
|
|
309
|
+
if c_norm > 0:
|
|
310
|
+
centers[k] = c / c_norm
|
|
311
|
+
return [[leaves[i] for i in range(len(leaves)) if labels[i] == k] for k in range(n_jets)]
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def charged_track_points(four_vector, charge, B, vertex=(0.0, 0.0), n_points=100, path_length=1.0):
|
|
315
|
+
r"""2D transverse-plane trajectory of a particle in a uniform axial magnetic field.
|
|
316
|
+
|
|
317
|
+
A charged particle with transverse momentum :math:`p_T` follows a
|
|
318
|
+
circular arc of radius
|
|
319
|
+
|
|
320
|
+
.. math::
|
|
321
|
+
|
|
322
|
+
r = \frac{p_T}{qB}
|
|
323
|
+
|
|
324
|
+
the standard relation for the curvature of a charged track in a
|
|
325
|
+
uniform axial field (see e.g. the Particle Data Group's "Passage of
|
|
326
|
+
particles through matter" review); here in schematic natural units
|
|
327
|
+
where :math:`q` is in units of the elementary charge and :math:`B`
|
|
328
|
+
is scaled so that :math:`r` comes out directly in the detector's
|
|
329
|
+
length unit (the familiar practical-unit form is :math:`r[{\rm m}]
|
|
330
|
+
=p_T[{\rm GeV}/c]/(0.3\,B[{\rm T}]\,q[e])`). A neutral particle
|
|
331
|
+
(``charge=0``) instead follows a straight line.
|
|
332
|
+
|
|
333
|
+
Parameters
|
|
334
|
+
----------
|
|
335
|
+
four_vector : FourVector
|
|
336
|
+
The particle's four-momentum.
|
|
337
|
+
charge : float
|
|
338
|
+
Charge, in units of the elementary charge (0 for neutral).
|
|
339
|
+
B : float
|
|
340
|
+
Magnetic field strength (along the axis perpendicular to the
|
|
341
|
+
transverse plane).
|
|
342
|
+
vertex : array_like of shape (2,), default=(0, 0)
|
|
343
|
+
Starting point of the track.
|
|
344
|
+
n_points : int, default=100
|
|
345
|
+
Number of points to sample along the trajectory.
|
|
346
|
+
path_length : float, default=1.0
|
|
347
|
+
For a neutral track, the length of the straight segment drawn;
|
|
348
|
+
for a charged track, the arc length traced out (capped
|
|
349
|
+
implicitly by how many points are requested along it).
|
|
350
|
+
|
|
351
|
+
Returns
|
|
352
|
+
-------
|
|
353
|
+
ndarray of shape (n_points, 2)
|
|
354
|
+
Points along the trajectory, starting at ``vertex`` and moving
|
|
355
|
+
off in ``four_vector``'s initial transverse direction.
|
|
356
|
+
|
|
357
|
+
Examples
|
|
358
|
+
--------
|
|
359
|
+
>>> from physicskit.particle.kinematics import FourVector
|
|
360
|
+
>>> p = FourVector(10.0, 3.0, 0.0, 5.0)
|
|
361
|
+
>>> pts = charged_track_points(p, charge=0.0, B=1.0, path_length=2.0)
|
|
362
|
+
>>> np.allclose(pts[0], [0.0, 0.0]) and np.allclose(pts[-1], [2.0, 0.0])
|
|
363
|
+
True
|
|
364
|
+
"""
|
|
365
|
+
vertex = np.asarray(vertex, dtype=float)
|
|
366
|
+
px, py = four_vector.px, four_vector.py
|
|
367
|
+
pT = float(np.hypot(px, py))
|
|
368
|
+
if charge == 0.0 or pT == 0.0:
|
|
369
|
+
direction = np.array([px, py]) / pT if pT > 0.0 else np.array([1.0, 0.0])
|
|
370
|
+
s = np.linspace(0.0, path_length, n_points)
|
|
371
|
+
return vertex + np.outer(s, direction)
|
|
372
|
+
r = pT / (abs(charge) * B)
|
|
373
|
+
phi0 = np.arctan2(py, px)
|
|
374
|
+
curve_sign = float(np.sign(charge * B))
|
|
375
|
+
center = vertex + r * np.array([-np.sin(phi0), np.cos(phi0)]) * curve_sign
|
|
376
|
+
max_angle = min(path_length / r, 2.0 * np.pi)
|
|
377
|
+
thetas = np.linspace(0.0, max_angle, n_points)
|
|
378
|
+
v0 = vertex - center
|
|
379
|
+
cs, sn = np.cos(curve_sign * thetas), np.sin(curve_sign * thetas)
|
|
380
|
+
xs = center[0] + v0[0] * cs - v0[1] * sn
|
|
381
|
+
ys = center[1] + v0[0] * sn + v0[1] * cs
|
|
382
|
+
return np.column_stack([xs, ys])
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
r"""Toy quark confinement and QCD string breaking.
|
|
2
|
+
|
|
3
|
+
Uses the same natural-unit convention (:math:`\hbar=c=1`) as
|
|
4
|
+
:mod:`physicskit.particle.kinematics`.
|
|
5
|
+
|
|
6
|
+
A pair of quarks confined by a linear potential :math:`V(r)=\kappa r`
|
|
7
|
+
(the standard long-distance behavior of the QCD static potential,
|
|
8
|
+
confirmed by lattice QCD, with :math:`\kappa` the string tension,
|
|
9
|
+
:math:`\kappa\approx0.9\ {\rm GeV/fm}\approx0.18\ {\rm GeV}^2` for real
|
|
10
|
+
QCD) is receding at a prescribed constant speed. The color flux tube
|
|
11
|
+
("string") connecting them stores energy :math:`\kappa r(t)`; once that
|
|
12
|
+
exceeds the threshold to pair-produce a light :math:`q\bar q` pair from
|
|
13
|
+
the vacuum, the string breaks.
|
|
14
|
+
|
|
15
|
+
- :func:`string_tension_energy` -- the stored linear-potential energy.
|
|
16
|
+
- :func:`string_break_chain` -- a sequence of such breaks as the
|
|
17
|
+
original pair keeps separating, sharing the growing total extent
|
|
18
|
+
evenly among the (growing number of) string segments.
|
|
19
|
+
|
|
20
|
+
**Simplifications, clearly flagged**: the two original quarks are given
|
|
21
|
+
a *prescribed* constant recession velocity rather than one obtained by
|
|
22
|
+
solving their equation of motion under the confining force plus
|
|
23
|
+
radiation reaction (a full dynamical treatment is out of scope for a
|
|
24
|
+
toy model); the newly created quark-antiquark pairs are bookkept only
|
|
25
|
+
through the energy balance :math:`\kappa r=2m_qN` (each of the ``N``
|
|
26
|
+
current segments must independently store enough energy to pair-produce
|
|
27
|
+
its own light quark pair) -- individual momentum conservation for the
|
|
28
|
+
produced pairs, and their own subsequent dynamics, are not tracked.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
import numpy as np
|
|
34
|
+
|
|
35
|
+
__all__ = ["string_tension_energy", "string_break_chain"]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def string_tension_energy(r, kappa):
|
|
39
|
+
r"""Energy stored in a confining linear-potential string, :math:`V(r)=\kappa r`.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
r : array_like
|
|
44
|
+
Quark-antiquark separation.
|
|
45
|
+
kappa : float
|
|
46
|
+
String tension.
|
|
47
|
+
|
|
48
|
+
Returns
|
|
49
|
+
-------
|
|
50
|
+
ndarray or float
|
|
51
|
+
|
|
52
|
+
Examples
|
|
53
|
+
--------
|
|
54
|
+
>>> float(string_tension_energy(2.0, 0.9))
|
|
55
|
+
1.8
|
|
56
|
+
"""
|
|
57
|
+
return kappa * np.abs(np.asarray(r, dtype=float))
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def string_break_chain(t, v, kappa, m_q, r0=0.0, n_breaks=3):
|
|
61
|
+
r"""Sequence of string-breaking events as a receding quark pair separates.
|
|
62
|
+
|
|
63
|
+
The original quark pair separates at the prescribed constant speed
|
|
64
|
+
``v``, :math:`r(t)=r_0+vt`. The ``k``-th break occurs when the total
|
|
65
|
+
stored string energy :math:`\kappa r(t)` first reaches :math:`2m_qk`
|
|
66
|
+
-- the energy needed for *each* of the ``k`` string segments existing
|
|
67
|
+
just before that break to independently pair-produce a light
|
|
68
|
+
:math:`q\bar q` pair at threshold (each of the ``k`` segments is
|
|
69
|
+
assumed, for this bookkeeping, to carry an equal share
|
|
70
|
+
:math:`\kappa r(t)/k` of the total stored energy). After the break
|
|
71
|
+
there are ``k+1`` segments.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
t : array_like
|
|
76
|
+
Times at which to evaluate the state of the system.
|
|
77
|
+
v : float
|
|
78
|
+
Constant recession speed of the original quark pair, :math:`0<v<1`.
|
|
79
|
+
kappa : float
|
|
80
|
+
String tension.
|
|
81
|
+
m_q : float
|
|
82
|
+
Constituent mass of the light quark pair created at each break
|
|
83
|
+
(the pair-production threshold for one string segment is
|
|
84
|
+
:math:`2m_q`).
|
|
85
|
+
r0 : float, default=0.0
|
|
86
|
+
Initial quark-antiquark separation at :math:`t=0`.
|
|
87
|
+
n_breaks : int, default=3
|
|
88
|
+
Maximum number of sequential breaks to compute.
|
|
89
|
+
|
|
90
|
+
Returns
|
|
91
|
+
-------
|
|
92
|
+
dict
|
|
93
|
+
``t``, ``r`` (total extent), ``energy_total`` (:math:`\kappa r`),
|
|
94
|
+
``n_segments`` (number of string segments at each time),
|
|
95
|
+
``energy_per_segment``, ``break_times``, ``r_break_unit``
|
|
96
|
+
(:math:`2m_q/\kappa`, the extent of a single fresh segment at
|
|
97
|
+
the instant it breaks), ``kappa``, ``m_q``.
|
|
98
|
+
|
|
99
|
+
Examples
|
|
100
|
+
--------
|
|
101
|
+
>>> import numpy as np
|
|
102
|
+
>>> sim = string_break_chain(np.linspace(0, 10, 5), v=0.5, kappa=1.0, m_q=1.0, n_breaks=2)
|
|
103
|
+
>>> sim["break_times"]
|
|
104
|
+
array([4., 8.])
|
|
105
|
+
"""
|
|
106
|
+
if not (0.0 < v < 1.0):
|
|
107
|
+
raise ValueError(f"v={v} must satisfy 0 < v < 1 (a sub-luminal recession speed).")
|
|
108
|
+
t = np.asarray(t, dtype=float)
|
|
109
|
+
r = r0 + v * t
|
|
110
|
+
energy_total = kappa * r
|
|
111
|
+
break_times = np.array([(2.0 * m_q * k / kappa - r0) / v for k in range(1, n_breaks + 1)])
|
|
112
|
+
break_times = break_times[break_times >= 0.0]
|
|
113
|
+
n_segments = 1 + np.searchsorted(break_times, t, side="right")
|
|
114
|
+
energy_per_segment = energy_total / n_segments
|
|
115
|
+
return {
|
|
116
|
+
"t": t,
|
|
117
|
+
"r": r,
|
|
118
|
+
"energy_total": energy_total,
|
|
119
|
+
"n_segments": n_segments,
|
|
120
|
+
"energy_per_segment": energy_per_segment,
|
|
121
|
+
"break_times": break_times,
|
|
122
|
+
"r_break_unit": 2.0 * m_q / kappa,
|
|
123
|
+
"kappa": kappa,
|
|
124
|
+
"m_q": m_q,
|
|
125
|
+
}
|