QuDrip is a modern C++ library designed for easy and efficient implementation of exact quantum many-body simulations. It values flexibility and development efficiency, while maintaining C++ native computational efficiency which is most suitable for small to medium system size with heterogenous fermion and boson dof combination as well as arbitrary constraint on the Hilbert space. It provides a flexible operator framework, Hilbert-space restrictions via conservation laws, sparse-matrix algorithms, and utilities for Hamiltonian and Lindblad-type dynamics.
- Operator framework (local and non-local)
- Index and Hilbert-space representations
- Conservation-law machinery
- Tools for constructing Hamiltonians from gates/operators
- Krylov-space methods
- Lanczos algorithm for ground-state search
- Arnoldi algorithm for dynamics and spectra
- Real-time evolution utilities
- Monte Carlo super-jump method for Markovian Lindblad dynamics
- Lattice and geometry constructors
- Helper routines for simulation workflows
- Eigen3
A typical workflow in QuDrip:
- Create a Hilbert space (e.g., qubits or fermions/bosons) and impose a conserved quantity.
- Define local or non-local operators (“gates”).
- Construct a Hamiltonian either lazily (computational graph) or eagerly (explicit sparse matrices).
- Use Krylov-based solvers such as Lanczos to obtain ground states or real-time evolution.
Create qubit chain (the Hilbert space), here it is a space of
auto prechain = getQbits(Nsite);Corresponding conserved quantity
auto Nset = getNset(prechain);Create boson (single-qbit) gates
auto gc = getBoseGate(prechain);
auto ga = getBoseGate(prechain);Constrain Hilbert space: Nsite/2 spin-up and spin-down
auto chain = Constrain(prechain, Nset = Nsite / 2);Feed spin matrices into gates. Here it is simple spin ladder operator
Matrix Uc = 0.5 * (pauli_x + II * pauli_y);
Matrix Ua = 0.5 * (pauli_x - II * pauli_y);
gc << Uc;
ga << Ua;Build Hamiltonian (the lazy way, where a computational graph is grenerated)
auto ham = getEmptyOperator();
for (int i = 0; i < Nsite - 1; ++i) {
ham = ham + gc(i + 1) * ga(i) + gc(i) * ga(i + 1);
}Apply graph to Hilbert space → sparse matrix
auto ham_mat = ham >> chain;
cout << "Time elapsed: " << c1.release() << std::endl;Lanczos ground-state search
int krylov_dim = 100;
auto psi = getState(chain, 1);
shuffle_state(psi(0));
auto solver = Arnoldi::getLanczosSolver(chain, krylov_dim);
solver.getGroundState(ham_mat, psi(0), 0);Ground-state energy is then evaluated
cout << "E = " << psi.eval(0, ham_mat) << endl;