{"id":27997325,"url":"https://github.com/34j/ss-hankel","last_synced_at":"2025-05-08T21:58:20.664Z","repository":{"id":290914158,"uuid":"975993754","full_name":"34j/ss-hankel","owner":"34j","description":"Derivative-free method to find zeros of analytic (holomorphic) functions / solve nonlinear (polynomial / generalized) eigenvalue problems using contour integration. (Block SS-Hankel method, Block Sakurai Sugiura method)","archived":false,"fork":false,"pushed_at":"2025-05-08T01:58:13.000Z","size":57,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-08T21:58:17.794Z","etag":null,"topics":["eigenvalues","eigenvector","eigenvectors","generalized-eigensolver","generalized-eigenvalue","linear-algebra","nonlinear-eigenvalue-problem","nonlinear-eigenvalue-problems","polynomial-eigenvalue-problem","root-finding"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/34j.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","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},"funding":{"github":["34j"]}},"created_at":"2025-05-01T09:30:05.000Z","updated_at":"2025-05-08T01:58:15.000Z","dependencies_parsed_at":"2025-05-01T10:02:06.504Z","dependency_job_id":"799fc45d-da9d-4fd4-9d05-775f03dbb32d","html_url":"https://github.com/34j/ss-hankel","commit_stats":null,"previous_names":["34j/ss-hankel"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/34j%2Fss-hankel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/34j%2Fss-hankel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/34j%2Fss-hankel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/34j%2Fss-hankel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/34j","download_url":"https://codeload.github.com/34j/ss-hankel/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253154976,"owners_count":21862621,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["eigenvalues","eigenvector","eigenvectors","generalized-eigensolver","generalized-eigenvalue","linear-algebra","nonlinear-eigenvalue-problem","nonlinear-eigenvalue-problems","polynomial-eigenvalue-problem","root-finding"],"created_at":"2025-05-08T21:58:20.192Z","updated_at":"2025-05-08T21:58:20.658Z","avatar_url":"https://github.com/34j.png","language":"Python","funding_links":["https://github.com/sponsors/34j"],"categories":[],"sub_categories":[],"readme":"# SS Hankel\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/34j/ss-hankel/actions/workflows/ci.yml?query=branch%3Amain\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/34j/ss-hankel/ci.yml?branch=main\u0026label=CI\u0026logo=github\u0026style=flat-square\" alt=\"CI Status\" \u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://ss-hankel.readthedocs.io\"\u003e\n    \u003cimg src=\"https://img.shields.io/readthedocs/ss-hankel.svg?logo=read-the-docs\u0026logoColor=fff\u0026style=flat-square\" alt=\"Documentation Status\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/34j/ss-hankel\"\u003e\n    \u003cimg src=\"https://img.shields.io/codecov/c/github/34j/ss-hankel.svg?logo=codecov\u0026logoColor=fff\u0026style=flat-square\" alt=\"Test coverage percentage\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/astral-sh/uv\"\u003e\n    \u003cimg src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/astral-sh/ruff\"\u003e\n    \u003cimg src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/pre-commit/pre-commit\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit\u0026logoColor=white\u0026style=flat-square\" alt=\"pre-commit\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://pypi.org/project/ss-hankel/\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/ss-hankel.svg?logo=python\u0026logoColor=fff\u0026style=flat-square\" alt=\"PyPI Version\"\u003e\n  \u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/pypi/pyversions/ss-hankel.svg?style=flat-square\u0026logo=python\u0026amp;logoColor=fff\" alt=\"Supported Python versions\"\u003e\n  \u003cimg src=\"https://img.shields.io/pypi/l/ss-hankel.svg?style=flat-square\" alt=\"License\"\u003e\n\u003c/p\u003e\n\n---\n\n**Documentation**: \u003ca href=\"https://ss-hankel.readthedocs.io\" target=\"_blank\"\u003ehttps://ss-hankel.readthedocs.io \u003c/a\u003e\n\n**Source Code**: \u003ca href=\"https://github.com/34j/ss-hankel\" target=\"_blank\"\u003ehttps://github.com/34j/ss-hankel \u003c/a\u003e\n\n---\n\n**Derivative-free** method to find zeros of analytic (holomorphic) functions / solve nonlinear (polynomial / generalized) eigenvalue problems using contour integration. (Block SS-Hankel method, Block Sakurai Sugiura method)\n\n## Installation\n\nInstall this via pip (or your favourite package manager):\n\n```shell\npip install ss-hankel\n```\n\n## Usage\n\nBelow is a simple example of solving the following nonlinear eigenvalue problem from [NEP-PACK Tutorial](https://nep-pack.github.io/NonlinearEigenproblems.jl/dev/tutorial_python_call/#Tutorial:-Using-NEP-PACK-from-python).\n\n$$\nf(x) = \\begin{pmatrix}\n3+e^{0.5x} \u0026 2+2x+e^{0.5x} \\\\\n3+e^{0.5x} \u0026 -1+x+e^{0.5x}\n\\end{pmatrix}\n, \\quad f(x) v = 0\n$$\n\n```python\nfrom typing import Any\n\nimport numpy as np\nfrom numpy.typing import NDArray\n\nfrom ss_hankel import score, ss_h_circle\n\n\ndef f(x: NDArray[Any]) -\u003e NDArray[Any]: # deriative is not needed!\n    return np.stack(\n        [\n            np.stack([3 + np.exp(0.5 * x), 2 + 2 * x + np.exp(0.5 * x)], axis=-1),\n            np.stack([3 + np.exp(0.5 * x), -1 + x + np.exp(0.5 * x)], axis=-1),\n        ],\n        axis=-2,\n    )\n\n\neig = ss_h_circle(\n    f,\n    num_vectors=2,\n    max_order=8,\n    circle_n_points=128, # number of integration points\n    circle_radius=3, # radius of the contour\n    circle_center=0, # center of the contour\n)\nprint(f\"Eigenvalues: {eig.eigval}\") # eigenvalues inside the contour\nprint(f\"Eigenvectors: {eig.eigvec}\") # corresponding eigenvectors\nprint(f\"|f(λ)v|/|f(λ)||v|: {score(f(eig.eigval), eig.eigvec)}\")\n```\n\n```text\nEigenvalues: [-3.+3.19507247e-15j]\nEigenvectors: [[-0.45042759-0.61296714j]\n [-0.38438888-0.52309795j]]\n|f(λ)v|/|f(λ)||v|: [1.37836544e-15]\n```\n\n- **Batch calculation** (function and/or contour) is supported.\n  - Steps until SVD are batched. Function evaluations are batched (called only once).\n  - Only the final step (solving small generalized eigenvalue problem) is not batched because the size of the eigenvalue problem (the number of eigenvalues in the contour) might be different and moreover `scipy.linalg.eig` does not support batch calculation.\n- Since random matrices `U,V` are used in the algorithm, the results may vary slightly on each run. `np.random.Generator` can be passed to control the randomness.\n- To get **zeros of an analytic function**, set `lambda x: f(x)[..., None, None]` as an argument. The SS-Hankel method for 1x1 matrix is completely equivalent to the Kravanja (1999)'s derivative-free root-finding method.\n- The default parameters are set to be impractically small. Consider increasing `circle_n_points` and `max_order` based on the problem and `num_vectors` based on the matrix size.\n- The number of eigenvalues (zeros) inside the contour is estimated by evaluating the numerical rank of the Hankel matrix. By default the singular values below the largest gap between singular values are considered meaningless, as propsed in Xiao (2016), but the behaviour can be controlled by manually setting `rtol`. `atol` (default: `1e-6`) is useful in the case when no eigenvalues are inside the contour.\n\n## CLI Usage\n\n```shell\n\u003e ss-hankel \"{{3+Exp[x/2],2+2x+Exp[x/2]},{3+Exp[x/2],-1+x+Exp[x/2]}}\" --circle-radius 4\neigenvalues:\n[-3.-2.29788612e-15j]\neigenvectors (columns):\n[[0.35283836-0.67388339j]\n [0.30110753-0.57508306j]]\n|F(λ)v|/|F(λ)||v|:\n[9.82824873e-16]\nsingular_values:\n[1.36659229e-01 5.51578001e-17 3.11252713e-17 2.25070948e-17\n 1.05446714e-17 9.42202841e-18 6.28427578e-18 2.84988862e-18]\n```\n\n## References\n\n- [Asakura, J., Sakurai, T., Tadano, H., Ikegami, T., \u0026 Kimura, K. (2009). A numerical method for nonlinear eigenvalue problems using contour integrals. JSIAM Letters, 1, 52–55.](https://doi.org/10.1007/s006070050051)\n- [Kravanja, P., \u0026 Van Barel, M. (1999). A Derivative-Free Algorithm for Computing Zeros of Analytic Functions. Computing (Vienna/New York), 63, 69–91.](https://doi.org/10.14495/jsiaml.1.52)\n- [Xiao, J., Meng, S., Zhang, C., \u0026 Zheng, C. (2016). Resolvent sampling based Rayleigh-Ritz method for large-scale nonlinear eigenvalue problems. Computer Methods in Applied Mechanics and Engineering, 310, 33–57.](https://doi.org/10.1016/j.cma.2016.06.018)\n\n## Alternatives\n\n- [nep-pack/NonlinearEigenproblems.jl: Nonlinear eigenvalue problems in Julia: Iterative methods and benchmarks](https://github.com/nep-pack/NonlinearEigenproblems.jl)\n\n### Zeros of analytic functions\n\n- [rparini/cxroots: Find all the roots (zeros) of a complex analytic function within a given contour in the complex plane.](https://github.com/rparini/cxroots)\n- [nennigb/polze: A python package to locate poles and zeros of a meromorphic function with their multiplicities](https://github.com/nennigb/polze)\n- [Spectral-Analysis-UPB/PyZEAL: Project dealing with the numerical calculation of zeros, poles and residues of holomorphic and meromorphic functions. It aspires to be a PYthon ZEAL (ZEros of AnaLytic functions, a Fortran90 package) successor.](https://github.com/Spectral-Analysis-UPB/PyZEAL)\n\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003c!-- markdownlint-enable --\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n\n## Credits\n\n[![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-orange.json)](https://github.com/copier-org/copier)\n\nThis package was created with\n[Copier](https://copier.readthedocs.io/) and the\n[browniebroke/pypackage-template](https://github.com/browniebroke/pypackage-template)\nproject template.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F34j%2Fss-hankel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F34j%2Fss-hankel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F34j%2Fss-hankel/lists"}