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,88 @@
1
+ """Wishart (Laguerre) ensembles -- LOE, LUE, LSE -- plus the continuum
2
+ Dyson-index generalization, built on the bidiagonal beta-Laguerre model
3
+ (see ``physicskit.rmt.utils.tridiagonal.sample_laguerre_beta_eigenvalues``).
4
+
5
+ References
6
+ ----------
7
+ V. A. Marchenko, L. A. Pastur, "Distribution of eigenvalues for some sets
8
+ of random matrices", Mat. Sb. 72 (1967) 507.
9
+ I. Dumitriu, A. Edelman, J. Math. Phys. 43, 5830 (2002).
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import numpy as np
15
+
16
+ from ..utils.tridiagonal import sample_laguerre_beta_eigenvalues
17
+ from .base import MatrixEnsemble
18
+
19
+
20
+ class LaguerreBetaEnsemble(MatrixEnsemble):
21
+ """General beta-Laguerre (Wishart) ensemble.
22
+
23
+ Corresponds to an m x n rectangular data matrix (m "samples", n
24
+ "variables", m >= n) with i.i.d. unit-variance entries. beta=1, 2, 4
25
+ recover LOE, LUE, LSE exactly; any beta > 0 is a valid continuum
26
+ generalization.
27
+
28
+ ``n`` (the ensemble/matrix size, per the ``MatrixEnsemble`` base
29
+ class) is the number of variables; ``m`` is the number of samples,
30
+ with aspect ratio gamma = n / m controlling the Marchenko-Pastur
31
+ support.
32
+ """
33
+
34
+ def __init__(self, n: int, m: int, beta: float, seed: int | np.random.Generator | None = None) -> None:
35
+ """
36
+ Parameters
37
+ ----------
38
+ n : int
39
+ Number of variables (matrix dimension).
40
+ m : int
41
+ Number of samples; must be >= n.
42
+ beta : float
43
+ Dyson index; must be positive.
44
+ seed : int, numpy.random.Generator, or None, optional
45
+ """
46
+ if beta <= 0:
47
+ raise ValueError(f"beta must be positive, got {beta}")
48
+ if m < n:
49
+ raise ValueError(f"m (samples={m}) must be >= n (variables={n})")
50
+ super().__init__(n, seed=seed)
51
+ self.m = m
52
+ self.beta: float = float(beta)
53
+
54
+ @property
55
+ def gamma(self) -> float:
56
+ """Aspect ratio n/m controlling the Marchenko-Pastur support."""
57
+ return self.n / self.m
58
+
59
+ def _sample_eigenvalues(self, rng: np.random.Generator) -> np.ndarray:
60
+ return sample_laguerre_beta_eigenvalues(self.m, self.n, self.beta, rng)
61
+
62
+ def natural_scale(self) -> float:
63
+ # The bidiagonal construction already returns eigenvalues in the
64
+ # standard Marchenko-Pastur normalization (support
65
+ # [(1-sqrt(gamma))^2, (1+sqrt(gamma))^2]); no further rescaling
66
+ # needed.
67
+ return 1.0
68
+
69
+
70
+ class LOE(LaguerreBetaEnsemble):
71
+ """Laguerre Orthogonal Ensemble (beta=1): real Wishart matrices."""
72
+
73
+ def __init__(self, n: int, m: int, seed: int | np.random.Generator | None = None) -> None:
74
+ super().__init__(n, m, beta=1, seed=seed)
75
+
76
+
77
+ class LUE(LaguerreBetaEnsemble):
78
+ """Laguerre Unitary Ensemble (beta=2): complex Wishart matrices."""
79
+
80
+ def __init__(self, n: int, m: int, seed: int | np.random.Generator | None = None) -> None:
81
+ super().__init__(n, m, beta=2, seed=seed)
82
+
83
+
84
+ class LSE(LaguerreBetaEnsemble):
85
+ """Laguerre Symplectic Ensemble (beta=4): quaternionic Wishart matrices."""
86
+
87
+ def __init__(self, n: int, m: int, seed: int | np.random.Generator | None = None) -> None:
88
+ super().__init__(n, m, beta=4, seed=seed)
File without changes
@@ -0,0 +1,82 @@
1
+ """The result of sampling an ensemble: eigenvalues plus the metadata needed
2
+ to compare them against theory."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from dataclasses import dataclass
7
+
8
+ import numpy as np
9
+
10
+
11
+ @dataclass
12
+ class Spectrum:
13
+ """Eigenvalues drawn from a :class:`~physicskit.rmt.ensembles.base.MatrixEnsemble`."""
14
+
15
+ eigenvalues: np.ndarray
16
+ """numpy.ndarray, shape (n_samples, n): Raw (unnormalized) eigenvalues,
17
+ one row per independent draw."""
18
+
19
+ n: int
20
+ """int: Matrix dimension used to generate this spectrum."""
21
+
22
+ beta: float | None
23
+ """float or None: Dyson index of the ensemble that produced this
24
+ spectrum, or None for ensembles outside Dyson's threefold way (e.g.
25
+ ``BuresHallEnsemble``, ``GraphLaplacianEnsemble``)."""
26
+
27
+ ensemble: str
28
+ """str: Name of the ensemble class, for provenance/repr purposes."""
29
+
30
+ scale: float = 1.0
31
+ """float: Factor by which ``eigenvalues`` should be divided to reach
32
+ the ensemble's standard asymptotic normalization (e.g. semicircle
33
+ support [-2, 2] for the Gaussian ensembles). Set by the ensemble via
34
+ ``natural_scale()``."""
35
+
36
+ eigenvectors: np.ndarray | None = None
37
+ """numpy.ndarray, shape (n_samples, m, n), or None: Eigenvectors as
38
+ columns, matching ``eigenvalues`` column-for-column
39
+ (``eigenvectors[s][:, i]`` is the eigenvector for
40
+ ``eigenvalues[s, i]``). Only present when the ensemble was sampled
41
+ with ``sample(return_eigenvectors=True)``; None otherwise. ``m`` is
42
+ usually ``n`` but can differ for ensembles whose eigenvalue count
43
+ isn't exactly ``n`` (see ``n_samples`` elsewhere in this package for
44
+ the analogous eigenvalue-count caveat)."""
45
+
46
+ @property
47
+ def flat(self) -> np.ndarray:
48
+ """All eigenvalues from all samples, raveled into one 1-D array.
49
+
50
+ Returns
51
+ -------
52
+ numpy.ndarray
53
+ 1-D array of all eigenvalues, shape ``(n_samples * eigenvalues.shape[1],)``.
54
+ """
55
+ return self.eigenvalues.ravel()
56
+
57
+ @property
58
+ def rescaled(self) -> np.ndarray:
59
+ """Eigenvalues divided by ``scale``.
60
+
61
+ This is the array to compare against a theoretical limiting
62
+ distribution.
63
+
64
+ Returns
65
+ -------
66
+ numpy.ndarray
67
+ Same shape as ``eigenvalues``.
68
+ """
69
+ return self.eigenvalues / self.scale
70
+
71
+ @property
72
+ def n_samples(self) -> int:
73
+ """Number of independent realizations drawn.
74
+
75
+ Returns
76
+ -------
77
+ int
78
+ """
79
+ return self.eigenvalues.shape[0]
80
+
81
+ def __repr__(self) -> str:
82
+ return f"Spectrum(ensemble={self.ensemble!r}, n={self.n}, beta={self.beta}, n_samples={self.n_samples})"
@@ -0,0 +1,160 @@
1
+ from .characteristic_polynomial import (
2
+ characteristic_polynomial_empirical_moment,
3
+ keating_snaith_moment,
4
+ )
5
+ from .circular_law import circular_law_radial_cdf, circular_law_radial_pdf
6
+ from .correlations import (
7
+ k_point_correlation,
8
+ kernel_d,
9
+ kernel_i,
10
+ kernel_s,
11
+ pair_correlation_estimate,
12
+ sine_kernel_r2,
13
+ )
14
+ from .density import empirical_density, semicircle_cdf, semicircle_pdf
15
+ from .entanglement import page_curve_average_entropy, von_neumann_entropy
16
+ from .free_probability import (
17
+ invert_stieltjes_transform_numerical,
18
+ r_transform_marchenko_pastur,
19
+ r_transform_numerical,
20
+ r_transform_semicircle,
21
+ stieltjes_transform_empirical,
22
+ stieltjes_transform_semicircle,
23
+ )
24
+ from .localization import (
25
+ generalized_ipr,
26
+ inverse_participation_ratio,
27
+ inverse_participation_ratio_quaternionic,
28
+ ipr_theory,
29
+ mass_exponent,
30
+ multifractal_dimension,
31
+ participation_ratio,
32
+ singularity_spectrum,
33
+ )
34
+ from .marchenko_pastur import mp_cdf, mp_pdf, mp_support
35
+ from .pt_symmetric import (
36
+ eigenvector_condition_number,
37
+ find_exceptional_points,
38
+ mean_exceptional_point_count,
39
+ real_axis_spacings,
40
+ real_eigenvalue_fraction,
41
+ semi_poisson_cdf,
42
+ semi_poisson_pdf,
43
+ )
44
+ from .ratios import RatioSurmise, ratio_statistics
45
+ from .real_ginibre import (
46
+ real_eigenvalue_count_asymptotic,
47
+ real_eigenvalue_count_empirical,
48
+ real_eigenvalue_density_asymptotic,
49
+ real_eigenvalue_density_empirical,
50
+ )
51
+ from .rigidity import (
52
+ number_variance_empirical,
53
+ number_variance_goe_asymptotic,
54
+ number_variance_gse_asymptotic,
55
+ number_variance_gue_exact,
56
+ number_variance_poisson,
57
+ number_variance_theory,
58
+ spectral_rigidity_empirical,
59
+ spectral_rigidity_poisson,
60
+ spectral_rigidity_theory,
61
+ )
62
+ from .single_ring import (
63
+ annulus_radial_cdf,
64
+ annulus_radial_pdf,
65
+ single_ring_radii,
66
+ single_ring_radii_wishart_theory,
67
+ )
68
+ from .spacing import (
69
+ circular_spacings,
70
+ nearest_neighbor_spacings,
71
+ wigner_surmise_cdf,
72
+ wigner_surmise_params,
73
+ wigner_surmise_pdf,
74
+ wigner_surmise_samples,
75
+ )
76
+ from .tracy_widom import (
77
+ largest_eigenvalues,
78
+ tracy_widom_cdf,
79
+ tracy_widom_edge_scale,
80
+ tracy_widom_rvs,
81
+ )
82
+ from .truncated_unitary import truncated_unitary_edge_radius
83
+ from .unfolding import unfold_by_cdf
84
+ from .wachter import wachter_cdf, wachter_pdf, wachter_support
85
+
86
+ __all__ = [
87
+ "empirical_density",
88
+ "semicircle_pdf",
89
+ "semicircle_cdf",
90
+ "unfold_by_cdf",
91
+ "nearest_neighbor_spacings",
92
+ "circular_spacings",
93
+ "wigner_surmise_params",
94
+ "wigner_surmise_pdf",
95
+ "wigner_surmise_cdf",
96
+ "wigner_surmise_samples",
97
+ "ratio_statistics",
98
+ "RatioSurmise",
99
+ "mp_pdf",
100
+ "mp_cdf",
101
+ "mp_support",
102
+ "pair_correlation_estimate",
103
+ "sine_kernel_r2",
104
+ "k_point_correlation",
105
+ "circular_law_radial_pdf",
106
+ "circular_law_radial_cdf",
107
+ "largest_eigenvalues",
108
+ "tracy_widom_cdf",
109
+ "tracy_widom_edge_scale",
110
+ "tracy_widom_rvs",
111
+ "wachter_pdf",
112
+ "wachter_cdf",
113
+ "wachter_support",
114
+ "truncated_unitary_edge_radius",
115
+ "keating_snaith_moment",
116
+ "characteristic_polynomial_empirical_moment",
117
+ "stieltjes_transform_empirical",
118
+ "stieltjes_transform_semicircle",
119
+ "r_transform_semicircle",
120
+ "r_transform_marchenko_pastur",
121
+ "invert_stieltjes_transform_numerical",
122
+ "r_transform_numerical",
123
+ "number_variance_empirical",
124
+ "number_variance_poisson",
125
+ "number_variance_gue_exact",
126
+ "number_variance_goe_asymptotic",
127
+ "number_variance_gse_asymptotic",
128
+ "number_variance_theory",
129
+ "spectral_rigidity_empirical",
130
+ "spectral_rigidity_poisson",
131
+ "spectral_rigidity_theory",
132
+ "von_neumann_entropy",
133
+ "page_curve_average_entropy",
134
+ "inverse_participation_ratio",
135
+ "inverse_participation_ratio_quaternionic",
136
+ "generalized_ipr",
137
+ "mass_exponent",
138
+ "multifractal_dimension",
139
+ "singularity_spectrum",
140
+ "participation_ratio",
141
+ "ipr_theory",
142
+ "real_eigenvalue_count_empirical",
143
+ "real_eigenvalue_count_asymptotic",
144
+ "real_eigenvalue_density_empirical",
145
+ "real_eigenvalue_density_asymptotic",
146
+ "single_ring_radii",
147
+ "single_ring_radii_wishart_theory",
148
+ "annulus_radial_pdf",
149
+ "annulus_radial_cdf",
150
+ "real_eigenvalue_fraction",
151
+ "find_exceptional_points",
152
+ "mean_exceptional_point_count",
153
+ "eigenvector_condition_number",
154
+ "semi_poisson_pdf",
155
+ "semi_poisson_cdf",
156
+ "real_axis_spacings",
157
+ "kernel_s",
158
+ "kernel_d",
159
+ "kernel_i",
160
+ ]
@@ -0,0 +1,77 @@
1
+ """Moments of the CUE characteristic polynomial (Keating-Snaith).
2
+
3
+ Reference: J. P. Keating, N. C. Snaith, "Random matrix theory and
4
+ zeta(1/2+it)", Commun. Math. Phys. 214 (2000) 57 -- moments of the CUE
5
+ characteristic polynomial as a model for moments of the Riemann zeta
6
+ function on the critical line (following C. P. Hughes, and the earlier
7
+ exact CUE moment formula of P. Diaconis, M. Shahshahani, "On the
8
+ eigenvalues of random matrices", J. Appl. Probab. 31A (1994) 49).
9
+
10
+ For U an n x n Haar-random unitary matrix (CUE) and its characteristic
11
+ polynomial evaluated on the unit circle, Z_n(theta) = det(I - U*e^{-i*theta}),
12
+ the exact moments (for positive integer k, any theta -- the Haar measure
13
+ is rotation-invariant, so the value does not depend on theta) are
14
+
15
+ ``E[|Z_n(theta)|^(2k)] = prod_{j=0}^{n-1} j! * (j+2k)! / (j+k)!^2``
16
+
17
+ verified numerically here against direct Monte Carlo (CUE via
18
+ ``physicskit.rmt.utils.haar.haar_unitary``) at several (n, k) pairs (matching to
19
+ within 1-2%, consistent with Monte Carlo noise) before being trusted --
20
+ see ``tests/test_characteristic_polynomial.py``. A useful special case
21
+ noticed and checked during that verification: k=1 gives exactly n+1 (the
22
+ product telescopes), a simple closed form worth knowing independently of
23
+ the general product formula.
24
+ """
25
+
26
+ from math import factorial
27
+
28
+ import numpy as np
29
+
30
+
31
+ def keating_snaith_moment(n: int, k: int) -> float:
32
+ """Exact CUE characteristic polynomial moment
33
+ ``E[|Z_n(theta)|^(2k)] = prod_{j=0}^{n-1} j!*(j+2k)! / (j+k)!^2``.
34
+
35
+ Parameters
36
+ ----------
37
+ n : int
38
+ Matrix dimension.
39
+ k : int
40
+ Moment order (positive integer).
41
+
42
+ Returns
43
+ -------
44
+ float
45
+ """
46
+ if k < 1:
47
+ raise ValueError(f"k must be a positive integer, got {k}")
48
+ product = 1.0
49
+ for j in range(n):
50
+ product *= factorial(j) * factorial(j + 2 * k) / factorial(j + k) ** 2
51
+ return product
52
+
53
+
54
+ def characteristic_polynomial_empirical_moment(eigenvalues: np.ndarray, k: int, theta: float = 0.0) -> float:
55
+ """Empirical mean of ``|det(I - U*e^{-i*theta})|^(2k)``, computed
56
+ directly from a CUE spectrum's eigenvalues (the phases of U):
57
+ det(I - U*e^{-i*theta}) = prod_j (1 - e^{i*(phi_j - theta)}) for
58
+ eigenvalue phases phi_j.
59
+
60
+ Parameters
61
+ ----------
62
+ eigenvalues : numpy.ndarray, shape (n_samples, n)
63
+ CUE eigenvalue phases (e.g. ``CUE.sample(...).eigenvalues``, or
64
+ ``.rescaled`` -- either works, since only the phase matters).
65
+ k : int
66
+ Moment order (positive integer).
67
+ theta : float, optional
68
+
69
+ Returns
70
+ -------
71
+ float
72
+ """
73
+ if k < 1:
74
+ raise ValueError(f"k must be a positive integer, got {k}")
75
+ eigenvalues = np.asarray(eigenvalues)
76
+ z = np.prod(1.0 - np.exp(1j * (eigenvalues - theta)), axis=-1)
77
+ return float(np.mean(np.abs(z) ** (2 * k)))
@@ -0,0 +1,54 @@
1
+ """The circular law: limiting eigenvalue density of the Ginibre
2
+ ensembles (uniform on the unit disk after the sqrt(n) rescaling).
3
+
4
+ Reference: J. Ginibre, J. Math. Phys. 6 (1965) 440.
5
+
6
+ Note on naming: this is a completely different concept from the
7
+ "circular ensembles" (COE/CUE/CSE, Dyson 1962) in
8
+ ``physicskit.rmt.ensembles.circular`` -- the shared word "circular" refers to
9
+ two unrelated things in the RMT literature (a disk-shaped eigenvalue
10
+ density here, vs. eigenvalues literally on the unit circle there). Do
11
+ not confuse the modules.
12
+
13
+ For a uniform distribution on the unit disk, the radial marginal
14
+ (density of eigenvalue *magnitude* ``|lambda|``, integrating out the
15
+ angle) has PDF f(r) = 2r and CDF F(r) = r^2 on [0, 1] -- an ordinary 1-D
16
+ distribution, which is what makes it possible to validate via the
17
+ existing KS/Wasserstein ``Benchmark`` machinery (unlike the raw 2-D
18
+ disk density itself).
19
+ """
20
+
21
+ import numpy as np
22
+
23
+
24
+ def circular_law_radial_pdf(r: np.ndarray) -> np.ndarray:
25
+ """Radial marginal density of the circular law: f(r) = 2r on [0, 1].
26
+
27
+ Parameters
28
+ ----------
29
+ r : numpy.ndarray
30
+
31
+ Returns
32
+ -------
33
+ numpy.ndarray
34
+ """
35
+ r = np.asarray(r, dtype=float)
36
+ out = np.zeros_like(r)
37
+ mask = (r >= 0) & (r <= 1)
38
+ out[mask] = 2.0 * r[mask]
39
+ return out
40
+
41
+
42
+ def circular_law_radial_cdf(r: np.ndarray) -> np.ndarray:
43
+ """Radial marginal CDF of the circular law: F(r) = r^2 on [0, 1].
44
+
45
+ Parameters
46
+ ----------
47
+ r : numpy.ndarray
48
+
49
+ Returns
50
+ -------
51
+ numpy.ndarray
52
+ """
53
+ r = np.asarray(r, dtype=float)
54
+ return np.clip(r, 0.0, 1.0) ** 2
@@ -0,0 +1,162 @@
1
+ """Two-point (pair) correlation function of a point process, and the
2
+ exact sine-kernel result for the Circular Unitary Ensemble.
3
+
4
+ Scope note: the exact bulk two-point correlation function for CUE
5
+ (beta=2) has the simple closed determinantal form used here. The
6
+ corresponding beta=1 (COE) and beta=4 (CSE) results also reduce to
7
+ sine-kernel-type expressions, but through the fuller Pfaffian
8
+ point-process machinery: a 2x2 matrix kernel built from companion
9
+ functions "S" (the same sine kernel as beta=2), "D" = S', and
10
+ "I" = integral of S (Mehta, "Random Matrices", Ch. 6-7; Dyson's
11
+ original papers). ``kernel_s``, ``kernel_d``, ``kernel_i`` below
12
+ implement these three individually exact, independently verifiable
13
+ building blocks (D and I are just the derivative and antiderivative of
14
+ the already-validated sine kernel S).
15
+
16
+ The COMBINATION of S, D, I into R_2 for beta=1, 4 is NOT implemented
17
+ here: an attempted reconstruction (from memory) of the standard
18
+ "R_2 = 1 - S^2 + D*I"-type combination was checked here two ways before
19
+ being ruled out -- (1) a small-r Taylor expansion shows that
20
+ combination can only ever produce a QUADRATIC leading term in r
21
+ (D*I ~ r^2 near r=0, same order as 1-S^2), which is structurally
22
+ incompatible with the well-established LINEAR level-repulsion exponent
23
+ required for beta=1; and (2) fitting against direct Monte Carlo COE
24
+ pair-correlation data (see ``pair_correlation_estimate``) confirmed no
25
+ value of an overall coefficient on the D*I term brings it into
26
+ agreement. Rather than ship a formula known to be structurally wrong,
27
+ only the qualitative, robustly-verified physics is asserted here (see
28
+ ``tests/test_correlations.py``): level repulsion strength orders
29
+ CSE >> CUE >> COE >> Poisson (uncorrelated) near r=0, and COE's own
30
+ empirical correlation is consistent with genuine (sub-quadratic) level
31
+ repulsion. The exact beta=1, 4 closed forms remain deferred.
32
+
33
+ Reference: F. J. Dyson, J. Math. Phys. 3 (1962) 140, 157, 166.
34
+ """
35
+
36
+ import numpy as np
37
+ from scipy.special import sici
38
+
39
+ from ..spectrum import Spectrum
40
+
41
+
42
+ def pair_correlation_estimate(spectrum: Spectrum, r_max: float = 4.0, n_bins: int = 60) -> tuple[np.ndarray, np.ndarray]:
43
+ """Estimate the two-point correlation function R_2(r) of an unfolded
44
+ point process (e.g. a circular ensemble's phases) by histogramming
45
+ pairwise circular distances.
46
+
47
+ Convention note: pairwise distances are unsigned, so a bin at
48
+ separation r receives contributions from *both* sides of each
49
+ reference point; the standard R_2(r) convention is defined per
50
+ signed separation, so raw counts must be divided by 2 in addition to
51
+ the usual (n_points * bin_width) normalization -- verified during
52
+ development against a Poisson (uncorrelated) reference process,
53
+ where R_2(r) = 1 identically and the un-halved estimator gave
54
+ exactly 2.0 instead.
55
+
56
+ Parameters
57
+ ----------
58
+ spectrum : physicskit.rmt.spectrum.Spectrum
59
+ A circular-ensemble spectrum (``spectrum.rescaled`` already
60
+ unfolded to unit mean spacing on a circle of circumference n).
61
+ r_max : float
62
+ Maximum separation to histogram.
63
+ n_bins : int
64
+
65
+ Returns
66
+ -------
67
+ centers, r2_estimate : numpy.ndarray
68
+ """
69
+ edges = np.linspace(0.0, r_max, n_bins + 1)
70
+ counts = np.zeros(n_bins)
71
+ total_points = 0
72
+ for row in spectrum.rescaled:
73
+ n = len(row)
74
+ diffs = np.abs(np.subtract.outer(row, row))
75
+ diffs = np.minimum(diffs, n - diffs) # circular distance
76
+ np.fill_diagonal(diffs, np.inf)
77
+ flat = diffs[diffs <= r_max]
78
+ counts += np.histogram(flat, bins=edges)[0]
79
+ total_points += n
80
+ bin_width = edges[1] - edges[0]
81
+ centers = 0.5 * (edges[:-1] + edges[1:])
82
+ r2_estimate = counts / (2.0 * total_points * bin_width)
83
+ return centers, r2_estimate
84
+
85
+
86
+ def sine_kernel_r2(r: np.ndarray) -> np.ndarray:
87
+ """Exact CUE (beta=2) two-point correlation function:
88
+ R_2(r) = 1 - [sin(pi*r) / (pi*r)]^2, with the removable singularity
89
+ at r=0 handled via its limit (R_2(0) = 0, full level repulsion)."""
90
+ r = np.asarray(r, dtype=float)
91
+ out = np.ones_like(r)
92
+ mask = np.abs(r) > 1e-8
93
+ out[mask] = 1.0 - (np.sin(np.pi * r[mask]) / (np.pi * r[mask])) ** 2
94
+ out[~mask] = 0.0
95
+ return out
96
+
97
+
98
+ def kernel_s(r: np.ndarray) -> np.ndarray:
99
+ """The "S" Pfaffian-point-process kernel: S(r) = sin(pi*r)/(pi*r),
100
+ the same sine kernel as beta=2 (see module docstring's scope note
101
+ on why only this building block, not the full beta=1/4 R_2
102
+ combination, is implemented)."""
103
+ r = np.asarray(r, dtype=float)
104
+ out = np.ones_like(r)
105
+ mask = np.abs(r) > 1e-10
106
+ out[mask] = np.sin(np.pi * r[mask]) / (np.pi * r[mask])
107
+ return out
108
+
109
+
110
+ def kernel_d(r: np.ndarray) -> np.ndarray:
111
+ """The "D" Pfaffian-point-process kernel: D(r) = dS/dr (an odd
112
+ function, since S is even)."""
113
+ r = np.asarray(r, dtype=float)
114
+ out = np.zeros_like(r)
115
+ mask = np.abs(r) > 1e-6
116
+ x = np.pi * r[mask]
117
+ out[mask] = np.pi * (x * np.cos(x) - np.sin(x)) / x**2
118
+ return out
119
+
120
+
121
+ def kernel_i(r: np.ndarray) -> np.ndarray:
122
+ """The "I" Pfaffian-point-process kernel: I(r) = integral_0^r S(t) dt
123
+ = Si(pi*r)/pi, where Si is the sine integral function."""
124
+ si, _ = sici(np.pi * np.asarray(r, dtype=float))
125
+ return si / np.pi
126
+
127
+
128
+ def k_point_correlation(positions: np.ndarray) -> float:
129
+ """Exact CUE (beta=2) k-point correlation function at the given
130
+ positions: R_k(x_1, ..., x_k) = det[S(x_i - x_j)]_{i,j=1}^k, the
131
+ defining property of a determinantal point process (Soshnikov,
132
+ "Determinantal random point fields", Russian Math. Surveys 55
133
+ (2000) 923; also Mehta Ch. 5) with kernel S (``kernel_s``, the same
134
+ sine kernel already validated for k=2 via ``sine_kernel_r2``).
135
+
136
+ Reduces EXACTLY to ``sine_kernel_r2`` at k=2 (checked directly:
137
+ ``det[[S(0),S(r)],[S(-r),S(0)]] = 1 - S(r)^2`` since S is even) --
138
+ this is the anchor this generalization rests on, since a fresh
139
+ Monte Carlo estimate of a k=3 (or higher) correlation value from
140
+ ensemble samples turned out to have a subtle reference-point-
141
+ selection bias that made a first attempt at direct verification
142
+ unreliable. What IS verified here (see ``tests/test_correlations.py``):
143
+ the formula vanishes exactly whenever two positions coincide (level
144
+ repulsion at all orders -- an algebraic property of a determinant
145
+ with a repeated row) and correctly factorizes,
146
+ ``R_3(x1, x2, x3) -> R_2(x1, x2)`` as ``x3`` moves to infinity
147
+ (cluster decomposition, checked numerically to 6 significant figures).
148
+
149
+ Parameters
150
+ ----------
151
+ positions : numpy.ndarray, shape (k,)
152
+ The k positions (unfolded, i.e. in units of the mean spacing).
153
+
154
+ Returns
155
+ -------
156
+ float
157
+ """
158
+ positions = np.asarray(positions, dtype=float)
159
+ k = len(positions)
160
+ diff = positions[:, None] - positions[None, :]
161
+ kernel_matrix = kernel_s(diff.ravel()).reshape(k, k)
162
+ return float(np.linalg.det(kernel_matrix))
@@ -0,0 +1,70 @@
1
+ """Empirical spectral density (ESD) and the Wigner semicircle reference
2
+ density/CDF."""
3
+
4
+ import numpy as np
5
+
6
+ from ..spectrum import Spectrum
7
+
8
+
9
+ def empirical_density(spectrum: Spectrum, bins: int = 100, rescaled: bool = True, density: bool = True) -> tuple[np.ndarray, np.ndarray]:
10
+ """Histogram-based empirical spectral density of a Spectrum.
11
+
12
+ Parameters
13
+ ----------
14
+ spectrum : physicskit.rmt.spectrum.Spectrum
15
+ bins : int
16
+ rescaled : bool
17
+ If True (default), histogram the ensemble-normalized eigenvalues
18
+ (``spectrum.rescaled``) rather than the raw ones.
19
+ density : bool
20
+ Passed through to ``numpy.histogram``.
21
+
22
+ Returns
23
+ -------
24
+ centers, counts : numpy.ndarray
25
+ Bin centers and (normalized, if density=True) counts.
26
+ """
27
+ data = spectrum.rescaled.ravel() if rescaled else spectrum.flat
28
+ counts, edges = np.histogram(data, bins=bins, density=density) # type: ignore[call-overload]
29
+ centers = 0.5 * (edges[:-1] + edges[1:])
30
+ return centers, counts
31
+
32
+
33
+ def semicircle_pdf(x: np.ndarray, radius: float = 2.0) -> np.ndarray:
34
+ """Wigner semicircle probability density on [-radius, radius].
35
+
36
+ f(x) = 2 / (pi * radius^2) * sqrt(radius^2 - x^2)
37
+
38
+ Parameters
39
+ ----------
40
+ x : numpy.ndarray
41
+ radius : float, optional
42
+
43
+ Returns
44
+ -------
45
+ numpy.ndarray
46
+ """
47
+ x = np.asarray(x, dtype=float)
48
+ out = np.zeros_like(x)
49
+ mask = np.abs(x) <= radius
50
+ out[mask] = 2.0 / (np.pi * radius**2) * np.sqrt(radius**2 - x[mask] ** 2)
51
+ return out
52
+
53
+
54
+ def semicircle_cdf(x: np.ndarray, radius: float = 2.0) -> np.ndarray:
55
+ """Wigner semicircle cumulative distribution function on
56
+ [-radius, radius].
57
+
58
+ F(x) = 1/2 + x*sqrt(radius^2 - x^2) / (pi * radius^2) + arcsin(x/radius) / pi
59
+
60
+ Parameters
61
+ ----------
62
+ x : numpy.ndarray
63
+ radius : float, optional
64
+
65
+ Returns
66
+ -------
67
+ numpy.ndarray
68
+ """
69
+ x = np.clip(np.asarray(x, dtype=float), -radius, radius)
70
+ return 0.5 + x * np.sqrt(radius**2 - x**2) / (np.pi * radius**2) + np.arcsin(x / radius) / np.pi