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.
- physicskit/__init__.py +51 -0
- physicskit/astro/__init__.py +66 -0
- physicskit/astro/cosmic_web.py +395 -0
- physicskit/astro/galactic_dynamics.py +137 -0
- physicskit/astro/nbody.py +208 -0
- physicskit/astro/orbital_mechanics.py +220 -0
- physicskit/astro/stellar_dynamo.py +628 -0
- physicskit/astro/stellar_structure.py +198 -0
- physicskit/astro/tests/__init__.py +0 -0
- physicskit/astro/tests/conftest.py +7 -0
- physicskit/astro/tests/test_cosmic_web.py +159 -0
- physicskit/astro/tests/test_galactic_dynamics.py +46 -0
- physicskit/astro/tests/test_nbody.py +81 -0
- physicskit/astro/tests/test_orbital_mechanics.py +73 -0
- physicskit/astro/tests/test_stellar_dynamo.py +198 -0
- physicskit/astro/tests/test_stellar_structure.py +52 -0
- physicskit/astro/tests/test_visualizers.py +159 -0
- physicskit/astro/visualizers.py +628 -0
- physicskit/chaos/__init__.py +55 -0
- physicskit/chaos/core/__init__.py +3 -0
- physicskit/chaos/core/base_system.py +342 -0
- physicskit/chaos/core/integrators.py +40 -0
- physicskit/chaos/exceptions.py +24 -0
- physicskit/chaos/quantum/__init__.py +38 -0
- physicskit/chaos/quantum/billiards.py +274 -0
- physicskit/chaos/quantum/husimi.py +85 -0
- physicskit/chaos/quantum/maps.py +366 -0
- physicskit/chaos/systems/__init__.py +38 -0
- physicskit/chaos/systems/billiards.py +1131 -0
- physicskit/chaos/systems/continuous.py +1276 -0
- physicskit/chaos/systems/maps.py +557 -0
- physicskit/chaos/tests/__init__.py +0 -0
- physicskit/chaos/tests/test_basins.py +76 -0
- physicskit/chaos/tests/test_bifurcation.py +132 -0
- physicskit/chaos/tests/test_billiards.py +115 -0
- physicskit/chaos/tests/test_continuous.py +224 -0
- physicskit/chaos/tests/test_dimension.py +69 -0
- physicskit/chaos/tests/test_divergence.py +90 -0
- physicskit/chaos/tests/test_dynamic_plots.py +269 -0
- physicskit/chaos/tests/test_integrators.py +96 -0
- physicskit/chaos/tests/test_io.py +41 -0
- physicskit/chaos/tests/test_maps.py +110 -0
- physicskit/chaos/tests/test_metrics.py +115 -0
- physicskit/chaos/tests/test_phase_space.py +73 -0
- physicskit/chaos/tests/test_properties.py +116 -0
- physicskit/chaos/tests/test_quantum_billiards.py +94 -0
- physicskit/chaos/tests/test_quantum_maps.py +144 -0
- physicskit/chaos/tests/test_recurrence.py +51 -0
- physicskit/chaos/tests/test_repr_and_api_consistency.py +134 -0
- physicskit/chaos/tests/test_section.py +49 -0
- physicskit/chaos/tests/test_spectral.py +48 -0
- physicskit/chaos/tests/test_streamlit_app.py +45 -0
- physicskit/chaos/tests/test_timeseries.py +131 -0
- physicskit/chaos/tests/test_viewer3d.py +41 -0
- physicskit/chaos/utils/__init__.py +46 -0
- physicskit/chaos/utils/dimension.py +139 -0
- physicskit/chaos/utils/io.py +95 -0
- physicskit/chaos/utils/metrics.py +304 -0
- physicskit/chaos/utils/recurrence.py +122 -0
- physicskit/chaos/utils/spectral.py +69 -0
- physicskit/chaos/utils/timeseries.py +303 -0
- physicskit/chaos/visualizers/__init__.py +85 -0
- physicskit/chaos/visualizers/basins.py +185 -0
- physicskit/chaos/visualizers/bifurcation.py +273 -0
- physicskit/chaos/visualizers/divergence.py +374 -0
- physicskit/chaos/visualizers/dynamic_plots.py +1372 -0
- physicskit/chaos/visualizers/phase_space.py +133 -0
- physicskit/chaos/visualizers/quantum.py +299 -0
- physicskit/chaos/visualizers/recurrence.py +91 -0
- physicskit/chaos/visualizers/section.py +161 -0
- physicskit/chaos/visualizers/theme.py +31 -0
- physicskit/chaos/visualizers/viewer3d.py +82 -0
- physicskit/classical/__init__.py +55 -0
- physicskit/classical/core/__init__.py +17 -0
- physicskit/classical/core/base_system.py +510 -0
- physicskit/classical/core/integrators.py +397 -0
- physicskit/classical/systems/__init__.py +32 -0
- physicskit/classical/systems/chains.py +334 -0
- physicskit/classical/systems/hamiltonian.py +215 -0
- physicskit/classical/systems/lagrangian.py +308 -0
- physicskit/classical/systems/newtonian.py +536 -0
- physicskit/classical/systems/rotations.py +614 -0
- physicskit/classical/tests/__init__.py +0 -0
- physicskit/classical/tests/conftest.py +7 -0
- physicskit/classical/tests/test_base_system.py +113 -0
- physicskit/classical/tests/test_chains.py +84 -0
- physicskit/classical/tests/test_conservation.py +244 -0
- physicskit/classical/tests/test_conservation_utils.py +47 -0
- physicskit/classical/tests/test_hamiltonian.py +44 -0
- physicskit/classical/tests/test_integrators.py +123 -0
- physicskit/classical/tests/test_lagrangian.py +69 -0
- physicskit/classical/tests/test_newtonian.py +45 -0
- physicskit/classical/tests/test_rotations.py +160 -0
- physicskit/classical/tests/test_stepsize.py +149 -0
- physicskit/classical/tests/test_symbolic.py +125 -0
- physicskit/classical/tests/test_visualizers.py +172 -0
- physicskit/classical/utils/__init__.py +20 -0
- physicskit/classical/utils/conservation.py +126 -0
- physicskit/classical/utils/stepsize.py +187 -0
- physicskit/classical/utils/symbolic.py +235 -0
- physicskit/classical/visualizers/__init__.py +25 -0
- physicskit/classical/visualizers/animations.py +508 -0
- physicskit/classical/visualizers/interactive.py +113 -0
- physicskit/classical/visualizers/modal_analysis.py +97 -0
- physicskit/classical/visualizers/phase_space.py +214 -0
- physicskit/condensed/__init__.py +122 -0
- physicskit/condensed/anderson_localization.py +155 -0
- physicskit/condensed/correlated.py +284 -0
- physicskit/condensed/ginzburg_landau.py +220 -0
- physicskit/condensed/landau_levels.py +246 -0
- physicskit/condensed/laughlin.py +229 -0
- physicskit/condensed/models.py +627 -0
- physicskit/condensed/tests/__init__.py +0 -0
- physicskit/condensed/tests/test_condensed.py +518 -0
- physicskit/condensed/tests/test_visualizers.py +87 -0
- physicskit/condensed/tight_binding.py +445 -0
- physicskit/condensed/topological_insulator_3d.py +178 -0
- physicskit/condensed/topology.py +217 -0
- physicskit/condensed/visualizers.py +296 -0
- physicskit/condensed/weyl.py +180 -0
- physicskit/constants.py +184 -0
- physicskit/fields/__init__.py +111 -0
- physicskit/fields/electrodynamics.py +671 -0
- physicskit/fields/quantum_fields.py +510 -0
- physicskit/fields/solitons.py +527 -0
- physicskit/fields/tests/__init__.py +0 -0
- physicskit/fields/tests/conftest.py +7 -0
- physicskit/fields/tests/test_field_animations.py +154 -0
- physicskit/fields/tests/test_fields.py +439 -0
- physicskit/fields/tests/test_visualizers.py +101 -0
- physicskit/fields/visualizers.py +503 -0
- physicskit/fluids/__init__.py +134 -0
- physicskit/fluids/core/__init__.py +23 -0
- physicskit/fluids/core/grid.py +165 -0
- physicskit/fluids/core/timestepping.py +231 -0
- physicskit/fluids/exceptions.py +26 -0
- physicskit/fluids/systems/__init__.py +70 -0
- physicskit/fluids/systems/compressible_flow.py +281 -0
- physicskit/fluids/systems/instabilities.py +343 -0
- physicskit/fluids/systems/navier_stokes.py +221 -0
- physicskit/fluids/systems/potential_flow.py +440 -0
- physicskit/fluids/systems/viscous_flow.py +425 -0
- physicskit/fluids/systems/vortex_dynamics.py +304 -0
- physicskit/fluids/tests/__init__.py +0 -0
- physicskit/fluids/tests/conftest.py +7 -0
- physicskit/fluids/tests/test_compressible_flow.py +66 -0
- physicskit/fluids/tests/test_instabilities.py +115 -0
- physicskit/fluids/tests/test_navier_stokes.py +67 -0
- physicskit/fluids/tests/test_potential_flow.py +92 -0
- physicskit/fluids/tests/test_static_visualizers.py +91 -0
- physicskit/fluids/tests/test_utils.py +100 -0
- physicskit/fluids/tests/test_viscous_flow.py +110 -0
- physicskit/fluids/tests/test_visualizers.py +34 -0
- physicskit/fluids/tests/test_vortex_dynamics.py +88 -0
- physicskit/fluids/utils/__init__.py +18 -0
- physicskit/fluids/utils/dimensionless.py +239 -0
- physicskit/fluids/utils/spectral_analysis.py +142 -0
- physicskit/fluids/visualizers/__init__.py +14 -0
- physicskit/fluids/visualizers/compressible.py +39 -0
- physicskit/fluids/visualizers/flow_fields.py +252 -0
- physicskit/fluids/visualizers/potential_flow.py +51 -0
- physicskit/fluids/visualizers/spectra.py +62 -0
- physicskit/fluids/visualizers/theme.py +38 -0
- physicskit/integrators/__init__.py +52 -0
- physicskit/integrators/adaptive.py +199 -0
- physicskit/integrators/fixed_step.py +360 -0
- physicskit/integrators/tests/__init__.py +0 -0
- physicskit/integrators/tests/test_integrators.py +101 -0
- physicskit/optics/__init__.py +124 -0
- physicskit/optics/_compat.py +5 -0
- physicskit/optics/gaussian.py +382 -0
- physicskit/optics/quantum_optics.py +428 -0
- physicskit/optics/ray.py +469 -0
- physicskit/optics/tests/__init__.py +0 -0
- physicskit/optics/tests/test_diffraction_animation.py +38 -0
- physicskit/optics/tests/test_gaussian.py +170 -0
- physicskit/optics/tests/test_quantum_optics.py +147 -0
- physicskit/optics/tests/test_ray.py +177 -0
- physicskit/optics/tests/test_visualizers.py +58 -0
- physicskit/optics/tests/test_wave.py +146 -0
- physicskit/optics/visualizers.py +264 -0
- physicskit/optics/wave.py +365 -0
- physicskit/particle/__init__.py +152 -0
- physicskit/particle/collider.py +382 -0
- physicskit/particle/confinement.py +125 -0
- physicskit/particle/decays.py +357 -0
- physicskit/particle/electroweak.py +300 -0
- physicskit/particle/kinematics.py +271 -0
- physicskit/particle/neutrinos.py +84 -0
- physicskit/particle/nuclear.py +100 -0
- physicskit/particle/scattering.py +159 -0
- physicskit/particle/tests/__init__.py +0 -0
- physicskit/particle/tests/conftest.py +7 -0
- physicskit/particle/tests/test_collider.py +119 -0
- physicskit/particle/tests/test_confinement.py +42 -0
- physicskit/particle/tests/test_decays.py +112 -0
- physicskit/particle/tests/test_electroweak.py +97 -0
- physicskit/particle/tests/test_kinematics.py +138 -0
- physicskit/particle/tests/test_neutrinos.py +36 -0
- physicskit/particle/tests/test_nuclear.py +45 -0
- physicskit/particle/tests/test_scattering.py +64 -0
- physicskit/particle/tests/test_visualizers.py +214 -0
- physicskit/particle/visualizers/__init__.py +38 -0
- physicskit/particle/visualizers/animations.py +705 -0
- physicskit/particle/visualizers/static.py +101 -0
- physicskit/plasma/__init__.py +176 -0
- physicskit/plasma/acceleration.py +152 -0
- physicskit/plasma/instabilities.py +417 -0
- physicskit/plasma/kinetic.py +588 -0
- physicskit/plasma/mhd.py +463 -0
- physicskit/plasma/single_particle.py +562 -0
- physicskit/plasma/tests/__init__.py +0 -0
- physicskit/plasma/tests/conftest.py +7 -0
- physicskit/plasma/tests/test_new_time_domain_features.py +222 -0
- physicskit/plasma/tests/test_plasma.py +232 -0
- physicskit/plasma/tests/test_visualizers.py +79 -0
- physicskit/plasma/turbulence.py +219 -0
- physicskit/plasma/visualizers.py +868 -0
- physicskit/plasma/waves.py +549 -0
- physicskit/quantum/__init__.py +180 -0
- physicskit/quantum/_compat.py +20 -0
- physicskit/quantum/chapters/__init__.py +0 -0
- physicskit/quantum/chapters/entanglement.py +489 -0
- physicskit/quantum/chapters/harmonic_spin.py +517 -0
- physicskit/quantum/chapters/hydrogen_am.py +292 -0
- physicskit/quantum/chapters/perturbation.py +350 -0
- physicskit/quantum/chapters/potentials.py +997 -0
- physicskit/quantum/chapters/spin.py +306 -0
- physicskit/quantum/chapters/wave_packets.py +541 -0
- physicskit/quantum/core/__init__.py +0 -0
- physicskit/quantum/core/eigensolvers.py +311 -0
- physicskit/quantum/core/operators.py +296 -0
- physicskit/quantum/core/solvers.py +271 -0
- physicskit/quantum/tests/__init__.py +0 -0
- physicskit/quantum/tests/conftest.py +7 -0
- physicskit/quantum/tests/test_animations.py +225 -0
- physicskit/quantum/tests/test_compat.py +43 -0
- physicskit/quantum/tests/test_eigensolvers.py +24 -0
- physicskit/quantum/tests/test_entanglement.py +127 -0
- physicskit/quantum/tests/test_harmonic_spin.py +140 -0
- physicskit/quantum/tests/test_hydrogen_am.py +48 -0
- physicskit/quantum/tests/test_measure.py +110 -0
- physicskit/quantum/tests/test_operators.py +105 -0
- physicskit/quantum/tests/test_perturbation.py +112 -0
- physicskit/quantum/tests/test_physics_checks.py +131 -0
- physicskit/quantum/tests/test_potentials.py +191 -0
- physicskit/quantum/tests/test_solvers.py +70 -0
- physicskit/quantum/tests/test_spin.py +22 -0
- physicskit/quantum/tests/test_unitarity.py +84 -0
- physicskit/quantum/tests/test_wave_packets.py +53 -0
- physicskit/quantum/utils/__init__.py +0 -0
- physicskit/quantum/utils/measure.py +253 -0
- physicskit/quantum/visualizers/__init__.py +0 -0
- physicskit/quantum/visualizers/bloch_sphere.py +205 -0
- physicskit/quantum/visualizers/entanglement.py +58 -0
- physicskit/quantum/visualizers/orbitals.py +187 -0
- physicskit/quantum/visualizers/phase_space.py +179 -0
- physicskit/quantum/visualizers/wavefunctions.py +230 -0
- physicskit/relativity/__init__.py +61 -0
- physicskit/relativity/chapters/__init__.py +33 -0
- physicskit/relativity/chapters/cosmology.py +190 -0
- physicskit/relativity/chapters/gw_merger.py +399 -0
- physicskit/relativity/chapters/kerr.py +371 -0
- physicskit/relativity/chapters/lensing.py +196 -0
- physicskit/relativity/chapters/neutron_star.py +149 -0
- physicskit/relativity/chapters/schwarzschild.py +412 -0
- physicskit/relativity/chapters/timekeeping.py +133 -0
- physicskit/relativity/core/__init__.py +12 -0
- physicskit/relativity/core/geodesics.py +216 -0
- physicskit/relativity/core/kerr_raytracer.py +259 -0
- physicskit/relativity/core/raytracer.py +241 -0
- physicskit/relativity/core/tensors.py +468 -0
- physicskit/relativity/tests/__init__.py +0 -0
- physicskit/relativity/tests/test_conservations.py +54 -0
- physicskit/relativity/tests/test_constants.py +34 -0
- physicskit/relativity/tests/test_cosmology.py +61 -0
- physicskit/relativity/tests/test_gw_merger.py +117 -0
- physicskit/relativity/tests/test_kerr.py +116 -0
- physicskit/relativity/tests/test_kerr_raytracer.py +103 -0
- physicskit/relativity/tests/test_lensing.py +75 -0
- physicskit/relativity/tests/test_neutron_star.py +48 -0
- physicskit/relativity/tests/test_raytracer.py +67 -0
- physicskit/relativity/tests/test_schwarzschild.py +126 -0
- physicskit/relativity/tests/test_shadow_render.py +81 -0
- physicskit/relativity/tests/test_tensors.py +86 -0
- physicskit/relativity/tests/test_timekeeping.py +51 -0
- physicskit/relativity/tests/test_visualizers_misc.py +115 -0
- physicskit/relativity/utils/__init__.py +1 -0
- physicskit/relativity/utils/constants.py +232 -0
- physicskit/relativity/visualizers/__init__.py +46 -0
- physicskit/relativity/visualizers/interactive.py +127 -0
- physicskit/relativity/visualizers/shadow_render.py +367 -0
- physicskit/relativity/visualizers/spacetime_3d.py +92 -0
- physicskit/relativity/visualizers/spacetime_diagrams.py +198 -0
- physicskit/relativity/visualizers/wave_plots.py +185 -0
- physicskit/rmt/__init__.py +8 -0
- physicskit/rmt/ensembles/__init__.py +108 -0
- physicskit/rmt/ensembles/banded.py +114 -0
- physicskit/rmt/ensembles/base.py +135 -0
- physicskit/rmt/ensembles/bdg.py +218 -0
- physicskit/rmt/ensembles/chiral.py +308 -0
- physicskit/rmt/ensembles/circular.py +104 -0
- physicskit/rmt/ensembles/crossover.py +82 -0
- physicskit/rmt/ensembles/density_matrix.py +148 -0
- physicskit/rmt/ensembles/effective_hamiltonian.py +230 -0
- physicskit/rmt/ensembles/embedded.py +207 -0
- physicskit/rmt/ensembles/gaussian.py +153 -0
- physicskit/rmt/ensembles/ginibre.py +110 -0
- physicskit/rmt/ensembles/girko.py +190 -0
- physicskit/rmt/ensembles/graph_laplacian.py +92 -0
- physicskit/rmt/ensembles/haar.py +57 -0
- physicskit/rmt/ensembles/jacobi.py +182 -0
- physicskit/rmt/ensembles/poisson.py +77 -0
- physicskit/rmt/ensembles/polynomial.py +139 -0
- physicskit/rmt/ensembles/pt_symmetric.py +120 -0
- physicskit/rmt/ensembles/single_ring.py +170 -0
- physicskit/rmt/ensembles/sparse.py +95 -0
- physicskit/rmt/ensembles/syk.py +170 -0
- physicskit/rmt/ensembles/truncated_unitary.py +80 -0
- physicskit/rmt/ensembles/universality.py +92 -0
- physicskit/rmt/ensembles/wishart.py +88 -0
- physicskit/rmt/py.typed +0 -0
- physicskit/rmt/spectrum.py +82 -0
- physicskit/rmt/stats/__init__.py +160 -0
- physicskit/rmt/stats/characteristic_polynomial.py +77 -0
- physicskit/rmt/stats/circular_law.py +54 -0
- physicskit/rmt/stats/correlations.py +162 -0
- physicskit/rmt/stats/density.py +70 -0
- physicskit/rmt/stats/entanglement.py +36 -0
- physicskit/rmt/stats/free_probability.py +202 -0
- physicskit/rmt/stats/localization.py +338 -0
- physicskit/rmt/stats/marchenko_pastur.py +55 -0
- physicskit/rmt/stats/pt_symmetric.py +265 -0
- physicskit/rmt/stats/ratios.py +110 -0
- physicskit/rmt/stats/real_ginibre.py +134 -0
- physicskit/rmt/stats/rigidity.py +272 -0
- physicskit/rmt/stats/single_ring.py +95 -0
- physicskit/rmt/stats/spacing.py +150 -0
- physicskit/rmt/stats/tracy_widom.py +175 -0
- physicskit/rmt/stats/truncated_unitary.py +40 -0
- physicskit/rmt/stats/unfolding.py +37 -0
- physicskit/rmt/stats/wachter.py +67 -0
- physicskit/rmt/tests/__init__.py +0 -0
- physicskit/rmt/tests/cache_utils.py +107 -0
- physicskit/rmt/tests/conftest.py +8 -0
- physicskit/rmt/tests/test_banded.py +86 -0
- physicskit/rmt/tests/test_base.py +29 -0
- physicskit/rmt/tests/test_bdg.py +133 -0
- physicskit/rmt/tests/test_characteristic_polynomial.py +50 -0
- physicskit/rmt/tests/test_chiral.py +273 -0
- physicskit/rmt/tests/test_circular.py +225 -0
- physicskit/rmt/tests/test_crossover.py +72 -0
- physicskit/rmt/tests/test_density.py +23 -0
- physicskit/rmt/tests/test_density_matrix.py +181 -0
- physicskit/rmt/tests/test_effective_hamiltonian.py +140 -0
- physicskit/rmt/tests/test_embedded.py +169 -0
- physicskit/rmt/tests/test_free_probability.py +81 -0
- physicskit/rmt/tests/test_gaussian_ensembles.py +22 -0
- physicskit/rmt/tests/test_gaussian_semicircle.py +127 -0
- physicskit/rmt/tests/test_ginibre_circular_law.py +131 -0
- physicskit/rmt/tests/test_girko.py +178 -0
- physicskit/rmt/tests/test_graph_laplacian.py +102 -0
- physicskit/rmt/tests/test_haar.py +118 -0
- physicskit/rmt/tests/test_jacobi_wachter.py +136 -0
- physicskit/rmt/tests/test_localization.py +240 -0
- physicskit/rmt/tests/test_poisson.py +149 -0
- physicskit/rmt/tests/test_polynomial.py +107 -0
- physicskit/rmt/tests/test_pt_symmetric.py +178 -0
- physicskit/rmt/tests/test_random_state.py +19 -0
- physicskit/rmt/tests/test_real_ginibre.py +112 -0
- physicskit/rmt/tests/test_rigidity_universality.py +167 -0
- physicskit/rmt/tests/test_single_ring.py +132 -0
- physicskit/rmt/tests/test_spacing_and_ratios.py +122 -0
- physicskit/rmt/tests/test_sparse.py +71 -0
- physicskit/rmt/tests/test_spectrum.py +27 -0
- physicskit/rmt/tests/test_syk.py +136 -0
- physicskit/rmt/tests/test_tracy_widom.py +113 -0
- physicskit/rmt/tests/test_tridiagonal.py +41 -0
- physicskit/rmt/tests/test_truncated_unitary.py +80 -0
- physicskit/rmt/tests/test_validation_base.py +25 -0
- physicskit/rmt/tests/test_validation_misc.py +67 -0
- physicskit/rmt/tests/test_wishart_marchenko_pastur.py +120 -0
- physicskit/rmt/utils/__init__.py +0 -0
- physicskit/rmt/utils/haar.py +128 -0
- physicskit/rmt/utils/random_state.py +24 -0
- physicskit/rmt/utils/tridiagonal.py +167 -0
- physicskit/rmt/validation/__init__.py +36 -0
- physicskit/rmt/validation/base.py +126 -0
- physicskit/rmt/validation/circular_law.py +80 -0
- physicskit/rmt/validation/marchenko_pastur.py +53 -0
- physicskit/rmt/validation/ratio_distribution.py +53 -0
- physicskit/rmt/validation/real_ginibre.py +60 -0
- physicskit/rmt/validation/sine_kernel.py +57 -0
- physicskit/rmt/validation/single_ring.py +68 -0
- physicskit/rmt/validation/tracy_widom.py +89 -0
- physicskit/rmt/validation/universality.py +100 -0
- physicskit/rmt/validation/wachter.py +52 -0
- physicskit/rmt/validation/wigner_semicircle.py +40 -0
- physicskit/rmt/validation/wigner_surmise.py +58 -0
- physicskit/semiclassical/__init__.py +94 -0
- physicskit/semiclassical/_compat.py +5 -0
- physicskit/semiclassical/core/__init__.py +41 -0
- physicskit/semiclassical/core/gutzwiller.py +215 -0
- physicskit/semiclassical/core/path_integral.py +594 -0
- physicskit/semiclassical/core/propagators.py +579 -0
- physicskit/semiclassical/core/wkb.py +308 -0
- physicskit/semiclassical/systems/__init__.py +13 -0
- physicskit/semiclassical/systems/scarring.py +278 -0
- physicskit/semiclassical/tests/__init__.py +0 -0
- physicskit/semiclassical/tests/test_gutzwiller.py +35 -0
- physicskit/semiclassical/tests/test_path_integral.py +194 -0
- physicskit/semiclassical/tests/test_propagators.py +82 -0
- physicskit/semiclassical/tests/test_scarring.py +43 -0
- physicskit/semiclassical/tests/test_visualizers.py +89 -0
- physicskit/semiclassical/tests/test_wkb.py +30 -0
- physicskit/semiclassical/visualizers/__init__.py +17 -0
- physicskit/semiclassical/visualizers/gutzwiller.py +55 -0
- physicskit/semiclassical/visualizers/path_integral.py +195 -0
- physicskit/semiclassical/visualizers/propagators.py +89 -0
- physicskit/semiclassical/visualizers/scarring.py +146 -0
- physicskit/semiclassical/visualizers/wkb.py +55 -0
- physicskit/statphys/__init__.py +80 -0
- physicskit/statphys/chapters/__init__.py +43 -0
- physicskit/statphys/chapters/ehrenfest_urn.py +112 -0
- physicskit/statphys/chapters/ising_lattice.py +431 -0
- physicskit/statphys/chapters/kpz_growth.py +129 -0
- physicskit/statphys/chapters/molecular_dynamics.py +258 -0
- physicskit/statphys/chapters/nonequilibrium_work.py +146 -0
- physicskit/statphys/chapters/percolation.py +305 -0
- physicskit/statphys/chapters/random_walk.py +142 -0
- physicskit/statphys/chapters/renormalization.py +148 -0
- physicskit/statphys/chapters/sandpile.py +109 -0
- physicskit/statphys/chapters/spin_glass.py +275 -0
- physicskit/statphys/core/__init__.py +10 -0
- physicskit/statphys/core/kpz_engine.py +53 -0
- physicskit/statphys/core/md_engine.py +157 -0
- physicskit/statphys/core/monte_carlo.py +462 -0
- physicskit/statphys/core/random_walk_engine.py +68 -0
- physicskit/statphys/core/sandpile_engine.py +52 -0
- physicskit/statphys/tests/__init__.py +0 -0
- physicskit/statphys/tests/test_dynamics.py +66 -0
- physicskit/statphys/tests/test_ehrenfest_urn.py +44 -0
- physicskit/statphys/tests/test_finite_size_scaling.py +62 -0
- physicskit/statphys/tests/test_interactive.py +33 -0
- physicskit/statphys/tests/test_ising.py +68 -0
- physicskit/statphys/tests/test_kpz.py +55 -0
- physicskit/statphys/tests/test_landau_theory.py +49 -0
- physicskit/statphys/tests/test_md_engine.py +31 -0
- physicskit/statphys/tests/test_molecular_dynamics.py +72 -0
- physicskit/statphys/tests/test_nonequilibrium_work.py +33 -0
- physicskit/statphys/tests/test_partition_function.py +26 -0
- physicskit/statphys/tests/test_percolation.py +116 -0
- physicskit/statphys/tests/test_potts_model.py +46 -0
- physicskit/statphys/tests/test_random_walk.py +50 -0
- physicskit/statphys/tests/test_renormalization.py +44 -0
- physicskit/statphys/tests/test_sandpile.py +44 -0
- physicskit/statphys/tests/test_spin_glass.py +73 -0
- physicskit/statphys/tests/test_thermodynamics.py +121 -0
- physicskit/statphys/tests/test_xy_model.py +45 -0
- physicskit/statphys/utils/__init__.py +1 -0
- physicskit/statphys/utils/dynamics.py +100 -0
- physicskit/statphys/utils/finite_size_scaling.py +171 -0
- physicskit/statphys/utils/landau_theory.py +151 -0
- physicskit/statphys/utils/partition_function.py +109 -0
- physicskit/statphys/utils/thermodynamics.py +356 -0
- physicskit/statphys/visualizers/__init__.py +87 -0
- physicskit/statphys/visualizers/interactive.py +161 -0
- physicskit/statphys/visualizers/jarzynski_render.py +44 -0
- physicskit/statphys/visualizers/kpz_render.py +65 -0
- physicskit/statphys/visualizers/lattice_render.py +212 -0
- physicskit/statphys/visualizers/particle_render.py +121 -0
- physicskit/statphys/visualizers/random_walk_render.py +106 -0
- physicskit/statphys/visualizers/rg_render.py +45 -0
- physicskit/statphys/visualizers/sandpile_render.py +65 -0
- physicskit/statphys/visualizers/spin_glass_render.py +40 -0
- physicskit/statphys/visualizers/urn_render.py +38 -0
- physicskit/statphys/visualizers/vortex_render.py +84 -0
- physicskit/tests/__init__.py +0 -0
- physicskit/tests/test_constants.py +38 -0
- physicskit-0.1.0.dist-info/METADATA +196 -0
- physicskit-0.1.0.dist-info/RECORD +484 -0
- physicskit-0.1.0.dist-info/WHEEL +5 -0
- physicskit-0.1.0.dist-info/licenses/LICENSE +21 -0
- physicskit-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pytest
|
|
3
|
+
|
|
4
|
+
from physicskit.statphys.chapters.renormalization import BlockSpinRG
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_iterate_shrinks_grid_by_half_each_step():
|
|
8
|
+
rg = BlockSpinRG(L=16, T=100.0, seed=0, n_equil_sweeps=5)
|
|
9
|
+
grids = rg.iterate(n_steps=3)
|
|
10
|
+
assert [g.shape[0] for g in grids] == [16, 8, 4, 2]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_default_n_steps_stops_at_2x2():
|
|
14
|
+
rg = BlockSpinRG(L=16, T=100.0, seed=0, n_equil_sweeps=5)
|
|
15
|
+
grids = rg.iterate()
|
|
16
|
+
assert grids[-1].shape == (2, 2)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_high_temperature_flows_toward_disorder():
|
|
20
|
+
rg = BlockSpinRG(L=32, T=1000.0, seed=1, n_equil_sweeps=5)
|
|
21
|
+
grids = rg.iterate(n_steps=4)
|
|
22
|
+
orders = [rg.order_parameter(g) for g in grids]
|
|
23
|
+
# disordered starting point: order parameter should stay small throughout
|
|
24
|
+
assert orders[0] < 0.3
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_low_temperature_flows_toward_order():
|
|
28
|
+
rg = BlockSpinRG(L=32, T=0.5, seed=2, n_equil_sweeps=200)
|
|
29
|
+
grids = rg.iterate(n_steps=3)
|
|
30
|
+
orders = [rg.order_parameter(g) for g in grids]
|
|
31
|
+
assert orders[-1] > 0.8
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_coarse_grain_step_requires_even_size():
|
|
35
|
+
rg = BlockSpinRG(L=16, T=100.0, seed=0, n_equil_sweeps=1)
|
|
36
|
+
with pytest.raises(ValueError):
|
|
37
|
+
rg.coarse_grain_step(np.ones((5, 5), dtype=np.int64))
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_majority_rule_unanimous_block():
|
|
41
|
+
rg = BlockSpinRG(L=8, T=100.0, seed=3, n_equil_sweeps=1)
|
|
42
|
+
block = np.ones((4, 4), dtype=np.int64)
|
|
43
|
+
coarse = rg.coarse_grain_step(block)
|
|
44
|
+
assert np.all(coarse == 1)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from physicskit.statphys.chapters.sandpile import BTWSandpile
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_initial_heights_are_zero():
|
|
7
|
+
pile = BTWSandpile(L=10, seed=0)
|
|
8
|
+
assert np.all(pile.heights == 0)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_heights_stay_below_threshold_after_relaxation():
|
|
12
|
+
pile = BTWSandpile(L=16, seed=1)
|
|
13
|
+
pile.run(n_grains=500)
|
|
14
|
+
assert np.all(pile.heights < pile.threshold)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_avalanche_sizes_are_non_negative():
|
|
18
|
+
pile = BTWSandpile(L=16, seed=2)
|
|
19
|
+
sizes = pile.run(n_grains=200)
|
|
20
|
+
assert np.all(sizes >= 0)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_add_grain_at_specific_site_below_threshold():
|
|
24
|
+
pile = BTWSandpile(L=10, threshold=4, seed=3)
|
|
25
|
+
size = pile.add_grain(site=(5, 5))
|
|
26
|
+
assert size == 0
|
|
27
|
+
assert pile.heights[5, 5] == 1
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_forced_toppling_conserves_grains_in_bulk():
|
|
31
|
+
pile = BTWSandpile(L=20, threshold=4, seed=4)
|
|
32
|
+
pile.heights[10, 10] = 3
|
|
33
|
+
grains_before = pile.total_grains()
|
|
34
|
+
size = pile.add_grain(site=(10, 10))
|
|
35
|
+
assert size == 1
|
|
36
|
+
# a single interior toppling conserves grains (4 out, 4 in); only the
|
|
37
|
+
# one added grain changes the total.
|
|
38
|
+
assert pile.total_grains() == grains_before + 1
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_large_run_produces_nontrivial_avalanches():
|
|
42
|
+
pile = BTWSandpile(L=24, seed=5)
|
|
43
|
+
sizes = pile.run(n_grains=2000, warmup=1000)
|
|
44
|
+
assert sizes.max() > 1
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pytest
|
|
3
|
+
|
|
4
|
+
from physicskit.statphys.chapters.spin_glass import EdwardsAndersonSpinGlass2D, SherringtonKirkpatrick
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_bonds_are_bimodal():
|
|
8
|
+
model = EdwardsAndersonSpinGlass2D(L=10, J=1.0, seed=0)
|
|
9
|
+
assert set(np.unique(model.J_right)) <= {-1.0, 1.0}
|
|
10
|
+
assert set(np.unique(model.J_down)) <= {-1.0, 1.0}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_frustration_density_between_zero_and_one():
|
|
14
|
+
model = EdwardsAndersonSpinGlass2D(L=20, seed=1)
|
|
15
|
+
f = model.frustration_density()
|
|
16
|
+
assert 0.0 <= f <= 1.0
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_frustration_density_near_one_half_for_random_bonds():
|
|
20
|
+
model = EdwardsAndersonSpinGlass2D(L=40, seed=2)
|
|
21
|
+
assert model.frustration_density() == pytest.approx(0.5, abs=0.05)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_ferromagnet_has_zero_frustration():
|
|
25
|
+
model = EdwardsAndersonSpinGlass2D(L=10, seed=3)
|
|
26
|
+
model.J_right[:] = 1.0
|
|
27
|
+
model.J_down[:] = 1.0
|
|
28
|
+
assert model.frustration_density() == pytest.approx(0.0)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_sweep_changes_configuration():
|
|
32
|
+
model = EdwardsAndersonSpinGlass2D(L=16, seed=4)
|
|
33
|
+
before = model.spins.copy()
|
|
34
|
+
model.sweep(beta=1.0, n_sweeps=5)
|
|
35
|
+
assert not np.array_equal(before, model.spins)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_energy_is_finite():
|
|
39
|
+
model = EdwardsAndersonSpinGlass2D(L=12, seed=5)
|
|
40
|
+
model.sweep(beta=1.0, n_sweeps=10)
|
|
41
|
+
assert np.isfinite(model.energy())
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_ea_order_parameter_bounds():
|
|
45
|
+
model = EdwardsAndersonSpinGlass2D(L=8, seed=6)
|
|
46
|
+
q2 = model.edwards_anderson_order_parameter(beta=2.0, n_equil=20, n_measure=20)
|
|
47
|
+
assert 0.0 <= q2 <= 1.0 + 1e-9
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_sk_coupling_matrix_is_symmetric_with_zero_diagonal():
|
|
51
|
+
model = SherringtonKirkpatrick(N=30, seed=0)
|
|
52
|
+
assert np.allclose(model.J, model.J.T)
|
|
53
|
+
assert np.all(np.diag(model.J) == 0.0)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_sk_sweep_changes_configuration():
|
|
57
|
+
model = SherringtonKirkpatrick(N=40, seed=1)
|
|
58
|
+
before = model.spins.copy()
|
|
59
|
+
model.sweep(beta=1.0, n_sweeps=5)
|
|
60
|
+
assert not np.array_equal(before, model.spins)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_sk_energy_is_finite():
|
|
64
|
+
model = SherringtonKirkpatrick(N=30, seed=2)
|
|
65
|
+
model.sweep(beta=1.0, n_sweeps=5)
|
|
66
|
+
assert np.isfinite(model.energy())
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_sk_overlap_distribution_shape_and_bounds():
|
|
70
|
+
model = SherringtonKirkpatrick(N=20, seed=3)
|
|
71
|
+
samples = model.overlap_distribution(beta=1.5, n_disorder=4, n_equil=10, n_measure=5)
|
|
72
|
+
assert samples.shape == (20,)
|
|
73
|
+
assert np.all(samples >= -1.0 - 1e-9) and np.all(samples <= 1.0 + 1e-9)
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pytest
|
|
3
|
+
from scipy.integrate import trapezoid
|
|
4
|
+
|
|
5
|
+
from physicskit.statphys.utils.thermodynamics import (
|
|
6
|
+
bec_condensate_fraction,
|
|
7
|
+
binder_cumulant,
|
|
8
|
+
bose_einstein_occupation,
|
|
9
|
+
fermi_dirac_occupation,
|
|
10
|
+
maxwell_boltzmann_component_pdf,
|
|
11
|
+
maxwell_boltzmann_speed_pdf,
|
|
12
|
+
specific_heat,
|
|
13
|
+
spin_correlation_function,
|
|
14
|
+
susceptibility,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_specific_heat_zero_for_constant_energy():
|
|
19
|
+
E = np.full(1000, -50.0)
|
|
20
|
+
assert specific_heat(E, temperature=2.0, n_sites=64) == pytest.approx(0.0)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_specific_heat_positive_for_fluctuating_energy():
|
|
24
|
+
rng = np.random.default_rng(0)
|
|
25
|
+
E = rng.normal(-100.0, 5.0, size=5000)
|
|
26
|
+
assert specific_heat(E, temperature=2.0, n_sites=64) > 0
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_susceptibility_scales_with_variance():
|
|
30
|
+
rng = np.random.default_rng(1)
|
|
31
|
+
M_low = rng.normal(0.0, 1.0, size=5000)
|
|
32
|
+
M_high = rng.normal(0.0, 5.0, size=5000)
|
|
33
|
+
assert susceptibility(M_high, 1.0, 64) > susceptibility(M_low, 1.0, 64)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_binder_cumulant_gaussian_limit():
|
|
37
|
+
rng = np.random.default_rng(2)
|
|
38
|
+
m = rng.normal(0.0, 1.0, size=200_000)
|
|
39
|
+
# for a zero-mean Gaussian, <m^4>/<m^2>^2 = 3, so U4 -> 0
|
|
40
|
+
assert binder_cumulant(m) == pytest.approx(0.0, abs=0.05)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_binder_cumulant_delta_distribution():
|
|
44
|
+
m = np.full(1000, 2.5)
|
|
45
|
+
assert binder_cumulant(m) == pytest.approx(2.0 / 3.0)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_spin_correlation_function_zero_lag_equals_variance():
|
|
49
|
+
rng = np.random.default_rng(3)
|
|
50
|
+
spins = rng.choice([-1, 1], size=(20, 20))
|
|
51
|
+
r, G = spin_correlation_function(spins)
|
|
52
|
+
assert r[0] == 0
|
|
53
|
+
assert G[0] == pytest.approx(1.0 - spins.mean() ** 2, abs=1e-9)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_maxwell_boltzmann_speed_pdf_normalizes_to_one():
|
|
57
|
+
v = np.linspace(0, 20, 200_000)
|
|
58
|
+
pdf = maxwell_boltzmann_speed_pdf(v, temperature=2.0, mass=1.0, dim=2)
|
|
59
|
+
integral = trapezoid(pdf, v)
|
|
60
|
+
assert integral == pytest.approx(1.0, abs=1e-3)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_maxwell_boltzmann_speed_pdf_invalid_dim_raises():
|
|
64
|
+
with pytest.raises(ValueError):
|
|
65
|
+
maxwell_boltzmann_speed_pdf(np.array([1.0]), temperature=1.0, dim=4)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@pytest.mark.parametrize("dim", [1, 3])
|
|
69
|
+
def test_maxwell_boltzmann_speed_pdf_normalizes_to_one_in_1d_and_3d(dim):
|
|
70
|
+
v = np.linspace(0, 20, 200_000)
|
|
71
|
+
pdf = maxwell_boltzmann_speed_pdf(v, temperature=2.0, mass=1.0, dim=dim)
|
|
72
|
+
integral = trapezoid(pdf, v)
|
|
73
|
+
assert integral == pytest.approx(1.0, abs=1e-3)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_maxwell_boltzmann_component_pdf_is_gaussian():
|
|
77
|
+
vx = np.linspace(-10, 10, 200_000)
|
|
78
|
+
pdf = maxwell_boltzmann_component_pdf(vx, temperature=1.5, mass=1.0)
|
|
79
|
+
integral = trapezoid(pdf, vx)
|
|
80
|
+
assert integral == pytest.approx(1.0, abs=1e-3)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_bose_einstein_occupation_diverges_near_ground_state():
|
|
84
|
+
n_close = bose_einstein_occupation(1.001, mu=1.0, temperature=1.0)
|
|
85
|
+
n_far = bose_einstein_occupation(5.0, mu=1.0, temperature=1.0)
|
|
86
|
+
assert n_close > n_far > 0
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_fermi_dirac_occupation_bounded_between_zero_and_one():
|
|
90
|
+
energies = np.linspace(-5, 5, 50)
|
|
91
|
+
n = fermi_dirac_occupation(energies, mu=0.0, temperature=1.0)
|
|
92
|
+
assert np.all(n > 0.0) and np.all(n < 1.0)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_fermi_dirac_occupation_step_function_at_zero_temperature():
|
|
96
|
+
# small enough to sharpen into a step, large enough that exp(x) doesn't overflow
|
|
97
|
+
n_below = fermi_dirac_occupation(-1.0, mu=0.0, temperature=0.05)
|
|
98
|
+
n_above = fermi_dirac_occupation(1.0, mu=0.0, temperature=0.05)
|
|
99
|
+
assert n_below == pytest.approx(1.0, abs=1e-6)
|
|
100
|
+
assert n_above == pytest.approx(0.0, abs=1e-6)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_fermi_dirac_occupation_half_at_the_fermi_energy():
|
|
104
|
+
n = fermi_dirac_occupation(2.0, mu=2.0, temperature=1.0)
|
|
105
|
+
assert n == pytest.approx(0.5)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_bec_condensate_fraction_full_at_zero_temperature():
|
|
109
|
+
f = bec_condensate_fraction(0.0, critical_temperature=1.0)
|
|
110
|
+
assert float(f) == pytest.approx(1.0)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def test_bec_condensate_fraction_zero_above_tc():
|
|
114
|
+
f = bec_condensate_fraction(2.0, critical_temperature=1.0)
|
|
115
|
+
assert float(f) == pytest.approx(0.0)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def test_bec_condensate_fraction_monotonically_decreasing():
|
|
119
|
+
T = np.linspace(0.0, 1.5, 20)
|
|
120
|
+
f = bec_condensate_fraction(T, critical_temperature=1.0)
|
|
121
|
+
assert np.all(np.diff(f) <= 1e-12)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from physicskit.statphys.chapters.ising_lattice import XYModel2D
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_theta_in_valid_range():
|
|
7
|
+
model = XYModel2D(L=12, seed=0)
|
|
8
|
+
assert np.all(model.theta >= 0.0)
|
|
9
|
+
assert np.all(model.theta < 2.0 * np.pi)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_sweep_keeps_theta_in_range():
|
|
13
|
+
model = XYModel2D(L=12, seed=1)
|
|
14
|
+
model.sweep(beta=1.0, n_sweeps=10)
|
|
15
|
+
assert np.all(model.theta >= 0.0)
|
|
16
|
+
assert np.all(model.theta < 2.0 * np.pi)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_kt_temperature_is_positive_and_reasonable():
|
|
20
|
+
model = XYModel2D(J=1.0, kB=1.0)
|
|
21
|
+
assert 0.5 < model.T_KT < 1.5
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_uniform_configuration_has_zero_vorticity():
|
|
25
|
+
model = XYModel2D(L=10, seed=2)
|
|
26
|
+
model.theta[:] = 0.0
|
|
27
|
+
q = model.vorticity()
|
|
28
|
+
assert np.allclose(q, 0.0, atol=1e-9)
|
|
29
|
+
n_v, n_av = model.vortex_count()
|
|
30
|
+
assert n_v == 0 and n_av == 0
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_low_temperature_has_small_ordered_magnetization():
|
|
34
|
+
model = XYModel2D(L=14, seed=3)
|
|
35
|
+
model.theta[:] = model._rng.uniform(-0.05, 0.05, size=model.theta.shape) % (2 * np.pi)
|
|
36
|
+
model.sweep(beta=10.0, n_sweeps=30)
|
|
37
|
+
mag = model.magnetization_vector()
|
|
38
|
+
norm = np.linalg.norm(mag) / model.n_sites
|
|
39
|
+
assert norm > 0.5 # strongly aligned spins retain a large net moment
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_energy_is_finite():
|
|
43
|
+
model = XYModel2D(L=10, seed=4)
|
|
44
|
+
model.sweep(beta=1.0, n_sweeps=5)
|
|
45
|
+
assert np.isfinite(model.energy())
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Thermodynamic observables computed from simulation trajectories."""
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""Dynamical diagnostics for Monte Carlo time series: autocorrelation and critical slowing down.
|
|
2
|
+
|
|
3
|
+
Near a continuous phase transition, successive Monte Carlo configurations
|
|
4
|
+
become strongly correlated in (simulation) time -- "critical slowing down"
|
|
5
|
+
-- so that naively spaced samples are not statistically independent. The
|
|
6
|
+
integrated autocorrelation time quantifies exactly how many sweeps separate
|
|
7
|
+
effectively independent samples, and comparing it between update algorithms
|
|
8
|
+
(e.g. single-spin-flip Metropolis versus the Wolff cluster algorithm) is the
|
|
9
|
+
standard way to demonstrate why cluster algorithms were invented.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
|
|
16
|
+
__all__ = ["autocorrelation_function", "integrated_autocorrelation_time"]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def autocorrelation_function(series, max_lag=None):
|
|
20
|
+
"""Normalized autocorrelation function of a scalar Monte Carlo time series.
|
|
21
|
+
|
|
22
|
+
.. math::
|
|
23
|
+
|
|
24
|
+
\\rho(t) = \\frac{\\langle (x_i - \\bar x)(x_{i+t} - \\bar x) \\rangle}{\\mathrm{Var}(x)}
|
|
25
|
+
|
|
26
|
+
computed efficiently via the FFT (Wiener-Khinchin theorem).
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
series : array_like
|
|
31
|
+
A scalar observable sampled at successive Monte Carlo sweeps (e.g.
|
|
32
|
+
magnetization or energy).
|
|
33
|
+
max_lag : int, optional
|
|
34
|
+
Largest lag to return. Defaults to ``len(series) // 2``.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
ndarray
|
|
39
|
+
:math:`\\rho(t)` for :math:`t = 0, 1, \\ldots,` ``max_lag``, with
|
|
40
|
+
:math:`\\rho(0) = 1`.
|
|
41
|
+
"""
|
|
42
|
+
x = np.asarray(series, dtype=np.float64)
|
|
43
|
+
x = x - x.mean()
|
|
44
|
+
n = len(x)
|
|
45
|
+
if max_lag is None:
|
|
46
|
+
max_lag = n // 2
|
|
47
|
+
|
|
48
|
+
padded = np.zeros(2 * n)
|
|
49
|
+
padded[:n] = x
|
|
50
|
+
fft = np.fft.fft(padded)
|
|
51
|
+
autocorr = np.fft.ifft(fft * np.conj(fft)).real[:n]
|
|
52
|
+
autocorr /= np.arange(n, 0, -1)
|
|
53
|
+
return autocorr[: max_lag + 1] / autocorr[0]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def integrated_autocorrelation_time(series, c=5.0, max_lag=None):
|
|
57
|
+
"""Estimate the integrated autocorrelation time via Sokal's automatic windowing.
|
|
58
|
+
|
|
59
|
+
.. math::
|
|
60
|
+
|
|
61
|
+
\\tau_{\\text{int}}(M) = 1 + 2 \\sum_{t=1}^{M} \\rho(t)
|
|
62
|
+
|
|
63
|
+
The summation window :math:`M` is chosen automatically as the smallest
|
|
64
|
+
value satisfying :math:`M \\ge c \\, \\tau_{\\text{int}}(M)` (Sokal
|
|
65
|
+
1997), balancing statistical noise against truncation bias.
|
|
66
|
+
:math:`2\\tau_{\\text{int}}` gives (approximately) the number of Monte
|
|
67
|
+
Carlo sweeps needed between effectively independent samples -- the
|
|
68
|
+
standard quantitative measure of critical slowing down.
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
series : array_like
|
|
73
|
+
A scalar Monte Carlo observable time series.
|
|
74
|
+
c : float, default=5.0
|
|
75
|
+
Windowing constant (Sokal recommends 4-10; smaller is noisier,
|
|
76
|
+
larger is more biased).
|
|
77
|
+
max_lag : int, optional
|
|
78
|
+
Largest lag considered; defaults to ``len(series) // 2``.
|
|
79
|
+
|
|
80
|
+
Returns
|
|
81
|
+
-------
|
|
82
|
+
float
|
|
83
|
+
Estimated integrated autocorrelation time, in units of sweeps.
|
|
84
|
+
|
|
85
|
+
Examples
|
|
86
|
+
--------
|
|
87
|
+
>>> rng = np.random.default_rng(0)
|
|
88
|
+
>>> x = rng.normal(size=5000) # independent samples: tau ~ 0.5-1
|
|
89
|
+
>>> tau = integrated_autocorrelation_time(x)
|
|
90
|
+
>>> tau < 3.0
|
|
91
|
+
True
|
|
92
|
+
"""
|
|
93
|
+
rho = autocorrelation_function(series, max_lag=max_lag)
|
|
94
|
+
cumulative = 0.0
|
|
95
|
+
for M in range(1, len(rho)):
|
|
96
|
+
cumulative += rho[M]
|
|
97
|
+
tau = 1.0 + 2.0 * cumulative
|
|
98
|
+
if c * tau <= M:
|
|
99
|
+
return float(tau)
|
|
100
|
+
return float(1.0 + 2.0 * cumulative)
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""Finite-size scaling analysis: locating T_C and estimating critical exponents.
|
|
2
|
+
|
|
3
|
+
Monte Carlo simulations necessarily run on finite lattices, so an apparent
|
|
4
|
+
thermodynamic singularity is always rounded and shifted relative to its
|
|
5
|
+
infinite-volume value. Finite-size scaling theory predicts precisely how
|
|
6
|
+
observables at different lattice sizes :math:`L` relate near a continuous
|
|
7
|
+
phase transition, letting :math:`T_C` and the critical exponents be
|
|
8
|
+
extracted from a family of finite simulations without ever simulating an
|
|
9
|
+
infinite system.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"binder_cumulant_crossing",
|
|
18
|
+
"estimate_beta_over_nu",
|
|
19
|
+
"estimate_gamma_over_nu",
|
|
20
|
+
"estimate_nu_from_binder_slope",
|
|
21
|
+
"power_law_exponent",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def power_law_exponent(x, y):
|
|
26
|
+
"""Fit the exponent of an assumed power law :math:`y = A x^p` via log-log linear regression.
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
x, y : array_like
|
|
31
|
+
Positive-valued samples believed to follow a power law.
|
|
32
|
+
|
|
33
|
+
Returns
|
|
34
|
+
-------
|
|
35
|
+
exponent : float
|
|
36
|
+
The fitted exponent :math:`p`.
|
|
37
|
+
prefactor : float
|
|
38
|
+
The fitted prefactor :math:`A`.
|
|
39
|
+
|
|
40
|
+
Examples
|
|
41
|
+
--------
|
|
42
|
+
>>> x = np.array([1.0, 2.0, 4.0, 8.0, 16.0])
|
|
43
|
+
>>> y = 3.0 * x**1.5
|
|
44
|
+
>>> p, A = power_law_exponent(x, y)
|
|
45
|
+
>>> round(p, 6)
|
|
46
|
+
1.5
|
|
47
|
+
"""
|
|
48
|
+
x = np.asarray(x, dtype=np.float64)
|
|
49
|
+
y = np.asarray(y, dtype=np.float64)
|
|
50
|
+
p, log_A = np.polyfit(np.log(x), np.log(y), 1)
|
|
51
|
+
return float(p), float(np.exp(log_A))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def estimate_gamma_over_nu(L_values, chi_max_values):
|
|
55
|
+
"""Estimate :math:`\\gamma/\\nu` from the lattice-size scaling of the peak susceptibility.
|
|
56
|
+
|
|
57
|
+
Finite-size scaling predicts :math:`\\chi_{\\max}(L) \\sim L^{\\gamma/\\nu}`.
|
|
58
|
+
|
|
59
|
+
Parameters
|
|
60
|
+
----------
|
|
61
|
+
L_values : array_like
|
|
62
|
+
Lattice sizes.
|
|
63
|
+
chi_max_values : array_like
|
|
64
|
+
Peak susceptibility measured at each lattice size (e.g. the maximum
|
|
65
|
+
of the ``"chi"`` array returned by ``Ising2D.run_temperature_sweep``).
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
float
|
|
70
|
+
Estimated :math:`\\gamma / \\nu`.
|
|
71
|
+
"""
|
|
72
|
+
exponent, _ = power_law_exponent(L_values, chi_max_values)
|
|
73
|
+
return exponent
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def estimate_beta_over_nu(L_values, magnetization_at_tc_values):
|
|
77
|
+
"""Estimate :math:`\\beta/\\nu` from the lattice-size scaling of the order parameter at T_C.
|
|
78
|
+
|
|
79
|
+
Finite-size scaling predicts :math:`M(T_C, L) \\sim L^{-\\beta/\\nu}`.
|
|
80
|
+
|
|
81
|
+
Parameters
|
|
82
|
+
----------
|
|
83
|
+
L_values : array_like
|
|
84
|
+
Lattice sizes.
|
|
85
|
+
magnetization_at_tc_values : array_like
|
|
86
|
+
Order parameter measured at (approximately) :math:`T_C` for each
|
|
87
|
+
lattice size.
|
|
88
|
+
|
|
89
|
+
Returns
|
|
90
|
+
-------
|
|
91
|
+
float
|
|
92
|
+
Estimated :math:`\\beta / \\nu`.
|
|
93
|
+
"""
|
|
94
|
+
exponent, _ = power_law_exponent(L_values, magnetization_at_tc_values)
|
|
95
|
+
return -exponent
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def estimate_nu_from_binder_slope(L_values, T_grids, U4_grids, T_c):
|
|
99
|
+
"""Estimate the correlation-length exponent :math:`\\nu` from the Binder cumulant's slope at T_C.
|
|
100
|
+
|
|
101
|
+
Finite-size scaling predicts the Binder cumulant's temperature
|
|
102
|
+
derivative at criticality scales as
|
|
103
|
+
:math:`\\left.\\frac{dU_4}{dT}\\right|_{T_C} \\sim L^{1/\\nu}`. This
|
|
104
|
+
numerically differentiates each lattice size's :math:`U_4(T)` curve at
|
|
105
|
+
:math:`T_C` (a finite-difference slope between the two grid points
|
|
106
|
+
bracketing :math:`T_C`) and fits the resulting :math:`L`-scaling.
|
|
107
|
+
|
|
108
|
+
Parameters
|
|
109
|
+
----------
|
|
110
|
+
L_values : array_like
|
|
111
|
+
Lattice sizes.
|
|
112
|
+
T_grids : list of array_like
|
|
113
|
+
Temperature grid used at each lattice size (need not be identical
|
|
114
|
+
across sizes, but each must bracket ``T_c``).
|
|
115
|
+
U4_grids : list of array_like
|
|
116
|
+
Binder cumulant values on each temperature grid.
|
|
117
|
+
T_c : float
|
|
118
|
+
Critical temperature at which to evaluate the slope.
|
|
119
|
+
|
|
120
|
+
Returns
|
|
121
|
+
-------
|
|
122
|
+
float
|
|
123
|
+
Estimated :math:`\\nu`.
|
|
124
|
+
"""
|
|
125
|
+
slopes = []
|
|
126
|
+
for T, U4 in zip(T_grids, U4_grids):
|
|
127
|
+
T = np.asarray(T, dtype=np.float64)
|
|
128
|
+
U4 = np.asarray(U4, dtype=np.float64)
|
|
129
|
+
order = np.argsort(T)
|
|
130
|
+
T, U4 = T[order], U4[order]
|
|
131
|
+
idx = np.clip(np.searchsorted(T, T_c), 1, len(T) - 1)
|
|
132
|
+
slope = (U4[idx] - U4[idx - 1]) / (T[idx] - T[idx - 1])
|
|
133
|
+
slopes.append(abs(slope))
|
|
134
|
+
exponent, _ = power_law_exponent(L_values, slopes)
|
|
135
|
+
return 1.0 / exponent
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def binder_cumulant_crossing(T, U4_by_L):
|
|
139
|
+
"""Estimate T_C as the crossing point of the two largest lattice sizes' Binder cumulant curves.
|
|
140
|
+
|
|
141
|
+
Interpolates linearly between grid points to find where the two curves
|
|
142
|
+
cross -- the standard, finite-size-correction-robust way to locate a
|
|
143
|
+
continuous transition's critical temperature.
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
T : array_like
|
|
148
|
+
Common temperature grid shared by all lattice sizes.
|
|
149
|
+
U4_by_L : dict of int -> array_like
|
|
150
|
+
Binder cumulant values at each lattice size, evaluated on ``T``.
|
|
151
|
+
|
|
152
|
+
Returns
|
|
153
|
+
-------
|
|
154
|
+
float
|
|
155
|
+
Estimated crossing temperature.
|
|
156
|
+
|
|
157
|
+
Raises
|
|
158
|
+
------
|
|
159
|
+
ValueError
|
|
160
|
+
If the two largest lattice sizes' curves never cross on ``T``.
|
|
161
|
+
"""
|
|
162
|
+
L1, L2 = sorted(U4_by_L.keys())[-2:]
|
|
163
|
+
T = np.asarray(T, dtype=np.float64)
|
|
164
|
+
diff = np.asarray(U4_by_L[L1], dtype=np.float64) - np.asarray(U4_by_L[L2], dtype=np.float64)
|
|
165
|
+
sign_changes = np.where(np.diff(np.sign(diff)) != 0)[0]
|
|
166
|
+
if len(sign_changes) == 0:
|
|
167
|
+
raise ValueError("Binder cumulant curves for the two largest L do not cross on this grid")
|
|
168
|
+
i = sign_changes[0]
|
|
169
|
+
t0, t1 = T[i], T[i + 1]
|
|
170
|
+
d0, d1 = diff[i], diff[i + 1]
|
|
171
|
+
return float(t0 - d0 * (t1 - t0) / (d1 - d0))
|