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,399 @@
1
+ """Binary black hole mergers: the inspiral chirp, plunge, and ringdown.
2
+
3
+ Two orbiting masses radiate gravitational waves, losing orbital energy and
4
+ spiraling closer together, which raises the orbital frequency, which
5
+ radiates more strongly still -- a runaway "chirp" that sweeps up in
6
+ frequency and amplitude right up until merger. This module implements the
7
+ leading-order (Newtonian quadrupole / restricted post-Newtonian) inspiral
8
+ waveform -- exactly what let LIGO recognize GW150914 in 2015, the first
9
+ direct detection of gravitational waves -- followed by a damped-sinusoid
10
+ ringdown as the merged remnant settles down by radiating away its
11
+ distortion in a superposition of quasinormal modes.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import numpy as np
17
+
18
+ __all__ = ["BinaryMerger"]
19
+
20
+
21
+ class BinaryMerger:
22
+ """A compact binary and its leading-order inspiral-merger-ringdown (IMR) waveform.
23
+
24
+ Parameters
25
+ ----------
26
+ m1, m2 : float
27
+ Component masses, in geometrized length units. Use
28
+ :func:`physicskit.relativity.utils.constants.solar_masses_to_geometrized`
29
+ to convert from solar masses. Unlike :class:`~physicskit.relativity.chapters.schwarzschild.SchwarzschildBlackHole`
30
+ or :class:`~physicskit.relativity.chapters.kerr.KerrBlackHole`, there is
31
+ no normalized ``M=1`` convention available here: the radiated
32
+ strain genuinely depends on the absolute physical scale, so an
33
+ unconverted mass doesn't just rescale the answer -- it silently
34
+ produces a wrong waveform. This constructor does *not* itself warn
35
+ on an implausible value (many legitimate uses -- unit tests of a
36
+ formula's mathematical properties, mainly -- pass small
37
+ "toy" numbers on purpose, with no claim of physical realism); use
38
+ :func:`~physicskit.relativity.utils.constants.check_geometrized_mass`
39
+ explicitly wherever real-world realism is actually the point (as
40
+ the visualizers in :mod:`physicskit.relativity.visualizers.wave_plots` do).
41
+ distance : float
42
+ Distance to the source, in geometrized length units. Same caveat
43
+ as ``m1``/``m2``.
44
+ inclination : float, default=0.0
45
+ Inclination angle between the orbital angular momentum and the
46
+ line of sight, in radians (``0`` = face-on, ``pi/2`` = edge-on).
47
+ """
48
+
49
+ def __init__(self, m1, m2, distance, inclination=0.0):
50
+ self.m1 = m1
51
+ self.m2 = m2
52
+ self.distance = distance
53
+ self.inclination = inclination
54
+
55
+ @property
56
+ def total_mass(self):
57
+ """Total mass, :math:`M = m_1 + m_2`."""
58
+ return self.m1 + self.m2
59
+
60
+ @property
61
+ def symmetric_mass_ratio(self):
62
+ """Symmetric mass ratio, :math:`\\eta = m_1 m_2 / M^2`."""
63
+ return self.m1 * self.m2 / self.total_mass**2
64
+
65
+ @property
66
+ def chirp_mass(self):
67
+ """Chirp mass, :math:`\\mathcal{M} = (m_1 m_2)^{3/5} / (m_1+m_2)^{1/5}`."""
68
+ return (self.m1 * self.m2) ** 0.6 / self.total_mass**0.2
69
+
70
+ def inspiral_frequency(self, t, t_merger):
71
+ """Gravitational-wave frequency during the inspiral, at leading (Newtonian quadrupole) order.
72
+
73
+ .. math::
74
+
75
+ f(t) = \\frac{1}{\\pi}\\left[\\frac{5}{256(t_{\\text{merger}} - t)}\\right]^{3/8}
76
+ \\mathcal{M}^{-5/8}
77
+
78
+ Parameters
79
+ ----------
80
+ t : float or array_like
81
+ Time(s), with ``t < t_merger``.
82
+ t_merger : float
83
+ Coalescence time.
84
+
85
+ Returns
86
+ -------
87
+ float or ndarray
88
+ GW frequency (twice the orbital frequency).
89
+ """
90
+ tau = t_merger - np.asarray(t, dtype=np.float64)
91
+ return (1.0 / np.pi) * (5.0 / (256.0 * tau)) ** 0.375 * self.chirp_mass ** (-5.0 / 8.0)
92
+
93
+ def inspiral_phase(self, t, t_merger, phase_ref=0.0):
94
+ """Gravitational-wave phase during the inspiral.
95
+
96
+ .. math::
97
+
98
+ \\Phi(t) = \\Phi_{\\text{ref}} - 2\\left[\\frac{t_{\\text{merger}} - t}
99
+ {5\\mathcal{M}}\\right]^{5/8}
100
+
101
+ The antiderivative of :math:`d\\Phi/dt = 2\\pi f(t)` with
102
+ :meth:`inspiral_frequency`.
103
+
104
+ Parameters
105
+ ----------
106
+ t : float or array_like
107
+ Time(s), with ``t < t_merger``.
108
+ t_merger : float
109
+ Coalescence time.
110
+ phase_ref : float, default=0.0
111
+ Reference phase (phase at merger).
112
+
113
+ Returns
114
+ -------
115
+ float or ndarray
116
+ """
117
+ tau = t_merger - np.asarray(t, dtype=np.float64)
118
+ return phase_ref - 2.0 * (tau / (5.0 * self.chirp_mass)) ** (5.0 / 8.0)
119
+
120
+ def inspiral_strain(self, t, t_merger, phase_ref=0.0):
121
+ """Plus and cross gravitational-wave strain during the inspiral.
122
+
123
+ .. math::
124
+
125
+ h_+(t) = \\frac{4}{R} \\mathcal{M}^{5/3} (\\pi f(t))^{2/3}
126
+ \\frac{1 + \\cos^2\\iota}{2} \\cos\\Phi(t), \\qquad
127
+ h_\\times(t) = \\frac{4}{R} \\mathcal{M}^{5/3} (\\pi f(t))^{2/3}
128
+ \\cos\\iota \\, \\sin\\Phi(t)
129
+
130
+ Parameters
131
+ ----------
132
+ t : array_like
133
+ Times, with ``t < t_merger``.
134
+ t_merger : float
135
+ Coalescence time.
136
+ phase_ref : float, default=0.0
137
+ Reference phase at merger, forwarded to :meth:`inspiral_phase`.
138
+
139
+ Returns
140
+ -------
141
+ h_plus : ndarray
142
+ h_cross : ndarray
143
+
144
+ Examples
145
+ --------
146
+ >>> merger = BinaryMerger(m1=30.0, m2=25.0, distance=1000.0)
147
+ >>> t = np.linspace(-2.0, -0.1, 100)
148
+ >>> hp, hc = merger.inspiral_strain(t, t_merger=0.0)
149
+ >>> hp.shape
150
+ (100,)
151
+ """
152
+ t = np.asarray(t, dtype=np.float64)
153
+ f = self.inspiral_frequency(t, t_merger)
154
+ phase = self.inspiral_phase(t, t_merger, phase_ref=phase_ref)
155
+ amplitude = (4.0 / self.distance) * self.chirp_mass ** (5.0 / 3.0) * (np.pi * f) ** (2.0 / 3.0)
156
+ h_plus = amplitude * 0.5 * (1.0 + np.cos(self.inclination) ** 2) * np.cos(phase)
157
+ h_cross = amplitude * np.cos(self.inclination) * np.sin(phase)
158
+ return h_plus, h_cross
159
+
160
+ def remnant_estimate(self):
161
+ """A simple, illustrative estimate of the merger remnant's mass and spin.
162
+
163
+ Not a precision numerical-relativity surrogate: it linearly
164
+ interpolates between the extreme-mass-ratio limit (negligible
165
+ radiated energy and spin-up, :math:`\\eta \\to 0`) and the
166
+ well-measured equal-mass, non-spinning result
167
+ (:math:`M_f \\approx 0.95 M`, :math:`a_f/M_f \\approx 0.69` at
168
+ :math:`\\eta = 1/4`), which is sufficient to demonstrate the
169
+ qualitative ringdown physics.
170
+
171
+ Returns
172
+ -------
173
+ M_f : float
174
+ Estimated remnant mass.
175
+ a_f : float
176
+ Estimated remnant spin parameter.
177
+ """
178
+ eta = self.symmetric_mass_ratio
179
+ M_f = self.total_mass * (1.0 - 0.05 * (4.0 * eta))
180
+ a_f = 0.69 * (4.0 * eta) * M_f
181
+ return M_f, a_f
182
+
183
+ def qnm_frequency_damping(self, M_f=None, a_f=None):
184
+ """Dominant (l=2, m=2, n=0) quasinormal mode frequency and damping time.
185
+
186
+ Fitting formulas of Berti, Cardoso & Will (2006):
187
+
188
+ .. math::
189
+
190
+ f_{\\text{QNM}} = \\frac{1}{2\\pi M_f}\\left[1.5251 - 1.1568(1-a_*)^{0.1292}\\right]
191
+
192
+ .. math::
193
+
194
+ Q = 0.7000 + 1.4187(1-a_*)^{-0.4990}, \\qquad
195
+ \\tau_{\\text{damp}} = \\frac{Q}{\\pi f_{\\text{QNM}}}
196
+
197
+ where :math:`a_* = a_f/M_f`.
198
+
199
+ Parameters
200
+ ----------
201
+ M_f : float, optional
202
+ Remnant mass. Defaults to :meth:`remnant_estimate`.
203
+ a_f : float, optional
204
+ Remnant spin parameter. Defaults to :meth:`remnant_estimate`.
205
+
206
+ Returns
207
+ -------
208
+ f_qnm : float
209
+ Ringdown frequency.
210
+ tau_damp : float
211
+ Damping time.
212
+ """
213
+ if M_f is None or a_f is None:
214
+ M_f, a_f = self.remnant_estimate()
215
+ a_star = a_f / M_f
216
+ f_qnm = (1.0 / (2.0 * np.pi * M_f)) * (1.5251 - 1.1568 * (1.0 - a_star) ** 0.1292)
217
+ Q = 0.7000 + 1.4187 * (1.0 - a_star) ** (-0.4990)
218
+ tau_damp = Q / (np.pi * f_qnm)
219
+ return f_qnm, tau_damp
220
+
221
+ def ringdown_strain(self, t, t_merger, amplitude, M_f=None, a_f=None, phase_ref=0.0):
222
+ """Damped-sinusoid ringdown strain for :math:`t \\ge t_{\\text{merger}}`.
223
+
224
+ .. math::
225
+
226
+ h_+(t) = A \\, e^{-(t-t_{\\text{merger}})/\\tau_{\\text{damp}}}
227
+ \\cos\\left(2\\pi f_{\\text{QNM}} (t - t_{\\text{merger}}) + \\Phi_{\\text{ref}}\\right)
228
+
229
+ with :math:`h_\\times` the corresponding sine (quarter-cycle
230
+ phase-shifted) quadrature, modulated by the same inclination
231
+ dependence as :meth:`inspiral_strain`.
232
+
233
+ Parameters
234
+ ----------
235
+ t : array_like
236
+ Times, with ``t >= t_merger``.
237
+ t_merger : float
238
+ Merger (ringdown onset) time.
239
+ amplitude : float
240
+ Ringdown strain amplitude at :math:`t = t_{\\text{merger}}`,
241
+ typically chosen to match the inspiral amplitude just before
242
+ merger for a continuous (if not perfectly smooth) toy waveform.
243
+ M_f, a_f : float, optional
244
+ Remnant mass and spin, forwarded to :meth:`qnm_frequency_damping`.
245
+ phase_ref : float, default=0.0
246
+ Reference phase at :math:`t = t_{\\text{merger}}`.
247
+
248
+ Returns
249
+ -------
250
+ h_plus : ndarray
251
+ h_cross : ndarray
252
+ """
253
+ t = np.asarray(t, dtype=np.float64)
254
+ f_qnm, tau_damp = self.qnm_frequency_damping(M_f=M_f, a_f=a_f)
255
+ dt = t - t_merger
256
+ envelope = amplitude * np.exp(-dt / tau_damp)
257
+ phase = 2.0 * np.pi * f_qnm * dt + phase_ref
258
+ h_plus = envelope * 0.5 * (1.0 + np.cos(self.inclination) ** 2) * np.cos(phase)
259
+ h_cross = envelope * np.cos(self.inclination) * np.sin(phase)
260
+ return h_plus, h_cross
261
+
262
+ def full_waveform(self, t, t_merger):
263
+ """A continuous inspiral-merger-ringdown toy waveform over an arbitrary time array.
264
+
265
+ Uses :meth:`inspiral_strain` for ``t < t_merger`` and
266
+ :meth:`ringdown_strain` for ``t >= t_merger``, with the ringdown
267
+ amplitude anchored to the inspiral amplitude evaluated just before
268
+ merger for continuity.
269
+
270
+ Parameters
271
+ ----------
272
+ t : array_like
273
+ Time array, spanning both before and after ``t_merger``.
274
+ t_merger : float
275
+ Coalescence time; should be strictly greater than every
276
+ pre-merger sample (the inspiral formula diverges at
277
+ ``t = t_merger``).
278
+
279
+ Returns
280
+ -------
281
+ h_plus : ndarray
282
+ h_cross : ndarray
283
+
284
+ Examples
285
+ --------
286
+ >>> merger = BinaryMerger(m1=30.0, m2=25.0, distance=1000.0)
287
+ >>> t = np.linspace(-1.0, 0.02, 500)
288
+ >>> hp, hc = merger.full_waveform(t, t_merger=0.0)
289
+ >>> hp.shape
290
+ (500,)
291
+ """
292
+ t = np.asarray(t, dtype=np.float64)
293
+ h_plus = np.zeros_like(t)
294
+ h_cross = np.zeros_like(t)
295
+
296
+ inspiral_mask = t < t_merger
297
+ ringdown_mask = ~inspiral_mask
298
+
299
+ if np.any(inspiral_mask):
300
+ hp, hc = self.inspiral_strain(t[inspiral_mask], t_merger)
301
+ h_plus[inspiral_mask] = hp
302
+ h_cross[inspiral_mask] = hc
303
+
304
+ t_match = t_merger - 1.0e-3 * abs(t_merger if t_merger != 0 else 1.0)
305
+ hp_match, hc_match = self.inspiral_strain(np.array([t_match]), t_merger)
306
+ match_amplitude = float(np.hypot(hp_match[0], hc_match[0]))
307
+
308
+ if np.any(ringdown_mask):
309
+ hp, hc = self.ringdown_strain(t[ringdown_mask], t_merger, amplitude=match_amplitude)
310
+ h_plus[ringdown_mask] = hp
311
+ h_cross[ringdown_mask] = hc
312
+
313
+ return h_plus, h_cross
314
+
315
+ def orbital_period(self, semi_major_axis):
316
+ """Newtonian (Keplerian) orbital period at a given semi-major axis.
317
+
318
+ .. math::
319
+
320
+ P = 2\\pi \\sqrt{\\frac{a^3}{M}}
321
+
322
+ Valid for the wide, slowly-decaying orbits this method's
323
+ counterparts describe (unlike :meth:`inspiral_frequency`, which
324
+ covers the final relativistic plunge).
325
+
326
+ Parameters
327
+ ----------
328
+ semi_major_axis : float
329
+ Orbital semi-major axis :math:`a`.
330
+
331
+ Returns
332
+ -------
333
+ float
334
+ """
335
+ return 2.0 * np.pi * np.sqrt(semi_major_axis**3 / self.total_mass)
336
+
337
+ def semi_major_axis_decay_rate(self, semi_major_axis, eccentricity):
338
+ """Rate of orbital shrinkage from gravitational-wave emission (Peters 1964).
339
+
340
+ .. math::
341
+
342
+ \\frac{da}{dt} = -\\frac{64}{5} \\frac{m_1 m_2 (m_1+m_2)}{a^3}
343
+ \\frac{1 + \\frac{73}{24}e^2 + \\frac{37}{96}e^4}{(1-e^2)^{7/2}}
344
+
345
+ This is the formula behind the first (indirect) detection of
346
+ gravitational waves: Hulse and Taylor's 1974 discovery of the
347
+ binary pulsar PSR B1913+16, whose orbital period was found to
348
+ decay at precisely the rate this equation predicts (1993 Nobel
349
+ Prize in Physics).
350
+
351
+ Parameters
352
+ ----------
353
+ semi_major_axis : float
354
+ Orbital semi-major axis :math:`a`.
355
+ eccentricity : float
356
+ Orbital eccentricity :math:`e \\in [0, 1)`.
357
+
358
+ Returns
359
+ -------
360
+ float
361
+ :math:`da/dt` (negative: the orbit shrinks).
362
+ """
363
+ e = eccentricity
364
+ enhancement = (1.0 + 73.0 / 24.0 * e**2 + 37.0 / 96.0 * e**4) / (1.0 - e**2) ** 3.5
365
+ return -64.0 / 5.0 * self.m1 * self.m2 * self.total_mass / semi_major_axis**3 * enhancement
366
+
367
+ def period_decay_rate(self, semi_major_axis, eccentricity):
368
+ """Rate of orbital period decay, :math:`dP/dt`, from gravitational-wave emission.
369
+
370
+ Obtained from :meth:`semi_major_axis_decay_rate` via the chain rule
371
+ through Kepler's third law, :math:`dP/dt = (dP/da)(da/dt)` with
372
+ :math:`dP/da = 3\\pi\\sqrt{a/M}`.
373
+
374
+ Parameters
375
+ ----------
376
+ semi_major_axis : float
377
+ Orbital semi-major axis :math:`a`.
378
+ eccentricity : float
379
+ Orbital eccentricity :math:`e \\in [0, 1)`.
380
+
381
+ Returns
382
+ -------
383
+ float
384
+ :math:`dP/dt` (dimensionless: a rate of change of time per unit
385
+ time; negative, since the period shrinks).
386
+
387
+ Examples
388
+ --------
389
+ >>> import physicskit.relativity.utils.constants as const
390
+ >>> m1 = const.solar_masses_to_geometrized(1.4398)
391
+ >>> m2 = const.solar_masses_to_geometrized(1.3886)
392
+ >>> psr_b1913 = BinaryMerger(m1=m1, m2=m2, distance=1.0)
393
+ >>> a = (psr_b1913.total_mass * (27906.98 * const.C_SI) ** 2 / (4 * np.pi**2)) ** (1 / 3)
394
+ >>> dPdt = psr_b1913.period_decay_rate(a, eccentricity=0.6171338)
395
+ >>> bool(-3e-12 < dPdt < -2e-12) # observed: -2.4e-12 (dimensionless)
396
+ True
397
+ """
398
+ dP_da = 3.0 * np.pi * np.sqrt(semi_major_axis / self.total_mass)
399
+ return dP_da * self.semi_major_axis_decay_rate(semi_major_axis, eccentricity)