Skip to content

Quick start

Hello World

Let us set up our first program using the xdiag library.

using XDiag
say_hello()
#include <xdiag/all.hpp>

using namespace xdiag;

int main() try {
  say_hello();
} catch (Error e) {
  error_trace(e);
}

The function say_hello() prints out a welcome message, which also contains information which exact XDiag version is used. In Julia this is all there is to it.

For the C++ code we need to create two files to compile the program. The first is the actual C++ code. What is maybe a bit unfamiliar is the try / catch block. XDiag implements a traceback mechanism for runtime errors, which is activated by this idiom. While not stricly necessary here, it is a good practice to make use of this.

Now that the application program is written, we next need to set up the compilation instructions using CMake. To do so we create a second file called CMakeLists.txt in the same directory.

cmake_minimum_required(VERSION 3.19)

project(
  hello_world
)

find_package(xdiag REQUIRED HINTS "../../install")
add_executable(main main.cpp)
target_link_libraries(main PRIVATE xdiag::xdiag)

You should replace "/path/to/xdiag/install" with the appropriate directory where your XDiag library is installed after compilation. This exact CMakeLists.txt file can be used to compile any XDiag application.

Info

For using the distributed XDiag library the last line of the above CMakeLists.txt should be changed to

target_link_libraries(main PUBLIC xdiag::xdiag_distributed)

We then compile the application code,

cmake -S . -B build
cmake --build build

and finally run our first xdiag application.

./build/main

Computing the ground state energy of a spin chain

We compute the ground state energy of the \(S=1/2\) Heisenberg chain on a periodic chain lattice in one dimension. The Hamiltonian is given by

\[ H = J\sum_{\langle i,j \rangle} \mathbf{S}_i \cdot \mathbf{S}_j\]

where \(\mathbf{S}_i = (S_i^x, S_i^y, S_i^z)\) are the spin \(S=1/2\) operators and \(\langle i,j \rangle\) denotes summation over nearest-meighbor sites \(i\) and \(j\).

The following code, sets up the Hilbert space, defines the Hamiltonian and finally calls an iterative eigenvalue solver to compute the ground state energy.

using XDiag

let 
    N = 16
    nup = N รท 2
    block = Spinhalf(N, nup)

    # Define the nearest-neighbor Heisenberg model
    ops = OpSum()
    for i in 1:N
        ops += Op("HB", "J", [i-1, i % N])
    end
    ops["J"] = 1.0

    set_verbosity(2)            # set verbosity for monitoring progress
    e0 = eigval0(ops, block)    # compute ground state energy

    println("Ground state energy: $e0")
end
#include <xdiag/all.hpp>

using namespace xdiag;

int main() try {
  int N = 16;
  int nup = N / 2;
  Spinhalf block(N, nup);

  // Define the nearest-neighbor Heisenberg model
  OpSum ops;
  for (int i = 0; i < N; ++i) {
    ops += Op("HB", "J", {i, (i + 1) % N});
  }
  ops["J"] = 1.0;

  set_verbosity(2);                  // set verbosity for monitoring progress
  double e0 = eigval0(ops, block); // compute ground state energy

  Log("Ground state energy: {:.12f}", e0);

} catch (Error e) {
  error_trace(e);
}