https://github.com/lan496/hsnf
Computing Hermite normal form and Smith normal form with transformation matrices
https://github.com/lan496/hsnf
matrix-functions numpy python
Last synced: 23 days ago
JSON representation
Computing Hermite normal form and Smith normal form with transformation matrices
- Host: GitHub
- URL: https://github.com/lan496/hsnf
- Owner: lan496
- License: mit
- Created: 2019-01-30T11:18:04.000Z (almost 7 years ago)
- Default Branch: develop
- Last Pushed: 2025-12-02T00:48:24.000Z (about 2 months ago)
- Last Synced: 2025-12-04T16:05:12.864Z (about 2 months ago)
- Topics: matrix-functions, numpy, python
- Language: Python
- Homepage: https://hsnf.readthedocs.io/en/latest/
- Size: 8.33 MB
- Stars: 20
- Watchers: 2
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# hsnf
[](https://github.com/lan496/hsnf/actions/workflows/testing.yml)
[](https://hsnf.readthedocs.io/en/latest/?badge=latest)
[](https://results.pre-commit.ci/latest/github/lan496/hsnf/master)
[](https://codecov.io/gh/lan496/hsnf)
[](https://github.com/lan496/hsnf/blob/master/LICENSE)

[](https://badge.fury.io/py/hsnf)

Computing Hermite normal form and Smith normal form with transformation matrices.
- Document:
- Document(develop):
- Github:
- PyPI:
## Usage
```python
import numpy as np
from hsnf import column_style_hermite_normal_form, row_style_hermite_normal_form, smith_normal_form
# Integer matrix to be decomposed
M = np.array(
[
[-6, 111, -36, 6],
[5, -672, 210, 74],
[0, -255, 81, 24],
]
)
# Smith normal form
D, L, R = smith_normal_form(M)
"""
D = array([
[ 1 0 0 0]
[ 0 3 0 0]
[ 0 0 2079 0]])
"""
assert np.allclose(L @ M @ R, D)
assert np.around(np.abs(np.linalg.det(L))) == 1 # unimodular
assert np.around(np.abs(np.linalg.det(R))) == 1 # unimodular
# Row-style hermite normal form
H, L = row_style_hermite_normal_form(M)
"""
H = array([
[ 1 0 420 -2522]
[ 0 3 1809 -10860]
[ 0 0 2079 -12474]])
"""
assert np.allclose(L @ M, H)
assert np.around(np.abs(np.linalg.det(L))) == 1 # unimodular
# Column-style hermite normal form
H, R = column_style_hermite_normal_form(M)
"""
H = array([
[ 3 0 0 0]
[ 0 1 0 0]
[1185 474 2079 0]])
"""
assert np.allclose(np.dot(M, R), H)
assert np.around(np.abs(np.linalg.det(R))) == 1 # unimodular
```
## Installation
hsnf works with Python3.8+ and can be installed via PyPI:
```shell
pip install hsnf
```
or in local:
```shell
git clone git@github.com:lan496/hsnf.git
cd hsnf
pip install -e .[dev,docs]
```
## References
- http://www.dlfer.xyz/post/2016-10-27-smith-normal-form/
- I appreciate Dr. D. L. Ferrario's instructive blog post and his approval for referring his scripts.
- [CSE206A: Lattices Algorithms and Applications (Spring 2014)](https://cseweb.ucsd.edu/classes/sp14/cse206A-a/index.html)
- Henri Cohen, A Course in Computational Algebraic Number Theory (Springer-Verlag, Berlin, 1993).