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,428 @@
1
+ r"""Quantum optics in the truncated Fock basis: states, Wigner functions, and Jaynes-Cummings dynamics.
2
+
3
+ Light is quantized in terms of the harmonic-oscillator (photon-number, or
4
+ Fock) states :math:`\lvert n\rangle` of a single cavity mode. This module
5
+ works throughout in a Fock basis truncated to a finite dimension
6
+ ``cutoff`` -- large enough that the state's amplitude on the highest
7
+ retained level is negligible -- and provides:
8
+
9
+ - constructors for the number, coherent, and squeezed states (built from
10
+ the ladder operators of :mod:`physicskit.quantum.core.operators`);
11
+ - the Wigner quasi-probability distribution, computed from its closed-form
12
+ matrix elements in the Fock basis (Cahill & Glauber, *Phys. Rev.* **177**,
13
+ 1857, 1969), using the dimensionless quadratures
14
+
15
+ .. math::
16
+
17
+ \hat x = \frac{\hat a + \hat a^\dagger}{\sqrt2}, \qquad
18
+ \hat p = \frac{\hat a - \hat a^\dagger}{i\sqrt2};
19
+
20
+ - the Jaynes-Cummings model (Jaynes & Cummings, *Proc. IEEE* **51**, 89,
21
+ 1963), the fully quantum treatment of a two-level atom coupled to a
22
+ single cavity mode in the rotating-wave approximation, famous for
23
+ predicting vacuum Rabi oscillations and collapse-and-revival -- effects
24
+ with no semiclassical analogue.
25
+ """
26
+
27
+ from __future__ import annotations
28
+
29
+ import numpy as np
30
+ from scipy.linalg import expm
31
+ from scipy.special import eval_genlaguerre, gammaln
32
+
33
+ from physicskit.optics._compat import trapz
34
+ from physicskit.quantum.core.operators import annihilation_operator, creation_operator
35
+
36
+ __all__ = [
37
+ "fock_state",
38
+ "coherent_state",
39
+ "squeezed_state",
40
+ "compute_wigner_function",
41
+ "wigner_negativity",
42
+ "JaynesCummingsModel",
43
+ ]
44
+
45
+
46
+ def fock_state(n, cutoff):
47
+ r"""The number (Fock) state :math:`\lvert n\rangle`.
48
+
49
+ Parameters
50
+ ----------
51
+ n : int
52
+ Photon number.
53
+ cutoff : int
54
+ Dimension of the truncated Fock space.
55
+
56
+ Returns
57
+ -------
58
+ ndarray of shape (cutoff,)
59
+ Complex state vector, all zeros except a ``1`` at index ``n``.
60
+
61
+ Raises
62
+ ------
63
+ ValueError
64
+ If ``n`` is negative or ``n >= cutoff``.
65
+
66
+ Examples
67
+ --------
68
+ >>> fock_state(1, 4)
69
+ array([0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j])
70
+ """
71
+ if n < 0 or n >= cutoff:
72
+ raise ValueError(f"n={n} must satisfy 0 <= n < cutoff={cutoff}.")
73
+ state = np.zeros(cutoff, dtype=complex)
74
+ state[n] = 1.0
75
+ return state
76
+
77
+
78
+ def coherent_state(alpha, cutoff):
79
+ r"""The coherent state :math:`\lvert\alpha\rangle`, truncated to a finite Fock basis.
80
+
81
+ .. math::
82
+
83
+ \lvert\alpha\rangle = e^{-\lvert\alpha\rvert^2/2}
84
+ \sum_{n=0}^{\infty} \frac{\alpha^n}{\sqrt{n!}}\,\lvert n\rangle
85
+
86
+ The sum is truncated to ``cutoff`` terms and the result renormalized,
87
+ so it is a good approximation only while :math:`\lvert\alpha\rvert^2
88
+ \ll` ``cutoff`` (i.e. the mean photon number is well within the
89
+ truncated space). Amplitudes are built iteratively in log-space via
90
+ :func:`scipy.special.gammaln` to avoid overflow for large ``cutoff``.
91
+
92
+ Parameters
93
+ ----------
94
+ alpha : complex
95
+ Coherent-state amplitude.
96
+ cutoff : int
97
+ Dimension of the truncated Fock space.
98
+
99
+ Returns
100
+ -------
101
+ ndarray of shape (cutoff,)
102
+ Complex, L2-normalized state vector.
103
+
104
+ Examples
105
+ --------
106
+ >>> psi = coherent_state(0.0, 8)
107
+ >>> psi
108
+ array([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])
109
+ """
110
+ alpha = complex(alpha)
111
+ n = np.arange(cutoff)
112
+ r = abs(alpha)
113
+ if r == 0.0:
114
+ log_amp = np.full(cutoff, -np.inf)
115
+ log_amp[0] = 0.0
116
+ else:
117
+ log_amp = -0.5 * r**2 + n * np.log(r) - 0.5 * gammaln(n + 1.0)
118
+ amp = np.exp(log_amp)
119
+ phase = np.exp(1j * n * np.angle(alpha)) if alpha != 0 else np.ones(cutoff)
120
+ psi = (amp * phase).astype(complex)
121
+ psi /= np.linalg.norm(psi)
122
+ return psi
123
+
124
+
125
+ def squeezed_state(xi, alpha=0.0, cutoff=30):
126
+ r"""The displaced squeezed vacuum state, using the squeeze-then-displace convention.
127
+
128
+ Constructs
129
+
130
+ .. math::
131
+
132
+ \lvert\xi, \alpha\rangle = \hat D(\alpha)\, \hat S(\xi)\, \lvert 0\rangle,
133
+ \qquad
134
+ \hat S(\xi) = \exp\!\left[\frac{\xi^* \hat a^2 - \xi \hat a^{\dagger 2}}{2}\right],
135
+ \qquad
136
+ \hat D(\alpha) = \exp\!\left(\alpha \hat a^\dagger - \alpha^* \hat a\right)
137
+
138
+ i.e. the vacuum is squeezed first and then displaced. (The opposite
139
+ order, displace-then-squeeze, gives a different, also physically valid,
140
+ state -- squeeze-then-displace is the convention adopted here and is
141
+ the more common one in the literature.) The ladder operators are built
142
+ on the same truncated Fock basis, so this is only accurate while the
143
+ squeezed/displaced amplitude is small relative to ``cutoff``.
144
+
145
+ Parameters
146
+ ----------
147
+ xi : complex
148
+ Squeezing parameter :math:`\xi = r e^{i\theta}`.
149
+ alpha : complex, default=0.0
150
+ Displacement amplitude.
151
+ cutoff : int, default=30
152
+ Dimension of the truncated Fock space.
153
+
154
+ Returns
155
+ -------
156
+ ndarray of shape (cutoff,)
157
+ Complex, L2-normalized state vector.
158
+
159
+ Examples
160
+ --------
161
+ >>> psi = squeezed_state(0.0, alpha=0.0, cutoff=6)
162
+ >>> psi
163
+ array([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])
164
+ """
165
+ xi = complex(xi)
166
+ alpha = complex(alpha)
167
+ a = annihilation_operator(cutoff)
168
+ a_dag = creation_operator(cutoff)
169
+ S = expm(0.5 * (np.conj(xi) * (a @ a) - xi * (a_dag @ a_dag)))
170
+ D = expm(alpha * a_dag - np.conj(alpha) * a)
171
+ vac = fock_state(0, cutoff)
172
+ psi = D @ (S @ vac)
173
+ psi = psi / np.linalg.norm(psi)
174
+ return psi
175
+
176
+
177
+ def _wigner_kernel(n, m, x, p):
178
+ r"""Fock-basis Wigner-function kernel :math:`K_{nm}(x,p)` for :math:`n \le m`.
179
+
180
+ Defined so that :math:`W(x,p) = \sum_{n \le m}\left[\rho_{nm} K_{nm}
181
+ + \rho_{mn} K_{nm}^*\right]` (with the ``n == m`` term counted once),
182
+ reducing at :math:`n=m` to the well-known diagonal Fock-state Wigner
183
+ function :math:`W_n(x,p) = (-1)^n/\pi\, e^{-(x^2+p^2)} L_n[2(x^2+p^2)]`.
184
+ """
185
+ s = x**2 + p**2
186
+ z = x - 1j * p
187
+ log_coeff = 0.5 * (gammaln(n + 1.0) - gammaln(m + 1.0))
188
+ coeff = (-1.0) ** n * np.exp(log_coeff)
189
+ return (1.0 / np.pi) * coeff * (np.sqrt(2.0) * z) ** (m - n) * np.exp(-s) * eval_genlaguerre(n, m - n, 2.0 * s)
190
+
191
+
192
+ def compute_wigner_function(state_vector, x_grid, p_grid):
193
+ r"""Wigner quasi-probability distribution of a Fock-basis state.
194
+
195
+ Computed from the density matrix :math:`\rho = \lvert\psi\rangle\langle\psi\rvert`
196
+ and the closed-form Fock-basis Wigner matrix elements,
197
+
198
+ .. math::
199
+
200
+ W(x,p) = \sum_{n,m} \rho_{nm}\, K_{nm}(x,p),
201
+
202
+ with :math:`K_{nm}` built from associated Laguerre polynomials of
203
+ :math:`2(x^2+p^2)` (see :func:`scipy.special.eval_genlaguerre`). Uses
204
+ dimensionless quadratures :math:`x = (a+a^\dagger)/\sqrt2`,
205
+ :math:`p = (a-a^\dagger)/(i\sqrt2)`, for which
206
+ :math:`\iint W(x,p)\,dx\,dp = 1` for any normalized state.
207
+
208
+ Parameters
209
+ ----------
210
+ state_vector : ndarray of shape (cutoff,)
211
+ Fock-basis ket.
212
+ x_grid : ndarray of shape (Nx,)
213
+ Grid of :math:`x` quadrature values.
214
+ p_grid : ndarray of shape (Np,)
215
+ Grid of :math:`p` quadrature values.
216
+
217
+ Returns
218
+ -------
219
+ ndarray of shape (Nx, Np)
220
+ Real-valued Wigner function :math:`W(x,p)`.
221
+
222
+ Examples
223
+ --------
224
+ >>> import numpy as np
225
+ >>> vac = fock_state(0, 8)
226
+ >>> xg = np.linspace(-4, 4, 41)
227
+ >>> pg = np.linspace(-4, 4, 41)
228
+ >>> W = compute_wigner_function(vac, xg, pg)
229
+ >>> W.shape
230
+ (41, 41)
231
+ >>> round(float(W[20, 20] * np.pi), 6)
232
+ 1.0
233
+ """
234
+ psi = np.asarray(state_vector, dtype=complex).reshape(-1)
235
+ cutoff = psi.shape[0]
236
+ rho = np.outer(psi, psi.conj())
237
+ x_grid = np.asarray(x_grid, dtype=float)
238
+ p_grid = np.asarray(p_grid, dtype=float)
239
+ X, P = np.meshgrid(x_grid, p_grid, indexing="ij")
240
+ W = np.zeros_like(X, dtype=complex)
241
+ for n in range(cutoff):
242
+ for m in range(n, cutoff):
243
+ K = _wigner_kernel(n, m, X, P)
244
+ if m == n:
245
+ W = W + rho[n, n] * K
246
+ else:
247
+ W = W + rho[n, m] * K + rho[m, n] * np.conj(K)
248
+ return W.real
249
+
250
+
251
+ def wigner_negativity(W, x_grid, p_grid):
252
+ r"""Wigner negativity: the integrated negative volume of a Wigner function.
253
+
254
+ .. math::
255
+
256
+ N_W = \iint \max(0, -W(x,p))\; dx\, dp
257
+
258
+ A standard non-classicality diagnostic: zero for classical/Gaussian
259
+ states (coherent, thermal, squeezed vacuum), strictly positive for
260
+ genuinely non-classical states such as Fock states with :math:`n \ge 1`.
261
+
262
+ Parameters
263
+ ----------
264
+ W : ndarray of shape (Nx, Np)
265
+ Wigner function, e.g. from :func:`compute_wigner_function`.
266
+ x_grid : ndarray of shape (Nx,)
267
+ Grid of :math:`x` quadrature values.
268
+ p_grid : ndarray of shape (Np,)
269
+ Grid of :math:`p` quadrature values.
270
+
271
+ Returns
272
+ -------
273
+ float
274
+ The (non-negative) integrated negative volume.
275
+
276
+ Examples
277
+ --------
278
+ >>> import numpy as np
279
+ >>> vac = fock_state(0, 8)
280
+ >>> xg = np.linspace(-5, 5, 61)
281
+ >>> pg = np.linspace(-5, 5, 61)
282
+ >>> W = compute_wigner_function(vac, xg, pg)
283
+ >>> wigner_negativity(W, xg, pg)
284
+ 0.0
285
+ """
286
+ negative_part = np.where(W < 0.0, -W, 0.0)
287
+ integral_over_p = trapz(negative_part, p_grid, axis=1)
288
+ return float(trapz(integral_over_p, x_grid))
289
+
290
+
291
+ class JaynesCummingsModel:
292
+ r"""The Jaynes-Cummings model: a two-level atom coupled to a single quantized cavity mode.
293
+
294
+ In the rotating-wave approximation, the Hamiltonian is
295
+
296
+ .. math::
297
+
298
+ \hat H = \omega_c\, \hat a^\dagger \hat a \otimes \hat I
299
+ + \frac{\omega_a}{2}\, \hat I \otimes \hat\sigma_z
300
+ + g\left(\hat a \otimes \hat\sigma_+ + \hat a^\dagger \otimes \hat\sigma_-\right)
301
+
302
+ with the cavity (dimension ``cutoff``) as the *left* tensor factor and
303
+ the atom (dimension 2, basis :math:`\{\lvert e\rangle, \lvert g\rangle\}`,
304
+ so :math:`\hat\sigma_z = \mathrm{diag}(+1,-1)`, :math:`\hat\sigma_+ =
305
+ \lvert e\rangle\langle g\rvert`, :math:`\hat\sigma_- = \lvert
306
+ g\rangle\langle e\rvert`) as the *right* factor, i.e. ``H = kron(H_cav,
307
+ H_atom)`` terms throughout. A combined basis state :math:`\lvert n,
308
+ e/g\rangle` therefore sits at flat index ``2*n`` (excited) or ``2*n+1``
309
+ (ground) of the ``2*cutoff``-dimensional Hilbert space.
310
+
311
+ Parameters
312
+ ----------
313
+ omega_c : float
314
+ Cavity mode frequency.
315
+ omega_a : float
316
+ Atomic transition frequency.
317
+ g : float
318
+ Atom-cavity coupling strength.
319
+ cutoff : int, default=10
320
+ Truncation of the cavity Fock space.
321
+ """
322
+
323
+ def __init__(self, omega_c, omega_a, g, cutoff=10):
324
+ self.omega_c = omega_c
325
+ self.omega_a = omega_a
326
+ self.g = g
327
+ self.cutoff = cutoff
328
+
329
+ def hamiltonian(self):
330
+ r"""The Jaynes-Cummings Hamiltonian as a dense matrix.
331
+
332
+ Returns
333
+ -------
334
+ ndarray of shape (2*cutoff, 2*cutoff)
335
+ The Hamiltonian :math:`\hat H`, in the ``cavity (x) atom``
336
+ basis ordering documented on the class.
337
+
338
+ Examples
339
+ --------
340
+ >>> import numpy as np
341
+ >>> jc = JaynesCummingsModel(omega_c=1.0, omega_a=1.0, g=0.1, cutoff=3)
342
+ >>> H = jc.hamiltonian()
343
+ >>> H.shape
344
+ (6, 6)
345
+ >>> bool(np.allclose(H, H.conj().T))
346
+ True
347
+ """
348
+ cutoff = self.cutoff
349
+ a = annihilation_operator(cutoff)
350
+ a_dag = creation_operator(cutoff)
351
+ N = a_dag @ a
352
+ I2 = np.eye(2, dtype=complex)
353
+ I_cav = np.eye(cutoff, dtype=complex)
354
+ sigma_z = np.diag([1.0, -1.0]).astype(complex)
355
+ sigma_plus = np.array([[0.0, 1.0], [0.0, 0.0]], dtype=complex) # |e><g|
356
+ sigma_minus = np.array([[0.0, 0.0], [1.0, 0.0]], dtype=complex) # |g><e|
357
+ H = self.omega_c * np.kron(N, I2) + 0.5 * self.omega_a * np.kron(I_cav, sigma_z) + self.g * (np.kron(a, sigma_plus) + np.kron(a_dag, sigma_minus))
358
+ return H
359
+
360
+ def evolve(self, psi0, t_array):
361
+ r"""Time-evolve a state under the Jaynes-Cummings Hamiltonian.
362
+
363
+ Diagonalizes :math:`\hat H` once and reconstructs
364
+ :math:`\lvert\psi(t)\rangle = e^{-i\hat H t}\lvert\psi_0\rangle` at
365
+ every requested time from the eigendecomposition, which is much
366
+ faster than exponentiating :math:`\hat H` separately for each
367
+ ``t``.
368
+
369
+ Parameters
370
+ ----------
371
+ psi0 : ndarray of shape (2*cutoff,)
372
+ Initial state.
373
+ t_array : ndarray of shape (T,)
374
+ Times at which to evaluate the evolved state.
375
+
376
+ Returns
377
+ -------
378
+ ndarray of shape (T, 2*cutoff)
379
+ Complex states :math:`\lvert\psi(t)\rangle` at each requested time.
380
+ """
381
+ H = self.hamiltonian()
382
+ eigvals, eigvecs = np.linalg.eigh(H)
383
+ psi0 = np.asarray(psi0, dtype=complex).reshape(-1)
384
+ c = eigvecs.conj().T @ psi0
385
+ t_array = np.asarray(t_array, dtype=float)
386
+ phase = np.exp(-1j * np.outer(t_array, eigvals))
387
+ coeffs_t = phase * c[np.newaxis, :]
388
+ return coeffs_t @ eigvecs.T
389
+
390
+ def excited_state_population(self, t_array, n_photons=0):
391
+ r"""Atomic excited-state population :math:`P_e(t)` starting from :math:`\lvert e, n\rangle`.
392
+
393
+ Starts from the initial state :math:`\lvert e, n_\text{photons}\rangle`
394
+ (atom excited, ``n_photons`` photons in the cavity) and returns
395
+
396
+ .. math::
397
+
398
+ P_e(t) = \sum_n \left\lvert \langle e, n \rvert \psi(t)\rangle \right\rvert^2.
399
+
400
+ On resonance (:math:`\omega_c = \omega_a`) with ``n_photons=0``,
401
+ this reduces to the textbook vacuum Rabi formula :math:`P_e(t) =
402
+ \cos^2(gt)`.
403
+
404
+ Parameters
405
+ ----------
406
+ t_array : ndarray of shape (T,)
407
+ Times at which to evaluate the population.
408
+ n_photons : int, default=0
409
+ Initial photon number (with the atom excited).
410
+
411
+ Returns
412
+ -------
413
+ ndarray of shape (T,)
414
+ Real-valued excited-state population at each time.
415
+
416
+ Examples
417
+ --------
418
+ >>> import numpy as np
419
+ >>> jc = JaynesCummingsModel(omega_c=1.0, omega_a=1.0, g=0.5, cutoff=10)
420
+ >>> t = np.array([0.0, np.pi / 2 / 0.5])
421
+ >>> Pe = jc.excited_state_population(t, n_photons=0)
422
+ >>> np.round(Pe, 6)
423
+ array([1., 0.])
424
+ """
425
+ psi0 = fock_state(2 * n_photons, 2 * self.cutoff)
426
+ psi_t = self.evolve(psi0, t_array)
427
+ excited_amplitudes = psi_t[:, 0::2]
428
+ return np.sum(np.abs(excited_amplitudes) ** 2, axis=1).real