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,179 @@
1
+ r"""Wigner quasi-probability distribution :math:`W(x,p)` and 3D phase-space plots."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+ import matplotlib.pyplot as plt
8
+ import numpy as np
9
+
10
+ __all__ = ["wigner_transform", "WignerVisualizer"]
11
+
12
+
13
+ def wigner_transform(x: np.ndarray, psi: np.ndarray, hbar: float = 1.0, n_p: int = 200, p_max: float | None = None):
14
+ r"""Compute the Wigner quasi-probability distribution.
15
+
16
+ .. math::
17
+
18
+ W(x,p) = \frac{1}{\pi\hbar} \int_{-\infty}^{\infty}
19
+ \psi^*(x+y)\,\psi(x-y)\, e^{2ipy/\hbar}\, dy,
20
+
21
+ on the same x-grid the wavefunction is given on, by direct quadrature
22
+ over the shift :math:`y=k\,dx` (:math:`\psi` is treated as zero outside
23
+ the grid).
24
+
25
+ Parameters
26
+ ----------
27
+ x : numpy.ndarray
28
+ Positions the wavefunction is sampled on (uniform grid).
29
+ psi : numpy.ndarray
30
+ Complex-valued wavefunction sampled on ``x``.
31
+ hbar : float, default=1.0
32
+ Value of :math:`\hbar` to use.
33
+ n_p : int, default=200
34
+ Number of momentum grid points.
35
+ p_max : float or None, optional
36
+ Half-width of the momentum grid; defaults to the Nyquist limit set
37
+ by the position-grid spacing, :math:`\pi\hbar/(2\,dx)`.
38
+
39
+ Returns
40
+ -------
41
+ x : numpy.ndarray
42
+ The (unchanged) position grid.
43
+ p : numpy.ndarray
44
+ The momentum grid, shape ``(n_p,)``.
45
+ W : numpy.ndarray
46
+ The Wigner function, shape ``(len(x), n_p)``.
47
+ """
48
+ x = np.asarray(x)
49
+ psi = np.asarray(psi, dtype=complex)
50
+ N = x.shape[0]
51
+ dx = x[1] - x[0]
52
+ if p_max is None:
53
+ # The transform's kernel is e^{2ipy/hbar} with y=k*dx, so the
54
+ # conjugate variable is 2p/hbar; its Nyquist limit pi/dx gives
55
+ # p_max = pi*hbar/(2*dx) (using the full pi*hbar/dx aliases W(x,p)
56
+ # periodically back onto itself well before that point).
57
+ p_max = np.pi * hbar / (2 * dx)
58
+
59
+ p = np.linspace(-p_max, p_max, n_p)
60
+ W = np.zeros((N, n_p))
61
+
62
+ for i in range(N):
63
+ kmax = min(i, N - 1 - i)
64
+ k = np.arange(-kmax, kmax + 1)
65
+ integrand = np.conj(psi[i + k]) * psi[i - k]
66
+ phase = np.exp(2j * np.outer(p, k * dx) / hbar) # (n_p, len(k))
67
+ W[i, :] = (dx / (np.pi * hbar)) * np.real(phase @ integrand)
68
+
69
+ return x, p, W
70
+
71
+
72
+ @dataclass
73
+ class WignerVisualizer:
74
+ """Convenience wrapper around :func:`wigner_transform` with plotting helpers.
75
+
76
+ Parameters
77
+ ----------
78
+ hbar : float, default=1.0
79
+ Value of :math:`\\hbar` to use.
80
+ n_p : int, default=200
81
+ Number of momentum grid points.
82
+ """
83
+
84
+ hbar: float = 1.0
85
+ n_p: int = 200
86
+
87
+ def compute(self, x: np.ndarray, psi: np.ndarray, p_max: float | None = None):
88
+ """See :func:`wigner_transform`.
89
+
90
+ Parameters
91
+ ----------
92
+ x : numpy.ndarray
93
+ psi : numpy.ndarray
94
+ p_max : float or None, optional
95
+
96
+ Returns
97
+ -------
98
+ x, p, W : numpy.ndarray
99
+ """
100
+ return wigner_transform(x, psi, self.hbar, self.n_p, p_max)
101
+
102
+ def position_marginal(self, p: np.ndarray, W: np.ndarray) -> np.ndarray:
103
+ r"""Integrate :math:`W(x,p)` over :math:`p`.
104
+
105
+ Should recover :math:`\lvert\psi(x)\rvert^2` -- a standard
106
+ correctness check for a Wigner-function implementation.
107
+
108
+ Parameters
109
+ ----------
110
+ p : numpy.ndarray
111
+ Momentum grid.
112
+ W : numpy.ndarray
113
+ Wigner function, shape ``(len(x), len(p))``.
114
+
115
+ Returns
116
+ -------
117
+ numpy.ndarray
118
+ """
119
+ dp = p[1] - p[0]
120
+ return np.sum(W, axis=1) * dp
121
+
122
+ def plot_surface(self, x: np.ndarray, p: np.ndarray, W: np.ndarray, ax=None, cmap: str = "RdBu_r"):
123
+ """3D surface plot of :math:`W(x,p)`.
124
+
125
+ Uses a diverging colormap so the negative (non-classical
126
+ interference) regions stand out from the positive ones.
127
+
128
+ Parameters
129
+ ----------
130
+ x, p : numpy.ndarray
131
+ Position and momentum grids.
132
+ W : numpy.ndarray
133
+ Wigner function, shape ``(len(x), len(p))``.
134
+ ax : matplotlib.axes.Axes or None, optional
135
+ A 3D axis to draw on; a new figure/axis is created if omitted.
136
+ cmap : str, default='RdBu_r'
137
+ Diverging colormap name.
138
+
139
+ Returns
140
+ -------
141
+ matplotlib.axes.Axes
142
+ """
143
+ if ax is None:
144
+ fig = plt.figure(figsize=(8, 6))
145
+ ax = fig.add_subplot(111, projection="3d")
146
+ X, P = np.meshgrid(x, p, indexing="ij")
147
+ vmax = np.abs(W).max()
148
+ ax.plot_surface(X, P, W, cmap=cmap, vmin=-vmax, vmax=vmax, linewidth=0, antialiased=True)
149
+ ax.set_xlabel("x")
150
+ ax.set_ylabel("p")
151
+ ax.set_zlabel("W(x,p)")
152
+ return ax
153
+
154
+ def plot_contour(self, x: np.ndarray, p: np.ndarray, W: np.ndarray, ax=None, cmap: str = "RdBu_r"):
155
+ """2D filled-contour plot of :math:`W(x,p)`.
156
+
157
+ Parameters
158
+ ----------
159
+ x, p : numpy.ndarray
160
+ Position and momentum grids.
161
+ W : numpy.ndarray
162
+ Wigner function, shape ``(len(x), len(p))``.
163
+ ax : matplotlib.axes.Axes or None, optional
164
+ Axis to draw on; a new figure/axis is created if omitted.
165
+ cmap : str, default='RdBu_r'
166
+ Diverging colormap name.
167
+
168
+ Returns
169
+ -------
170
+ matplotlib.axes.Axes
171
+ """
172
+ if ax is None:
173
+ _, ax = plt.subplots(figsize=(6, 5))
174
+ vmax = np.abs(W).max()
175
+ cs = ax.contourf(x, p, W.T, levels=60, cmap=cmap, vmin=-vmax, vmax=vmax)
176
+ ax.set_xlabel("x")
177
+ ax.set_ylabel("p")
178
+ plt.colorbar(cs, ax=ax, label="W(x,p)")
179
+ return ax
@@ -0,0 +1,230 @@
1
+ r"""Phase-colored HSV complex wavefunction plots and density animations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import matplotlib.colors as mcolors
8
+ import matplotlib.pyplot as plt
9
+ import numpy as np
10
+ from matplotlib.animation import FuncAnimation
11
+
12
+ __all__ = ["complex_to_rgb", "plot_complex_wavefunction", "animate_density", "animate_density_2d"]
13
+
14
+
15
+ def complex_to_rgb(psi: np.ndarray, max_abs: Optional[float] = None) -> np.ndarray:
16
+ r"""Map a complex array to RGB: hue = phase, value = amplitude.
17
+
18
+ .. math::
19
+
20
+ \text{hue} = \frac{\arg\psi + \pi}{2\pi}, \qquad
21
+ \text{value} = \min\!\left(\frac{\lvert\psi\rvert}{\max\lvert\psi\rvert}, 1\right).
22
+
23
+ Parameters
24
+ ----------
25
+ psi : numpy.ndarray
26
+ Complex-valued array.
27
+ max_abs : float or None, optional
28
+ Amplitude that maps to full brightness; defaults to ``abs(psi).max()``.
29
+
30
+ Returns
31
+ -------
32
+ numpy.ndarray
33
+ RGB array of shape ``(..., 3)``, suitable for ``imshow``/plotting.
34
+ """
35
+ amp = np.abs(psi)
36
+ phase = np.angle(psi)
37
+ if max_abs is None:
38
+ max_abs = amp.max() if amp.max() > 0 else 1.0
39
+ hue = (phase + np.pi) / (2 * np.pi)
40
+ saturation = np.ones_like(hue)
41
+ value = np.clip(amp / max_abs, 0, 1)
42
+ hsv = np.stack([hue, saturation, value], axis=-1)
43
+ return mcolors.hsv_to_rgb(hsv)
44
+
45
+
46
+ def plot_complex_wavefunction(x: np.ndarray, psi: np.ndarray, ax=None, density_scale: float = 1.0):
47
+ r"""Plot a phase-colored probability density curve.
48
+
49
+ Plots :math:`\lvert\psi(x)\rvert^2` as a filled curve, colored by the
50
+ local phase :math:`\arg\psi(x)` (HSV hue) -- a compact way to show both
51
+ the probability density and the complex phase of a wavefunction at once.
52
+
53
+ Parameters
54
+ ----------
55
+ x : numpy.ndarray
56
+ Positions.
57
+ psi : numpy.ndarray
58
+ Complex-valued wavefunction sampled on ``x``.
59
+ ax : matplotlib.axes.Axes or None, optional
60
+ Axis to draw on; a new figure/axis is created if omitted.
61
+ density_scale : float, default=1.0
62
+ Multiplicative scale factor applied to the plotted density.
63
+
64
+ Returns
65
+ -------
66
+ matplotlib.axes.Axes
67
+ """
68
+ if ax is None:
69
+ _, ax = plt.subplots(figsize=(7, 4))
70
+
71
+ density = np.abs(psi) ** 2 * density_scale
72
+ colors = complex_to_rgb(psi)
73
+
74
+ for i in range(len(x) - 1):
75
+ ax.fill_between(x[i : i + 2], 0, density[i : i + 2], color=colors[i], linewidth=0)
76
+
77
+ ax.set_xlabel("x")
78
+ ax.set_ylabel(r"$|\psi(x)|^2$")
79
+
80
+ sm = plt.cm.ScalarMappable(cmap=_phase_colormap(), norm=mcolors.Normalize(-np.pi, np.pi))
81
+ sm.set_array([])
82
+ cbar = plt.colorbar(sm, ax=ax, pad=0.02)
83
+ cbar.set_label(r"$\arg\,\psi(x)$")
84
+ return ax
85
+
86
+
87
+ def _phase_colormap():
88
+ hues = np.linspace(0, 1, 256)
89
+ rgb = mcolors.hsv_to_rgb(np.stack([hues, np.ones_like(hues), np.ones_like(hues)], axis=-1))
90
+ return mcolors.ListedColormap(rgb)
91
+
92
+
93
+ def animate_density(
94
+ x: np.ndarray, frames: np.ndarray, times: np.ndarray | None = None, interval: int = 30, phase_colored: bool = True, ax=None
95
+ ) -> FuncAnimation:
96
+ """Animate a stack of wavefunction snapshots over time.
97
+
98
+ Parameters
99
+ ----------
100
+ x : numpy.ndarray
101
+ Positions.
102
+ frames : numpy.ndarray
103
+ Wavefunction snapshots, shape ``(n_frames, len(x))``. May be complex
104
+ (density and phase both shown via :func:`complex_to_rgb`) or real
105
+ (plain probability density curve).
106
+ times : numpy.ndarray or None, optional
107
+ Time of each frame, used to label the animation title.
108
+ interval : int, default=30
109
+ Delay between frames, in milliseconds.
110
+ phase_colored : bool, default=True
111
+ Whether to color the curve by phase (only applies if ``frames`` is
112
+ complex).
113
+ ax : matplotlib.axes.Axes or None, optional
114
+ Axis to draw on; a new figure/axis is created if omitted.
115
+
116
+ Returns
117
+ -------
118
+ matplotlib.animation.FuncAnimation
119
+ """
120
+ if ax is None:
121
+ fig, ax = plt.subplots(figsize=(7, 4))
122
+ else:
123
+ fig = ax.figure
124
+
125
+ density = np.abs(frames) ** 2
126
+ ymax = density.max() * 1.1
127
+
128
+ if phase_colored and np.iscomplexobj(frames):
129
+ line_collections = []
130
+
131
+ def init():
132
+ ax.set_xlim(x.min(), x.max())
133
+ ax.set_ylim(0, ymax)
134
+ ax.set_xlabel("x")
135
+ ax.set_ylabel(r"$|\psi(x,t)|^2$")
136
+ return []
137
+
138
+ def update(i):
139
+ for coll in line_collections:
140
+ coll.remove()
141
+ line_collections.clear()
142
+ colors = complex_to_rgb(frames[i], max_abs=np.abs(frames).max())
143
+ for j in range(len(x) - 1):
144
+ line_collections.append(ax.fill_between(x[j : j + 2], 0, density[i, j : j + 2], color=colors[j], linewidth=0))
145
+ title = f"t = {times[i]:.3f}" if times is not None else f"frame {i}"
146
+ ax.set_title(title)
147
+ return line_collections
148
+
149
+ return FuncAnimation(fig, update, init_func=init, frames=len(frames), interval=interval, blit=False)
150
+
151
+ (line,) = ax.plot(x, density[0])
152
+ ax.set_xlim(x.min(), x.max())
153
+ ax.set_ylim(0, ymax)
154
+ ax.set_xlabel("x")
155
+ ax.set_ylabel(r"$|\psi(x,t)|^2$")
156
+
157
+ def update_simple(i):
158
+ line.set_ydata(density[i])
159
+ title = f"t = {times[i]:.3f}" if times is not None else f"frame {i}"
160
+ ax.set_title(title)
161
+ return (line,)
162
+
163
+ return FuncAnimation(fig, update_simple, frames=len(frames), interval=interval, blit=False)
164
+
165
+
166
+ def animate_density_2d(
167
+ X: np.ndarray,
168
+ Y: np.ndarray,
169
+ frames: np.ndarray,
170
+ times: np.ndarray | None = None,
171
+ interval: int = 30,
172
+ phase_colored: bool = True,
173
+ cmap: str = "viridis",
174
+ ax=None,
175
+ ) -> FuncAnimation:
176
+ """Animate a stack of 2D wavefunction/density snapshots via ``imshow``.
177
+
178
+ Parameters
179
+ ----------
180
+ X, Y : numpy.ndarray
181
+ Coordinate meshgrid (``indexing='ij'``), e.g.
182
+ ``SplitOperatorSolver2D.X/.Y``.
183
+ frames : numpy.ndarray
184
+ Snapshots, shape ``(n_frames, *X.shape)``. May be complex
185
+ (density and phase both shown via :func:`complex_to_rgb`) or real
186
+ (a plain probability-density heatmap).
187
+ times : numpy.ndarray or None, optional
188
+ Time of each frame, used to label the animation title.
189
+ interval : int, default=30
190
+ Delay between frames, in milliseconds.
191
+ phase_colored : bool, default=True
192
+ Whether to color by phase (only applies if ``frames`` is complex).
193
+ cmap : str, default='viridis'
194
+ Colormap used when not phase-colored.
195
+ ax : matplotlib.axes.Axes or None, optional
196
+ Axis to draw on; a new figure/axis is created if omitted.
197
+
198
+ Returns
199
+ -------
200
+ matplotlib.animation.FuncAnimation
201
+ """
202
+ if ax is None:
203
+ fig, ax = plt.subplots(figsize=(6, 5))
204
+ else:
205
+ fig = ax.figure
206
+
207
+ extent = [X.min(), X.max(), Y.min(), Y.max()]
208
+ is_complex = phase_colored and np.iscomplexobj(frames)
209
+
210
+ if is_complex:
211
+ max_abs = np.abs(frames).max()
212
+ im = ax.imshow(np.transpose(complex_to_rgb(frames[0], max_abs=max_abs), (1, 0, 2)), origin="lower", extent=extent, aspect="auto")
213
+ else:
214
+ density = np.abs(frames) ** 2 if np.iscomplexobj(frames) else frames
215
+ vmax = density.max() * 1.1
216
+ im = ax.imshow(density[0].T, origin="lower", extent=extent, aspect="auto", cmap=cmap, vmin=0, vmax=vmax)
217
+
218
+ ax.set_xlabel("x")
219
+ ax.set_ylabel("y")
220
+
221
+ def update(i):
222
+ if is_complex:
223
+ im.set_data(np.transpose(complex_to_rgb(frames[i], max_abs=np.abs(frames).max()), (1, 0, 2)))
224
+ else:
225
+ im.set_data(density[i].T)
226
+ title = f"t = {times[i]:.3f}" if times is not None else f"frame {i}"
227
+ ax.set_title(title)
228
+ return (im,)
229
+
230
+ return FuncAnimation(fig, update, frames=len(frames), interval=interval, blit=False)
@@ -0,0 +1,61 @@
1
+ """physicskit.relativity: fast, visually captivating numerical General Relativity.
2
+
3
+ ``physicskit.relativity`` brings curved spacetime geometry, black hole physics,
4
+ ray-traced gravitational lensing, and gravitational wave dynamics into an
5
+ interactive, computational Python framework, in geometrized units
6
+ (:math:`G = c = 1`; see :mod:`physicskit.relativity.utils.constants`):
7
+
8
+ - **Black hole physics** (:mod:`physicskit.relativity.chapters.schwarzschild`,
9
+ :mod:`physicskit.relativity.chapters.kerr`): timelike orbits, perihelion precession, the
10
+ innermost stable circular orbit (ISCO), the photon sphere, light
11
+ deflection and the Shapiro delay, disk redshift, tidal forces, frame
12
+ dragging, the ergosphere, and the Penrose process.
13
+ - **Spacetime geometry** (:mod:`physicskit.relativity.core.tensors`): a numerical
14
+ differential geometry engine computing Christoffel symbols and curvature
15
+ tensors for arbitrary metrics (Schwarzschild, Kerr, Reissner-Nordstrom,
16
+ FLRW, the Alcubierre warp drive).
17
+ - **Gravitational lensing** (:mod:`physicskit.relativity.core.raytracer`,
18
+ :mod:`physicskit.relativity.core.kerr_raytracer`, :mod:`physicskit.relativity.visualizers.shadow_render`,
19
+ :mod:`physicskit.relativity.chapters.lensing`): Numba-accelerated backward photon
20
+ ray-tracers (Schwarzschild and Kerr) rendering black hole shadows and
21
+ redshift-shaded lensed accretion disks, plus point-source Einstein rings,
22
+ multiple images, and microlensing magnification.
23
+ - **Gravitational waves** (:mod:`physicskit.relativity.chapters.gw_merger`): binary black
24
+ hole inspiral chirps and ringdown, and Hulse-Taylor-style orbital decay.
25
+ - **Cosmology & compact objects** (:mod:`physicskit.relativity.chapters.cosmology`,
26
+ :mod:`physicskit.relativity.chapters.neutron_star`): the FLRW Friedmann equations for
27
+ cosmic expansion, and the Tolman-Oppenheimer-Volkoff equations for
28
+ neutron star structure and the maximum neutron star mass.
29
+ - **Relativity in everyday technology** (:mod:`physicskit.relativity.chapters.timekeeping`):
30
+ the GPS satellite relativistic clock correction.
31
+
32
+ Examples
33
+ --------
34
+ >>> from physicskit.relativity.chapters import SchwarzschildBlackHole
35
+ >>> bh = SchwarzschildBlackHole(M=1.0)
36
+ >>> bh.isco_radius
37
+ 6.0
38
+ >>> bh.photon_sphere_radius
39
+ 3.0
40
+ """
41
+
42
+ from physicskit.relativity.chapters import (
43
+ BinaryMerger,
44
+ FLRWCosmology,
45
+ KerrBlackHole,
46
+ NeutronStar,
47
+ PointMassLens,
48
+ SchwarzschildBlackHole,
49
+ )
50
+
51
+ __version__ = "0.2.0"
52
+
53
+ __all__ = [
54
+ "BinaryMerger",
55
+ "FLRWCosmology",
56
+ "KerrBlackHole",
57
+ "NeutronStar",
58
+ "PointMassLens",
59
+ "SchwarzschildBlackHole",
60
+ "__version__",
61
+ ]
@@ -0,0 +1,33 @@
1
+ """Physics chapters: user-facing model classes built on :mod:`physicskit.relativity.core`.
2
+
3
+ - :mod:`physicskit.relativity.chapters.schwarzschild` -- orbits, precession, the photon
4
+ sphere, light deflection, the Shapiro delay, disk redshift, and tidal
5
+ forces.
6
+ - :mod:`physicskit.relativity.chapters.kerr` -- frame dragging, the ergosphere, the ISCO,
7
+ and the Penrose process.
8
+ - :mod:`physicskit.relativity.chapters.lensing` -- Einstein rings, multiple images, and
9
+ microlensing magnification.
10
+ - :mod:`physicskit.relativity.chapters.gw_merger` -- binary black hole inspiral chirps,
11
+ ringdown, and Hulse-Taylor-style orbital decay.
12
+ - :mod:`physicskit.relativity.chapters.cosmology` -- FLRW cosmic expansion and redshift.
13
+ - :mod:`physicskit.relativity.chapters.neutron_star` -- the Tolman-Oppenheimer-Volkoff
14
+ equations and the neutron star maximum mass.
15
+ - :mod:`physicskit.relativity.chapters.timekeeping` -- relativistic satellite clock
16
+ corrections (GPS).
17
+ """
18
+
19
+ from physicskit.relativity.chapters.cosmology import FLRWCosmology
20
+ from physicskit.relativity.chapters.gw_merger import BinaryMerger
21
+ from physicskit.relativity.chapters.kerr import KerrBlackHole
22
+ from physicskit.relativity.chapters.lensing import PointMassLens
23
+ from physicskit.relativity.chapters.neutron_star import NeutronStar
24
+ from physicskit.relativity.chapters.schwarzschild import SchwarzschildBlackHole
25
+
26
+ __all__ = [
27
+ "BinaryMerger",
28
+ "FLRWCosmology",
29
+ "KerrBlackHole",
30
+ "NeutronStar",
31
+ "PointMassLens",
32
+ "SchwarzschildBlackHole",
33
+ ]
@@ -0,0 +1,190 @@
1
+ """FLRW cosmology: the Friedmann equations, cosmic expansion, and redshift.
2
+
3
+ The Friedmann-Lemaitre-Robertson-Walker (FLRW) metric is the unique
4
+ spacetime describing a homogeneous, isotropic universe -- an excellent
5
+ approximation to our own on large scales. Plugging it into Einstein's field
6
+ equations yields the Friedmann equation, which governs how the universe's
7
+ scale factor :math:`a(t)` evolves under the combined gravity of radiation,
8
+ matter, curvature, and dark energy (:math:`\\Lambda`). This single equation
9
+ explains Hubble's 1929 discovery of cosmic expansion, predicts the
10
+ universe's age, and -- through the distance-redshift relation -- underlies
11
+ the 1998 discovery (via observations of distant supernovae) that this
12
+ expansion is accelerating.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import numpy as np
18
+ from scipy.integrate import quad
19
+
20
+ from physicskit.relativity.utils.constants import C_SI, PARSEC_M
21
+
22
+ __all__ = ["FLRWCosmology"]
23
+
24
+ _MPC_M = PARSEC_M * 1.0e6
25
+ _GYR_S = 365.25 * 24.0 * 3600.0 * 1.0e9
26
+
27
+
28
+ class FLRWCosmology:
29
+ """A flat or curved FLRW universe with radiation, matter, curvature, and dark energy.
30
+
31
+ Parameters
32
+ ----------
33
+ H0 : float, default=70.0
34
+ Hubble constant today, in km/s/Mpc.
35
+ Omega_m : float, default=0.3
36
+ Matter density parameter today.
37
+ Omega_r : float, default=1e-4
38
+ Radiation density parameter today.
39
+ Omega_Lambda : float, default=0.7
40
+ Dark energy (cosmological constant) density parameter today.
41
+
42
+ Attributes
43
+ ----------
44
+ Omega_k : float
45
+ Curvature density parameter, :math:`1 - \\Omega_m - \\Omega_r - \\Omega_\\Lambda`
46
+ (computed so all density parameters sum to 1, as required by the
47
+ Friedmann equation at :math:`a=1`).
48
+ """
49
+
50
+ def __init__(self, H0=70.0, Omega_m=0.3, Omega_r=1.0e-4, Omega_Lambda=0.7):
51
+ self.H0 = H0
52
+ self.Omega_m = Omega_m
53
+ self.Omega_r = Omega_r
54
+ self.Omega_Lambda = Omega_Lambda
55
+ self.Omega_k = 1.0 - Omega_m - Omega_r - Omega_Lambda
56
+
57
+ def _H0_si(self):
58
+ return self.H0 * 1.0e3 / _MPC_M # km/s/Mpc -> 1/s
59
+
60
+ def E(self, a):
61
+ """Dimensionless expansion rate :math:`E(a) = H(a)/H_0`.
62
+
63
+ .. math::
64
+
65
+ E(a) = \\sqrt{\\Omega_r a^{-4} + \\Omega_m a^{-3} + \\Omega_k a^{-2} + \\Omega_\\Lambda}
66
+
67
+ Parameters
68
+ ----------
69
+ a : float or array_like
70
+ Scale factor (:math:`a=1` today).
71
+
72
+ Returns
73
+ -------
74
+ float or ndarray
75
+ """
76
+ a = np.asarray(a, dtype=np.float64)
77
+ return np.sqrt(self.Omega_r * a**-4 + self.Omega_m * a**-3 + self.Omega_k * a**-2 + self.Omega_Lambda)
78
+
79
+ def hubble_parameter(self, a):
80
+ """Hubble parameter :math:`H(a) = H_0 E(a)`, in km/s/Mpc.
81
+
82
+ Parameters
83
+ ----------
84
+ a : float or array_like
85
+ Scale factor.
86
+
87
+ Returns
88
+ -------
89
+ float or ndarray
90
+ """
91
+ return self.H0 * self.E(a)
92
+
93
+ def redshift_to_scale_factor(self, z):
94
+ """Convert redshift to scale factor, :math:`a = 1/(1+z)`."""
95
+ return 1.0 / (1.0 + np.asarray(z, dtype=np.float64))
96
+
97
+ def scale_factor_to_redshift(self, a):
98
+ """Convert scale factor to redshift, :math:`z = 1/a - 1`."""
99
+ return 1.0 / np.asarray(a, dtype=np.float64) - 1.0
100
+
101
+ def comoving_distance_mpc(self, z):
102
+ """Comoving distance to redshift ``z``, in Mpc.
103
+
104
+ .. math::
105
+
106
+ D_C(z) = c \\int_0^z \\frac{dz'}{H(z')}
107
+
108
+ Parameters
109
+ ----------
110
+ z : float
111
+ Redshift.
112
+
113
+ Returns
114
+ -------
115
+ float
116
+ """
117
+ H0_si = self._H0_si()
118
+
119
+ def integrand(zp):
120
+ a = 1.0 / (1.0 + zp)
121
+ return 1.0 / (H0_si * self.E(a))
122
+
123
+ distance_m = C_SI * quad(integrand, 0.0, z)[0]
124
+ return distance_m / _MPC_M
125
+
126
+ def luminosity_distance_mpc(self, z):
127
+ """Luminosity distance to redshift ``z``, in Mpc, :math:`D_L = (1+z) D_C` (flat-sky FLRW).
128
+
129
+ Parameters
130
+ ----------
131
+ z : float
132
+ Redshift.
133
+
134
+ Returns
135
+ -------
136
+ float
137
+ """
138
+ return (1.0 + z) * self.comoving_distance_mpc(z)
139
+
140
+ def age_gyr(self, a=1.0):
141
+ """Cosmic age at scale factor ``a``, in Gyr.
142
+
143
+ .. math::
144
+
145
+ t(a) = \\int_0^a \\frac{da'}{a' H(a')}
146
+
147
+ Parameters
148
+ ----------
149
+ a : float, default=1.0
150
+ Scale factor at which to evaluate the age (``a=1`` gives the
151
+ current age of the universe).
152
+
153
+ Returns
154
+ -------
155
+ float
156
+
157
+ Examples
158
+ --------
159
+ >>> cosmo = FLRWCosmology(H0=70.0, Omega_m=0.3, Omega_r=0.0, Omega_Lambda=0.7)
160
+ >>> 12.0 < cosmo.age_gyr() < 15.0
161
+ True
162
+ """
163
+ H0_si = self._H0_si()
164
+
165
+ def integrand(ap):
166
+ return 1.0 / (ap * H0_si * self.E(ap))
167
+
168
+ age_s = quad(integrand, 1.0e-8, a, limit=200)[0]
169
+ return age_s / _GYR_S
170
+
171
+ def scale_factor_history(self, n_points=200, a_min=1.0e-3, a_max=3.0):
172
+ """Tabulate the age of the universe at a range of scale factors, for plotting :math:`a(t)`.
173
+
174
+ Parameters
175
+ ----------
176
+ n_points : int, default=200
177
+ Number of scale-factor grid points.
178
+ a_min, a_max : float
179
+ Range of scale factors to tabulate.
180
+
181
+ Returns
182
+ -------
183
+ t_gyr : ndarray of shape (n_points,)
184
+ Cosmic age at each scale factor, in Gyr.
185
+ a : ndarray of shape (n_points,)
186
+ The scale factor grid.
187
+ """
188
+ a_grid = np.linspace(a_min, a_max, n_points)
189
+ t_gyr = np.array([self.age_gyr(a) for a in a_grid])
190
+ return t_gyr, a_grid