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.
Files changed (484) hide show
  1. physicskit/__init__.py +51 -0
  2. physicskit/astro/__init__.py +66 -0
  3. physicskit/astro/cosmic_web.py +395 -0
  4. physicskit/astro/galactic_dynamics.py +137 -0
  5. physicskit/astro/nbody.py +208 -0
  6. physicskit/astro/orbital_mechanics.py +220 -0
  7. physicskit/astro/stellar_dynamo.py +628 -0
  8. physicskit/astro/stellar_structure.py +198 -0
  9. physicskit/astro/tests/__init__.py +0 -0
  10. physicskit/astro/tests/conftest.py +7 -0
  11. physicskit/astro/tests/test_cosmic_web.py +159 -0
  12. physicskit/astro/tests/test_galactic_dynamics.py +46 -0
  13. physicskit/astro/tests/test_nbody.py +81 -0
  14. physicskit/astro/tests/test_orbital_mechanics.py +73 -0
  15. physicskit/astro/tests/test_stellar_dynamo.py +198 -0
  16. physicskit/astro/tests/test_stellar_structure.py +52 -0
  17. physicskit/astro/tests/test_visualizers.py +159 -0
  18. physicskit/astro/visualizers.py +628 -0
  19. physicskit/chaos/__init__.py +55 -0
  20. physicskit/chaos/core/__init__.py +3 -0
  21. physicskit/chaos/core/base_system.py +342 -0
  22. physicskit/chaos/core/integrators.py +40 -0
  23. physicskit/chaos/exceptions.py +24 -0
  24. physicskit/chaos/quantum/__init__.py +38 -0
  25. physicskit/chaos/quantum/billiards.py +274 -0
  26. physicskit/chaos/quantum/husimi.py +85 -0
  27. physicskit/chaos/quantum/maps.py +366 -0
  28. physicskit/chaos/systems/__init__.py +38 -0
  29. physicskit/chaos/systems/billiards.py +1131 -0
  30. physicskit/chaos/systems/continuous.py +1276 -0
  31. physicskit/chaos/systems/maps.py +557 -0
  32. physicskit/chaos/tests/__init__.py +0 -0
  33. physicskit/chaos/tests/test_basins.py +76 -0
  34. physicskit/chaos/tests/test_bifurcation.py +132 -0
  35. physicskit/chaos/tests/test_billiards.py +115 -0
  36. physicskit/chaos/tests/test_continuous.py +224 -0
  37. physicskit/chaos/tests/test_dimension.py +69 -0
  38. physicskit/chaos/tests/test_divergence.py +90 -0
  39. physicskit/chaos/tests/test_dynamic_plots.py +269 -0
  40. physicskit/chaos/tests/test_integrators.py +96 -0
  41. physicskit/chaos/tests/test_io.py +41 -0
  42. physicskit/chaos/tests/test_maps.py +110 -0
  43. physicskit/chaos/tests/test_metrics.py +115 -0
  44. physicskit/chaos/tests/test_phase_space.py +73 -0
  45. physicskit/chaos/tests/test_properties.py +116 -0
  46. physicskit/chaos/tests/test_quantum_billiards.py +94 -0
  47. physicskit/chaos/tests/test_quantum_maps.py +144 -0
  48. physicskit/chaos/tests/test_recurrence.py +51 -0
  49. physicskit/chaos/tests/test_repr_and_api_consistency.py +134 -0
  50. physicskit/chaos/tests/test_section.py +49 -0
  51. physicskit/chaos/tests/test_spectral.py +48 -0
  52. physicskit/chaos/tests/test_streamlit_app.py +45 -0
  53. physicskit/chaos/tests/test_timeseries.py +131 -0
  54. physicskit/chaos/tests/test_viewer3d.py +41 -0
  55. physicskit/chaos/utils/__init__.py +46 -0
  56. physicskit/chaos/utils/dimension.py +139 -0
  57. physicskit/chaos/utils/io.py +95 -0
  58. physicskit/chaos/utils/metrics.py +304 -0
  59. physicskit/chaos/utils/recurrence.py +122 -0
  60. physicskit/chaos/utils/spectral.py +69 -0
  61. physicskit/chaos/utils/timeseries.py +303 -0
  62. physicskit/chaos/visualizers/__init__.py +85 -0
  63. physicskit/chaos/visualizers/basins.py +185 -0
  64. physicskit/chaos/visualizers/bifurcation.py +273 -0
  65. physicskit/chaos/visualizers/divergence.py +374 -0
  66. physicskit/chaos/visualizers/dynamic_plots.py +1372 -0
  67. physicskit/chaos/visualizers/phase_space.py +133 -0
  68. physicskit/chaos/visualizers/quantum.py +299 -0
  69. physicskit/chaos/visualizers/recurrence.py +91 -0
  70. physicskit/chaos/visualizers/section.py +161 -0
  71. physicskit/chaos/visualizers/theme.py +31 -0
  72. physicskit/chaos/visualizers/viewer3d.py +82 -0
  73. physicskit/classical/__init__.py +55 -0
  74. physicskit/classical/core/__init__.py +17 -0
  75. physicskit/classical/core/base_system.py +510 -0
  76. physicskit/classical/core/integrators.py +397 -0
  77. physicskit/classical/systems/__init__.py +32 -0
  78. physicskit/classical/systems/chains.py +334 -0
  79. physicskit/classical/systems/hamiltonian.py +215 -0
  80. physicskit/classical/systems/lagrangian.py +308 -0
  81. physicskit/classical/systems/newtonian.py +536 -0
  82. physicskit/classical/systems/rotations.py +614 -0
  83. physicskit/classical/tests/__init__.py +0 -0
  84. physicskit/classical/tests/conftest.py +7 -0
  85. physicskit/classical/tests/test_base_system.py +113 -0
  86. physicskit/classical/tests/test_chains.py +84 -0
  87. physicskit/classical/tests/test_conservation.py +244 -0
  88. physicskit/classical/tests/test_conservation_utils.py +47 -0
  89. physicskit/classical/tests/test_hamiltonian.py +44 -0
  90. physicskit/classical/tests/test_integrators.py +123 -0
  91. physicskit/classical/tests/test_lagrangian.py +69 -0
  92. physicskit/classical/tests/test_newtonian.py +45 -0
  93. physicskit/classical/tests/test_rotations.py +160 -0
  94. physicskit/classical/tests/test_stepsize.py +149 -0
  95. physicskit/classical/tests/test_symbolic.py +125 -0
  96. physicskit/classical/tests/test_visualizers.py +172 -0
  97. physicskit/classical/utils/__init__.py +20 -0
  98. physicskit/classical/utils/conservation.py +126 -0
  99. physicskit/classical/utils/stepsize.py +187 -0
  100. physicskit/classical/utils/symbolic.py +235 -0
  101. physicskit/classical/visualizers/__init__.py +25 -0
  102. physicskit/classical/visualizers/animations.py +508 -0
  103. physicskit/classical/visualizers/interactive.py +113 -0
  104. physicskit/classical/visualizers/modal_analysis.py +97 -0
  105. physicskit/classical/visualizers/phase_space.py +214 -0
  106. physicskit/condensed/__init__.py +122 -0
  107. physicskit/condensed/anderson_localization.py +155 -0
  108. physicskit/condensed/correlated.py +284 -0
  109. physicskit/condensed/ginzburg_landau.py +220 -0
  110. physicskit/condensed/landau_levels.py +246 -0
  111. physicskit/condensed/laughlin.py +229 -0
  112. physicskit/condensed/models.py +627 -0
  113. physicskit/condensed/tests/__init__.py +0 -0
  114. physicskit/condensed/tests/test_condensed.py +518 -0
  115. physicskit/condensed/tests/test_visualizers.py +87 -0
  116. physicskit/condensed/tight_binding.py +445 -0
  117. physicskit/condensed/topological_insulator_3d.py +178 -0
  118. physicskit/condensed/topology.py +217 -0
  119. physicskit/condensed/visualizers.py +296 -0
  120. physicskit/condensed/weyl.py +180 -0
  121. physicskit/constants.py +184 -0
  122. physicskit/fields/__init__.py +111 -0
  123. physicskit/fields/electrodynamics.py +671 -0
  124. physicskit/fields/quantum_fields.py +510 -0
  125. physicskit/fields/solitons.py +527 -0
  126. physicskit/fields/tests/__init__.py +0 -0
  127. physicskit/fields/tests/conftest.py +7 -0
  128. physicskit/fields/tests/test_field_animations.py +154 -0
  129. physicskit/fields/tests/test_fields.py +439 -0
  130. physicskit/fields/tests/test_visualizers.py +101 -0
  131. physicskit/fields/visualizers.py +503 -0
  132. physicskit/fluids/__init__.py +134 -0
  133. physicskit/fluids/core/__init__.py +23 -0
  134. physicskit/fluids/core/grid.py +165 -0
  135. physicskit/fluids/core/timestepping.py +231 -0
  136. physicskit/fluids/exceptions.py +26 -0
  137. physicskit/fluids/systems/__init__.py +70 -0
  138. physicskit/fluids/systems/compressible_flow.py +281 -0
  139. physicskit/fluids/systems/instabilities.py +343 -0
  140. physicskit/fluids/systems/navier_stokes.py +221 -0
  141. physicskit/fluids/systems/potential_flow.py +440 -0
  142. physicskit/fluids/systems/viscous_flow.py +425 -0
  143. physicskit/fluids/systems/vortex_dynamics.py +304 -0
  144. physicskit/fluids/tests/__init__.py +0 -0
  145. physicskit/fluids/tests/conftest.py +7 -0
  146. physicskit/fluids/tests/test_compressible_flow.py +66 -0
  147. physicskit/fluids/tests/test_instabilities.py +115 -0
  148. physicskit/fluids/tests/test_navier_stokes.py +67 -0
  149. physicskit/fluids/tests/test_potential_flow.py +92 -0
  150. physicskit/fluids/tests/test_static_visualizers.py +91 -0
  151. physicskit/fluids/tests/test_utils.py +100 -0
  152. physicskit/fluids/tests/test_viscous_flow.py +110 -0
  153. physicskit/fluids/tests/test_visualizers.py +34 -0
  154. physicskit/fluids/tests/test_vortex_dynamics.py +88 -0
  155. physicskit/fluids/utils/__init__.py +18 -0
  156. physicskit/fluids/utils/dimensionless.py +239 -0
  157. physicskit/fluids/utils/spectral_analysis.py +142 -0
  158. physicskit/fluids/visualizers/__init__.py +14 -0
  159. physicskit/fluids/visualizers/compressible.py +39 -0
  160. physicskit/fluids/visualizers/flow_fields.py +252 -0
  161. physicskit/fluids/visualizers/potential_flow.py +51 -0
  162. physicskit/fluids/visualizers/spectra.py +62 -0
  163. physicskit/fluids/visualizers/theme.py +38 -0
  164. physicskit/integrators/__init__.py +52 -0
  165. physicskit/integrators/adaptive.py +199 -0
  166. physicskit/integrators/fixed_step.py +360 -0
  167. physicskit/integrators/tests/__init__.py +0 -0
  168. physicskit/integrators/tests/test_integrators.py +101 -0
  169. physicskit/optics/__init__.py +124 -0
  170. physicskit/optics/_compat.py +5 -0
  171. physicskit/optics/gaussian.py +382 -0
  172. physicskit/optics/quantum_optics.py +428 -0
  173. physicskit/optics/ray.py +469 -0
  174. physicskit/optics/tests/__init__.py +0 -0
  175. physicskit/optics/tests/test_diffraction_animation.py +38 -0
  176. physicskit/optics/tests/test_gaussian.py +170 -0
  177. physicskit/optics/tests/test_quantum_optics.py +147 -0
  178. physicskit/optics/tests/test_ray.py +177 -0
  179. physicskit/optics/tests/test_visualizers.py +58 -0
  180. physicskit/optics/tests/test_wave.py +146 -0
  181. physicskit/optics/visualizers.py +264 -0
  182. physicskit/optics/wave.py +365 -0
  183. physicskit/particle/__init__.py +152 -0
  184. physicskit/particle/collider.py +382 -0
  185. physicskit/particle/confinement.py +125 -0
  186. physicskit/particle/decays.py +357 -0
  187. physicskit/particle/electroweak.py +300 -0
  188. physicskit/particle/kinematics.py +271 -0
  189. physicskit/particle/neutrinos.py +84 -0
  190. physicskit/particle/nuclear.py +100 -0
  191. physicskit/particle/scattering.py +159 -0
  192. physicskit/particle/tests/__init__.py +0 -0
  193. physicskit/particle/tests/conftest.py +7 -0
  194. physicskit/particle/tests/test_collider.py +119 -0
  195. physicskit/particle/tests/test_confinement.py +42 -0
  196. physicskit/particle/tests/test_decays.py +112 -0
  197. physicskit/particle/tests/test_electroweak.py +97 -0
  198. physicskit/particle/tests/test_kinematics.py +138 -0
  199. physicskit/particle/tests/test_neutrinos.py +36 -0
  200. physicskit/particle/tests/test_nuclear.py +45 -0
  201. physicskit/particle/tests/test_scattering.py +64 -0
  202. physicskit/particle/tests/test_visualizers.py +214 -0
  203. physicskit/particle/visualizers/__init__.py +38 -0
  204. physicskit/particle/visualizers/animations.py +705 -0
  205. physicskit/particle/visualizers/static.py +101 -0
  206. physicskit/plasma/__init__.py +176 -0
  207. physicskit/plasma/acceleration.py +152 -0
  208. physicskit/plasma/instabilities.py +417 -0
  209. physicskit/plasma/kinetic.py +588 -0
  210. physicskit/plasma/mhd.py +463 -0
  211. physicskit/plasma/single_particle.py +562 -0
  212. physicskit/plasma/tests/__init__.py +0 -0
  213. physicskit/plasma/tests/conftest.py +7 -0
  214. physicskit/plasma/tests/test_new_time_domain_features.py +222 -0
  215. physicskit/plasma/tests/test_plasma.py +232 -0
  216. physicskit/plasma/tests/test_visualizers.py +79 -0
  217. physicskit/plasma/turbulence.py +219 -0
  218. physicskit/plasma/visualizers.py +868 -0
  219. physicskit/plasma/waves.py +549 -0
  220. physicskit/quantum/__init__.py +180 -0
  221. physicskit/quantum/_compat.py +20 -0
  222. physicskit/quantum/chapters/__init__.py +0 -0
  223. physicskit/quantum/chapters/entanglement.py +489 -0
  224. physicskit/quantum/chapters/harmonic_spin.py +517 -0
  225. physicskit/quantum/chapters/hydrogen_am.py +292 -0
  226. physicskit/quantum/chapters/perturbation.py +350 -0
  227. physicskit/quantum/chapters/potentials.py +997 -0
  228. physicskit/quantum/chapters/spin.py +306 -0
  229. physicskit/quantum/chapters/wave_packets.py +541 -0
  230. physicskit/quantum/core/__init__.py +0 -0
  231. physicskit/quantum/core/eigensolvers.py +311 -0
  232. physicskit/quantum/core/operators.py +296 -0
  233. physicskit/quantum/core/solvers.py +271 -0
  234. physicskit/quantum/tests/__init__.py +0 -0
  235. physicskit/quantum/tests/conftest.py +7 -0
  236. physicskit/quantum/tests/test_animations.py +225 -0
  237. physicskit/quantum/tests/test_compat.py +43 -0
  238. physicskit/quantum/tests/test_eigensolvers.py +24 -0
  239. physicskit/quantum/tests/test_entanglement.py +127 -0
  240. physicskit/quantum/tests/test_harmonic_spin.py +140 -0
  241. physicskit/quantum/tests/test_hydrogen_am.py +48 -0
  242. physicskit/quantum/tests/test_measure.py +110 -0
  243. physicskit/quantum/tests/test_operators.py +105 -0
  244. physicskit/quantum/tests/test_perturbation.py +112 -0
  245. physicskit/quantum/tests/test_physics_checks.py +131 -0
  246. physicskit/quantum/tests/test_potentials.py +191 -0
  247. physicskit/quantum/tests/test_solvers.py +70 -0
  248. physicskit/quantum/tests/test_spin.py +22 -0
  249. physicskit/quantum/tests/test_unitarity.py +84 -0
  250. physicskit/quantum/tests/test_wave_packets.py +53 -0
  251. physicskit/quantum/utils/__init__.py +0 -0
  252. physicskit/quantum/utils/measure.py +253 -0
  253. physicskit/quantum/visualizers/__init__.py +0 -0
  254. physicskit/quantum/visualizers/bloch_sphere.py +205 -0
  255. physicskit/quantum/visualizers/entanglement.py +58 -0
  256. physicskit/quantum/visualizers/orbitals.py +187 -0
  257. physicskit/quantum/visualizers/phase_space.py +179 -0
  258. physicskit/quantum/visualizers/wavefunctions.py +230 -0
  259. physicskit/relativity/__init__.py +61 -0
  260. physicskit/relativity/chapters/__init__.py +33 -0
  261. physicskit/relativity/chapters/cosmology.py +190 -0
  262. physicskit/relativity/chapters/gw_merger.py +399 -0
  263. physicskit/relativity/chapters/kerr.py +371 -0
  264. physicskit/relativity/chapters/lensing.py +196 -0
  265. physicskit/relativity/chapters/neutron_star.py +149 -0
  266. physicskit/relativity/chapters/schwarzschild.py +412 -0
  267. physicskit/relativity/chapters/timekeeping.py +133 -0
  268. physicskit/relativity/core/__init__.py +12 -0
  269. physicskit/relativity/core/geodesics.py +216 -0
  270. physicskit/relativity/core/kerr_raytracer.py +259 -0
  271. physicskit/relativity/core/raytracer.py +241 -0
  272. physicskit/relativity/core/tensors.py +468 -0
  273. physicskit/relativity/tests/__init__.py +0 -0
  274. physicskit/relativity/tests/test_conservations.py +54 -0
  275. physicskit/relativity/tests/test_constants.py +34 -0
  276. physicskit/relativity/tests/test_cosmology.py +61 -0
  277. physicskit/relativity/tests/test_gw_merger.py +117 -0
  278. physicskit/relativity/tests/test_kerr.py +116 -0
  279. physicskit/relativity/tests/test_kerr_raytracer.py +103 -0
  280. physicskit/relativity/tests/test_lensing.py +75 -0
  281. physicskit/relativity/tests/test_neutron_star.py +48 -0
  282. physicskit/relativity/tests/test_raytracer.py +67 -0
  283. physicskit/relativity/tests/test_schwarzschild.py +126 -0
  284. physicskit/relativity/tests/test_shadow_render.py +81 -0
  285. physicskit/relativity/tests/test_tensors.py +86 -0
  286. physicskit/relativity/tests/test_timekeeping.py +51 -0
  287. physicskit/relativity/tests/test_visualizers_misc.py +115 -0
  288. physicskit/relativity/utils/__init__.py +1 -0
  289. physicskit/relativity/utils/constants.py +232 -0
  290. physicskit/relativity/visualizers/__init__.py +46 -0
  291. physicskit/relativity/visualizers/interactive.py +127 -0
  292. physicskit/relativity/visualizers/shadow_render.py +367 -0
  293. physicskit/relativity/visualizers/spacetime_3d.py +92 -0
  294. physicskit/relativity/visualizers/spacetime_diagrams.py +198 -0
  295. physicskit/relativity/visualizers/wave_plots.py +185 -0
  296. physicskit/rmt/__init__.py +8 -0
  297. physicskit/rmt/ensembles/__init__.py +108 -0
  298. physicskit/rmt/ensembles/banded.py +114 -0
  299. physicskit/rmt/ensembles/base.py +135 -0
  300. physicskit/rmt/ensembles/bdg.py +218 -0
  301. physicskit/rmt/ensembles/chiral.py +308 -0
  302. physicskit/rmt/ensembles/circular.py +104 -0
  303. physicskit/rmt/ensembles/crossover.py +82 -0
  304. physicskit/rmt/ensembles/density_matrix.py +148 -0
  305. physicskit/rmt/ensembles/effective_hamiltonian.py +230 -0
  306. physicskit/rmt/ensembles/embedded.py +207 -0
  307. physicskit/rmt/ensembles/gaussian.py +153 -0
  308. physicskit/rmt/ensembles/ginibre.py +110 -0
  309. physicskit/rmt/ensembles/girko.py +190 -0
  310. physicskit/rmt/ensembles/graph_laplacian.py +92 -0
  311. physicskit/rmt/ensembles/haar.py +57 -0
  312. physicskit/rmt/ensembles/jacobi.py +182 -0
  313. physicskit/rmt/ensembles/poisson.py +77 -0
  314. physicskit/rmt/ensembles/polynomial.py +139 -0
  315. physicskit/rmt/ensembles/pt_symmetric.py +120 -0
  316. physicskit/rmt/ensembles/single_ring.py +170 -0
  317. physicskit/rmt/ensembles/sparse.py +95 -0
  318. physicskit/rmt/ensembles/syk.py +170 -0
  319. physicskit/rmt/ensembles/truncated_unitary.py +80 -0
  320. physicskit/rmt/ensembles/universality.py +92 -0
  321. physicskit/rmt/ensembles/wishart.py +88 -0
  322. physicskit/rmt/py.typed +0 -0
  323. physicskit/rmt/spectrum.py +82 -0
  324. physicskit/rmt/stats/__init__.py +160 -0
  325. physicskit/rmt/stats/characteristic_polynomial.py +77 -0
  326. physicskit/rmt/stats/circular_law.py +54 -0
  327. physicskit/rmt/stats/correlations.py +162 -0
  328. physicskit/rmt/stats/density.py +70 -0
  329. physicskit/rmt/stats/entanglement.py +36 -0
  330. physicskit/rmt/stats/free_probability.py +202 -0
  331. physicskit/rmt/stats/localization.py +338 -0
  332. physicskit/rmt/stats/marchenko_pastur.py +55 -0
  333. physicskit/rmt/stats/pt_symmetric.py +265 -0
  334. physicskit/rmt/stats/ratios.py +110 -0
  335. physicskit/rmt/stats/real_ginibre.py +134 -0
  336. physicskit/rmt/stats/rigidity.py +272 -0
  337. physicskit/rmt/stats/single_ring.py +95 -0
  338. physicskit/rmt/stats/spacing.py +150 -0
  339. physicskit/rmt/stats/tracy_widom.py +175 -0
  340. physicskit/rmt/stats/truncated_unitary.py +40 -0
  341. physicskit/rmt/stats/unfolding.py +37 -0
  342. physicskit/rmt/stats/wachter.py +67 -0
  343. physicskit/rmt/tests/__init__.py +0 -0
  344. physicskit/rmt/tests/cache_utils.py +107 -0
  345. physicskit/rmt/tests/conftest.py +8 -0
  346. physicskit/rmt/tests/test_banded.py +86 -0
  347. physicskit/rmt/tests/test_base.py +29 -0
  348. physicskit/rmt/tests/test_bdg.py +133 -0
  349. physicskit/rmt/tests/test_characteristic_polynomial.py +50 -0
  350. physicskit/rmt/tests/test_chiral.py +273 -0
  351. physicskit/rmt/tests/test_circular.py +225 -0
  352. physicskit/rmt/tests/test_crossover.py +72 -0
  353. physicskit/rmt/tests/test_density.py +23 -0
  354. physicskit/rmt/tests/test_density_matrix.py +181 -0
  355. physicskit/rmt/tests/test_effective_hamiltonian.py +140 -0
  356. physicskit/rmt/tests/test_embedded.py +169 -0
  357. physicskit/rmt/tests/test_free_probability.py +81 -0
  358. physicskit/rmt/tests/test_gaussian_ensembles.py +22 -0
  359. physicskit/rmt/tests/test_gaussian_semicircle.py +127 -0
  360. physicskit/rmt/tests/test_ginibre_circular_law.py +131 -0
  361. physicskit/rmt/tests/test_girko.py +178 -0
  362. physicskit/rmt/tests/test_graph_laplacian.py +102 -0
  363. physicskit/rmt/tests/test_haar.py +118 -0
  364. physicskit/rmt/tests/test_jacobi_wachter.py +136 -0
  365. physicskit/rmt/tests/test_localization.py +240 -0
  366. physicskit/rmt/tests/test_poisson.py +149 -0
  367. physicskit/rmt/tests/test_polynomial.py +107 -0
  368. physicskit/rmt/tests/test_pt_symmetric.py +178 -0
  369. physicskit/rmt/tests/test_random_state.py +19 -0
  370. physicskit/rmt/tests/test_real_ginibre.py +112 -0
  371. physicskit/rmt/tests/test_rigidity_universality.py +167 -0
  372. physicskit/rmt/tests/test_single_ring.py +132 -0
  373. physicskit/rmt/tests/test_spacing_and_ratios.py +122 -0
  374. physicskit/rmt/tests/test_sparse.py +71 -0
  375. physicskit/rmt/tests/test_spectrum.py +27 -0
  376. physicskit/rmt/tests/test_syk.py +136 -0
  377. physicskit/rmt/tests/test_tracy_widom.py +113 -0
  378. physicskit/rmt/tests/test_tridiagonal.py +41 -0
  379. physicskit/rmt/tests/test_truncated_unitary.py +80 -0
  380. physicskit/rmt/tests/test_validation_base.py +25 -0
  381. physicskit/rmt/tests/test_validation_misc.py +67 -0
  382. physicskit/rmt/tests/test_wishart_marchenko_pastur.py +120 -0
  383. physicskit/rmt/utils/__init__.py +0 -0
  384. physicskit/rmt/utils/haar.py +128 -0
  385. physicskit/rmt/utils/random_state.py +24 -0
  386. physicskit/rmt/utils/tridiagonal.py +167 -0
  387. physicskit/rmt/validation/__init__.py +36 -0
  388. physicskit/rmt/validation/base.py +126 -0
  389. physicskit/rmt/validation/circular_law.py +80 -0
  390. physicskit/rmt/validation/marchenko_pastur.py +53 -0
  391. physicskit/rmt/validation/ratio_distribution.py +53 -0
  392. physicskit/rmt/validation/real_ginibre.py +60 -0
  393. physicskit/rmt/validation/sine_kernel.py +57 -0
  394. physicskit/rmt/validation/single_ring.py +68 -0
  395. physicskit/rmt/validation/tracy_widom.py +89 -0
  396. physicskit/rmt/validation/universality.py +100 -0
  397. physicskit/rmt/validation/wachter.py +52 -0
  398. physicskit/rmt/validation/wigner_semicircle.py +40 -0
  399. physicskit/rmt/validation/wigner_surmise.py +58 -0
  400. physicskit/semiclassical/__init__.py +94 -0
  401. physicskit/semiclassical/_compat.py +5 -0
  402. physicskit/semiclassical/core/__init__.py +41 -0
  403. physicskit/semiclassical/core/gutzwiller.py +215 -0
  404. physicskit/semiclassical/core/path_integral.py +594 -0
  405. physicskit/semiclassical/core/propagators.py +579 -0
  406. physicskit/semiclassical/core/wkb.py +308 -0
  407. physicskit/semiclassical/systems/__init__.py +13 -0
  408. physicskit/semiclassical/systems/scarring.py +278 -0
  409. physicskit/semiclassical/tests/__init__.py +0 -0
  410. physicskit/semiclassical/tests/test_gutzwiller.py +35 -0
  411. physicskit/semiclassical/tests/test_path_integral.py +194 -0
  412. physicskit/semiclassical/tests/test_propagators.py +82 -0
  413. physicskit/semiclassical/tests/test_scarring.py +43 -0
  414. physicskit/semiclassical/tests/test_visualizers.py +89 -0
  415. physicskit/semiclassical/tests/test_wkb.py +30 -0
  416. physicskit/semiclassical/visualizers/__init__.py +17 -0
  417. physicskit/semiclassical/visualizers/gutzwiller.py +55 -0
  418. physicskit/semiclassical/visualizers/path_integral.py +195 -0
  419. physicskit/semiclassical/visualizers/propagators.py +89 -0
  420. physicskit/semiclassical/visualizers/scarring.py +146 -0
  421. physicskit/semiclassical/visualizers/wkb.py +55 -0
  422. physicskit/statphys/__init__.py +80 -0
  423. physicskit/statphys/chapters/__init__.py +43 -0
  424. physicskit/statphys/chapters/ehrenfest_urn.py +112 -0
  425. physicskit/statphys/chapters/ising_lattice.py +431 -0
  426. physicskit/statphys/chapters/kpz_growth.py +129 -0
  427. physicskit/statphys/chapters/molecular_dynamics.py +258 -0
  428. physicskit/statphys/chapters/nonequilibrium_work.py +146 -0
  429. physicskit/statphys/chapters/percolation.py +305 -0
  430. physicskit/statphys/chapters/random_walk.py +142 -0
  431. physicskit/statphys/chapters/renormalization.py +148 -0
  432. physicskit/statphys/chapters/sandpile.py +109 -0
  433. physicskit/statphys/chapters/spin_glass.py +275 -0
  434. physicskit/statphys/core/__init__.py +10 -0
  435. physicskit/statphys/core/kpz_engine.py +53 -0
  436. physicskit/statphys/core/md_engine.py +157 -0
  437. physicskit/statphys/core/monte_carlo.py +462 -0
  438. physicskit/statphys/core/random_walk_engine.py +68 -0
  439. physicskit/statphys/core/sandpile_engine.py +52 -0
  440. physicskit/statphys/tests/__init__.py +0 -0
  441. physicskit/statphys/tests/test_dynamics.py +66 -0
  442. physicskit/statphys/tests/test_ehrenfest_urn.py +44 -0
  443. physicskit/statphys/tests/test_finite_size_scaling.py +62 -0
  444. physicskit/statphys/tests/test_interactive.py +33 -0
  445. physicskit/statphys/tests/test_ising.py +68 -0
  446. physicskit/statphys/tests/test_kpz.py +55 -0
  447. physicskit/statphys/tests/test_landau_theory.py +49 -0
  448. physicskit/statphys/tests/test_md_engine.py +31 -0
  449. physicskit/statphys/tests/test_molecular_dynamics.py +72 -0
  450. physicskit/statphys/tests/test_nonequilibrium_work.py +33 -0
  451. physicskit/statphys/tests/test_partition_function.py +26 -0
  452. physicskit/statphys/tests/test_percolation.py +116 -0
  453. physicskit/statphys/tests/test_potts_model.py +46 -0
  454. physicskit/statphys/tests/test_random_walk.py +50 -0
  455. physicskit/statphys/tests/test_renormalization.py +44 -0
  456. physicskit/statphys/tests/test_sandpile.py +44 -0
  457. physicskit/statphys/tests/test_spin_glass.py +73 -0
  458. physicskit/statphys/tests/test_thermodynamics.py +121 -0
  459. physicskit/statphys/tests/test_xy_model.py +45 -0
  460. physicskit/statphys/utils/__init__.py +1 -0
  461. physicskit/statphys/utils/dynamics.py +100 -0
  462. physicskit/statphys/utils/finite_size_scaling.py +171 -0
  463. physicskit/statphys/utils/landau_theory.py +151 -0
  464. physicskit/statphys/utils/partition_function.py +109 -0
  465. physicskit/statphys/utils/thermodynamics.py +356 -0
  466. physicskit/statphys/visualizers/__init__.py +87 -0
  467. physicskit/statphys/visualizers/interactive.py +161 -0
  468. physicskit/statphys/visualizers/jarzynski_render.py +44 -0
  469. physicskit/statphys/visualizers/kpz_render.py +65 -0
  470. physicskit/statphys/visualizers/lattice_render.py +212 -0
  471. physicskit/statphys/visualizers/particle_render.py +121 -0
  472. physicskit/statphys/visualizers/random_walk_render.py +106 -0
  473. physicskit/statphys/visualizers/rg_render.py +45 -0
  474. physicskit/statphys/visualizers/sandpile_render.py +65 -0
  475. physicskit/statphys/visualizers/spin_glass_render.py +40 -0
  476. physicskit/statphys/visualizers/urn_render.py +38 -0
  477. physicskit/statphys/visualizers/vortex_render.py +84 -0
  478. physicskit/tests/__init__.py +0 -0
  479. physicskit/tests/test_constants.py +38 -0
  480. physicskit-0.1.0.dist-info/METADATA +196 -0
  481. physicskit-0.1.0.dist-info/RECORD +484 -0
  482. physicskit-0.1.0.dist-info/WHEEL +5 -0
  483. physicskit-0.1.0.dist-info/licenses/LICENSE +21 -0
  484. 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
+ }