# FermPy
A Python package for exactly solving low-dimensional fermionic Hamiltonians. It was developed with the intention of constructing and diagonalizing matrix representations of low-dimensional, interacting fermionic Hamiltonians, in particular effective (surrogate) models that describe the low-energy (sub-gap) physics of the superconducting Anderson impurity model (see the [arXiv preprint](https://arxiv.org/abs/2307.11646)).
FermPy is based on [NumPy](https://numpy.org/) and [SciPy](https://scipy.org/). Small systems use *dense* NumPy arrays as operator representations while large systems employ *sparse* SciPy arrays.
Functionality of this package includes:
- Construction of matrix representations of operators ($H, S_z$, etc.) from a basis (chosen from symmetry considerations)
- Diagonalization (*numpy.linalg.eigh*, *scipy.sparse.linalg.eigh*) of operators
- Calculation of expectation values and thermal averages of operators
## Installation
FermPy is found on [PyPI](https://pypi.org/project/fermpy/) and easily installed by running
```
pip install fermpy
```
from the command-line.
## Usage
As an example of the intended usage of FermPy, we calculate and plot the excitation spectrum and average spin on a quantum dot (QD), coupled to a superconducting (SC) lead which is described by an effective three-level discretization (see the [arXiv preprint](https://arxiv.org/abs/2307.11646) for more details).
<br />
Import the necessary packages.
```
import numpy as np
import matplotlib.pyplot as plt
from fermpy.operator_sum import OpSum
from fermpy.hamiltonian_constructors import build_ham_op_sum_S_D
from fermpy.operator_representation import OpRep, operator_exp_val
from fermpy.bases import BasisS2
```
Construct the operator sum for the Hamiltonian $H$ of an SC-QD junction with an effective three-level lead. The effective couplings `gamma` and level positions `xi` are collected in Table 1 of the Supplemental Material of [arXiv preprint](https://arxiv.org/abs/2307.11646). Everything is in units of the SC gap `Delta`.
```
Gamma = np.linspace(0, 10, 201)
h_os = build_ham_op_sum_S_D(epsilon_d=-7.5,
U=15,
Gamma=Gamma,
Delta=1,
gamma=[0.5080, 1.8454, 1.8454],
xi=[0, 2.7546, -2.7546])
```
Define the basis. Here, we choose the eigenstates of total spin $S^2$ (the Hamiltonian preserves spin rotational symmetry).
```
basis = BasisS2(1 + 3) # One quantum dot level + three lead levels
```
Build the matrix representation of the Hamiltonian from the operator sum `h_os` and `basis`. We only consider the singlet, doublet, and triplet states ($s = 0, 1/2, 1$) - the quantum numbers of $S^2$: $S^2 |s\rangle = s(s+1)|s\rangle$.
```
h_op = OpRep(h_os, basis, qns_to_consider=(0, 1, 2)) # quantum numbers: 2*s
```
Diagonalize $H$, giving the eigenenergies and eigenvectors. `energies` and `eigenvectors` are dictionaries with quantum numbers as keys ($2s = 0, 1, 2$) and NumPy arrays as values.
```
energies: dict[int, np.ndarray]
eigenvectors: dict[int, np.ndarray]
energies, eigenvectors = h_op.diagonalize_all_qns(return_eigenvectors=True)
```
Extract the ground state quantum number and energy.
```
s_gs = np.argmin([E[:, 0] for E in energies.values()], axis=0)
E_gs = np.array([energies[s][idx, 0] for idx, s in enumerate(s_gs)])
```
Calculate the z-projection of spin on the quantum dot in the ground state. The syntax of `OpSum` is similar to [ITensor](https://itensor.org/).
```
sz_op = OpRep(opsum=OpSum([('sz', 0)]), basis=basis)
sz_exp = operator_exp_val(op_rep=sz_op, state_rep=eigenvectors, axis=1)
sz_exp_gs = [sz_exp[s][idx, 0] for idx, s in enumerate(s_gs)]
```
Plot the excitation spectrum and average dot spin in the ground state.
```
fig, (ax_top, ax_bot) = plt.subplots(2, 1,
figsize=(5.5, 5.5),
sharex=True,
constrained_layout=True
)
ax_top.set(ylabel=r'$(E - E_\mathrm{GS}) / \Delta$',
xlim=(0, 10),
ylim=(-0.05, 2)
)
ax_bot.set(xlabel=r'$\Gamma / \Delta$',
ylabel=r'$\langle S_{z, \mathrm{dot}} \rangle$',
xlim=(0, 10),
ylim=(-0.05, 0.55)
)
ax_top.hlines(1, 0, 10, linestyle='dashed', color='k', linewidth=0.5)
ax_bot.hlines(0, 0, 10, linestyle='dashed', color='k', linewidth=0.5)
colors = {0: 'tab:blue', 1: 'tab:orange', 2: 'tab:green'}
lines_to_label = []
for s, energies_s in energies.items():
lines_to_label.append(ax_top.plot(Gamma,
energies_s - E_gs[:, None],
color=colors[s])[0]
)
ax_top.legend(handles=lines_to_label,
labels=range(3),
loc='upper right',
title='s'
)
ax_bot.plot(Gamma, sz_exp_gs)
```
Here's the output figure.
<p align="center">
<img src="https://github.com/emilfrost/fermpy/blob/cd4825a47f1b91a25fe757eaf379343602534296/example.png" width="500" />
</p>
Raw data
{
"_id": null,
"home_page": "",
"name": "fermpy",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "",
"keywords": "Hamiltonian,condensed matter,exact diagonalization,fermion,physics,sparse",
"author": "",
"author_email": "Emil Frost <emiljpfrost@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/68/d7/bb44ae38ec1cf708e9f9b835b0a223379de8f94759679d6547920c2ea19c/fermpy-0.0.2.tar.gz",
"platform": null,
"description": "# FermPy\nA Python package for exactly solving low-dimensional fermionic Hamiltonians. It was developed with the intention of constructing and diagonalizing matrix representations of low-dimensional, interacting fermionic Hamiltonians, in particular effective (surrogate) models that describe the low-energy (sub-gap) physics of the superconducting Anderson impurity model (see the [arXiv preprint](https://arxiv.org/abs/2307.11646)).\n\nFermPy is based on [NumPy](https://numpy.org/) and [SciPy](https://scipy.org/). Small systems use *dense* NumPy arrays as operator representations while large systems employ *sparse* SciPy arrays.\n\nFunctionality of this package includes:\n- Construction of matrix representations of operators ($H, S_z$, etc.) from a basis (chosen from symmetry considerations)\n- Diagonalization (*numpy.linalg.eigh*, *scipy.sparse.linalg.eigh*) of operators\n- Calculation of expectation values and thermal averages of operators\n\n## Installation\nFermPy is found on [PyPI](https://pypi.org/project/fermpy/) and easily installed by running\n```\npip install fermpy\n```\nfrom the command-line.\n\n## Usage\nAs an example of the intended usage of FermPy, we calculate and plot the excitation spectrum and average spin on a quantum dot (QD), coupled to a superconducting (SC) lead which is described by an effective three-level discretization (see the [arXiv preprint](https://arxiv.org/abs/2307.11646) for more details).\n\n<br />\nImport the necessary packages.\n\n```\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom fermpy.operator_sum import OpSum\nfrom fermpy.hamiltonian_constructors import build_ham_op_sum_S_D\nfrom fermpy.operator_representation import OpRep, operator_exp_val\nfrom fermpy.bases import BasisS2\n```\n\nConstruct the operator sum for the Hamiltonian $H$ of an SC-QD junction with an effective three-level lead. The effective couplings `gamma` and level positions `xi` are collected in Table 1 of the Supplemental Material of [arXiv preprint](https://arxiv.org/abs/2307.11646). Everything is in units of the SC gap `Delta`.\n```\nGamma = np.linspace(0, 10, 201)\nh_os = build_ham_op_sum_S_D(epsilon_d=-7.5,\n U=15,\n Gamma=Gamma,\n Delta=1,\n gamma=[0.5080, 1.8454, 1.8454],\n xi=[0, 2.7546, -2.7546])\n```\n\nDefine the basis. Here, we choose the eigenstates of total spin $S^2$ (the Hamiltonian preserves spin rotational symmetry).\n```\nbasis = BasisS2(1 + 3) # One quantum dot level + three lead levels\n```\n\nBuild the matrix representation of the Hamiltonian from the operator sum `h_os` and `basis`. We only consider the singlet, doublet, and triplet states ($s = 0, 1/2, 1$) - the quantum numbers of $S^2$: $S^2 |s\\rangle = s(s+1)|s\\rangle$.\n```\nh_op = OpRep(h_os, basis, qns_to_consider=(0, 1, 2)) # quantum numbers: 2*s\n```\n\nDiagonalize $H$, giving the eigenenergies and eigenvectors. `energies` and `eigenvectors` are dictionaries with quantum numbers as keys ($2s = 0, 1, 2$) and NumPy arrays as values.\n```\nenergies: dict[int, np.ndarray]\neigenvectors: dict[int, np.ndarray]\nenergies, eigenvectors = h_op.diagonalize_all_qns(return_eigenvectors=True)\n```\n\nExtract the ground state quantum number and energy.\n```\ns_gs = np.argmin([E[:, 0] for E in energies.values()], axis=0)\nE_gs = np.array([energies[s][idx, 0] for idx, s in enumerate(s_gs)])\n```\n\nCalculate the z-projection of spin on the quantum dot in the ground state. The syntax of `OpSum` is similar to [ITensor](https://itensor.org/).\n```\nsz_op = OpRep(opsum=OpSum([('sz', 0)]), basis=basis)\nsz_exp = operator_exp_val(op_rep=sz_op, state_rep=eigenvectors, axis=1)\nsz_exp_gs = [sz_exp[s][idx, 0] for idx, s in enumerate(s_gs)]\n```\n\nPlot the excitation spectrum and average dot spin in the ground state.\n```\nfig, (ax_top, ax_bot) = plt.subplots(2, 1,\n figsize=(5.5, 5.5),\n sharex=True,\n constrained_layout=True\n )\n\nax_top.set(ylabel=r'$(E - E_\\mathrm{GS}) / \\Delta$',\n xlim=(0, 10),\n ylim=(-0.05, 2)\n )\nax_bot.set(xlabel=r'$\\Gamma / \\Delta$',\n ylabel=r'$\\langle S_{z, \\mathrm{dot}} \\rangle$',\n xlim=(0, 10),\n ylim=(-0.05, 0.55)\n )\n\nax_top.hlines(1, 0, 10, linestyle='dashed', color='k', linewidth=0.5)\nax_bot.hlines(0, 0, 10, linestyle='dashed', color='k', linewidth=0.5)\n\ncolors = {0: 'tab:blue', 1: 'tab:orange', 2: 'tab:green'}\nlines_to_label = []\nfor s, energies_s in energies.items():\n lines_to_label.append(ax_top.plot(Gamma,\n energies_s - E_gs[:, None],\n color=colors[s])[0]\n )\nax_top.legend(handles=lines_to_label,\n labels=range(3),\n loc='upper right',\n title='s'\n )\nax_bot.plot(Gamma, sz_exp_gs)\n```\n\nHere's the output figure.\n\n<p align=\"center\">\n <img src=\"https://github.com/emilfrost/fermpy/blob/cd4825a47f1b91a25fe757eaf379343602534296/example.png\" width=\"500\" />\n</p>\n\n",
"bugtrack_url": null,
"license": "",
"summary": "Package for exactly solving low-dimensional fermionic Hamiltonians",
"version": "0.0.2",
"project_urls": {
"Homepage": "https://github.com/emilfrost/fermpy"
},
"split_keywords": [
"hamiltonian",
"condensed matter",
"exact diagonalization",
"fermion",
"physics",
"sparse"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "26e8fb260015d0d73556cc03139a9998353f477ffb36c209e38bad03f428b759",
"md5": "57bcd22b59236e24bfdae5a114297311",
"sha256": "b6fc254a46b0204a8b4461cbf075266e8d44704fb617f2af4587083f88e64d68"
},
"downloads": -1,
"filename": "fermpy-0.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "57bcd22b59236e24bfdae5a114297311",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 20695,
"upload_time": "2023-07-24T14:51:21",
"upload_time_iso_8601": "2023-07-24T14:51:21.218099Z",
"url": "https://files.pythonhosted.org/packages/26/e8/fb260015d0d73556cc03139a9998353f477ffb36c209e38bad03f428b759/fermpy-0.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "68d7bb44ae38ec1cf708e9f9b835b0a223379de8f94759679d6547920c2ea19c",
"md5": "13544bdc24dce8b83ce1dc1bc01a7aeb",
"sha256": "827dc7da6f0df69eda277599a5afaafbe7b40cf8dca850a12156b207cac337ae"
},
"downloads": -1,
"filename": "fermpy-0.0.2.tar.gz",
"has_sig": false,
"md5_digest": "13544bdc24dce8b83ce1dc1bc01a7aeb",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 69823,
"upload_time": "2023-07-24T14:51:23",
"upload_time_iso_8601": "2023-07-24T14:51:23.196200Z",
"url": "https://files.pythonhosted.org/packages/68/d7/bb44ae38ec1cf708e9f9b835b0a223379de8f94759679d6547920c2ea19c/fermpy-0.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-07-24 14:51:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "emilfrost",
"github_project": "fermpy",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "fermpy"
}