genQC logo genQC
  • Overview
  • Get Started
  • Tutorials
  • API Reference
  • Research
  • Code Repository
  1. Benchmark
  2. Compilation benchmark

API Reference

  • Modules Overview
  • Release notes

  • Benchmark
    • Compilation benchmark
  • Dataset
    • Dataset balancing
    • Cached dataset
    • Quantum circuit dataset
    • Config dataset
    • Dataset helper functions
    • Mixed cached dataset
  • Inference
    • Evaluation metrics
    • Evaluation helper
    • Sampling functions
  • Models
    • Config model
    • Frozen OpenCLIP
    • Layers
    • Position encodings
    • Conditional qc-UNet
    • Encoder for unitaries
    • Clip
      • Frozen OpenCLIP
      • Unitary CLIP
    • Embedding
      • Base embedder
      • Rotational preset embedder
    • Transformers
      • Transformers and attention
      • CirDiT - Circuit Diffusion Transformer
      • Transformers
  • Pipeline
    • Callbacks
    • Compilation Diffusion Pipeline
    • Diffusion Pipeline
    • Diffusion Pipeline Special
    • Metrics
    • Multimodal Diffusion Pipeline
    • Pipeline
    • Unitary CLIP Pipeline
  • Platform
    • Circuits dataset generation functions
    • Circuits instructions
    • Simulation backend
    • Backends
      • Base backend
      • CUDA-Q circuits backend
      • Pennylane circuits backend
      • Qiskit circuits backend
    • Tokenizer
      • Base tokenizer
      • Circuits tokenizer
      • Tensor tokenizer
  • Scheduler
    • Scheduler
    • DDIM Scheduler
    • DDPM Scheduler
    • DPM Scheduler
  • Utils
    • Async functions
    • Config loader
    • Math and algorithms
    • Miscellaneous util

On this page

  • Special unitaries
    • SpecialUnitaries
  • Hamiltonian evolutions
    • qubit_tensor_product
    • BaseHamiltonian
    • IsingHamiltonian
    • XXZHamiltonian
  • Report an issue
  • View source
  1. Benchmark
  2. Compilation benchmark

Compilation benchmark

Functions to test and benchmark unitary compilation.

Special unitaries

Quantum Fourier transform

\[ \begin{equation} \mathrm{QFT}: |x\rangle \mapsto \frac{1}{\sqrt{N}} \sum_{k=0}^{N-1} \omega_N^{xk}\;|k\rangle, \end{equation} \] where \[ \begin{equation} \omega_N=\exp{\frac{2\pi i}{N}} \quad\text{and}\quad N=2^{\text{qubits}}. \end{equation} \]


source

SpecialUnitaries

 SpecialUnitaries ()

Special unitary matrices to benchmark compilation.

# test QFT for N=4
QFT_2_qubits = 0.5 * torch.tensor([[1,  1,   1,  1],
                                   [1,  1j, -1, -1j],
                                   [1, -1,   1, -1],
                                   [1, -1j, -1,  1j]], dtype=torch.complex128)

assert torch.allclose(SpecialUnitaries.QFT(num_qubits=2), QFT_2_qubits)
np.round(SpecialUnitaries.QFT(3), 3)
tensor([[ 0.3540+0.0000j,  0.3540+0.0000j,  0.3540+0.0000j,  0.3540+0.0000j,  0.3540+0.0000j,  0.3540+0.0000j,  0.3540+0.0000j,  0.3540+0.0000j],
        [ 0.3540+0.0000j,  0.2500+0.2500j,  0.0000+0.3540j, -0.2500+0.2500j, -0.3540+0.0000j, -0.2500-0.2500j,  0.0000-0.3540j,  0.2500-0.2500j],
        [ 0.3540+0.0000j,  0.0000+0.3540j, -0.3540+0.0000j,  0.0000-0.3540j,  0.3540+0.0000j,  0.0000+0.3540j, -0.3540+0.0000j,  0.0000-0.3540j],
        [ 0.3540+0.0000j, -0.2500+0.2500j,  0.0000-0.3540j,  0.2500+0.2500j, -0.3540+0.0000j,  0.2500-0.2500j,  0.0000+0.3540j, -0.2500-0.2500j],
        [ 0.3540+0.0000j, -0.3540+0.0000j,  0.3540+0.0000j, -0.3540+0.0000j,  0.3540+0.0000j, -0.3540+0.0000j,  0.3540+0.0000j, -0.3540+0.0000j],
        [ 0.3540+0.0000j, -0.2500-0.2500j,  0.0000+0.3540j,  0.2500-0.2500j, -0.3540+0.0000j,  0.2500+0.2500j,  0.0000-0.3540j, -0.2500+0.2500j],
        [ 0.3540+0.0000j,  0.0000-0.3540j, -0.3540+0.0000j,  0.0000+0.3540j,  0.3540+0.0000j,  0.0000-0.3540j, -0.3540+0.0000j,  0.0000+0.3540j],
        [ 0.3540+0.0000j,  0.2500-0.2500j,  0.0000-0.3540j, -0.2500-0.2500j, -0.3540+0.0000j, -0.2500+0.2500j,  0.0000+0.3540j,  0.2500+0.2500j]], dtype=torch.complex128)

Hamiltonian evolutions

assert torch.allclose(sigma_x@sigma_x, torch.eye(2, dtype=torch.complex128))
assert torch.allclose(sigma_y@sigma_y, torch.eye(2, dtype=torch.complex128))
assert torch.allclose(sigma_z@sigma_z, torch.eye(2, dtype=torch.complex128))

source

qubit_tensor_product

 qubit_tensor_product (num_qubits:int, *ops:torch.Tensor,
                       pos:Union[int,Sequence[int]])

Make tensor product with identities, assumes ops placed at pos in the tensor product ordering.

\(\sigma_x \otimes I\):

qubit_tensor_product(2, sigma_x, pos=0)
tensor([[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
        [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]], dtype=torch.complex128)

\(I \otimes \sigma_x\):

qubit_tensor_product(2, sigma_x, pos=-1)
tensor([[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
        [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j]], dtype=torch.complex128)

\(\sigma_z \otimes \sigma_z\):

qubit_tensor_product(2, sigma_z, sigma_z, pos=[0, 1])
tensor([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],
        [ 0.+0.j, -1.+0.j,  0.+0.j, -0.+0.j],
        [ 0.+0.j,  0.+0.j, -1.+0.j, -0.+0.j],
        [ 0.+0.j, -0.+0.j, -0.+0.j,  1.-0.j]], dtype=torch.complex128)

Base Hamiltonian


source

BaseHamiltonian

 BaseHamiltonian (device:Union[str,torch.device,NoneType]=None)

Base implementation of a Hamiltonian.

Ising Hamiltonian

Defined as \[ H = -J \sum_{\langle i, j \rangle} \sigma_i^z \sigma_j^z - h \sum_i \sigma_i^x, \] where \(J\) is the coupling constant and \(h\) a magnetic field.


source

IsingHamiltonian

 IsingHamiltonian (h:float, J:float, num_qubits:int,
                   periodic_boundary:bool=True,
                   device:Union[str,torch.device,NoneType]=None)

Implementation of the Ising Hamiltonian on a qubit chain.

hamiltonian = IsingHamiltonian(h=0, J=1, num_qubits=2)
hamiltonian.data
tensor([[-2.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],
        [ 0.+0.j,  2.+0.j,  0.+0.j,  0.+0.j],
        [ 0.+0.j,  0.+0.j,  2.+0.j,  0.+0.j],
        [ 0.+0.j,  0.+0.j,  0.+0.j, -2.+0.j]], dtype=torch.complex128)

Eigenvalues of this Hamiltonian:

torch.linalg.eigvalsh(hamiltonian.data)
tensor([-2., -2.,  2.,  2.], dtype=torch.float64)
e, v = torch.linalg.eigh(hamiltonian.data)
v
tensor([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]], dtype=torch.complex128)

And the evolution unitary is:

hamiltonian.get_evolution(t=np.pi/6)
tensor([[0.5000+0.8660j, 0.0000+0.0000j, 0.0000+0.0000j, 0.0000+0.0000j],
        [0.0000+0.0000j, 0.5000-0.8660j, 0.0000+0.0000j, 0.0000+0.0000j],
        [0.0000+0.0000j, 0.0000+0.0000j, 0.5000-0.8660j, 0.0000+0.0000j],
        [0.0000+0.0000j, 0.0000+0.0000j, 0.0000+0.0000j, 0.5000+0.8660j]], dtype=torch.complex128)

XXZ Hamiltonian

Defined as \[ H = -J \sum_{\langle i, j \rangle} ( \sigma_i^x \sigma_j^x + \sigma_i^y \sigma_j^y + \Delta \sigma_i^z \sigma_j^z ) - h \sum_i \sigma_i^x, \] where \(J\) is the coupling constant, \(\Delta\) a perturbation and \(h\) a magnetic field.


source

XXZHamiltonian

 XXZHamiltonian (h:float, J:float, delta:float, num_qubits:int,
                 periodic_boundary:bool=True,
                 device:Union[str,torch.device,NoneType]=None)

Implementation of the XXZ Hamiltonian on a qubit chain.

hamiltonian = XXZHamiltonian(h=1, J=1, delta=1, num_qubits=2)
hamiltonian.data
tensor([[-2.+0.j, -1.+0.j, -1.+0.j,  0.+0.j],
        [-1.+0.j,  2.+0.j, -4.+0.j, -1.+0.j],
        [-1.+0.j, -4.+0.j,  2.+0.j, -1.+0.j],
        [ 0.+0.j, -1.+0.j, -1.+0.j, -2.+0.j]], dtype=torch.complex128)

Eigenvalues of this Hamiltonian:

torch.linalg.eigvalsh(hamiltonian.data)
tensor([-4.0000e+00, -2.0000e+00,  8.8818e-16,  6.0000e+00], dtype=torch.float64)

And the evolution unitary is:

hamiltonian.get_evolution(t=np.pi/6)
tensor([[ 0.3750+0.6495j, -0.3750+0.2165j, -0.3750+0.2165j, -0.1250-0.2165j],
        [-0.3750+0.2165j, -0.3750+0.2165j,  0.6250+0.2165j, -0.3750+0.2165j],
        [-0.3750+0.2165j,  0.6250+0.2165j, -0.3750+0.2165j, -0.3750+0.2165j],
        [-0.1250-0.2165j, -0.3750+0.2165j, -0.3750+0.2165j,  0.3750+0.6495j]], dtype=torch.complex128)
hamiltonian.get_evolution(t=np.pi/6, split_complex_channel=True)
tensor([[[ 0.3750, -0.3750, -0.3750, -0.1250],
         [-0.3750, -0.3750,  0.6250, -0.3750],
         [-0.3750,  0.6250, -0.3750, -0.3750],
         [-0.1250, -0.3750, -0.3750,  0.3750]],

        [[ 0.6495,  0.2165,  0.2165, -0.2165],
         [ 0.2165,  0.2165,  0.2165,  0.2165],
         [ 0.2165,  0.2165,  0.2165,  0.2165],
         [-0.2165,  0.2165,  0.2165,  0.6495]]], dtype=torch.float64)
Back to top
Dataset balancing
 

Copyright 2025, Florian Fürrutter

  • Report an issue
  • View source