Skip to content


Repository files navigation

DOI Build Status

Full documenation:
Also see:

Always work against a versioned release. See "Quickstart" below for instructions on how to checkout the latest release.


Welcome to TBTK, a library for modeling and solving second quantized Hamiltonians with discrete indices. That is, Hamiltonians of the form

TBTK itself originated as a Tight-Binding ToolKit, and currently have complete support for modeling and solving the first bilinear term. However, the scope of TBTK has expanded vastly since its inception. It is today more generally a collection of data structures that are meant to enable rapid development of new algorithms for both interacting and non-interacting systems. Examples include general purpose data structures for quantities such as the Density, DOS, EigenValues, (spin-polarized) LDOS, Magnetization, WaveFunctions, etc. In addition to providing native solvers, TBTK also aims to enable the development of frontends and backends to already existing packages. Thereby allowing for seamless integration with the codebase already developed by the scientific community. To aid such integration, TBTK is specifically designed to allow for solution algorithms to be used interchangably with minimal amount of modification of the code.


Consider the tight-binding Hamiltonian

on a square lattice of size 30x30, where angle brackets denotes summation over nearest neighbors, and sigma is a spin summation index. The parameters t = 1 eV and J = 0.5 eV are the nearest neighbor hopping amplitude and the strength of the Zeeman term, respectively. Moreover, let the chemical potential be mu = -1 eV, the temperature be T = 300K, and the particles have Fermi-Dirac statistics.

const int SIZE_X                = 30;
const int SIZE_Y                = 30;
const double mu                 = 0;
const double t                  = 1;
const double J                  = 0.5;
const double T                  = 300;
const Statistics statistics     = Statistics::FermiDirac;

Now assume that we are interested in calculating the density of states (DOS) and magnetization for the system. For the DOS we want to use the energy window [-10, 10] and an energy resolution of 1000 points.

const double LOWER_BOUND        = -10;
const double UPPER_BOUND        = 10;
const int RESOLUTION            = 1000;

In addition we decide that the appropriate solution method for the system is diagonalization. We proceed as follows.

Setup the model

Model model;
for(int x = 0; x < SIZE_X; x++){
        for(int y = 0; y < SIZE_Y; y++){
                for(int s = 0; s < 2; s++){
                        //Add nearest neighbor hopping (HC for Hermitian conjugate).
                        if(x+1 < SIZE_X)
                                model << HoppingAmplitude(-t, {x+1, y, s}, {x, y, s}) + HC;
                        if(y+1 < SIZE_Y)
                                model << HoppingAmplitude(-t, {x, y+1, s}, {x, y, s}) + HC;

                        //Add Zeeman term.
                        model << HoppingAmplitude(-J*2*(1/2. - s), {x, y, s}, {x, y, s});
//Create Hilbert space basis.

//Set the chemical potential, temperature, and statistics.

Select solution method

Solver::Diagonalizer solver;

Calculate properties

PropertyExtractor::Diagonalizer propertyExtractor(solver);
propertyExtractor.setEnergyWindow(LOWER_BOUND, UPPER_BOUND, RESOLUTION);

//Calculate the DOS.
Propery::DOS dos = propertyExtractor.calculateDOS();

//Calculate the Magnetization for all x and y values by passing the wildcard
//_a_ in the correpsonding positions. IDX_SPIN is used to tell the
//PropertyExtractor which subindex that corresponds to spin.
Property::Magnetization magnetization
        = propertyExtractor.calculateMagnetization({{_a_, _a_, IDX_SPIN}});

Smooth the DOS

const double SMOOTHING_SIGMA = 0.07;
const unsigned int SMOOTHING_WINDOW = 51;
dos = Smooth::gaussian(dos, SMOOTHING_SIGMA, SMOOTHING_WINDOW);

Plot and print results

//Create a Plotter.
Plotter plotter;

//Plot the DOS.

//Plot the Magnetization along the z-axis.
plotter.clear({_a_, _a_, IDX_SPIN}, {0, 0, 1}, magnetization)"figures/Magnetization.png");


For each point (x, y) on the lattice, the magnetization is a two-by-two complex matrix called a SpinMatrix. The up and down components of the spin are given by the two diagonal entries. We can therefore print the magnetization (the real part of the difference between the up and down components) at site (10, 10) as follows.

SpinMatrix m = magnetization({10, 10, IDX_SPIN});
Streams::out << "Magnetization:\t" << real(, 0) -, 1)) << "\n";


Magnetization:	0.144248

Additional solution methods and properties

The example above demonstrates the general workflow for writing a TBTK application, but the solution method and quantities calculated can vary. The following is a list of native production ready solvers.

The list of production ready properties is.

For more examples and complete applications, see and the templates in the Templates folder.

System requirements

Verified to work with:

  • gcc (v5.4 and up)
  • clang (exact version number not known at the moment).
Required software Further information
CMake (Minimum version 3.1)
Required libraries Further information

Additional features will also be available if one or more of the following libraries are installed. (Note: some of these libraries enable experimental components not yet listed in the public API. Only entries marked in bold below are relevant for one or more official components to work.)

Optional libraries/softwares Further information
Google Test
Matplotlib (Python)
NumPy (Python)
SuperLU (v5.2.1)

The following table shows the optional libraries that are required to enable extensions to the core capabilities. See the documentation for deatiled information about the corresponding components.

Extensions ARPACK CUDA cURL FFTW3 Python with matplotlib and numpy SuperLU (v5.2.1) OpenMP Google Test
ArnoldiIterator X X
ChebyshevExapnder (GPU execution) X
FourierTransform X
Parallel CPU execution of various algorithms X
Plotter X
Resource X
Unit testing X



git clone
git checkout v2.6.2
mkdir TBTKBuild
cd TBTKBuild
cmake ../TBTK
sudo make install

Run unit tests (optional, requires Google Test to be installed)

make test

Create a first application

cd ..
mkdir TBTKApplications
cd TBTKApplications
TBTKCreateAppliaction MyFirstApplication
cd MyFirstApplication

Build and run the application

cmake .


TBTK is free software that is licensed under the Apache 2.0 license (see the file "License"). Please give attribution in accordance with the "Cite" section below.

Third party licenses

json/TBTK/json.hpp (for serialization)

A third-party library hosted at and is licensed under the MIT license.

External/TBTK/External/Boost/gnuplot-iostream.h (for an exeprimental plotter)

This Boost header file is licensed under the Boost license.

Lib/include/TBTK/Visualization/MatPlotLib/ (for the Matplotlib based plotter)

Some of the files in this and the corresponding source folder are based on a rewritten version of matplotlib-cpp (, which originally is licensed under the MIT license.


To cite TBTK, mention TBTK in the text and cite

Kristofer Björnson, TBTK: A quantum mechanics software development kit, SoftwareX 9, 205-210 (2019).

If you use the ChebyshevExpander to produce results, please also cite the following references:

A. Weiße, G. Wellein, A. Alvermann, and H. Fehske,
Rev. Mod. Phys. 78, 275 (2006).

L. Covaci, F. M. Peeters, and M. Berciu,
Phys. Rev. Lett. 105, 167006 (2010).