Calculation Example#

The following tutorial shows how to use qse to run a calculation. We use pulser here for the backend.

import numpy as np
import qse

Create a 2D square lattice#

We generate the qbits object that represents a 2D lattice, keeping the lattice spacing a bit below the blockade radius keeps the nearest neighbours antiferromagnetic.

omega_max = 2.0 * 2 * np.pi  # rad/µs
rabi_frequency = omega_max / 2.0  # rad/µs

blockade_radius = qse.calc.blockade_radius(rabi_frequency)
q2d = qse.lattices.square(
    lattice_spacing=0.8 * blockade_radius, repeats_x=3, repeats_y=2
)

print(f"Blockade radius: {blockade_radius:.2f} µm")
q2d.draw(radius="nearest", units="µm")
Blockade radius: 9.76 µm
../_images/e63a2fc29a82048cafc2a6ad76b036e0b122f9b14a66b69d64bd55dd8c781c99.png

Create the hamiltonian#

delta_0 = -6 * rabi_frequency  # ns
delta_f = 2 * rabi_frequency  # ns
t_rise = 252  # ns
t_fall = 500  # ns
t_sweep = int((delta_f - delta_0) / (2 * np.pi * 10) * 1000)  # ns
amplitude_afm = qse.Signals()
amplitude_afm += qse.Signal(np.linspace(0.0, omega_max, t_rise))
amplitude_afm += qse.Signal([omega_max], t_sweep)
amplitude_afm += qse.Signal(np.linspace(omega_max, 0.0, t_fall))

detuning_afm = qse.Signals()
detuning_afm += qse.Signal([delta_0], t_rise)
detuning_afm += qse.Signal(np.linspace(delta_0, delta_f, t_sweep))
detuning_afm += qse.Signal([delta_f], t_fall)

# Check both signals have the same duration
assert amplitude_afm.duration == detuning_afm.duration

fig = qse.vis.draw_amp_and_det(amplitude_afm, detuning_afm, "ns", "rad/µs")
../_images/e0476ca8ddaedb49d2d5c7a2bd5e2169ee1e01c49355b2eefbb1b38046708e8c.png

Set up the calculator and run the job#

pcalc = qse.calc.Pulser(qbits=q2d, amplitude=amplitude_afm, detuning=detuning_afm)
pcalc.build_sequence()
pcalc.calculate()
10.1%. Run time:   0.00s. Est. time left: 00:00:00:00
20.0%. Run time:   0.01s. Est. time left: 00:00:00:00
30.0%. Run time:   0.01s. Est. time left: 00:00:00:00
40.0%. Run time:   0.01s. Est. time left: 00:00:00:00
50.0%. Run time:   0.01s. Est. time left: 00:00:00:00
60.1%. Run time:   0.02s. Est. time left: 00:00:00:00
70.0%. Run time:   0.02s. Est. time left: 00:00:00:00
80.0%. Run time:   0.02s. Est. time left: 00:00:00:00
90.0%. Run time:   0.03s. Est. time left: 00:00:00:00
100.0%. Run time:   0.03s. Est. time left: 00:00:00:00
Total run time:   0.03s
time in compute and simulation = 0.09626054763793945 s.

Sample the result#

count = pcalc.results.sample_final_state(N_samples=1000)
# Let's order by measurement frequency
count = {w: count[w] for w in sorted(count, key=count.get, reverse=True)}
fig = qse.vis.bar(count, cutoff=10)
../_images/803e2d62dff5f7c32b17304f34041dcb11114ddce7da3ca23ed346a593aae254.png

The states 011001 and 100110 are the most prevalent, we can visualise them using the colouring parameter in draw. We see that they correspond to anti-ferromagnetic orderings.

q2d.draw(radius="nearest", colouring="011001", units="µm")
../_images/d9e7b498d8f10f69550e5d99ad90898ba4db8c35f741f3b5045a68673759b2ab.png
q2d.draw(radius="nearest", colouring="100110", units="µm")
../_images/f7d14d96798fb06339915e7f93b3b05724612295b200bfe441b384cfbcd48826.png

Version#

qse.utils.print_environment()
Python version: 3.12.13
qse version: 1.1.13