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,151 @@
1
+ """Landau's phenomenological theory of continuous phase transitions.
2
+
3
+ Rather than derive a phase transition from microscopic interactions, Landau
4
+ (1937) asked what the *free energy itself* must look like, given only the
5
+ symmetry of the order parameter, near a continuous transition. For an
6
+ order parameter :math:`m` (magnetization, density difference, ...) that
7
+ the disordered phase's symmetry forbids from appearing at odd order, the
8
+ simplest possible expansion is
9
+
10
+ .. math::
11
+
12
+ F(m, T) = a(T - T_C)\\, m^2 + b\\, m^4 - h\\, m, \\qquad a, b > 0,
13
+
14
+ with an external field :math:`h` coupling linearly to :math:`m`. Minimizing
15
+ this quartic over :math:`m` reproduces, from symmetry and analyticity
16
+ alone, the qualitative shape of every continuous transition: a single
17
+ minimum at :math:`m = 0` above :math:`T_C`, a spontaneous, symmetry-broken
18
+ pair of minima :math:`m = \\pm\\sqrt{a(T_C - T)/2b}` below it, and a
19
+ susceptibility that diverges from both sides as :math:`T \\to T_C`. Landau
20
+ theory's mean-field critical exponents (:math:`\\beta = 1/2`, :math:`\\gamma
21
+ = 1`) are quantitatively wrong in low dimensions -- famously not matching
22
+ Onsager's exact 2D Ising values -- but the qualitative order-parameter
23
+ picture it introduced, and the idea of classifying transitions by how they
24
+ break symmetry, underlies the entire modern theory of phase transitions
25
+ that the renormalization group later completed.
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ import numpy as np
31
+
32
+ __all__ = ["landau_equilibrium_magnetization", "landau_free_energy", "landau_susceptibility"]
33
+
34
+
35
+ def landau_free_energy(m, T, Tc, a=1.0, b=1.0, h=0.0):
36
+ """Landau free energy :math:`F(m) = a(T - T_C) m^2 + b m^4 - h m`.
37
+
38
+ Parameters
39
+ ----------
40
+ m : array_like
41
+ Order parameter value(s) at which to evaluate :math:`F`.
42
+ T : float
43
+ Temperature.
44
+ Tc : float
45
+ Critical temperature.
46
+ a, b : float, default=1.0
47
+ Positive Landau expansion coefficients.
48
+ h : float, default=0.0
49
+ External field, linearly coupled to :math:`m`.
50
+
51
+ Returns
52
+ -------
53
+ ndarray
54
+ """
55
+ m = np.asarray(m, dtype=np.float64)
56
+ return a * (T - Tc) * m**2 + b * m**4 - h * m
57
+
58
+
59
+ def landau_equilibrium_magnetization(T, Tc, a=1.0, b=1.0, h=0.0):
60
+ """Order parameter minimizing the Landau free energy at temperature T.
61
+
62
+ Solves :math:`\\partial F/\\partial m = 2a(T-T_C)m + 4bm^3 - h = 0` for
63
+ every real root, and returns the one with the lowest :math:`F` (the
64
+ true equilibrium branch, correctly following the symmetry-broken
65
+ minimum rather than the unstable one once :math:`h \\ne 0` tilts the
66
+ double well). At :math:`h = 0` below :math:`T_C` the two symmetry-broken
67
+ roots :math:`\\pm\\sqrt{a(T_C-T)/2b}` are exactly degenerate in
68
+ :math:`F`; ties are broken deterministically in favor of the
69
+ non-negative root (the conventional "up" branch of spontaneous symmetry
70
+ breaking), so that :math:`m(T)` is a single-valued, continuous curve
71
+ rather than jumping unpredictably between the two equally valid
72
+ branches as :math:`T` is swept. At :math:`h = 0` this reduces to the
73
+ textbook result :math:`m = 0` for :math:`T \\ge T_C` and :math:`m =
74
+ \\sqrt{a(T_C - T)/2b}` for :math:`T < T_C` -- the mean-field
75
+ :math:`\\beta = 1/2` critical exponent.
76
+
77
+ Parameters
78
+ ----------
79
+ T : float or array_like
80
+ Temperature(s).
81
+ Tc : float
82
+ Critical temperature.
83
+ a, b : float, default=1.0
84
+ Positive Landau expansion coefficients.
85
+ h : float, default=0.0
86
+ External field.
87
+
88
+ Returns
89
+ -------
90
+ float or ndarray
91
+ Equilibrium order parameter, matching the shape of ``T``.
92
+
93
+ Examples
94
+ --------
95
+ >>> round(landau_equilibrium_magnetization(T=1.0, Tc=2.0, a=1.0, b=1.0, h=0.0), 6)
96
+ 0.707107
97
+ >>> landau_equilibrium_magnetization(T=3.0, Tc=2.0, a=1.0, b=1.0, h=0.0)
98
+ 0.0
99
+ """
100
+ T_arr = np.atleast_1d(np.asarray(T, dtype=np.float64))
101
+ m_eq = np.empty_like(T_arr)
102
+ for i, Ti in enumerate(T_arr):
103
+ coeffs = [4.0 * b, 0.0, 2.0 * a * (Ti - Tc), -h]
104
+ roots = np.roots(coeffs)
105
+ real_roots = roots[np.abs(roots.imag) < 1e-8].real
106
+ F_vals = a * (Ti - Tc) * real_roots**2 + b * real_roots**4 - h * real_roots
107
+ # Below T_C at h=0 the +/-m branches are exactly degenerate in F, so
108
+ # argmin alone would tie-break on np.roots' arbitrary root ordering,
109
+ # flipping sign unpredictably as T is swept. Restrict to the
110
+ # (numerically) tied minimizers and deterministically prefer the
111
+ # largest (non-negative, "up"-branch) one among them.
112
+ is_min = F_vals <= F_vals.min() + 1e-9 * (1.0 + np.abs(F_vals.min()))
113
+ m_eq[i] = real_roots[is_min].max()
114
+ return float(m_eq[0]) if np.ndim(T) == 0 else m_eq
115
+
116
+
117
+ def landau_susceptibility(T, Tc, a=1.0, b=1.0):
118
+ """Zero-field susceptibility :math:`\\chi = (\\partial^2 F/\\partial m^2)^{-1}` at equilibrium.
119
+
120
+ Evaluated at the :math:`h=0` equilibrium magnetization, this gives the
121
+ standard mean-field result
122
+
123
+ .. math::
124
+
125
+ \\chi(T) = \\begin{cases}
126
+ \\dfrac{1}{2a(T - T_C)}, & T > T_C, \\\\[4pt]
127
+ \\dfrac{1}{4a(T_C - T)}, & T < T_C,
128
+ \\end{cases}
129
+
130
+ diverging on both sides of :math:`T_C` with the same exponent
131
+ :math:`\\gamma = 1` but different amplitudes -- the universal
132
+ mean-field amplitude ratio of 2.
133
+
134
+ Parameters
135
+ ----------
136
+ T : array_like
137
+ Temperature(s); may include ``Tc`` itself, where :math:`\\chi`
138
+ diverges (``inf`` is returned there).
139
+ Tc : float
140
+ Critical temperature.
141
+ a, b : float, default=1.0
142
+ Positive Landau expansion coefficients (``b`` is unused above
143
+ :math:`T_C`, kept for a uniform signature).
144
+
145
+ Returns
146
+ -------
147
+ ndarray
148
+ """
149
+ T = np.asarray(T, dtype=np.float64)
150
+ with np.errstate(divide="ignore"):
151
+ return np.where(T > Tc, 1.0 / (2.0 * a * (T - Tc)), 1.0 / (4.0 * a * (Tc - T)))
@@ -0,0 +1,109 @@
1
+ """Exact partition-function enumeration and the Lee-Yang circle theorem.
2
+
3
+ Lee and Yang (1952) asked where a phase transition -- a genuine
4
+ discontinuity or divergence in the free energy -- could possibly come from,
5
+ given that a finite system's partition function is a finite sum of
6
+ manifestly analytic terms. Their answer: it comes from the zeros of the
7
+ partition function, analytically continued into the *complex* fugacity
8
+ plane. For a finite ferromagnetic Ising system in a field, every such zero
9
+ lies exactly on the unit circle (the "Lee-Yang circle theorem"); as the
10
+ system size grows, these zeros multiply and crowd toward the positive real
11
+ axis, and a phase transition occurs exactly where, in the thermodynamic
12
+ limit, they pinch that axis. No finite system has a true singularity, but
13
+ the zeros' approach to one is visible well before that limit.
14
+
15
+ This module computes the partition function of a small Ising system
16
+ *exactly*, by full enumeration of every spin configuration -- feasible up to roughly
17
+ :math:`N \\approx 20` (:math:`2^N` configurations are enumerated
18
+ explicitly) -- as a polynomial in the fugacity, and finds
19
+ that polynomial's roots directly.
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ import numpy as np
25
+
26
+ __all__ = ["ising_partition_polynomial", "yang_lee_zeros"]
27
+
28
+
29
+ def ising_partition_polynomial(N, beta, J=1.0, periodic=True):
30
+ """Exact partition function of a small 1D Ising chain, as a polynomial in the fugacity.
31
+
32
+ With an external field :math:`h`, the Hamiltonian is :math:`H =
33
+ -J\\sum_{\\langle i,j\\rangle} s_i s_j - h \\sum_i s_i`. Writing the
34
+ fugacity :math:`z = e^{2\\beta h}`, the partition function factors as
35
+
36
+ .. math::
37
+
38
+ Z(\\beta, h) = e^{-\\beta h N} \\sum_{k=0}^{N} g_k\\, z^k,
39
+
40
+ where :math:`g_k = \\sum_{\\{s\\}:\\, n_\\uparrow(s) = k}
41
+ e^{-\\beta H_0(s)}` sums the field-free Boltzmann weight over every
42
+ configuration with exactly :math:`k` up-spins. The prefactor
43
+ :math:`e^{-\\beta h N}` is nonzero and analytic in :math:`h`, so it
44
+ never contributes a zero: the zeros of :math:`Z` as a function of
45
+ :math:`z` are exactly the roots of this polynomial's coefficients
46
+ ``g_k``, which is all :func:`yang_lee_zeros` needs.
47
+
48
+ Every one of the :math:`2^N` configurations is enumerated directly, so
49
+ this is only practical for modest :math:`N` (roughly 20 at most --
50
+ ``2**30`` configurations will exhaust memory).
51
+
52
+ Parameters
53
+ ----------
54
+ N : int
55
+ Number of spins.
56
+ beta : float
57
+ Inverse temperature.
58
+ J : float, default=1.0
59
+ Nearest-neighbor coupling. ``J > 0`` (ferromagnetic) is the regime
60
+ the Lee-Yang circle theorem applies to.
61
+ periodic : bool, default=True
62
+ Periodic (ring) vs. open chain boundary conditions.
63
+
64
+ Returns
65
+ -------
66
+ ndarray of shape (N + 1,)
67
+ Coefficients ``g_k``, ordered by increasing power of ``z`` (i.e.
68
+ ``g[k]`` is the coefficient of ``z**k``).
69
+ """
70
+ configs = np.arange(2**N, dtype=np.int64)
71
+ bits = (configs[:, None] >> np.arange(N)) & 1
72
+ spins = bits.astype(np.float64) * 2 - 1 # shape (2**N, N), values +/-1
73
+
74
+ if periodic:
75
+ neighbor_product = spins * np.roll(spins, -1, axis=1)
76
+ else:
77
+ neighbor_product = spins[:, :-1] * spins[:, 1:]
78
+ E0 = -J * np.sum(neighbor_product, axis=1)
79
+
80
+ n_up = np.sum(bits, axis=1)
81
+ weights = np.exp(-beta * E0)
82
+
83
+ g = np.zeros(N + 1, dtype=np.float64)
84
+ np.add.at(g, n_up, weights)
85
+ return g
86
+
87
+
88
+ def yang_lee_zeros(coeffs):
89
+ """Roots, in the complex fugacity plane, of the polynomial :math:`\\sum_k g_k z^k`.
90
+
91
+ Lee and Yang's circle theorem predicts that for a ferromagnetic Ising
92
+ system (``J > 0`` in :func:`ising_partition_polynomial`), every one of
93
+ these roots lies exactly on the unit circle :math:`|z| = 1`, regardless
94
+ of system size -- a striking, exact constraint on where a phase
95
+ transition's mathematical signature is allowed to live.
96
+
97
+ Parameters
98
+ ----------
99
+ coeffs : array_like
100
+ Polynomial coefficients ``g_k``, ordered by increasing power of
101
+ ``z`` (as returned by :func:`ising_partition_polynomial`).
102
+
103
+ Returns
104
+ -------
105
+ ndarray of complex
106
+ The polynomial's roots.
107
+ """
108
+ coeffs = np.asarray(coeffs, dtype=np.float64)
109
+ return np.roots(coeffs[::-1])
@@ -0,0 +1,356 @@
1
+ """Thermodynamic observables derived from Monte Carlo and molecular dynamics samples.
2
+
3
+ Every function here takes arrays of samples collected during a simulation
4
+ (energies, magnetizations, velocities, spin configurations, ...) and returns a
5
+ scalar or array observable, following the standard fluctuation-dissipation
6
+ relations of the canonical ensemble.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import numpy as np
12
+
13
+ __all__ = [
14
+ "bec_condensate_fraction",
15
+ "binder_cumulant",
16
+ "bose_einstein_occupation",
17
+ "fermi_dirac_occupation",
18
+ "maxwell_boltzmann_component_pdf",
19
+ "maxwell_boltzmann_speed_pdf",
20
+ "specific_heat",
21
+ "spin_correlation_function",
22
+ "susceptibility",
23
+ ]
24
+
25
+
26
+ def specific_heat(energies, temperature, n_sites, kB=1.0):
27
+ """Specific heat per site from the energy fluctuations of a canonical sample.
28
+
29
+ .. math::
30
+
31
+ C_v = \\frac{\\langle E^2 \\rangle - \\langle E \\rangle^2}{k_B T^2 N}
32
+
33
+ Parameters
34
+ ----------
35
+ energies : array_like
36
+ Sampled total energies at fixed temperature.
37
+ temperature : float
38
+ Sampling temperature.
39
+ n_sites : int
40
+ Number of lattice sites (or particles) ``N``, used to report an
41
+ intensive, per-site quantity.
42
+ kB : float, default=1.0
43
+ Boltzmann constant.
44
+
45
+ Returns
46
+ -------
47
+ float
48
+ Specific heat per site.
49
+
50
+ Examples
51
+ --------
52
+ >>> rng = np.random.default_rng(0)
53
+ >>> E = rng.normal(loc=-100.0, scale=5.0, size=10000)
54
+ >>> bool(specific_heat(E, temperature=2.0, n_sites=64) > 0)
55
+ True
56
+ """
57
+ energies = np.asarray(energies, dtype=np.float64)
58
+ var_E = energies.var()
59
+ return var_E / (kB * temperature**2 * n_sites)
60
+
61
+
62
+ def susceptibility(magnetizations, temperature, n_sites, kB=1.0):
63
+ """Magnetic susceptibility per site from magnetization fluctuations.
64
+
65
+ .. math::
66
+
67
+ \\chi = \\frac{\\langle M^2 \\rangle - \\langle M \\rangle^2}{k_B T N}
68
+
69
+ Parameters
70
+ ----------
71
+ magnetizations : array_like
72
+ Sampled total magnetizations at fixed temperature.
73
+ temperature : float
74
+ Sampling temperature.
75
+ n_sites : int
76
+ Number of lattice sites ``N``.
77
+ kB : float, default=1.0
78
+ Boltzmann constant.
79
+
80
+ Returns
81
+ -------
82
+ float
83
+ Susceptibility per site.
84
+ """
85
+ magnetizations = np.asarray(magnetizations, dtype=np.float64)
86
+ var_M = magnetizations.var()
87
+ return var_M / (kB * temperature * n_sites)
88
+
89
+
90
+ def binder_cumulant(magnetizations):
91
+ """Fourth-order Binder cumulant of a magnetization sample.
92
+
93
+ .. math::
94
+
95
+ U_4 = 1 - \\frac{\\langle M^4 \\rangle}{3 \\langle M^2 \\rangle^2}
96
+
97
+ ``U_4`` is a standard finite-size-scaling diagnostic: it is
98
+ size-independent exactly at the critical temperature, which makes
99
+ crossing plots for several lattice sizes a robust way to locate
100
+ :math:`T_c`.
101
+
102
+ Parameters
103
+ ----------
104
+ magnetizations : array_like
105
+ Sampled total (or per-site) magnetizations.
106
+
107
+ Returns
108
+ -------
109
+ float
110
+ The Binder cumulant, in :math:`[0, 2/3]` for a symmetric
111
+ distribution.
112
+ """
113
+ m = np.asarray(magnetizations, dtype=np.float64)
114
+ m2 = np.mean(m**2)
115
+ m4 = np.mean(m**4)
116
+ return 1.0 - m4 / (3.0 * m2**2)
117
+
118
+
119
+ def spin_correlation_function(spins, max_r=None):
120
+ """Radially averaged equal-time spin-spin correlation function :math:`G(r)`.
121
+
122
+ Computed efficiently via the Wiener-Khinchin theorem: the autocorrelation
123
+ of a periodic field equals the inverse FFT of its power spectrum.
124
+
125
+ .. math::
126
+
127
+ G(r) = \\langle s_0 s_r \\rangle - \\langle s \\rangle^2
128
+
129
+ averaged over all site pairs at (periodic, Euclidean-rounded) separation
130
+ ``r``.
131
+
132
+ Parameters
133
+ ----------
134
+ spins : ndarray of shape (L, L)
135
+ Spin (or angle-cosine) configuration on a periodic square lattice.
136
+ max_r : int, optional
137
+ Largest separation to report. Defaults to ``L // 2``.
138
+
139
+ Returns
140
+ -------
141
+ r : ndarray of shape (max_r,)
142
+ Integer separations ``0, 1, ..., max_r - 1``.
143
+ G : ndarray of shape (max_r,)
144
+ Correlation function averaged over all pairs at each rounded
145
+ separation.
146
+ """
147
+ spins = np.asarray(spins, dtype=np.float64)
148
+ L = spins.shape[0]
149
+ if max_r is None:
150
+ max_r = L // 2
151
+
152
+ mean_s = spins.mean()
153
+ fft = np.fft.fft2(spins)
154
+ autocorr = np.fft.ifft2(fft * np.conj(fft)).real / (L * L)
155
+
156
+ ii, jj = np.meshgrid(np.arange(L), np.arange(L), indexing="ij")
157
+ di = np.minimum(ii, L - ii)
158
+ dj = np.minimum(jj, L - jj)
159
+ dist = np.sqrt(di**2 + dj**2)
160
+ r_bin = np.round(dist).astype(int)
161
+
162
+ G = np.zeros(max_r, dtype=np.float64)
163
+ for r in range(max_r):
164
+ mask = r_bin == r
165
+ if np.any(mask):
166
+ G[r] = autocorr[mask].mean() - mean_s**2
167
+ return np.arange(max_r), G
168
+
169
+
170
+ def maxwell_boltzmann_speed_pdf(v, temperature, mass=1.0, kB=1.0, dim=2):
171
+ """Equilibrium Maxwell-Boltzmann probability density of the speed :math:`|v|`.
172
+
173
+ In :math:`d` dimensions,
174
+
175
+ .. math::
176
+
177
+ f(v) = v^{d-1}
178
+ \\left(\\frac{m}{2\\pi k_B T}\\right)^{d/2}
179
+ S_{d-1} \\, e^{-m v^2 / 2 k_B T}
180
+
181
+ where :math:`S_{d-1}` is the surface area of the unit :math:`(d-1)`-sphere
182
+ (:math:`2` for :math:`d=1`, :math:`2\\pi` for :math:`d=2`, :math:`4\\pi`
183
+ for :math:`d=3`).
184
+
185
+ Parameters
186
+ ----------
187
+ v : array_like
188
+ Speed values (must be non-negative) at which to evaluate the density.
189
+ temperature : float
190
+ Temperature.
191
+ mass : float, default=1.0
192
+ Particle mass.
193
+ kB : float, default=1.0
194
+ Boltzmann constant.
195
+ dim : {1, 2, 3}, default=2
196
+ Spatial dimension.
197
+
198
+ Returns
199
+ -------
200
+ ndarray
201
+ Probability density :math:`f(v)`, normalized so that
202
+ :math:`\\int_0^\\infty f(v)\\, dv = 1`.
203
+ """
204
+ v = np.asarray(v, dtype=np.float64)
205
+ beta_m = mass / (kB * temperature)
206
+ if dim == 1:
207
+ surface = 2.0
208
+ elif dim == 2:
209
+ surface = 2.0 * np.pi
210
+ elif dim == 3:
211
+ surface = 4.0 * np.pi
212
+ else:
213
+ raise ValueError("dim must be 1, 2, or 3")
214
+ prefactor = surface * (beta_m / (2.0 * np.pi)) ** (dim / 2.0)
215
+ return prefactor * v ** (dim - 1) * np.exp(-0.5 * beta_m * v**2)
216
+
217
+
218
+ def maxwell_boltzmann_component_pdf(vx, temperature, mass=1.0, kB=1.0):
219
+ """Equilibrium Gaussian density of a single Cartesian velocity component.
220
+
221
+ .. math::
222
+
223
+ f(v_x) = \\sqrt{\\frac{m}{2\\pi k_B T}} \\, e^{-m v_x^2 / 2 k_B T}
224
+
225
+ Parameters
226
+ ----------
227
+ vx : array_like
228
+ Velocity component values.
229
+ temperature : float
230
+ Temperature.
231
+ mass : float, default=1.0
232
+ Particle mass.
233
+ kB : float, default=1.0
234
+ Boltzmann constant.
235
+
236
+ Returns
237
+ -------
238
+ ndarray
239
+ Probability density :math:`f(v_x)`.
240
+ """
241
+ vx = np.asarray(vx, dtype=np.float64)
242
+ beta_m = mass / (kB * temperature)
243
+ return np.sqrt(beta_m / (2.0 * np.pi)) * np.exp(-0.5 * beta_m * vx**2)
244
+
245
+
246
+ def bose_einstein_occupation(energy, mu, temperature, kB=1.0):
247
+ """Mean occupation number of a bosonic single-particle state, the Bose-Einstein distribution.
248
+
249
+ .. math::
250
+
251
+ n_{\\text{BE}}(\\varepsilon) = \\frac{1}{e^{(\\varepsilon - \\mu)/k_B T} - 1}
252
+
253
+ Unlike Fermi-Dirac statistics, there is no restriction on how many
254
+ identical bosons can occupy the same state; as the chemical potential
255
+ :math:`\\mu` approaches the ground-state energy from below, the
256
+ ground-state occupation diverges -- the onset of Bose-Einstein
257
+ condensation.
258
+
259
+ Parameters
260
+ ----------
261
+ energy : array_like
262
+ Single-particle state energies. Must satisfy ``energy > mu``
263
+ (otherwise the occupation is unphysical).
264
+ mu : float
265
+ Chemical potential.
266
+ temperature : float
267
+ Temperature.
268
+ kB : float, default=1.0
269
+ Boltzmann constant.
270
+
271
+ Returns
272
+ -------
273
+ ndarray
274
+ Mean occupation number :math:`n_{\\text{BE}}(\\varepsilon)`.
275
+ """
276
+ x = (np.asarray(energy, dtype=np.float64) - mu) / (kB * temperature)
277
+ return 1.0 / np.expm1(x)
278
+
279
+
280
+ def fermi_dirac_occupation(energy, mu, temperature, kB=1.0):
281
+ """Mean occupation number of a fermionic single-particle state, the Fermi-Dirac distribution.
282
+
283
+ .. math::
284
+
285
+ n_{\\text{FD}}(\\varepsilon) = \\frac{1}{e^{(\\varepsilon - \\mu)/k_B T} + 1}
286
+
287
+ The Pauli exclusion principle caps :math:`n_{\\text{FD}}` at 1 for every
288
+ state, in sharp contrast to Bose-Einstein statistics; as :math:`T \\to
289
+ 0`, this sharpens into a step function at the Fermi energy
290
+ :math:`\\varepsilon = \\mu`.
291
+
292
+ Parameters
293
+ ----------
294
+ energy : array_like
295
+ Single-particle state energies.
296
+ mu : float
297
+ Chemical potential (the Fermi energy at :math:`T = 0`).
298
+ temperature : float
299
+ Temperature.
300
+ kB : float, default=1.0
301
+ Boltzmann constant.
302
+
303
+ Returns
304
+ -------
305
+ ndarray
306
+ Mean occupation number :math:`n_{\\text{FD}}(\\varepsilon) \\in (0, 1)`.
307
+
308
+ Examples
309
+ --------
310
+ >>> import numpy as np
311
+ >>> bool(np.all(fermi_dirac_occupation(np.array([0.0, 1.0, 2.0]), mu=1.0, temperature=0.01) >= 0))
312
+ True
313
+ """
314
+ x = (np.asarray(energy, dtype=np.float64) - mu) / (kB * temperature)
315
+ with np.errstate(over="ignore"):
316
+ # exp(x) legitimately overflows to inf deep in the low-T step-function
317
+ # limit; 1/(inf+1) still gives the mathematically correct 0 occupation.
318
+ return 1.0 / (np.exp(x) + 1.0)
319
+
320
+
321
+ def bec_condensate_fraction(temperature, critical_temperature):
322
+ """Condensate fraction of an ideal, homogeneous 3D Bose gas below the BEC transition.
323
+
324
+ .. math::
325
+
326
+ \\frac{N_0}{N} =
327
+ \\begin{cases}
328
+ 1 - (T / T_c)^{3/2} & T < T_c \\\\
329
+ 0 & T \\ge T_c
330
+ \\end{cases}
331
+
332
+ A textbook prediction of Bose-Einstein statistics for a trapped ideal
333
+ gas, first confirmed experimentally in 1995 in dilute alkali-atom gases
334
+ (Cornell and Wieman; Ketterle; 2001 Nobel Prize in Physics).
335
+
336
+ Parameters
337
+ ----------
338
+ temperature : array_like
339
+ Temperature(s) at which to evaluate the condensate fraction.
340
+ critical_temperature : float
341
+ The BEC transition temperature :math:`T_c`.
342
+
343
+ Returns
344
+ -------
345
+ ndarray
346
+ Condensate fraction :math:`N_0/N \\in [0, 1]`.
347
+
348
+ Examples
349
+ --------
350
+ >>> f = bec_condensate_fraction(np.array([0.0, 0.5, 1.0, 2.0]), critical_temperature=1.0)
351
+ >>> [round(float(v), 3) for v in f]
352
+ [1.0, 0.646, 0.0, 0.0]
353
+ """
354
+ T = np.asarray(temperature, dtype=np.float64)
355
+ fraction = 1.0 - (T / critical_temperature) ** 1.5
356
+ return np.where(critical_temperature > T, fraction, 0.0)
@@ -0,0 +1,87 @@
1
+ """Matplotlib- and Plotly-based visualizers for every physicskit.statphys chapter.
2
+
3
+ - :mod:`physicskit.statphys.visualizers.lattice_render` -- spin grid heatmaps, sweep
4
+ animations, thermodynamic diagnostic plots, and percolation cluster and
5
+ cluster-size-distribution plots.
6
+ - :mod:`physicskit.statphys.visualizers.vortex_render` -- XY model vector fields and
7
+ topological vortex/antivortex overlays.
8
+ - :mod:`physicskit.statphys.visualizers.particle_render` -- Lennard-Jones gas snapshots,
9
+ velocity histograms, and motion animations.
10
+ - :mod:`physicskit.statphys.visualizers.rg_render` -- side-by-side block-spin
11
+ renormalization group flow panels.
12
+ - :mod:`physicskit.statphys.visualizers.random_walk_render` -- walk trajectories, MSD,
13
+ and central-limit-theorem histograms.
14
+ - :mod:`physicskit.statphys.visualizers.sandpile_render` -- sandpile heights and
15
+ avalanche size distributions.
16
+ - :mod:`physicskit.statphys.visualizers.urn_render` -- Ehrenfest urn relaxation and
17
+ entropy history.
18
+ - :mod:`physicskit.statphys.visualizers.spin_glass_render` -- spin-glass replica-overlap
19
+ distributions.
20
+ - :mod:`physicskit.statphys.visualizers.kpz_render` -- RSOS interface profiles and
21
+ width-growth scaling.
22
+ - :mod:`physicskit.statphys.visualizers.jarzynski_render` -- nonequilibrium work
23
+ distributions and free-energy estimates.
24
+ - :mod:`physicskit.statphys.visualizers.interactive` -- Plotly-based interactive
25
+ counterparts of the temperature sweep, vortex field, and particle
26
+ snapshot plots.
27
+ """
28
+
29
+ from physicskit.statphys.visualizers.interactive import (
30
+ interactive_particle_snapshot,
31
+ interactive_temperature_sweep,
32
+ interactive_vortex_field,
33
+ )
34
+ from physicskit.statphys.visualizers.jarzynski_render import plot_work_distribution
35
+ from physicskit.statphys.visualizers.kpz_render import plot_interface_profile, plot_width_growth
36
+ from physicskit.statphys.visualizers.lattice_render import (
37
+ animate_lattice_sweeps,
38
+ plot_cluster_size_distribution,
39
+ plot_percolation_clusters,
40
+ plot_spin_grid,
41
+ plot_thermodynamics,
42
+ )
43
+ from physicskit.statphys.visualizers.particle_render import (
44
+ animate_gas,
45
+ plot_particle_snapshot,
46
+ plot_velocity_histogram,
47
+ )
48
+ from physicskit.statphys.visualizers.random_walk_render import (
49
+ plot_clt_histogram,
50
+ plot_msd,
51
+ plot_trajectories_2d,
52
+ )
53
+ from physicskit.statphys.visualizers.rg_render import plot_rg_flow
54
+ from physicskit.statphys.visualizers.sandpile_render import (
55
+ plot_avalanche_size_distribution,
56
+ plot_sandpile_heights,
57
+ )
58
+ from physicskit.statphys.visualizers.spin_glass_render import plot_overlap_distribution
59
+ from physicskit.statphys.visualizers.urn_render import plot_ehrenfest_history
60
+ from physicskit.statphys.visualizers.vortex_render import plot_vortices, plot_xy_vector_field
61
+
62
+ __all__ = [
63
+ "animate_gas",
64
+ "animate_lattice_sweeps",
65
+ "interactive_particle_snapshot",
66
+ "interactive_temperature_sweep",
67
+ "interactive_vortex_field",
68
+ "plot_avalanche_size_distribution",
69
+ "plot_clt_histogram",
70
+ "plot_cluster_size_distribution",
71
+ "plot_ehrenfest_history",
72
+ "plot_interface_profile",
73
+ "plot_msd",
74
+ "plot_overlap_distribution",
75
+ "plot_particle_snapshot",
76
+ "plot_percolation_clusters",
77
+ "plot_rg_flow",
78
+ "plot_sandpile_heights",
79
+ "plot_spin_grid",
80
+ "plot_thermodynamics",
81
+ "plot_trajectories_2d",
82
+ "plot_velocity_histogram",
83
+ "plot_vortices",
84
+ "plot_width_growth",
85
+ "plot_work_distribution",
86
+ "plot_xy_vector_field",
87
+ ]