Introduction to TBTK – A software development kit for quantum mechanical calculations.

Most recent TBTK release at the time of writing: v0.9.6

What is TBTK?

As industry is approaching the nanometer scale and quantum mechanical effects begin to play a major role in device manufacturing, it is important to enable engineers to model devices using a quantum mechanical description. Decades of development have lead to a range of algorithms being developed in the scientific community, but most packages used for scientific calculations require extensive experience to handle. Many current scientific packages effectively act as black boxes that present themselves to the user through an interface consisting of a set of input and output files. Moreover, these input and output files are often application specific and therefore severely limits the ease with which applications can be interfaced with each other.

TBTK is first and foremost a C++ library of efficient general purpose data structures that are useful when developing quantum mechanical calculations. The data structures provide a high level of abstraction that allow developers to put more focus on physics and less focus on numerical details without sacrificing performance. The data structures are also meant to enable sharing between different applications and making it possible to grow an echo system of applications for quantum mechanical calculations.

While data structures are at the core of TBTK, it also comes with a range of implemented algorithms such as diagonalization, Arnoldi iteration, Chebyshev expansion of the Green’s function, etc. As such, it is already out of the box ready to be used to setup and perform many types of quantum mechanical calculations. The range of solution methods will certainly continue to expand, but TBTK does not necessarily aim to replace many of the already well developed packages in the scientific community. Instead it aims to simplify the development of new algorithms as well as front ends and back ends for already existing packages. Such front ends and back ends would allow already well established packages to communicate with both each other and new algorithms much more closely. It would also limit the demand on developers to understand the intricate details of specific packages in order to use them and thereby make them accessible to a much larger community of developers.

TBTK already provides partial front ends for libraries such as ARPACK, BLAS, FFTW3, LAPACK, and SuperLU, making it simple for users to utilize the power of these libraries without requiring extensive understanding of them. TBTK also uses the CMake build system to simplify the build procedure, which allows developers to focus on their code rather than struggling with configuring compilation and linking dependencies.

What does TBTK stand for?

TBTK stands for Tight-Binding ToolKit and reflects the codes origin as a package for performing tight-binding calculations. However, the code has since expanded significantly in scope and is today most appropriately thought of as a package for setting up and solving Hamiltonians on a second-quantized form

    \[ H = \sum_{\mathbf{i}\mathbf{j}}a_{\mathbf{i}\mathbf{j}}c_{\mathbf{i}}^{\dagger}c_{\mathbf{j}} + H_{Int}. \]

Drawing on its tight-binding origin, the coefficients a_{\mathbf{i}\mathbf{j}} are referred to as hopping amplitudes.

How do I specify a model using TBTK?

Assume we have a model on a square lattice

    \[ H = -\mu\sum_{\mathbf{i}}c_{\mathbf{i}}^{\dagger}c_{\mathbf{i}} - t\sum_{\langle\mathbf{i}\mathbf{j}\rangle}c_{\mathbf{i}}^{\dagger}c_{\mathbf{j}}, \]

where angle brackets denote summation over nearest neighbors. We further write the two-dimensional indices as \mathbf{i} = \{x, y\} and identify the coefficients above as a_{\mathbf{i}\mathbf{i}} = -\mu and a_{\mathbf{i}\mathbf{j}} = -t. Specifying the model is now a matter of feeding the hopping amplitudes a_{\mathbf{i}\mathbf{j}} to the application, which is done in TBTK by creating hopping amplitudes using the notation

HoppingAmplitude(value, i, j)

and feeding them to a Model object. For example, we can setup the Hamiltonian above on a 50\times 50 square lattice with \mu = 1 and t = 1 as follows

const int SIZE_X = 50;
const int SIZE_Y = 50;
const double mu = 1;
const double t = 1;

Model model;
for(int x = 0; x < SIZE_X; x++){
    for(int y = 0; y < SIZE_Y; y++){
        //Add chemical potential mu.
        model << HoppingAmplitude(-mu, {x, y}, {x, y});

        //Add hopping parameter t. The if-statements guard against
        //adding terms at the boundary, while "+ HC" ensures that
        //the Hermitian conjugate is added too.
        if(x+1 < SIZE_X)
            model << HoppingAmplitude(-t, {x+1, y}, {x, y}) + HC;
        if(y+1 < SIZE_Y)
            model << HoppingAmplitude(-t, {x, y+1}, {x, y}) + HC;
//Construct Hilbert space basis for the model.

Rather than making the chemical potential enter into the problem through the Hamiltonian, it is also possible to instead set it as a single parameter of the model using


Similarly, the temperature and particle statistics can be set using


How do I choose a method with which to solve my model?

Once a Model object has been specified we can chose solution algorithm by selecting a solver. We can for example chose to solve the model above through diagonalization as follows

Solver::Diagonalizer solver;

How do I extract properties from my model?

Once a solver has been chosen, properties are most easily extracted from the model by wrapping the solver in a property extractor. In particular, wrapping the solver in a property extractor often allows us to write code that is independent from a particular solver. The solution method can therefore often be changed later without modifying more than a few lines of code. Using a property extractor we can for example calculate the density of states (DOS) for the model above, in the energy window [-10,10] and using an energy resolution of 1000 points, as follows

PropertyExtractor::Diagonalizer propertyExtractor(solver);
propertyExtractor.setEnergyWindow(-10, 10, 1000);
Property::DOS dos = propertyExtractor.calculateDOS();

It is now possible to for example access the 100th DOS value using


Other properties are calculated for specific indices and it is then similarly possible to access these values using

//Property with index structure.
property0({x, y});
//Property with index and energy structure.
property1({x, y}, 100);

What solvers are available by default?

In the latest release (v0.9.6) there are four production ready solvers.


Solves the Hamiltonian using diagonalization.


Solves the Hamiltonian utilizing its block structure to reduce the computational cost.


Calculates a few eigenvalues and eigenvectors using Arnoldi iteration.


Calculates the Green’s function using a Chebyshev expansion method that allows for large systems to be handled on CUDA enabled GPUs.

What properties are available by default?

In the latest release (v0.9.6) there are seven production ready properties. These are: DOS, Density, EigenValues, LDOS, Magnetization, SpinPolarizedLDOS, and WaveFunction.

Where do I learn more?

The best place to learn more about TBTK is the documentation at In particular, the installation instructions and tutorials are the quickest ways to get up and running. The manual provides plenty of material that both clarifies the underlying design philosophy of the package as well as gives an extensive outline of its core components.

Also stay up to date on the Second Tech blog for future announcements and case studies.

How do I get involved?

Contributions are more than welcome to TBTK. The best way to get started is to fork the project on github and start experimenting with the code by writing applications. Extensions can then either be  hosted as separate projects on github under your own user account or a pull request can be made to the main branch. For major new contributions to be accepted back into the main branch, they need to solve relatively general problems and adhere to the overall design principles outlined in the manual. Code will therefore be reviewed based both on general applicability of the contributions as well as the design principles followed. Therefore, please read the manual and review other parts of the code before you begin working on a major contribution to ensure that the style is compatible with the rest of the TBTK code base.

The second quantum revolution

Much of the technological progress of the 20th century is a consequence of the understanding of the quantum mechanical world that has been developed since the beginning of the 20th century. The behavior of semiconductors, lasers, superconductors, nuclear reactors, etc. cannot be understood without a quantum mechanical description, and the period can appropriately be described as the first quantum revolution. However, for practical purposes, classical or semi-classical models has been sufficient to engineer ever more sophisticated applications of these technologies. The underlying quantum mechanical principles have played a relatively minor role in the engineering process and the final end products.

The semiconductor industry has for more than half a century made exponential progress described my Moore’s law and the International Technology Roadmap for Semiconductors targets 5 nm technology in 2021. With a lattice spacing of 0.54 nm for Silicon, this means that industry scale manufacturing is reaching length scales that are as small as ten atoms wide. At the same time the increased computational power and development of more efficient algorithms now allow researchers to simulate the behavior of thousands of atoms starting from quantum mechanical principles, while experimentally ever more complex structures can be built up atom by atom. An impressive demonstration of the later fact can be seen in IBM’s movie “A Boy And His Atom: The World’s Smallest Movie”.

The length scales accessible for industrial applications and the length scales accessible to fundamental quantum mechanical research is therefore rapidly converging. This is the second quantum revolution, where new technology emerge that fundamentally requires a quantum mechanical description to be taken into account in the engineering department as well as manifests quantum mechanical behavior in the end products themselves.

The second quantum revolution is already well on its way. This is not least clear from the many companies that are leaping into the field of quantum computation. IBM has launched a primitive five qubit quantum computer that is possible to interact with online and has recently announced a 50 qubit quantum computer. Microsoft has through Station Q partnered with Universities around the world to develop new quantum computing devices, and recently released a software development kit and the programming language Q# for programming and simulating quantum computers. Recently the European Union also announced a €1 billion project called the Quantum Technology Flagship to kickstart the quantum technology industry in Europe.

The second quantum revolution means that quantum mechanical calculations and experiments will move from being performed in small and relatively independent research groups, to an industrial scale that puts strong requirements on the scalability of the methods used. This will create new job opportunities for physicists and require effective communication of quantum mechanical concepts to a broad engineering community not necessarily familiar with the scientific literature. It also puts strong requirements on the software development practices used to perform quantum mechanical calculations, especially the ability to seamlessly integrate different software components written by experts in different fields. aims to address the first problem by providing resources and a meeting place for quantum physicists, engineers, etc. to collectively build a knowledge base centered around quantum technology. The blog covers recent advances in the field, the Q&A section allows for the community to exchange ideas, and the job section provides a space for employers a employees to meet.

The sister site provides documentation for the source development kit TBTK, which aims to address the software scalability issue by providing reusable data structures for second-quantized models.

Let me know your thoughts in the comments below.