{"id":17651082,"url":"https://github.com/krivenko/libcommute","last_synced_at":"2025-08-24T17:17:30.156Z","repository":{"id":41413113,"uuid":"186312779","full_name":"krivenko/libcommute","owner":"krivenko","description":"A quantum operator algebra domain-specific language and exact diagonalization toolkit for C++11/14/17","archived":false,"fork":false,"pushed_at":"2025-07-20T12:29:49.000Z","size":18018,"stargazers_count":22,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-20T14:30:03.840Z","etag":null,"topics":["algebra","cpp11","exact-diagonalization","many-body-physics","operators","physics","quantum"],"latest_commit_sha":null,"homepage":"https://krivenko.github.io/libcommute/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/krivenko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATIONS.bib","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-05-12T22:57:42.000Z","updated_at":"2025-07-20T12:27:05.000Z","dependencies_parsed_at":"2024-01-20T15:26:18.026Z","dependency_job_id":"8322bff1-5a5c-4dd8-8413-2461ab48080c","html_url":"https://github.com/krivenko/libcommute","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/krivenko/libcommute","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krivenko%2Flibcommute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krivenko%2Flibcommute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krivenko%2Flibcommute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krivenko%2Flibcommute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/krivenko","download_url":"https://codeload.github.com/krivenko/libcommute/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krivenko%2Flibcommute/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271912608,"owners_count":24842763,"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","status":"online","status_checked_at":"2025-08-24T02:00:11.135Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["algebra","cpp11","exact-diagonalization","many-body-physics","operators","physics","quantum"],"created_at":"2024-10-23T11:40:13.374Z","updated_at":"2025-08-24T17:17:30.109Z","avatar_url":"https://github.com/krivenko.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"![libcommute logo](doc/images/logo.svg)\n\n[![CI](https://github.com/krivenko/libcommute/actions/workflows/build-test-deploy.yml/badge.svg)](\nhttps://github.com/krivenko/libcommute/actions/workflows/build-test-deploy.yml)\n[![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-red)](\nhttps://krivenko.github.io/libcommute)\n[![DOI](https://zenodo.org/badge/186312779.svg)](\nhttps://zenodo.org/badge/latestdoi/186312779)\n\n\n*libcommute* is a C++11/14/17 template library made of two major parts.\n\n* A Domain-Specific Language (DSL) designed to easily construct and manipulate\n  polynomial expressions with quantum-mechanical operators,\n  especially those used in the theory of many interacting fermions, bosons and\n  spins. The goal here is to make expressions written in C++ code closely\n  resemble the standard mathematical notation.\n\n* A fast representation of the quantum-mechanical operators that enables\n  their action on finite-dimensional state vectors.\n  This feature provides a basis for writing highly performant Exact\n  Diagonalization (ED) codes without loss of flexibility.\n\nPython bindings for *libcommute* are available as a\n[separate project](https://github.com/krivenko/pycommute).\n\nDependencies\n------------\n\nA C++11 conformant compiler. C++17 support is required for\nthe dynamic index sequence feature.\n\nInstallation\n------------\n\n*libcommute* is usable without installation, just add\n`-I/\u003cpath_to_libcommute_sources\u003e/include` to the compiler command line.\n\nYou will need CMake version 3.8.0 or newer [1] to build examples/unit tests and\nto install *libcommute* so that it can be used from other CMake projects.\n\nAssuming that *libcommute* is to be installed in `\u003clibcommute_prefix\u003e`,\nthe installation normally proceeds in a few simple steps.\n\n```\n$ git clone https://github.com/krivenko/libcommute.git libcommute.src\n$ mkdir libcommute.build \u0026\u0026 cd libcommute.build\n$ cmake ../libcommute.src                    \\\n  -DCMAKE_INSTALL_PREFIX=\u003clibcommute_prefix\u003e \\\n  -DEXAMPLES=ON                              \\\n  -DTESTS=ON\n$ make\n$ make test\n$ make install\n```\n\nCompilation of the tests can be disabled with CMake flag `-DTESTS=OFF`\n*(not recommended)*. Examples are compiled by default, disable them with\n`-DEXAMPLES=OFF`.\n\nUsage\n-----\n\nOnce *libcommute* is installed, you can use it in your CMake project. Here is\na minimal example of an application `CMakeLists.txt` file.\n\n```cmake\n  cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)\n\n  project(myproject LANGUAGES CXX)\n\n  # Change the C++ standard to '17' if you plan to use\n  # the dynamic index sequence feature\n  set(CMAKE_CXX_STANDARD 11)\n\n  # libcommute_ROOT is the installation prefix of libcommute\n  set(libcommute_DIR ${libcommute_ROOT}/lib/cmake)\n\n  # Import libcommute target\n  find_package(libcommute 0.7.2 CONFIG REQUIRED)\n\n  # Build an executable called 'myprog'\n  add_executable(myprog myprog.cpp)\n  target_link_libraries(myprog PRIVATE libcommute::libcommute)\n```\n\nDSL for quantum-mechanical operators\n------------------------------------\n\nThe following program constructs Hamiltonian of the Hubbard-Holstein model\non a square 10x10 lattice with nearest-neighbor hopping.\n\n![libcommute logo](doc/images/hubbard_holstein.svg)\n\nIn addition, it\n\n* prints the total number of terms (monomials) in the Hamiltonian;\n* checks that it is Hermitian;\n* checks that it commutes with the total number of electrons and\n  with a projection of the total spin;\n* prints all monomials of degree 3.\n\n```c++\n#include \u003ccstdlib\u003e\n#include \u003ciostream\u003e\n\n#include \u003clibcommute/libcommute.hpp\u003e\n\nusing namespace libcommute;\n\nint main() {\n\n  //\n  // Parameters of the system\n  //\n\n  // Linear sizes of the lattice\n  int const Nx = 10;\n  int const Ny = 10;\n\n  // Hopping constant\n  double const t = 0.5;\n  // Coulomb repulsion\n  double const U = 2.0;\n  // Electron-phonon coupling constant\n  double const g = 0.1;\n\n  // Expression with real coefficients 'H' will represent the Hamiltonian.\n  // It is initially set to zero by its default-constructor.\n  // Every creation and annihilation operator met in the expression must\n  // carry two integer (coordinates of a lattice site) and one string\n  // index.\n  expression\u003cdouble,               // type of expression's coefficients\n             int, int, std::string // types of operator indices\n             \u003e H;\n\n  // The following 'factory' functions make quantum operators with\n  // statically typed indices and real coefficients.\n  using static_indices::c_dag; // Create an electron\n  using static_indices::c;     // Destroy an electron\n  using static_indices::n;     // Number of electrons\n  using static_indices::a_dag; // Create a phonon\n  using static_indices::a;     // Destroy a phonon\n\n  // Are two sites neighbors along the x-axis with periodicity?\n  auto neighbors_x = [Nx](int ix, int jx) {\n    return std::abs(ix - jx) == 1 || std::abs(ix - jx) == Nx - 1;\n  };\n  // Are two sites neighbors along the y-axis with periodicity?\n  auto neighbors_y = [Ny](int iy, int jy) {\n    return std::abs(iy - jy) == 1 || std::abs(iy - jy) == Ny - 1;\n  };\n\n  // Hopping terms of H\n  for(auto spin : {\"up\", \"down\"}) {\n    for(int ix = 0; ix \u003c Nx; ++ix) {\n      for(int iy = 0; iy \u003c Ny; ++iy) {\n        for(int jx = 0; jx \u003c Nx; ++jx) {\n          for(int jy = 0; jy \u003c Ny; ++jy) {\n            // Skip all pairs of lattice sites (ix,iy) and (jx,jy) that are\n            // not nearest-neighbors.\n            if((neighbors_x(ix, jx) \u0026\u0026 iy == jy) ||\n               (ix == jx \u0026\u0026 neighbors_y(iy, jy))\n            ) {\n              // Add a hopping term\n              H += -t * c_dag(ix, iy, spin) * c(jx, jy, spin);\n            }\n          }\n        }\n      }\n    }\n  }\n\n  // Coulomb repulsion terms\n  for(int ix = 0; ix \u003c Nx; ++ix)\n    for(int iy = 0; iy \u003c Ny; ++iy) {\n      H += U * n(ix, iy, \"up\") * n(ix, iy, \"down\");\n    }\n\n  // Energy of phonons\n  for(int ix = 0; ix \u003c Nx; ++ix)\n    for(int iy = 0; iy \u003c Ny; ++iy) {\n      // The spin index is left blank for bosonic operators\n      H += a_dag(ix, iy, \"\") * a(ix, iy, \"\");\n    }\n\n  // Electron-phonon coupling\n  for(auto spin : {\"up\", \"down\"}) {\n    for(int ix = 0; ix \u003c Nx; ++ix) {\n      for(int iy = 0; iy \u003c Ny; ++iy) {\n        H += g * n(ix, iy, spin) * (a_dag(ix, iy, \"\") + a(ix, iy, \"\"));\n      }\n    }\n  }\n\n  // Total number of terms (monomials) in 'H'.\n  std::cout \u003c\u003c \"Total number of terms in H: \" \u003c\u003c H.size() \u003c\u003c '\\n';\n  // Is H Hermitian?\n  std::cout \u003c\u003c \"H^\\\\dagger - H = \" \u003c\u003c (conj(H) - H) \u003c\u003c '\\n';\n\n  // Does H commute with N and S_z?\n  decltype(H) N, S_z;\n  for(int ix = 0; ix \u003c Nx; ++ix) {\n    for(int iy = 0; iy \u003c Ny; ++iy) {\n      N += n(ix, iy, \"up\") + n(ix, iy, \"down\");\n      S_z += 0.5 * (n(ix, iy, \"up\") - n(ix, iy, \"down\"));\n    }\n  }\n  std::cout \u003c\u003c \"[H, N] = \" \u003c\u003c (H * N - N * H) \u003c\u003c '\\n';\n  std::cout \u003c\u003c \"[H, S_z] = \" \u003c\u003c (H * S_z - S_z * H) \u003c\u003c '\\n';\n\n  // Iterate over all terms in 'H' and print those of degree 3.\n  //\n  // Monomials of degree 3 come from the electron-phonon coupling and\n  // are products of two fermionic and one bosonic operators.\n  for(auto const\u0026 term: H) {\n    if(term.monomial.size() == 3) {\n      // term.coeff is coefficient in front of the monomial\n      std::cout \u003c\u003c term.monomial \u003c\u003c \" =\u003e \" \u003c\u003c term.coeff \u003c\u003c '\\n';\n    }\n  }\n\n  return 0;\n}\n```\n\nCode example: matrix representation of an operator\n--------------------------------------------------\n\nIn this example we show how to construct a matrix representation of\nthe Heisenberg exchange interaction term between two spins 1/2.\n\n![libcommute logo](doc/images/exchange_matrix.svg)\n\nPlease note that computed matrix does not have to be stored in memory all at\nonce. *libcommute* needs storage only for two state vectors.\n\n```c++\n#include \u003calgorithm\u003e\n#include \u003ccstdlib\u003e\n#include \u003ciostream\u003e\n#include \u003cvector\u003e\n\n#include \u003clibcommute/libcommute.hpp\u003e\n\nusing namespace libcommute;\n\nint main() {\n\n  // The following 'factory' functions make spin operators with statically typed\n  // indices and real coefficients.\n  using static_indices::S_p;  // Spin-1/2 raising operator S_+\n  using static_indices::S_m;  // Spin-1/2 lowering operator S_-\n  using static_indices::S_z;  // Spin-1/2 operator S_z\n\n  // Expression 'H' will represent the exchange interaction term.\n  // Our spin operators will carry one integer index (site 1 or 2).\n  auto H = 0.5 * (S_p(1) * S_m(2) + S_m(1) * S_p(2)) + S_z(1) * S_z(2);\n\n  // Print 'H'\n  std::cout \u003c\u003c \"H = \" \u003c\u003c H \u003c\u003c '\\n';\n\n  // Automatically analyze structure of 'H' and construct a 4-dimensional\n  // Hilbert space (direct product of two spin-1/2 spaces).\n  auto hs = make_hilbert_space(H);\n  std::cout \u003c\u003c \"dim(hs) = \" \u003c\u003c hs.dim() \u003c\u003c '\\n';\n\n  // Construct a 'loperator' object that represents action of expression 'H' on\n  // state vectors in the Hilbert space 'hs'.\n  auto Hop = make_loperator(H, hs);\n\n  // Here, we will act with 'Hop' on each of the 4 basis states |\\psi\u003e in 'hs',\n  // |\\phi\u003e = Hop |\\psi\u003e, and print components of |\\phi\u003e. In other words,\n  // we are going to construct the matrix representation \u003c\\phi|Hop|\\psi\u003e.\n\n  // Preallocate state vectors.\n  // Other containers, such as Eigen::VectorXd could be used instead.\n  std::vector\u003cdouble\u003e phi(4), psi(4);\n  // Iterate over basis states\n  for(int i = 0; i \u003c 4; ++i) {\n    std::fill(phi.begin(), phi.end(), 0);\n    std::fill(psi.begin(), psi.end(), 0);\n    psi[i] = 1; // 'psi' is i-th basis vector now\n\n    phi = Hop(psi);\n    // NB.: It is generally recommended to use the in-place syntax\n    //  Hop(psi, phi);\n    // as it eliminates a memory allocation needed to store the result.\n\n    std::cout \u003c\u003c \"H|\" \u003c\u003c i \u003c\u003c \"\u003e = \";\n    for(int j = 0; j \u003c 4; ++j) {\n      std::cout \u003c\u003c \"+(\" \u003c\u003c phi[j] \u003c\u003c \")|\" \u003c\u003c j \u003c\u003c \"\u003e\";\n    }\n    std::cout \u003c\u003c '\\n';\n  }\n\n  return 0;\n}\n```\n\nIt is easy to check that eigenvalues of the computed matrix are\n{-3/4, 1/4, 1/4, 1/4}, which correspond to the spin singlet-triplet splitting.\n\nCiting\n------\n\nIf you find this library useful for your research, you can help me by citing it\nusing the following BibTeX entry.\n\n```\n@article{libcommute,\n    title = {{libcommute/pycommute: A quantum operator algebra domain-specific\n              language and exact diagonalization toolkit}},\n    author = {Igor Krivenko},\n    journal = {SoftwareX},\n    volume = {17},\n    pages = {100937},\n    year = {2022},\n    issn = {2352-7110},\n    doi = {10.1016/j.softx.2021.100937}\n}\n```\n\nLicense\n-------\n\nThis Source Code Form is subject to the terms of the Mozilla Public\nLicense, v. 2.0. If a copy of the MPL was not distributed with this\nfile, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n[1]: https://cmake.org/download\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrivenko%2Flibcommute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkrivenko%2Flibcommute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrivenko%2Flibcommute/lists"}