Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

963 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

blueqat

A Quantum Computing SDK

Documentation: https://blueqat.github.io/blueqatSDK/

Blueqat's simulator is built on PyTorch, with two selectable execution modes: a dense statevector simulator and a memory-scalable tensornet (tensor-network contraction) simulator, which is the default. Both are differentiable, so circuits with torch.Tensor parameters keep their gradients through Circuit.run().

Tutorial

https://github.com/Blueqat/Blueqat-tutorials

Examples

Runnable scripts in examples/:

  • bell_state.py -- circuit basics: statevector, single amplitude, shot sampling
  • teleportation.py -- quantum teleportation, coherent and measured versions
  • grover_search.py -- Grover's search over 8 items with oracle + diffusion
  • qft.py -- Quantum Fourier Transform vs. the DFT matrix, period readout
  • vqe_ground_state.py -- VQE with a custom AnsatzBase (not tied to QAOA)
  • maxcut_qaoa.py -- QAOA for the graph Max-Cut problem
  • numpartition_qaoa.py -- QAOA for number partitioning
  • exchange_only.py -- exchange-only spin qubits: logical circuits from pure exchange pulses
  • shor_15.py -- Shor's order finding for N=15 structured with nested named blocks

Install

git clone https://github.com/blueqat/blueqatSDK
cd blueqatSDK
pip install -e .

Circuit

from blueqat import Circuit
import math

#number of qubit is not specified
c = Circuit()

#if you want to specified the number of qubit
c = Circuit(50) #50qubits

Method Chain

# write as chain
Circuit().h[0].x[0].z[0]

# write in separately
c = Circuit().h[0]
c.x[0].z[0]

Slice

Circuit().z[1:3] # Zgate on 1,2
Circuit().x[:3] # Xgate on (0, 1, 2)
Circuit().h[:] # Hgate on all qubits
Circuit().x[1, 2] # 1qubit gate with comma

Rotation Gate

Circuit().rz(math.pi / 4)[0]

Run

from blueqat import Circuit
Circuit(20).h[:].run() # returns a torch.Tensor statevector

# Select the execution mode explicitly (tensornet is the default)
Circuit(20).h[:].run(mode="statevector")
Circuit(20).h[:].run(mode="tensornet")

Run(shots=n)

Circuit(100).x[:].run(shots=1)
# => Counter({'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111': 1})

Large-scale circuits

The dense statevector has 2**n_qubits entries, so for large n_qubits in tensornet mode (the default), run() requires either shots= or returns="amplitude" instead of materializing the full vector:

Circuit(50).h[:].run(shots=3)
Circuit(50).h[:].run(returns="amplitude", amplitude="0" * 50)

Single Amplitude

Circuit(4).h[:].run(amplitude="0101")

Reset and mid-circuit measurement

# reset[i] forces qubit i back to |0>. Any circuit containing reset is run
# shot-by-shot with a real probabilistic collapse at each measure/reset.
Circuit(2).h[0].cx[0, 1].reset[0].m[:].run(shots=100)

# Measurement keys let you tag a measurement and read it back per-shot.
Circuit().x[0].m(key="a")[0].run(shots=10, returns="samples")
# => [{'a': [1]}, {'a': [1]}, ...]

Ancilla qubits

c = Circuit(4).h[0].h[1].h[2].h[3]
with c.ancilla() as a:       # allocate a fresh qubit past the current width
    c.cx[0, a[0]]
    c.cx[0, a[0]]
with c.ancilla(pos=6, stop=8, reset=True) as a:  # or pin an explicit range
    c.cx[3, a[0]]
# a[i] is reset back to |0> on exiting the `with` block when reset=True (the default)

Expectation value of hamiltonian

from blueqat.utils import Z
hamiltonian = 1*Z[0]+1*Z[1]
Circuit(4).x[:].run(hamiltonian=hamiltonian)
# => -2.0

# Or the equivalent convenience method (differentiable):
Circuit(4).x[:].expect(hamiltonian)

Named gate blocks (nested subcircuits)

c = Circuit(7)
with c.block("order-finding"):
    with c.block("superposition"):
        c.h[4, 5, 6]
    with c.block("c-U^1"):
        c.cswap[4, 2, 3].cswap[4, 1, 2].cswap[4, 0, 1]
    c.append_block("IQFT", qft_circuit(3).dagger(), offset=4)

print(c.tree())      # shows the nested structure (see examples/shor_15.py)
c.run()              # backends see the plain gates -- execution is unchanged
c.dagger()           # inverts blocks as blocks ("order-finding†")

c.run(backend="draw")                     # blocks drawn as labeled boxes
c.run(backend="draw", expand_blocks=True) # ...or expanded into their gates

Probabilities, depth and gate counts

Circuit(2).h[0].cx[0, 1].probs()        # measurement probabilities (differentiable)
Circuit(2).h[0].cx[0, 1].probs([1])     # marginal on selected qubits
Circuit(2).h[0].cx[0, 1].depth()        # => 2
Circuit(2).h[0].cx[0, 1].count_ops()    # => Counter({'h': 1, 'cx': 1})

Exchange-only spin qubits (silicon quantum dots)

import blueqat.eo                      # registers the 'eo' backend
from blueqat.eo import encoding, synthesize_1q

# The native hardware primitive: a Heisenberg exchange pulse
Circuit(2).exch(math.pi)[0, 1]         # theta = pi is an exact SWAP

# Transpile a logical circuit into pure exchange pulses
# (3 spins per logical qubit; H = 3 pulses, Fong-Wandzura CNOT = 28 pulses)
physical = Circuit(2).h[0].cx[0, 1].run(backend='eo')

# Run the pulses on the encoded state and inspect the logical result
init = encoding.encode_state([(1, 0), (1, 0)])   # |00>_L
final = physical.run(initial=init)
encoding.leakage(final, 0)                       # leakage out of the code space

# Differentiable pulse synthesis: any SU(2) in 4 constant-amplitude pulses
seq = synthesize_1q(target_2x2_unitary, n_pulses=4)

# Re-calibrate a drifted 2-qubit sequence back to an exact gate
from blueqat.eo import synthesize_2q, quantize_sequence, to_schedule
refined = synthesize_2q(cx_4x4, pairs=pulse_pairs, initial_thetas=drifted)

# Discrete pulse durations (hardware clock ticks) and time-resolved schedules
seq_q = quantize_sequence(seq, step=2 * math.pi / 4096)
schedule = to_schedule(physical)   # ASAP-parallel, JSON-ready pulse schedule

Cloud access (API key groundwork)

import blueqat.cloud as cloud
cloud.save_api_key("YOUR_API_KEY")   # stored in ~/.blueqat/config.json (0600)
# or: export BLUEQAT_API_KEY=...    # environment variable takes priority

import blueqat.cloud                 # registers the 'cloud' backend
# Circuit(2).h[0].cx[0, 1].m[:].run(backend='cloud', shots=100)
# (submits the JSON-serialized circuit once the public endpoint is live)

Blueqat to/from QASM

Circuit().h[0].to_qasm()

#OPENQASM 2.0;
#include "qelib1.inc";
#qreg q[1];
#creg c[1];
#h q[0];

from blueqat.circuit_funcs import from_qasm
from_qasm(Circuit().h[0].to_qasm())  # parses back into an equivalent Circuit

Hamiltonian

from blueqat.utils import X, Y, Z, I

h1 = 1.23 * Z[0] + 4.56 * X[1] * Z[2]
h2 = 2.46 * Y[0] + 5.55 * Z[1] * X[2] * X[1]
hamiltonian = h1 * h1 + h2 * h2
print(hamiltonian)

Simplify the Hamiltonian

hamiltonian = hamiltonian.simplify()
print(hamiltonian)

QUBO Hamiltonian

from blueqat.utils import qubo_bit as q

hamiltonian = -3*q(0)-3*q(1)-3*q(2)-3*q(3)-3*q(4)+2*q(0)*q(1)+2*q(0)*q(2)+2*q(0)*q(3)+2*q(0)*q(4)
print(hamiltonian)

Time Evolution

import numpy as np
from blueqat import Circuit
from blueqat.utils import Z, X

hamiltonian = [1.0*Z[0], 1.0*X[0]]
a = [term.get_time_evolution() for term in hamiltonian]

time_evolution = Circuit().h[0]
for evo in a:
    evo(time_evolution, np.random.rand())

print(time_evolution)

VQE

import torch
from blueqat import Circuit
from blueqat.utils import Z, AnsatzBase, Vqe

class MyAnsatz(AnsatzBase):
    def get_circuit(self, params: torch.Tensor) -> Circuit:
        return Circuit(1).rx(params[0])[0]

hamiltonian = 1.0 * Z[0]
vqe = Vqe(MyAnsatz(hamiltonian, n_params=1))
result = vqe.run(initial_params=torch.tensor([0.1]))  # initial_params is optional
print(result.params, result.circuit.run())
print(vqe.sampler_call_count)  # 0 unless a sampler was supplied to Vqe(...)

QAOA

from blueqat.utils import qubo_bit as q, QaoaAnsatz, Vqe

hamiltonian = q(0)-q(1)
step = 1

vqe = Vqe(QaoaAnsatz(hamiltonian, step))
result = vqe.run()
result.circuit.run(shots=100)

# => Counter({'10': 100})

Drawing

Circuit().h[0].cx[0, 1].m[:].run(backend="draw")     # circuit diagram
Circuit().h[0].cx[0, 1].run(backend="draw_tn")        # tensor-network graph

Document

https://blueqat.github.io/blueqatSDK/ (日本語版: https://blueqat.github.io/blueqatSDK/ja/index.html)

Disclaimer

Copyright 2026 The blueqat Developers.

Releases

Packages

Used by

Contributors

Languages