{"id":17277629,"url":"https://github.com/cchandre/pyhamsys","last_synced_at":"2026-04-29T08:02:11.026Z","repository":{"id":151252855,"uuid":"624007459","full_name":"cchandre/pyhamsys","owner":"cchandre","description":"pyHamSys is a Python package for scientific computations involving Hamiltonian systems","archived":false,"fork":false,"pushed_at":"2026-02-04T16:56:26.000Z","size":399,"stargazers_count":12,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-04T23:41:25.041Z","etag":null,"topics":["hamiltonian","hamiltonian-dynamics","hamiltonian-systems","numpy","ode-solver","python3","symplectic-integration","symplectic-integrators"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cchandre.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-04-05T14:48:44.000Z","updated_at":"2026-02-04T16:56:29.000Z","dependencies_parsed_at":"2025-10-03T09:16:02.154Z","dependency_job_id":null,"html_url":"https://github.com/cchandre/pyhamsys","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cchandre/pyhamsys","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cchandre%2Fpyhamsys","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cchandre%2Fpyhamsys/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cchandre%2Fpyhamsys/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cchandre%2Fpyhamsys/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cchandre","download_url":"https://codeload.github.com/cchandre/pyhamsys/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cchandre%2Fpyhamsys/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32416146,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T06:29:02.080Z","status":"ssl_error","status_checked_at":"2026-04-29T06:29:00.631Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hamiltonian","hamiltonian-dynamics","hamiltonian-systems","numpy","ode-solver","python3","symplectic-integration","symplectic-integrators"],"created_at":"2024-10-15T09:09:32.804Z","updated_at":"2026-04-29T08:02:11.021Z","avatar_url":"https://github.com/cchandre.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pyHamSys\npyHamSys (short for Python Hamiltonian Systems) is an open-source Python library for scientific computing involving Hamiltonian systems. It provides tools to model, analyze, and simulate Hamiltonian systems. In particular, the library offers a streamlined and user-friendly environment for implementing and running symplectic-split integrators. These specialized numerical methods are designed to preserve the geometric structure of Hamiltonian systems, ensuring accurate and stable simulations of their dynamics over long time periods. \n\n![PyPI](https://img.shields.io/pypi/v/pyhamsys)\n![License](https://img.shields.io/badge/license-BSD-lightgray)\n[![SWH](https://archive.softwareheritage.org/badge/swh:1:dir:ee0bf7bb42dc8bba132eb67175cfb384be7c9f3d/)](https://archive.softwareheritage.org/swh:1:dir:ee0bf7bb42dc8bba132eb67175cfb384be7c9f3d;origin=https://github.com/cchandre/pyhamsys;visit=swh:1:snp:37db4c3c24cb9f94211881570756d4265235afe8;anchor=swh:1:rev:bcf5c7d9174d7401ec40b6abeb6d8fe689fca26c)\n\n## Installation \nInstallation within a Python virtual environment: \n```\npython3 -m pip install pyhamsys\n```\nFor more information on creating a Python virtual environment, click [here](https://realpython.com/python-virtual-environments-a-primer/). For a summary with the main steps, click [here](https://github.com/cchandre/HamLorenz/wiki/Python-Virtual-Environment-Primer).\n\n\n## Symplectic Integrators\n\npyHamSys features a dedicated class, `SymplecticIntegrator`, which provides a comprehensive implementation of symplectic-split integrators. These integrators are designed specifically for the numerical integration of Hamiltonian systems, ensuring the preservation of the symplectic structure of phase space—a key property that underpins the stability and accuracy of long-term simulations of such systems.\nSymplectic-split integrators decompose the Hamiltonian into subcomponents that are individually solvable, allowing for efficient and accurate integration. This decomposition is particularly effective for complex or high-dimensional systems, as it minimizes numerical drift and conserves critical invariants like energy over extended time intervals.\nThe `SymplecticIntegrator` class offers a variety of splitting methods, enabling users to select the most appropriate scheme for their specific Hamiltonian system and computational requirements. Each integrator is implemented to handle both autonomous and non-autonomous systems, supporting applications in classical mechanics, molecular dynamics, astrophysics, and quantum mechanics.\n\nPre-defined integrators are:\n\n- `Verlet` (order 2, all-purpose), also referred to as Strang or Störmer-Verlet splitting \n- From [Forest, Ruth, Physica D 43, 105 (1990)](https://doi.org/10.1016/0167-2789(90)90019-L): \n    - `FR` (order 4, all-purpose)\n- From [Yoshida, Phys. Lett. A 150, 262 (1990)](https://doi.org/10.1016/0375-9601(90)90092-3):\n    - `Yo#`: # should be replaced by an even integer, e.g., `Yo6` for 6th order symplectic integrator (all-purpose)\n    - `Yos6`: (order 6, all-purpose) optimized symplectic integrator (solution A from Table 1)\n- From [McLachlan, SIAM J. Sci. Comp. 16, 151 (1995)](https://doi.org/10.1137/0916010):\n    - `M2` (order 2, all-purpose)\n    - `M4` (order 4, all-purpose)\n- From [Omelyan, Mryglod, Folk, Comput. Phys. Commun. 146, 188 (2002)](https://doi.org/10.1016/S0010-4655(02)00451-4): \n    - `EFRL` (order 4) optimized for *H* = *A* + *B*\n    - `PEFRL` and `VEFRL` (order 4) optimized for *H* = *A*(*p*) + *B*(*q*). For `PEFRL`, *chi* should be exp(*h* X\u003csub\u003eA\u003c/sub\u003e)exp(*h* X\u003csub\u003eB\u003c/sub\u003e). For `VEFRL`, *chi* should be exp(*h* X\u003csub\u003eB\u003c/sub\u003e)exp(*h* X\u003csub\u003eA\u003c/sub\u003e).\n- From [Blanes, Moan, J. Comput. Appl. Math. 142, 313 (2002)](https://doi.org/10.1016/S0377-0427(01)00492-7):\n    - `BM4` (order 4, all-purpose) refers to S\u003csub\u003e6\u003c/sub\u003e \n    - `BM6` (order 6, all-purpose) refers to S\u003csub\u003e10\u003c/sub\u003e\n    - `RKN4b` (order 4) refers to SRKN\u003csub\u003e6\u003c/sub\u003e\u003csup\u003e*b*\u003c/sup\u003e optimized for *H* = *A*(*p*) + *B*(*q*). Here *chi* should be exp(*h* X\u003csub\u003eB\u003c/sub\u003e)exp(*h* X\u003csub\u003eA\u003c/sub\u003e).\n    - `RKN6b` (order 6) refers to SRKN\u003csub\u003e11\u003c/sub\u003e\u003csup\u003e*b*\u003c/sup\u003e optimized for *H* = *A*(*p*) + *B*(*q*). Here *chi* should be exp(*h* X\u003csub\u003eB\u003c/sub\u003e)exp(*h* X\u003csub\u003eA\u003c/sub\u003e).\n    - `RKN6a` (order 6) refers to SRKN\u003csub\u003e14\u003c/sub\u003e\u003csup\u003e*a*\u003c/sup\u003e optimized for *H* = *A*(*p*) + *B*(*q*). Here *chi* should be exp(*h* X\u003csub\u003eA\u003c/sub\u003e)exp(*h* X\u003csub\u003eB\u003c/sub\u003e).\n- From [Blanes, Casas, Farrés, Laskar, Makazaga, Murua, Appl. Numer. Math. 68, 58 (2013)](http://dx.doi.org/10.1016/j.apnum.2013.01.003):\n    - `ABA104` (order (10,4)) optimized for *H* = *A* + \u0026epsilon; *B*. Here *chi* should be exp(*h* X\u003csub\u003eA\u003c/sub\u003e)exp(*h* X\u003csub\u003eB\u003c/sub\u003e).\n    - `ABA864` (order (8,6,4)) optimized for *H* = *A* + \u0026epsilon; *B*. Here *chi* should be exp(*h* X\u003csub\u003eA\u003c/sub\u003e)exp(*h* X\u003csub\u003eB\u003c/sub\u003e).\n    - `ABA1064` (order (10,6,4)) optimized for *H* = *A* + \u0026epsilon; *B*. Here *chi* should be exp(*h* X\u003csub\u003eA\u003c/sub\u003e)exp(*h* X\u003csub\u003eB\u003c/sub\u003e). \n    \nAll-purpose integrators are for any splitting of the Hamiltonian *H*=\u0026sum;\u003csub\u003e*k*\u003c/sub\u003e *A*\u003csub\u003e*k*\u003c/sub\u003e in any order of the functions *A*\u003csub\u003e*k*\u003c/sub\u003e. Otherwise, the order of the operators is specified for each integrator. These integrators are used in the functions `solve_ivp_symp` and `solve_ivp_sympext` by specifying the entry `method` (default is `BM4`). \n\n----\n## HamSys class   \nThe `HamSys` class provides a robust framework for defining and integrating Hamiltonian systems. It allows users to specify the number of degrees of freedom, coordinate representations, and key attributes like the Hamiltonian and associated equations of motion.\n\n### Parameters\n- `ndof` : integer or half-integer, optional   \n       \tThe number of degrees of freedom in the Hamiltonian system. Half integers denote an explicit time dependence. Default is 1.  \n- `btype` : str, optional\n  \tInformation on the Poisson bracket used in the equations of motion. For btype='pq', a canonical Poisson bracket in (p,q) is used, i.e., the dynamical variables (*q*, *p*) are real and canonically conjugate. If btype='psi', the dynamical variables are (\u0026psi;, \u0026psi;\u003csup\u003e*\u003c/sup\u003e) where $\\psi=(q + i p)/\\sqrt{2}$. Default is 'pq'. For other btypes, the function `coupling` should be specified for the element of the class `HamSys`. \n\n### Parameters and Attributes\n- `y_dot` : callable, optional   \n  \tA function of (*t*, *y*) which returns {*y*,*H*(*t*,*y*)} where *y* is the state vector and *H* is the Hamiltonian. In (real) canonical coordinates where *y* = (*q*, *p*), this function returns (\u0026part;*H*/\u0026part;*p*, -\u0026part;*H*/\u0026part;*q*). In complex coordinate \u0026psi;, this function returns -i \u0026part;*H*/\u0026part;\u0026psi;\u003csup\u003e*\u003c/sup\u003e. For practical implementation, the state vector *y* should be represented as a one-dimensional array with a shape of (*n*,), where *n* denotes the total number of dynamical variables in the system. This ensures compatibility with numerical solvers and facilitates efficient computation of the system's evolution.  \n- `k_dot` : callable, optional   \n\tA function of (*t*, *y*) which returns {*k*,*H*(*t*,*y*)} = -\u0026part;*H*/\u0026part;*t* where *k* is canonically conjugate to *t* and *H* is the Hamiltonian.\n- `chi` and `chi_star` : callable, optional   \n    Functions of (*h*, *t*, *y*) which returns, respectively, exp(*h* X\u003csub\u003eN\u003c/sub\u003e)...exp(*h* X\u003csub\u003e1\u003c/sub\u003e)*y* and exp(*h* X\u003csub\u003e1\u003c/sub\u003e)...exp(*h* X\u003csub\u003eN\u003c/sub\u003e)*y* at time *t* for its use in symplectic-split integration (without phase space extension). See [2] for more details.     \n- `hamiltonian` : callable, optional   \n\tA function of (*t*, *y*) which returns the Hamiltonian *H*(*t*,*y*) where *y* is the state vector.\n- `coupling` (for exended phases space with the restraint as in [3]) : callable, optional   \n  \tA function of (*h*, *y*, \u0026omega;) which advances *y* from time *t* to *t*+*h* for the coupling Hamiltonian $\\omega (y - \\bar{y})^2/2$. This function is already computed for the types btype='pq' and 'psi'. For any other type, it should be provided. \n\n### Functions\n- `compute_vector_field` : from a callable function (Hamiltonian in canonical coordinates) written with symbolic variables ([SymPy](https://www.sympy.org/en/index.html)), computes the vector fields, `y_dot` and `k_dot`.\n\n\tDetermine Hamilton's equations of motion from a given scalar function \u0026ndash;the Hamiltonian\u0026ndash; *H*(*q*, *p*, *t*) where *q* and *p* are respectively positions and momenta. However, it is preferrable to code explicitly and optimize `y_dot` and `k_dot`. For systems with *n* degrees of freedom, the Hamiltonian should be of the form $$H(q_1,\\ldots,q_n,p_1,\\ldots,p_n,t)$$ (see [Example 1](./Examples/Example1_short.py)).\n\n\t#### Parameters\n\t- `hamiltonian` : callable   \n\t\tFunction *H*(*q*, *p*, *t*) \u0026ndash;the Hamiltonian expressed in symbolic variables\u0026ndash;, expressed using [SymPy](https://www.sympy.org/en/index.html) functions.\n\t- `output` : bool, optional   \n\t\tIf True, displays the equations of motion. Default is False.\n\t\n\tThe function `compute_vector_field` determines the HamSys function attributes `y_dot` and `k_dot` to be used in `solve_ivp_sympext`. The derivatives are computed symbolically using SymPy.\n\n- `integrate` : callable   \n    Integrate the Hamiltonian system using either a pre-defined **symplectic solver** (see above for a complete list) or a **standard IVP solver** ('RK23', 'RK45', 'DOP853', 'Radau', 'BDF', 'LSODA'). Supports optional *symplectic extension* and *energy conservation checks*.\n\n   - **z0** (`array_like`)  \n  Initial condition(s) of the system.\n   - **t_eval** (`array_like`)  \n  Times at which the solution is evaluated and stored.\n   - **params** (`Parameters`)   \n  Parameters for the integration of the Hamiltonian system. Step must be provided. \n   - **command** (void function of (*t*, *y*), optional)    \n\tVoid function to be run at each step size (e.g., plotting an observable associated with the state vector *y*, modify global or mutable variables, or register specific events).\n\n   #### Parameters\n  The integration parameters are defined through an element **params** of the dataclass `Parameters` of `pyHamSys`. See examples for its usage. Below are all the possible parameters to tune.   \n  - **step** (`float`)  \n  Fixed integration step size used in symplectic solvers, and maximium step size in variable step size methods for IVP solvers.   \n  - **solver** (`str`, optional, default=`\"BM4\"`)  \n  Solver method. Must be a member of `METHODS` (symplectic solvers), or  `IVP_METHODS` (classical IVP solvers).\n  - **extension** (`bool`, optional, default=`False`)  \n  If `True`, use a symplectic extension method in phase space.\n  - **tol** (`float`, optional, default=`1e-8`)  \n  Absolute and relative tolerance for IVP solvers.\n  Also, tolerance for the implict determination of the symmetric projection.\n  - **display** (`bool`, optional, default=`True`)  \n  If `True`, prints runtime information such as CPU time, error in energy, and copy distance (if available).      \n  - **check_energy** (`bool`, optional, default=`False`)  \n  If `True`, appends an auxiliary variable to track the Hamiltonian. Requires `hamiltonian` and `k_dot` to be defined.\n  - **projection** (`str`, optional, default=None)   \n  If specified, uses the 'midpoint' or 'symmetric' projection to move from the extended phase space to the true phase\n  space. Possibilities include `symmetric` and `midpoint`. \n   - **omega** (`float`, optional, default=None)  \n  Restraint parameter for symplectic extension solvers as in [4].\n   - **diss** (`float`, optional, default=`0`)   \n  Dissipative coefficient for improved accuracy when time steps are too large.\n  - **max_iter** (`int`, optional, default=100)   \n  Maximum number of iterations for the implict determination of the symmetric projection.\n  \n  \n    #### Returns\n   - **sol** (`object`)  \n    Solution object. Its attributes depend on the solver used:\n     - `y` : state trajectory  \n     - `t` : time points  \n     - `step` : integration time step  \n     - `cpu_time` : total CPU time used  \n     - `err` : (if `check_energy`=True) maximum error in energy   \n     - `projection` : Type of projection successfully used in the computation (only for `extension`=True)   \n     - `proj_dist` : Maximum distance between the two copies of the state in the extended phase space (only for `extension`=True)    \n\n    #### Notes\n    - **Symplectic solvers (`METHODS`)**  \n    If `extension=False`, requires `chi` and `chi_star` to be defined. If `extension=True`, requires `y_dot` to be defined.   \n    Preserves geometric properties of Hamiltonian flows.  \n    - **IVP solvers (`IVP_METHODS`)**  \n    Require `y_dot` (and `k_dot` if `check_energy`=True). Allow adaptive step sizes bounded by `step`.  \n    - **Energy checking**  \n    When `check_energy`=True, an auxiliary variable is added and the error in Hamiltonian is computed relative to its initial value. \n\n\n### Remarks:   \n  - Use `extension=False` if the Hamiltonian can be split and if each partial operator exp(*h* X\u003csub\u003e*k*\u003c/sub\u003e) can be easily and explicitly expressed/computed. Otherwise use `extension=True`.  \n  - The step size is slightly readjusted so that the final time *t*\u003csub\u003ef\u003c/sub\u003e corresponds to an integer number of step sizes. The step size used in the computation is recorded in the solution as `sol.step`.   \n  - For integrating multiple trajectories at the same time, extend phase space and define a state vector y = (y\u003csub\u003e1\u003c/sub\u003e, y\u003csub\u003e2\u003c/sub\u003e,...y\u003csub\u003eN\u003c/sub\u003e) where N is the number of trajectories. The Hamiltonian is given by $H(t,\\mathbf{y})=\\sum_{i=1}^N h(t, y_i)$.   \n\n### References:  \n  - [1] Hairer, Lubich, Wanner, 2003, *Geometric Numerical Integration: Structure-Preserving Algorithms for Ordinary Differential Equations* (Springer)  \n  - [2] McLachlan, R., *Tuning symplectic integrators is easy and worthwhile*, Commun. Comput. Phys. 31, 987 (2022); [arxiv:2104.10269](https://arxiv.org/abs/2104.10269)   \n  - [3] Pihajoki, P., *Explicit methods in extended phase space for inseparable Hamiltonian problems*, Celest. Mech. Dyn. Astron. 121, 211 (2015)   \n  - [4] Tao, M., *Explicit symplectic approximation of nonseparable Hamiltonians: Algorithm and long time performance*, Phys. Rev. E 94, 043303 (2016)   \n  - [5] Jayawardana, B., Ohsawa, T. *Semiexplicit symplectic integrators for non-separable Hamiltonian systems*, Math. Comp. 92.339, 251 (2023)   \n\n### Example\n\n```python\nimport numpy as np\nimport sympy as sp\nimport matplotlib.pyplot as plt\nfrom pyhamsys import HamSys, Parameters\n\nhs = HamSys()\nhamiltonian = lambda q, p, t: p**2 / 2 - sp.cos(q)\nhs.compute_vector_field(hamiltonian, output=True)\ny0 = np.asarray([3, 0])\nt_eval = np.linspace(0, 20, 2**9)\nparams = Parameters(step=1e-1, extension=True, check_energy=True)\nsol = hs.integrate(y0, t_eval, params=params)\nplt.plot(sol.y[0], sol.y[1])\nplt.show()\n\n```\nFor more examples, click [Examples](./Examples)\n\n---\n\nThis work has been carried out within the framework of the French Federation for Magnetic Fusion Studies (FR-FCM).\n\n---\nFor more information: \u003ccristel.chandre@cnrs.fr\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcchandre%2Fpyhamsys","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcchandre%2Fpyhamsys","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcchandre%2Fpyhamsys/lists"}