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,311 @@
1
+ r"""Matrix Numerov eigensolver for the time-independent Schrodinger equation.
2
+
3
+ Solves
4
+
5
+ .. math::
6
+
7
+ -\frac{\hbar^2}{2m}\,\psi''(x) + V(x)\,\psi(x) = E\,\psi(x)
8
+
9
+ on a uniform grid with :math:`\psi = 0` at the domain boundary, using the
10
+ generalized-eigenvalue formulation of the Numerov method (Pillai, Goglio &
11
+ Walker, *Am. J. Phys.* **80**, 1017 (2012)).
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from dataclasses import dataclass
17
+
18
+ import numpy as np
19
+ from numba import njit
20
+ from scipy.linalg import eigh
21
+ from scipy.sparse import diags
22
+
23
+ from .._compat import trapz
24
+
25
+ __all__ = [
26
+ "EigenResult",
27
+ "NumerovSolver",
28
+ "infinite_well",
29
+ "finite_well",
30
+ "asymmetric_step_well",
31
+ "linear_gravitational_well",
32
+ "double_well",
33
+ "harmonic_well",
34
+ ]
35
+
36
+
37
+ @njit(cache=True)
38
+ def _tridiag_arrays(V: np.ndarray, h: float, hbar: float, m: float):
39
+ n = V.shape[0]
40
+ a_main = np.empty(n)
41
+ a_off = np.empty(n - 1)
42
+ b_main = np.empty(n)
43
+ b_off = np.empty(n - 1)
44
+
45
+ kin = hbar**2 / (2.0 * m * h * h)
46
+ for i in range(n):
47
+ a_main[i] = 2.0 * kin + (10.0 / 12.0) * V[i]
48
+ b_main[i] = 10.0 / 12.0
49
+ for i in range(n - 1):
50
+ a_off[i] = -kin + (1.0 / 12.0) * 0.5 * (V[i] + V[i + 1])
51
+ b_off[i] = 1.0 / 12.0
52
+ return a_main, a_off, b_main, b_off
53
+
54
+
55
+ @dataclass
56
+ class EigenResult:
57
+ """Container for the output of :meth:`NumerovSolver.solve`."""
58
+
59
+ x: np.ndarray
60
+ """numpy.ndarray: The spatial grid the wavefunctions are sampled on."""
61
+
62
+ energies: np.ndarray
63
+ r"""numpy.ndarray: Eigenenergies :math:`E_n`, ascending, shape ``(n_states,)``."""
64
+
65
+ wavefunctions: np.ndarray
66
+ r"""numpy.ndarray: Normalized eigenfunctions :math:`\psi_n(x)`, shape
67
+ ``(n_states, len(x))``, with :math:`\int \lvert\psi_n\rvert^2\,dx = 1`
68
+ and :math:`\psi_n(x[0]) = \psi_n(x[-1]) = 0`."""
69
+
70
+
71
+ class NumerovSolver:
72
+ r"""Bound-state solver for an arbitrary 1D potential :math:`V(x)` on a fixed grid.
73
+
74
+ Parameters
75
+ ----------
76
+ x : array_like
77
+ Uniform spatial grid. The wavefunction is forced to vanish at
78
+ ``x[0]`` and ``x[-1]`` (hard walls), so the domain should extend
79
+ well into the classically forbidden region for soft potentials.
80
+ V : callable or array_like
81
+ Potential energy, either a function ``V(x)`` or a precomputed array
82
+ matching ``x``.
83
+ hbar : float, default=1.0
84
+ Value of :math:`\hbar` to use.
85
+ m : float, default=1.0
86
+ Particle mass.
87
+
88
+ Notes
89
+ -----
90
+ The Numerov finite-difference relation for :math:`\psi'' = f\psi` is
91
+ recast as the generalized eigenvalue problem
92
+
93
+ .. math::
94
+
95
+ \hat A \boldsymbol\psi = E \hat B \boldsymbol\psi, \qquad
96
+ \hat A = -\frac{\hbar^2}{2m h^2}\hat T + \hat B\,\mathrm{diag}(V),
97
+
98
+ where :math:`\hat T` and :math:`\hat B` are the tridiagonal matrices
99
+ :math:`\mathrm{tridiag}(1,-2,1)` and :math:`\mathrm{tridiag}(1,10,1)/12`
100
+ and :math:`h` is the grid spacing. Validated against the analytic
101
+ infinite-well and harmonic-oscillator spectra to four decimal places.
102
+ """
103
+
104
+ def __init__(self, x: np.ndarray, V, hbar: float = 1.0, m: float = 1.0):
105
+ self.x = np.asarray(x, dtype=float)
106
+ h = self.x[1] - self.x[0]
107
+ if not np.allclose(np.diff(self.x), h, rtol=1e-8):
108
+ raise ValueError("NumerovSolver requires a uniform grid.")
109
+ self.h = h
110
+ self.hbar = hbar
111
+ self.m = m
112
+ self.V_full = np.asarray(V(self.x) if callable(V) else V, dtype=float)
113
+
114
+ def solve(self, n_states: int = 6) -> EigenResult:
115
+ """Compute the lowest bound states.
116
+
117
+ Parameters
118
+ ----------
119
+ n_states : int, default=6
120
+ Number of lowest-energy eigenstates to return. Must be smaller
121
+ than the number of interior grid points.
122
+
123
+ Returns
124
+ -------
125
+ EigenResult
126
+ The energies and normalized wavefunctions.
127
+
128
+ Raises
129
+ ------
130
+ ValueError
131
+ If ``n_states`` is not smaller than the number of interior grid
132
+ points.
133
+ """
134
+ # Interior points only; psi vanishes at the two boundary points.
135
+ V_int = self.V_full[1:-1]
136
+ n = V_int.shape[0]
137
+ if n_states >= n:
138
+ raise ValueError("n_states must be smaller than the number of interior grid points.")
139
+
140
+ a_main, a_off, b_main, b_off = _tridiag_arrays(V_int, self.h, self.hbar, self.m)
141
+
142
+ A = diags([a_off, a_main, a_off], offsets=[-1, 0, 1]).toarray()
143
+ B = diags([b_off, b_main, b_off], offsets=[-1, 0, 1]).toarray()
144
+
145
+ eigvals, eigvecs = eigh(A, B)
146
+
147
+ energies = eigvals[:n_states]
148
+ psis = np.zeros((n_states, self.x.shape[0]))
149
+ for k in range(n_states):
150
+ psi_int = eigvecs[:, k]
151
+ psi = np.zeros(self.x.shape[0])
152
+ psi[1:-1] = psi_int
153
+ norm = np.sqrt(trapz(psi**2, self.x))
154
+ psis[k] = psi / norm
155
+
156
+ return EigenResult(x=self.x, energies=energies, wavefunctions=psis)
157
+
158
+
159
+ # --- Convenience potential builders ---------------------------------------
160
+
161
+
162
+ def infinite_well():
163
+ r"""The infinite square well: :math:`V(x) = 0` inside the domain.
164
+
165
+ The grid boundaries passed to :class:`NumerovSolver` act as the
166
+ infinite walls, since the wavefunction is forced to vanish there.
167
+
168
+ Returns
169
+ -------
170
+ callable
171
+ A function ``V(x)`` returning zeros the same shape as ``x``.
172
+ """
173
+
174
+ def V(x):
175
+ return np.zeros_like(x)
176
+
177
+ return V
178
+
179
+
180
+ def finite_well(V0: float, width: float):
181
+ r"""A finite square well,
182
+
183
+ .. math::
184
+
185
+ V(x) = \begin{cases} 0 & \lvert x\rvert \le \text{width}/2 \\
186
+ V_0 & \text{otherwise} \end{cases}.
187
+
188
+ Parameters
189
+ ----------
190
+ V0 : float
191
+ Height of the barrier outside the well.
192
+ width : float
193
+ Full width of the well (zero-potential region).
194
+
195
+ Returns
196
+ -------
197
+ callable
198
+ A function ``V(x)``.
199
+ """
200
+
201
+ def V(x):
202
+ return np.where(np.abs(x) <= width / 2, 0.0, V0)
203
+
204
+ return V
205
+
206
+
207
+ def asymmetric_step_well(width: float, V_left: float, V_right: float):
208
+ r"""A well of unequal left/right wall heights,
209
+
210
+ .. math::
211
+
212
+ V(x) = \begin{cases}
213
+ V_\text{left} & x < -\text{width}/2 \\
214
+ 0 & \lvert x\rvert \le \text{width}/2 \\
215
+ V_\text{right} & x > \text{width}/2
216
+ \end{cases}.
217
+
218
+ Parameters
219
+ ----------
220
+ width : float
221
+ Full width of the zero-potential region.
222
+ V_left : float
223
+ Wall height on the left side.
224
+ V_right : float
225
+ Wall height on the right side.
226
+
227
+ Returns
228
+ -------
229
+ callable
230
+ A function ``V(x)``.
231
+ """
232
+
233
+ def V(x):
234
+ out = np.zeros_like(x)
235
+ out[x < -width / 2] = V_left
236
+ out[x > width / 2] = V_right
237
+ return out
238
+
239
+ return V
240
+
241
+
242
+ def linear_gravitational_well(alpha: float):
243
+ r"""The V-shaped 'quantum bouncer' well, :math:`V(x) = \alpha \lvert x\rvert`.
244
+
245
+ A particle in this potential is the quantum analogue of a ball bouncing
246
+ under uniform gravity (:math:`\alpha = mg` on the half-line); its
247
+ eigenstates are Airy functions (see :func:`physicskit.quantum.chapters.potentials.airy_bouncer_energies`).
248
+
249
+ Parameters
250
+ ----------
251
+ alpha : float
252
+ Slope of the linear potential (e.g. :math:`mg` for gravity).
253
+
254
+ Returns
255
+ -------
256
+ callable
257
+ A function ``V(x)``.
258
+ """
259
+
260
+ def V(x):
261
+ return alpha * np.abs(x)
262
+
263
+ return V
264
+
265
+
266
+ def double_well(lam: float, a: float):
267
+ r"""The symmetric quartic double well, :math:`V(x) = \lambda (x^2 - a^2)^2`.
268
+
269
+ Has minima at :math:`x = \pm a`, each of depth 0, separated by a barrier
270
+ of height :math:`\lambda a^4` at :math:`x=0`.
271
+
272
+ Parameters
273
+ ----------
274
+ lam : float
275
+ Overall strength :math:`\lambda` of the quartic potential.
276
+ a : float
277
+ Half-separation of the two minima.
278
+
279
+ Returns
280
+ -------
281
+ callable
282
+ A function ``V(x)``.
283
+ """
284
+
285
+ def V(x):
286
+ return lam * (x**2 - a**2) ** 2
287
+
288
+ return V
289
+
290
+
291
+ def harmonic_well(m: float = 1.0, omega: float = 1.0):
292
+ r"""The quantum harmonic oscillator potential,
293
+ :math:`V(x) = \tfrac{1}{2} m \omega^2 x^2`.
294
+
295
+ Parameters
296
+ ----------
297
+ m : float, default=1.0
298
+ Particle mass.
299
+ omega : float, default=1.0
300
+ Angular frequency :math:`\omega`.
301
+
302
+ Returns
303
+ -------
304
+ callable
305
+ A function ``V(x)``.
306
+ """
307
+
308
+ def V(x):
309
+ return 0.5 * m * omega**2 * x**2
310
+
311
+ return V
@@ -0,0 +1,296 @@
1
+ r"""Dirac algebra helpers: Pauli matrices, spin/ladder operators, commutators.
2
+
3
+ Conventions follow Cohen-Tannoudji, Diu & Laloe, with :math:`\hbar = 1`
4
+ unless a function explicitly takes ``hbar`` as a parameter.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import numpy as np
10
+
11
+ __all__ = [
12
+ "sigma_x",
13
+ "sigma_y",
14
+ "sigma_z",
15
+ "identity2",
16
+ "PAULI",
17
+ "spin_operator",
18
+ "annihilation_operator",
19
+ "creation_operator",
20
+ "number_operator",
21
+ "position_operator",
22
+ "momentum_operator",
23
+ "commutator",
24
+ "anticommutator",
25
+ "expectation",
26
+ "is_hermitian",
27
+ ]
28
+
29
+ # --- Pauli matrices -------------------------------------------------------
30
+
31
+ sigma_x = np.array([[0, 1], [1, 0]], dtype=complex)
32
+ r"""The Pauli matrix :math:`\sigma_x = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}`."""
33
+
34
+ sigma_y = np.array([[0, -1j], [1j, 0]], dtype=complex)
35
+ r"""The Pauli matrix :math:`\sigma_y = \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix}`."""
36
+
37
+ sigma_z = np.array([[1, 0], [0, -1]], dtype=complex)
38
+ r"""The Pauli matrix :math:`\sigma_z = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}`."""
39
+
40
+ identity2 = np.eye(2, dtype=complex)
41
+ """The :math:`2\\times 2` identity matrix."""
42
+
43
+ PAULI = {"x": sigma_x, "y": sigma_y, "z": sigma_z, "i": identity2}
44
+ """Dict mapping ``'x'``, ``'y'``, ``'z'``, ``'i'`` to the corresponding matrix."""
45
+
46
+
47
+ def spin_operator(axis: str, s: float = 0.5, hbar: float = 1.0) -> np.ndarray:
48
+ r"""Angular-momentum operator :math:`\hat S_\text{axis}` for spin quantum number ``s``.
49
+
50
+ For :math:`s=1/2` this reduces to :math:`(\hbar/2)\,\sigma_\text{axis}`. For
51
+ general :math:`s`, the :math:`(2s+1)`-dimensional matrix representation is
52
+ built from the ladder operators
53
+
54
+ .. math::
55
+
56
+ \hat S_\pm \lvert s, m\rangle
57
+ = \hbar\sqrt{s(s+1) - m(m\pm 1)}\, \lvert s, m\pm 1\rangle,
58
+
59
+ with :math:`\hat S_x = (\hat S_+ + \hat S_-)/2` and
60
+ :math:`\hat S_y = (\hat S_+ - \hat S_-)/2i`.
61
+
62
+ Parameters
63
+ ----------
64
+ axis : {'x', 'y', 'z', '+', '-'}
65
+ Which component (or ladder operator) to return.
66
+ s : float, default=0.5
67
+ Spin quantum number (may be integer or half-integer).
68
+ hbar : float, default=1.0
69
+ Value of :math:`\hbar` to use.
70
+
71
+ Returns
72
+ -------
73
+ numpy.ndarray
74
+ The :math:`(2s+1)\times(2s+1)` operator matrix, in the
75
+ :math:`\lvert s, m\rangle` basis ordered :math:`m = s, s-1, \dots, -s`.
76
+
77
+ Raises
78
+ ------
79
+ ValueError
80
+ If ``axis`` is not one of ``'x'``, ``'y'``, ``'z'``, ``'+'``, ``'-'``.
81
+ """
82
+ dim = int(round(2 * s + 1))
83
+ m_values = np.array([s - k for k in range(dim)]) # m = s, s-1, ..., -s
84
+
85
+ if axis == "z":
86
+ return hbar * np.diag(m_values).astype(complex)
87
+
88
+ s_plus = np.zeros((dim, dim), dtype=complex)
89
+ for k in range(dim - 1):
90
+ m = m_values[k + 1]
91
+ coeff = hbar * np.sqrt(s * (s + 1) - m * (m + 1))
92
+ s_plus[k, k + 1] = coeff
93
+ s_minus = s_plus.conj().T
94
+
95
+ if axis == "+":
96
+ return s_plus
97
+ if axis == "-":
98
+ return s_minus
99
+ if axis == "x":
100
+ return 0.5 * (s_plus + s_minus)
101
+ if axis == "y":
102
+ return (s_plus - s_minus) / (2j)
103
+ raise ValueError(f"Unknown axis {axis!r}; expected 'x', 'y', 'z', '+' or '-'.")
104
+
105
+
106
+ # --- Harmonic-oscillator ladder operators (truncated Fock basis) ---------
107
+
108
+
109
+ def annihilation_operator(n_max: int) -> np.ndarray:
110
+ r"""Lowering operator :math:`\hat a` in a truncated Fock basis.
111
+
112
+ Acts as :math:`\hat a \lvert n\rangle = \sqrt{n}\,\lvert n-1\rangle` on the
113
+ truncated basis :math:`\{\lvert 0\rangle, \dots, \lvert n_\text{max}-1\rangle\}`.
114
+
115
+ Parameters
116
+ ----------
117
+ n_max : int
118
+ Dimension of the truncated Fock space.
119
+
120
+ Returns
121
+ -------
122
+ numpy.ndarray
123
+ The :math:`n_\text{max}\times n_\text{max}` matrix representation of
124
+ :math:`\hat a`.
125
+ """
126
+ a = np.zeros((n_max, n_max), dtype=complex)
127
+ for n in range(1, n_max):
128
+ a[n - 1, n] = np.sqrt(n)
129
+ return a
130
+
131
+
132
+ def creation_operator(n_max: int) -> np.ndarray:
133
+ r"""Raising operator :math:`\hat a^\dagger`, the Hermitian conjugate of
134
+ :func:`annihilation_operator`.
135
+
136
+ Parameters
137
+ ----------
138
+ n_max : int
139
+ Dimension of the truncated Fock space.
140
+
141
+ Returns
142
+ -------
143
+ numpy.ndarray
144
+ The :math:`n_\text{max}\times n_\text{max}` matrix representation of
145
+ :math:`\hat a^\dagger`.
146
+ """
147
+ return annihilation_operator(n_max).conj().T
148
+
149
+
150
+ def number_operator(n_max: int) -> np.ndarray:
151
+ r"""Number operator :math:`\hat N = \hat a^\dagger \hat a`, diagonal with
152
+ eigenvalues :math:`0, 1, \dots, n_\text{max}-1`.
153
+
154
+ Parameters
155
+ ----------
156
+ n_max : int
157
+ Dimension of the truncated Fock space.
158
+
159
+ Returns
160
+ -------
161
+ numpy.ndarray
162
+ The :math:`n_\text{max}\times n_\text{max}` matrix representation of
163
+ :math:`\hat N`.
164
+ """
165
+ a = annihilation_operator(n_max)
166
+ return a.conj().T @ a
167
+
168
+
169
+ def position_operator(n_max: int, m: float = 1.0, omega: float = 1.0, hbar: float = 1.0) -> np.ndarray:
170
+ r"""Harmonic-oscillator position operator in the truncated Fock basis,
171
+
172
+ .. math::
173
+
174
+ \hat x = \sqrt{\frac{\hbar}{2 m \omega}} \left(\hat a + \hat a^\dagger\right).
175
+
176
+ Parameters
177
+ ----------
178
+ n_max : int
179
+ Dimension of the truncated Fock space.
180
+ m : float, default=1.0
181
+ Particle mass.
182
+ omega : float, default=1.0
183
+ Angular frequency of the oscillator.
184
+ hbar : float, default=1.0
185
+ Value of :math:`\hbar` to use.
186
+
187
+ Returns
188
+ -------
189
+ numpy.ndarray
190
+ The :math:`n_\text{max}\times n_\text{max}` matrix representation of
191
+ :math:`\hat x`.
192
+ """
193
+ a = annihilation_operator(n_max)
194
+ return np.sqrt(hbar / (2 * m * omega)) * (a + a.conj().T)
195
+
196
+
197
+ def momentum_operator(n_max: int, m: float = 1.0, omega: float = 1.0, hbar: float = 1.0) -> np.ndarray:
198
+ r"""Harmonic-oscillator momentum operator in the truncated Fock basis,
199
+
200
+ .. math::
201
+
202
+ \hat p = i\sqrt{\frac{\hbar m \omega}{2}} \left(\hat a^\dagger - \hat a\right).
203
+
204
+ Parameters
205
+ ----------
206
+ n_max : int
207
+ Dimension of the truncated Fock space.
208
+ m : float, default=1.0
209
+ Particle mass.
210
+ omega : float, default=1.0
211
+ Angular frequency of the oscillator.
212
+ hbar : float, default=1.0
213
+ Value of :math:`\hbar` to use.
214
+
215
+ Returns
216
+ -------
217
+ numpy.ndarray
218
+ The :math:`n_\text{max}\times n_\text{max}` matrix representation of
219
+ :math:`\hat p`.
220
+ """
221
+ a = annihilation_operator(n_max)
222
+ return 1j * np.sqrt(hbar * m * omega / 2) * (a.conj().T - a)
223
+
224
+
225
+ # --- Algebra utilities ------------------------------------------------------
226
+
227
+
228
+ def commutator(A: np.ndarray, B: np.ndarray) -> np.ndarray:
229
+ r"""The commutator :math:`[\hat A, \hat B] = \hat A \hat B - \hat B \hat A`.
230
+
231
+ Parameters
232
+ ----------
233
+ A, B : numpy.ndarray
234
+ Square matrices of matching shape.
235
+
236
+ Returns
237
+ -------
238
+ numpy.ndarray
239
+ :math:`\hat A \hat B - \hat B \hat A`.
240
+ """
241
+ return A @ B - B @ A
242
+
243
+
244
+ def anticommutator(A: np.ndarray, B: np.ndarray) -> np.ndarray:
245
+ r"""The anticommutator :math:`\{\hat A, \hat B\} = \hat A \hat B + \hat B \hat A`.
246
+
247
+ Parameters
248
+ ----------
249
+ A, B : numpy.ndarray
250
+ Square matrices of matching shape.
251
+
252
+ Returns
253
+ -------
254
+ numpy.ndarray
255
+ :math:`\hat A \hat B + \hat B \hat A`.
256
+ """
257
+ return A @ B + B @ A
258
+
259
+
260
+ def expectation(operator: np.ndarray, state: np.ndarray) -> complex:
261
+ r"""Expectation value :math:`\langle\psi\rvert \hat A \lvert\psi\rangle` of
262
+ an operator in a discrete-basis state vector.
263
+
264
+ Parameters
265
+ ----------
266
+ operator : numpy.ndarray
267
+ The operator matrix :math:`\hat A`.
268
+ state : numpy.ndarray
269
+ The (not necessarily normalized) state vector :math:`\lvert\psi\rangle`;
270
+ flattened if not already 1D.
271
+
272
+ Returns
273
+ -------
274
+ complex
275
+ :math:`\langle\psi\rvert \hat A \lvert\psi\rangle`.
276
+ """
277
+ state = np.asarray(state).reshape(-1)
278
+ return complex(np.vdot(state, operator @ state))
279
+
280
+
281
+ def is_hermitian(A: np.ndarray, atol: float = 1e-10) -> bool:
282
+ r"""Check whether a matrix is Hermitian, :math:`\hat A = \hat A^\dagger`.
283
+
284
+ Parameters
285
+ ----------
286
+ A : numpy.ndarray
287
+ The matrix to test.
288
+ atol : float, default=1e-10
289
+ Absolute tolerance passed to :func:`numpy.allclose`.
290
+
291
+ Returns
292
+ -------
293
+ bool
294
+ ``True`` if ``A`` equals its conjugate transpose within ``atol``.
295
+ """
296
+ return np.allclose(A, A.conj().T, atol=atol)