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,127 @@
1
+ """Tests for physicskit.quantum.chapters.entanglement: Bell states, EPR/CHSH
2
+ correlations, Ising-coupling entanglement generation, and the
3
+ Aharonov-Bohm ring -- covering the parts test_physics_checks.py and
4
+ test_animations.py don't already exercise (measurement_probabilities,
5
+ monte_carlo_correlation, the reduced-density-matrix/purity/trajectory
6
+ helpers, and the ring's spectrum/eigenstate/persistent_current).
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import numpy as np
12
+ import pytest
13
+
14
+ from physicskit.quantum.chapters.entanglement import (
15
+ AharonovBohmRing,
16
+ BellCorrelations,
17
+ IsingEntangler,
18
+ bell_state,
19
+ )
20
+
21
+
22
+ # --- Bell states -------------------------------------------------------------
23
+
24
+
25
+ @pytest.mark.parametrize("kind", ["phi+", "phi-", "psi+", "psi-"])
26
+ def test_bell_state_is_normalized(kind):
27
+ state = bell_state(kind)
28
+ assert np.vdot(state, state).real == pytest.approx(1.0)
29
+
30
+
31
+ def test_bell_state_rejects_unknown_kind():
32
+ with pytest.raises(ValueError):
33
+ bell_state("not-a-bell-state")
34
+
35
+
36
+ # --- BellCorrelations ---------------------------------------------------------
37
+
38
+
39
+ def test_measurement_probabilities_of_singlet_at_matched_angles_are_anticorrelated():
40
+ bc = BellCorrelations()
41
+ probs = bc.measurement_probabilities(0.0, 0.0)
42
+ assert probs["++"] == pytest.approx(0.0, abs=1e-12)
43
+ assert probs["--"] == pytest.approx(0.0, abs=1e-12)
44
+ assert probs["+-"] == pytest.approx(0.5)
45
+ assert probs["-+"] == pytest.approx(0.5)
46
+ assert sum(probs.values()) == pytest.approx(1.0)
47
+
48
+
49
+ def test_measurement_probabilities_sum_to_one_at_arbitrary_angles():
50
+ bc = BellCorrelations()
51
+ probs = bc.measurement_probabilities(0.7, -1.3)
52
+ assert sum(probs.values()) == pytest.approx(1.0)
53
+ assert all(0.0 <= p <= 1.0 for p in probs.values())
54
+
55
+
56
+ def test_monte_carlo_correlation_converges_to_exact_correlation():
57
+ bc = BellCorrelations()
58
+ rng = np.random.default_rng(0)
59
+ empirical = bc.monte_carlo_correlation(0.0, 0.0, n_trials=20000, rng=rng)
60
+ assert empirical == pytest.approx(bc.correlation(0.0, 0.0), abs=0.03)
61
+
62
+
63
+ # --- IsingEntangler ------------------------------------------------------------
64
+
65
+
66
+ def test_reduced_density_matrix_and_purity_of_initial_product_state_are_pure():
67
+ ising = IsingEntangler(J=1.0)
68
+ psi0 = ising.initial_state()
69
+ rho = ising.reduced_density_matrix(psi0)
70
+ assert rho.shape == (2, 2)
71
+ assert np.trace(rho).real == pytest.approx(1.0)
72
+ assert ising.purity(psi0) == pytest.approx(1.0)
73
+
74
+
75
+ def test_purity_drops_to_one_half_at_maximal_entanglement():
76
+ ising = IsingEntangler(J=1.0)
77
+ t_max_entangle = np.pi / 4
78
+ psi = ising.state(t_max_entangle)
79
+ assert ising.purity(psi) == pytest.approx(0.5, abs=1e-9)
80
+ assert ising.concurrence(psi) == pytest.approx(1.0, abs=1e-9)
81
+
82
+
83
+ def test_state_trajectory_matches_pointwise_state_calls():
84
+ ising = IsingEntangler(J=1.0)
85
+ t_values = np.linspace(0, 1, 5)
86
+ trajectory = ising.state_trajectory(t_values)
87
+ assert trajectory.shape == (5, 4)
88
+ for i, t in enumerate(t_values):
89
+ np.testing.assert_allclose(trajectory[i], ising.state(t))
90
+
91
+
92
+ def test_concurrence_trajectory_starts_at_zero_and_peaks_at_one():
93
+ ising = IsingEntangler(J=1.0)
94
+ t_values = np.array([0.0, np.pi / 4])
95
+ concurrences = ising.concurrence_trajectory(t_values)
96
+ assert concurrences[0] == pytest.approx(0.0, abs=1e-9)
97
+ assert concurrences[1] == pytest.approx(1.0, abs=1e-9)
98
+
99
+
100
+ # --- Aharonov-Bohm ring --------------------------------------------------------
101
+
102
+
103
+ def test_spectrum_is_sorted_and_minimal_at_n_zero_for_zero_flux():
104
+ ring = AharonovBohmRing(R=1.0)
105
+ spectrum = ring.spectrum(Phi=0.0, n_range=5)
106
+ assert spectrum.shape == (11,)
107
+ np.testing.assert_allclose(spectrum, np.sort(spectrum))
108
+ assert spectrum[0] == pytest.approx(0.0)
109
+
110
+
111
+ def test_eigenstate_has_constant_magnitude():
112
+ ring = AharonovBohmRing(R=2.0)
113
+ phi = np.linspace(0, 2 * np.pi, 50, endpoint=False)
114
+ psi = ring.eigenstate(n=3, phi=phi)
115
+ np.testing.assert_allclose(np.abs(psi), 1.0 / np.sqrt(2 * np.pi * ring.R))
116
+
117
+
118
+ def test_persistent_current_matches_analytic_derivative_of_energy():
119
+ ring = AharonovBohmRing(R=1.0, m=1.0, hbar=1.0, q=1.0)
120
+ n, Phi = 1, 0.0
121
+ expected = (ring.hbar**2 / (ring.m * ring.R**2 * ring.flux_quantum)) * (n - Phi / ring.flux_quantum)
122
+ assert ring.persistent_current(n, Phi) == pytest.approx(expected, rel=1e-6)
123
+
124
+
125
+ def test_persistent_current_vanishes_by_symmetry_for_n_zero_at_zero_flux():
126
+ ring = AharonovBohmRing(R=1.0)
127
+ assert ring.persistent_current(n=0, Phi=0.0) == pytest.approx(0.0, abs=1e-9)
@@ -0,0 +1,140 @@
1
+ """Tests for physicskit.quantum.chapters.harmonic_spin: the parts of
2
+ HarmonicOscillator/ThermalState not already exercised by
3
+ test_physics_checks.py or test_animations.py -- time-evolved stationary
4
+ states, squeezed states, thermal populations/distributions/variance, and
5
+ the ThermalState convenience wrapper.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import numpy as np
11
+ import pytest
12
+
13
+ from physicskit.quantum._compat import trapz
14
+ from physicskit.quantum.chapters.harmonic_spin import HarmonicOscillator, ThermalState
15
+
16
+
17
+ @pytest.fixture
18
+ def osc():
19
+ return HarmonicOscillator(m=1.0, omega=1.0, hbar=1.0)
20
+
21
+
22
+ # --- Time-evolved stationary states ---------------------------------------
23
+
24
+
25
+ def test_eigenfunction_t_has_time_independent_density(osc):
26
+ x = np.linspace(-6, 6, 200)
27
+ psi_t0 = osc.eigenfunction_t(2, x, t=0.0)
28
+ psi_t1 = osc.eigenfunction_t(2, x, t=1.7)
29
+ np.testing.assert_allclose(np.abs(psi_t0) ** 2, np.abs(psi_t1) ** 2, atol=1e-10)
30
+ np.testing.assert_allclose(psi_t0.real, osc.eigenfunction(2, x))
31
+
32
+
33
+ def test_eigenfunction_t_accumulates_correct_phase(osc):
34
+ x = np.linspace(-6, 6, 200)
35
+ t = 0.3
36
+ psi_t = osc.eigenfunction_t(1, x, t)
37
+ expected_phase = np.exp(-1j * osc.energy(1) * t / osc.hbar)
38
+ np.testing.assert_allclose(psi_t, osc.eigenfunction(1, x) * expected_phase)
39
+
40
+
41
+ # --- Squeezed states ---------------------------------------------------------
42
+
43
+
44
+ def test_squeezed_vacuum_wavefunction_is_normalized(osc):
45
+ x = np.linspace(-10, 10, 4000)
46
+ psi = osc.squeezed_vacuum_wavefunction(x, r=0.5)
47
+ assert trapz(np.abs(psi) ** 2, x) == pytest.approx(1.0, abs=1e-3)
48
+
49
+
50
+ def test_squeezed_vacuum_wavefunction_is_real_when_phi_is_zero(osc):
51
+ x = np.linspace(-10, 10, 100)
52
+ psi = osc.squeezed_vacuum_wavefunction(x, r=0.8, phi=0.0)
53
+ np.testing.assert_allclose(psi.imag, 0.0, atol=1e-12)
54
+
55
+
56
+ def test_squeezed_vacuum_wavefunction_has_complex_chirp_when_phi_nonzero(osc):
57
+ x = np.linspace(-10, 10, 100)
58
+ psi = osc.squeezed_vacuum_wavefunction(x, r=0.8, phi=0.5)
59
+ assert np.any(np.abs(psi.imag) > 1e-12)
60
+
61
+
62
+ def test_squeezed_uncertainties_matches_variance_formula(osc):
63
+ r = 0.6
64
+ dx, dp = osc.squeezed_uncertainties(r)
65
+ assert dx == pytest.approx(np.sqrt(osc.hbar / (2 * osc.m * osc.omega) * np.exp(-2 * r)))
66
+ assert dp == pytest.approx(np.sqrt(osc.hbar * osc.m * osc.omega / 2 * np.exp(2 * r)))
67
+
68
+
69
+ def test_squeezed_uncertainties_saturates_heisenberg_bound_for_any_r(osc):
70
+ for r in (0.0, 0.5, 1.5):
71
+ dx, dp = osc.squeezed_uncertainties(r)
72
+ assert dx * dp == pytest.approx(osc.hbar / 2)
73
+
74
+
75
+ def test_zero_point_uncertainties_matches_squeezed_at_r_zero(osc):
76
+ assert osc.zero_point_uncertainties() == osc.squeezed_uncertainties(r=0.0)
77
+
78
+
79
+ # --- Thermal (mixed) states ---------------------------------------------------
80
+
81
+
82
+ def test_thermal_populations_at_zero_temperature_is_ground_state(osc):
83
+ pops = osc.thermal_populations(T=0.0, n_max=5)
84
+ np.testing.assert_allclose(pops, [1.0, 0.0, 0.0, 0.0, 0.0, 0.0])
85
+
86
+
87
+ def test_thermal_populations_sum_to_one_and_decay_with_n(osc):
88
+ pops = osc.thermal_populations(T=2.0, n_max=50)
89
+ assert pops.sum() == pytest.approx(1.0)
90
+ assert np.all(np.diff(pops) < 0) # monotonically decreasing Boltzmann weights
91
+
92
+
93
+ def test_thermal_position_distribution_is_normalized_and_symmetric(osc):
94
+ x = np.linspace(-15, 15, 3000)
95
+ P = osc.thermal_position_distribution(x, T=1.0, n_max=60)
96
+ assert trapz(P, x) == pytest.approx(1.0, abs=1e-2)
97
+ np.testing.assert_allclose(P, P[::-1], atol=1e-6)
98
+
99
+
100
+ def test_thermal_position_variance_matches_numerical_integral(osc):
101
+ x = np.linspace(-20, 20, 6000)
102
+ T = 1.5
103
+ P = osc.thermal_position_distribution(x, T=T, n_max=80)
104
+ numeric_var = trapz(x**2 * P, x)
105
+ assert osc.thermal_position_variance_analytic(T) == pytest.approx(numeric_var, rel=1e-2)
106
+
107
+
108
+ def test_thermal_position_variance_reduces_to_zero_point_as_t_to_zero(osc):
109
+ assert osc.thermal_position_variance_analytic(T=0.0) == pytest.approx(osc.hbar / (2 * osc.m * osc.omega))
110
+
111
+
112
+ def test_thermal_position_variance_grows_with_temperature(osc):
113
+ var_cold = osc.thermal_position_variance_analytic(T=0.1)
114
+ var_hot = osc.thermal_position_variance_analytic(T=10.0)
115
+ assert var_hot > var_cold
116
+
117
+
118
+ # --- ThermalState convenience wrapper -----------------------------------------
119
+
120
+
121
+ def test_thermal_state_populations_delegates_to_oscillator(osc):
122
+ ts = ThermalState(oscillator=osc, T=2.0, n_max=30)
123
+ np.testing.assert_allclose(ts.populations(), osc.thermal_populations(2.0, 30, 1.0))
124
+
125
+
126
+ def test_thermal_state_position_distribution_delegates_to_oscillator(osc):
127
+ x = np.linspace(-10, 10, 200)
128
+ ts = ThermalState(oscillator=osc, T=2.0, n_max=30)
129
+ np.testing.assert_allclose(ts.position_distribution(x), osc.thermal_position_distribution(x, 2.0, 1.0, 30))
130
+
131
+
132
+ def test_thermal_state_variance_delegates_to_oscillator(osc):
133
+ ts = ThermalState(oscillator=osc, T=2.0)
134
+ assert ts.variance() == osc.thermal_position_variance_analytic(2.0, 1.0)
135
+
136
+
137
+ def test_thermal_state_check_normalization_is_close_to_one(osc):
138
+ x = np.linspace(-15, 15, 3000)
139
+ ts = ThermalState(oscillator=osc, T=1.0, n_max=60)
140
+ assert ts.check_normalization(x) == pytest.approx(1.0, abs=1e-2)
@@ -0,0 +1,48 @@
1
+ """Tests for physicskit.quantum.chapters.hydrogen_am: the quantum-number
2
+ validation, density, and most_probable_radius paths not already
3
+ exercised by test_physics_checks.py/test_animations.py.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import numpy as np
9
+ import pytest
10
+
11
+ from physicskit.quantum.chapters.hydrogen_am import HydrogenOrbital, radial_wavefunction
12
+
13
+
14
+ def test_radial_wavefunction_rejects_l_greater_or_equal_n():
15
+ with pytest.raises(ValueError):
16
+ radial_wavefunction(n=1, l=1, r=np.array([1.0]))
17
+
18
+
19
+ def test_hydrogen_orbital_rejects_invalid_l():
20
+ with pytest.raises(ValueError):
21
+ HydrogenOrbital(n=1, l=1, m=0)
22
+ with pytest.raises(ValueError):
23
+ HydrogenOrbital(n=2, l=-1, m=0)
24
+
25
+
26
+ def test_hydrogen_orbital_rejects_m_out_of_range():
27
+ with pytest.raises(ValueError):
28
+ HydrogenOrbital(n=2, l=0, m=1)
29
+
30
+
31
+ def test_hydrogen_orbital_density_matches_abs_psi_squared():
32
+ orbital = HydrogenOrbital(n=2, l=1, m=0)
33
+ r = np.array([1.0, 2.0, 3.0])
34
+ theta = np.array([0.3, 1.0, 2.0])
35
+ phi = np.array([0.1, 0.5, 1.5])
36
+ np.testing.assert_allclose(orbital.density(r, theta, phi), np.abs(orbital.psi(r, theta, phi)) ** 2)
37
+
38
+
39
+ def test_1s_orbital_most_probable_radius_equals_bohr_radius():
40
+ # The textbook result: the 1s orbital's most probable radius is exactly a0.
41
+ orbital = HydrogenOrbital(n=1, l=0, m=0, Z=1, a0=1.0)
42
+ assert orbital.most_probable_radius() == pytest.approx(1.0, rel=1e-3)
43
+
44
+
45
+ def test_most_probable_radius_scales_inversely_with_z():
46
+ orbital_z1 = HydrogenOrbital(n=1, l=0, m=0, Z=1, a0=1.0)
47
+ orbital_z2 = HydrogenOrbital(n=1, l=0, m=0, Z=2, a0=1.0)
48
+ assert orbital_z2.most_probable_radius() == pytest.approx(orbital_z1.most_probable_radius() / 2, rel=1e-2)
@@ -0,0 +1,110 @@
1
+ """Tests for physicskit.quantum.utils.measure, using a normalized Gaussian
2
+ wavepacket ``psi(x) = (2*pi*sigma^2)^(-1/4) * exp(-(x-x0)^2/(4*sigma^2))
3
+ * exp(i*p0*x/hbar)`` as a fixture with exactly known moments:
4
+ ``<x> = x0``, ``Var(x) = sigma^2``, ``<p> = p0``,
5
+ ``Var(p) = hbar^2/(4*sigma^2)`` -- the standard minimum-uncertainty
6
+ state, so ``dx*dp`` should equal ``hbar/2`` exactly (to numerical
7
+ precision), not merely satisfy the Heisenberg inequality.
8
+
9
+ No test in this package previously covered this module at all.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import numpy as np
15
+ import pytest
16
+
17
+ from physicskit.quantum.utils.measure import (
18
+ ExpectationMonitor,
19
+ expectation_value,
20
+ momentum_density,
21
+ momentum_expectation,
22
+ momentum_variance,
23
+ position_expectation,
24
+ position_variance,
25
+ simulate_position_measurement,
26
+ uncertainty,
27
+ )
28
+
29
+ HBAR = 1.0
30
+ X0, P0, SIGMA = 2.0, 3.0, 1.0
31
+ X = np.linspace(-20.0, 20.0, 4000)
32
+
33
+
34
+ def _gaussian_wavepacket(x0=X0, p0=P0, sigma=SIGMA):
35
+ return (2.0 * np.pi * sigma**2) ** -0.25 * np.exp(-((X - x0) ** 2) / (4.0 * sigma**2)) * np.exp(1j * p0 * X / HBAR)
36
+
37
+
38
+ def test_expectation_value_of_position_operator_matches_position_expectation():
39
+ psi = _gaussian_wavepacket()
40
+ ev = expectation_value(lambda x, p: x * p, X, psi)
41
+ assert ev.real == pytest.approx(X0, abs=1e-9)
42
+ assert ev.imag == pytest.approx(0.0, abs=1e-9)
43
+ assert ev.real == pytest.approx(position_expectation(X, psi))
44
+
45
+
46
+ def test_position_expectation_and_variance_match_gaussian_moments():
47
+ psi = _gaussian_wavepacket()
48
+ assert position_expectation(X, psi) == pytest.approx(X0, abs=1e-9)
49
+ assert position_variance(X, psi) == pytest.approx(SIGMA**2, abs=1e-9)
50
+
51
+
52
+ def test_momentum_density_is_normalized():
53
+ psi = _gaussian_wavepacket()
54
+ p, psi_p = momentum_density(X, psi, HBAR)
55
+ assert np.all(np.diff(p) > 0) # returned ascending, per docstring
56
+ assert np.trapezoid(np.abs(psi_p) ** 2, p) == pytest.approx(1.0, rel=1e-6)
57
+
58
+
59
+ def test_momentum_expectation_and_variance_match_gaussian_moments():
60
+ psi = _gaussian_wavepacket()
61
+ assert momentum_expectation(X, psi, HBAR) == pytest.approx(P0, rel=1e-6)
62
+ assert momentum_variance(X, psi, HBAR) == pytest.approx(HBAR**2 / (4.0 * SIGMA**2), rel=1e-4)
63
+
64
+
65
+ def test_uncertainty_saturates_heisenberg_bound_for_minimum_uncertainty_gaussian():
66
+ psi = _gaussian_wavepacket()
67
+ dx, dp, product = uncertainty(X, psi, HBAR)
68
+ assert dx == pytest.approx(SIGMA, abs=1e-6)
69
+ assert dp == pytest.approx(HBAR / (2.0 * SIGMA), rel=1e-4)
70
+ assert product == pytest.approx(HBAR / 2.0, rel=1e-4)
71
+ assert product >= HBAR / 2.0 - 1e-9
72
+
73
+
74
+ def test_expectation_monitor_record_all_matches_direct_calls_per_frame():
75
+ times = np.array([0.0, 1.0, 2.0])
76
+ frames = np.array([_gaussian_wavepacket(x0=X0 + dt) for dt in times])
77
+
78
+ monitor = ExpectationMonitor(x=X, hbar=HBAR)
79
+ monitor.record_all(times, frames)
80
+ arrays = monitor.as_arrays()
81
+
82
+ np.testing.assert_allclose(arrays["t"], times)
83
+ np.testing.assert_allclose(arrays["x"], X0 + times, atol=1e-9)
84
+ np.testing.assert_allclose(arrays["norm"], 1.0, atol=1e-6)
85
+ np.testing.assert_allclose(arrays["dx"], SIGMA, atol=1e-6)
86
+
87
+
88
+ def test_expectation_monitor_record_single_snapshot_matches_uncertainty_directly():
89
+ monitor = ExpectationMonitor(x=X, hbar=HBAR)
90
+ psi = _gaussian_wavepacket()
91
+ monitor.record(0.5, psi)
92
+ dx, dp, _ = uncertainty(X, psi, HBAR)
93
+ assert monitor.history["t"] == [0.5]
94
+ assert monitor.history["dx"][0] == pytest.approx(dx)
95
+ assert monitor.history["dp"][0] == pytest.approx(dp)
96
+
97
+
98
+ def test_simulate_position_measurement_samples_match_born_rule_moments():
99
+ psi = _gaussian_wavepacket()
100
+ samples = simulate_position_measurement(X, psi, n_samples=200_000, rng=np.random.default_rng(0))
101
+ assert samples.shape == (200_000,)
102
+ assert samples.mean() == pytest.approx(X0, abs=0.05)
103
+ assert samples.var() == pytest.approx(SIGMA**2, rel=0.05)
104
+
105
+
106
+ def test_simulate_position_measurement_defaults_to_a_single_sample():
107
+ psi = _gaussian_wavepacket()
108
+ sample = simulate_position_measurement(X, psi)
109
+ assert sample.shape == (1,)
110
+ assert X.min() <= sample[0] <= X.max()
@@ -0,0 +1,105 @@
1
+ """Tests for physicskit.quantum.core.operators, none of which any other
2
+ test in the suite exercises directly (test_physics_checks.py etc. work
3
+ at the wavefunction/solver level, not the operator-algebra level)."""
4
+
5
+ from __future__ import annotations
6
+
7
+ import numpy as np
8
+ import pytest
9
+
10
+ from physicskit.quantum.core.operators import (
11
+ annihilation_operator,
12
+ anticommutator,
13
+ commutator,
14
+ creation_operator,
15
+ expectation,
16
+ is_hermitian,
17
+ momentum_operator,
18
+ number_operator,
19
+ position_operator,
20
+ sigma_x,
21
+ sigma_y,
22
+ sigma_z,
23
+ spin_operator,
24
+ )
25
+
26
+
27
+ def test_spin_operator_half_reduces_to_scaled_pauli_matrices():
28
+ np.testing.assert_allclose(spin_operator("x", 0.5), 0.5 * sigma_x)
29
+ np.testing.assert_allclose(spin_operator("y", 0.5), 0.5 * sigma_y)
30
+ np.testing.assert_allclose(spin_operator("z", 0.5), 0.5 * sigma_z)
31
+
32
+
33
+ def test_spin_operator_ladder_operators_reconstruct_x_and_y():
34
+ s_plus = spin_operator("+", 0.5)
35
+ s_minus = spin_operator("-", 0.5)
36
+ np.testing.assert_allclose(0.5 * (s_plus + s_minus), spin_operator("x", 0.5))
37
+ np.testing.assert_allclose((s_plus - s_minus) / (2j), spin_operator("y", 0.5))
38
+ np.testing.assert_allclose(s_minus, s_plus.conj().T)
39
+
40
+
41
+ @pytest.mark.parametrize("s", [0.5, 1.0, 1.5, 2.0])
42
+ def test_spin_operator_satisfies_angular_momentum_commutation_relations(s):
43
+ """[Sx, Sy] = i*hbar*Sz (and cyclic permutations), for both integer
44
+ and half-integer spin, not just the spin-1/2 Pauli case."""
45
+ sx, sy, sz = spin_operator("x", s), spin_operator("y", s), spin_operator("z", s)
46
+ np.testing.assert_allclose(commutator(sx, sy), 1j * sz, atol=1e-10)
47
+ np.testing.assert_allclose(commutator(sy, sz), 1j * sx, atol=1e-10)
48
+ np.testing.assert_allclose(commutator(sz, sx), 1j * sy, atol=1e-10)
49
+
50
+
51
+ def test_spin_operator_rejects_unknown_axis():
52
+ with pytest.raises(ValueError):
53
+ spin_operator("q")
54
+
55
+
56
+ def test_creation_operator_is_hermitian_conjugate_of_annihilation():
57
+ a = annihilation_operator(6)
58
+ a_dagger = creation_operator(6)
59
+ np.testing.assert_allclose(a_dagger, a.conj().T)
60
+
61
+
62
+ def test_number_operator_is_diagonal_with_fock_state_eigenvalues():
63
+ n_max = 6
64
+ N = number_operator(n_max)
65
+ np.testing.assert_allclose(np.diag(N).real, np.arange(n_max))
66
+ off_diag = N - np.diag(np.diag(N))
67
+ np.testing.assert_allclose(off_diag, 0.0)
68
+
69
+
70
+ def test_position_and_momentum_operators_satisfy_canonical_commutation():
71
+ """[x, p] = i*hbar*I, except at the last row/column where truncating
72
+ the Fock basis necessarily breaks the identity (a itself already
73
+ truncates there)."""
74
+ n_max = 8
75
+ x = position_operator(n_max, m=2.0, omega=3.0, hbar=1.0)
76
+ p = momentum_operator(n_max, m=2.0, omega=3.0, hbar=1.0)
77
+ comm = commutator(x, p)
78
+ np.testing.assert_allclose(np.diag(comm)[:-1], 1j * np.ones(n_max - 1), atol=1e-10)
79
+
80
+
81
+ def test_commutator_and_anticommutator_of_pauli_matrices():
82
+ # Standard su(2) identities: [sigma_x, sigma_y] = 2i*sigma_z,
83
+ # {sigma_x, sigma_y} = 0 (distinct Pauli matrices anticommute).
84
+ np.testing.assert_allclose(commutator(sigma_x, sigma_y), 2j * sigma_z)
85
+ np.testing.assert_allclose(anticommutator(sigma_x, sigma_y), np.zeros((2, 2)), atol=1e-12)
86
+ np.testing.assert_allclose(anticommutator(sigma_x, sigma_x), 2 * np.eye(2))
87
+
88
+
89
+ def test_expectation_of_sigma_z_on_basis_states():
90
+ up = np.array([1.0, 0.0])
91
+ down = np.array([0.0, 1.0])
92
+ assert expectation(sigma_z, up) == pytest.approx(1.0)
93
+ assert expectation(sigma_z, down) == pytest.approx(-1.0)
94
+
95
+
96
+ def test_expectation_flattens_non_1d_state_input():
97
+ up_column = np.array([[1.0], [0.0]])
98
+ assert expectation(sigma_z, up_column) == pytest.approx(1.0)
99
+
100
+
101
+ def test_is_hermitian_true_for_pauli_matrices_false_for_non_hermitian():
102
+ assert is_hermitian(sigma_x)
103
+ assert is_hermitian(sigma_y)
104
+ assert is_hermitian(sigma_z)
105
+ assert not is_hermitian(np.array([[0.0, 1.0], [0.0, 0.0]]))
@@ -0,0 +1,112 @@
1
+ """Tests for physicskit.quantum.chapters.perturbation: Zeeman and linear
2
+ Stark shifts (closed-form formulas), and the Floquet-driven infinite box.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ import numpy as np
8
+ import pytest
9
+
10
+ from physicskit.quantum._compat import trapz
11
+ from physicskit.quantum.chapters.perturbation import (
12
+ FloquetDrivenBox,
13
+ linear_stark_shift,
14
+ stark_n2_quartet,
15
+ zeeman_splitting,
16
+ zeeman_spectrum,
17
+ )
18
+ from physicskit.quantum.core.solvers import SplitOperatorSolver1D
19
+
20
+
21
+ # --- Zeeman -------------------------------------------------------------
22
+
23
+
24
+ def test_zeeman_splitting_matches_formula():
25
+ # Delta E = mu_B * B * (m_l + g_s * m_s)
26
+ assert zeeman_splitting(m_l=1, m_s=0.5, B=2.0, mu_B=1.0, g_s=2.0) == pytest.approx(4.0)
27
+ assert zeeman_splitting(m_l=0, m_s=0.0, B=5.0) == pytest.approx(0.0)
28
+
29
+
30
+ def test_zeeman_splitting_zero_field_has_no_shift():
31
+ assert zeeman_splitting(m_l=3, m_s=-0.5, B=0.0) == pytest.approx(0.0)
32
+
33
+
34
+ def test_zeeman_spectrum_has_2_times_2l_plus_1_sorted_sublevels():
35
+ l = 1
36
+ shifts = zeeman_spectrum(l, B=1.0, mu_B=1.0, g_s=2.0)
37
+ assert shifts.shape == (2 * (2 * l + 1),)
38
+ np.testing.assert_allclose(shifts, np.sort(shifts))
39
+ np.testing.assert_allclose(shifts, [-2.0, -1.0, 0.0, 0.0, 1.0, 2.0])
40
+
41
+
42
+ # --- Linear Stark effect --------------------------------------------------
43
+
44
+
45
+ def test_linear_stark_shift_matches_formula():
46
+ # valid: n1+n2+|m|+1 = n
47
+ shift = linear_stark_shift(n=2, n1=1, n2=0, m=0, F=1.0, a0=1.0)
48
+ assert shift == pytest.approx(1.5 * 2 * (1 - 0) * 1.0 * 1.0)
49
+
50
+
51
+ def test_linear_stark_shift_rejects_invalid_parabolic_numbers():
52
+ with pytest.raises(ValueError):
53
+ linear_stark_shift(n=2, n1=0, n2=0, m=0, F=1.0)
54
+
55
+
56
+ def test_stark_n2_quartet_reproduces_classic_minus3_0_0_plus3_pattern():
57
+ levels = stark_n2_quartet(F=1.0, a0=1.0)
58
+ shifts = [lv.shift for lv in levels]
59
+ assert shifts == sorted(shifts)
60
+ np.testing.assert_allclose(shifts, [-3.0, 0.0, 0.0, 3.0])
61
+
62
+
63
+ def test_stark_n2_quartet_scales_linearly_with_field():
64
+ levels_1 = stark_n2_quartet(F=1.0)
65
+ levels_2 = stark_n2_quartet(F=2.0)
66
+ np.testing.assert_allclose([lv.shift for lv in levels_2], [2 * lv.shift for lv in levels_1])
67
+
68
+
69
+ # --- Floquet-driven box ---------------------------------------------------
70
+
71
+
72
+ @pytest.fixture
73
+ def small_box():
74
+ return FloquetDrivenBox(L=1.0, V0=5.0, omega=20.0, n_grid=256)
75
+
76
+
77
+ def test_box_eigenstate_is_normalized_and_vanishes_outside_well(small_box):
78
+ psi = small_box.box_eigenstate(1)
79
+ assert trapz(psi**2, small_box.x) == pytest.approx(1.0, abs=1e-3)
80
+ outside = (small_box.x < 0) | (small_box.x > small_box.L)
81
+ np.testing.assert_allclose(psi[outside], 0.0)
82
+
83
+
84
+ def test_box_energy_matches_infinite_well_formula(small_box):
85
+ for n in (1, 2, 3):
86
+ expected = (n**2 * np.pi**2 * small_box.hbar**2) / (2 * small_box.m * small_box.L**2)
87
+ assert small_box.box_energy(n) == pytest.approx(expected)
88
+
89
+
90
+ def test_make_solver_returns_configured_split_operator_solver(small_box):
91
+ solver = small_box.make_solver(dt=1e-4)
92
+ assert isinstance(solver, SplitOperatorSolver1D)
93
+ np.testing.assert_allclose(solver.x, small_box.x)
94
+
95
+
96
+ def test_transition_probability_starts_near_delta_function(small_box):
97
+ times, probs = small_box.transition_probability(n_initial=1, n_final=1, t_max=1e-3, dt=1e-4)
98
+ assert times.shape == probs.shape
99
+ assert probs[0] == pytest.approx(1.0, abs=1e-2)
100
+ assert np.all(probs >= -1e-9) and np.all(probs <= 1.0 + 1e-9)
101
+
102
+
103
+ def test_transition_probability_off_diagonal_starts_near_zero(small_box):
104
+ _, probs = small_box.transition_probability(n_initial=1, n_final=2, t_max=1e-3, dt=1e-4)
105
+ assert probs[0] == pytest.approx(0.0, abs=1e-2)
106
+
107
+
108
+ def test_floquet_quasienergies_are_real_and_sorted(small_box):
109
+ quasi_energies = small_box.floquet_quasienergies(n_levels=2, dt=1e-3)
110
+ assert quasi_energies.shape == (2,)
111
+ assert np.all(np.isreal(quasi_energies))
112
+ np.testing.assert_allclose(quasi_energies, np.sort(quasi_energies))