Skip to content

Commit 5bdfe17

Browse files
authored
update to v0.1.2: Pluto reactivity, user control
Running the pluto notebook is a lot more enjoyable from the user side. Configuration changes are buffered by a PlutoUI.confirm query, meaning many variables can be changed before any simulation is run. Restarting/running the simulation also are now buffered with buttons.
1 parent 420151f commit 5bdfe17

File tree

11 files changed

+403
-109
lines changed

11 files changed

+403
-109
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ QuantumHardware
66
BPGates.jl
77
Manifest.toml
88
meeting_notes.txt
9+
10+
# Coverage files
11+
*.cov
12+
*/*.cov

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# News
22

3+
## v0.1.2 - 2025-08-12
4+
5+
- Pluto reactivity. Running the pluto notebook is a lot more enjoyable from the user side. Configuration changes are buffered by a PlutoUI.confirm query, meaning many variables can be changed before any simulation is run. Restarting/running the simulation also are now buffered with buttons.
6+
- Pluto output select. The user can select which outputs to see
7+
8+
Things to note:
9+
- To make the reactivity improvements on pluto, some hacks are used (see the second code block, and the config block). This increases load time by a small amount.
10+
311
## v0.1.1 - 2025-07-29
412
- Performance evaluations carry over from previous runs.
513
- Warning when simulation is throttled (fidelity = 1)
@@ -9,4 +17,5 @@
917
- Simulation capabilities for commond gates.
1018
- Simulation capabilities for Pauli noise.
1119
- Simple genetic algorithm for optimization of circuits
12-
- Simple Pluto UI example
20+
- Simple Pluto UI example
21+

Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
name = "QEPOptimize"
22
uuid = "9f67e06f-6394-43be-a72d-a2000081c01d"
33
authors = ["Stefan Krastanov <[email protected]>", "QEPOptimize contributors"]
4-
version = "0.1.1"
4+
version = "0.1.2"
55

66
[deps]
77
BPGates = "2c1a90cd-bec4-4415-ae35-245016909a8f"
88
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
99
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
1010
OhMyThreads = "67456a42-1dca-4109-a031-0a68de7e3ad5"
11+
ProgressLogging = "33c8b6b6-d38a-422a-b730-caa89a2f386c"
1112
QuantumClifford = "0525e862-1e90-11e9-3e4d-1b39d7109de1"
1213
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1314
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1415

1516
[compat]
1617
BPGates = "1.2"
18+
ProgressLogging = "0.1.4"
1719
DataStructures = "0.18.22, 0.19"
1820
Makie = "0.22.4, 0.23, 0.24"
1921
OhMyThreads = "0.8.3"

example/pluto.jl

Lines changed: 163 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@ end
2020
# ╠═╡ show_logs = false
2121
begin
2222
using Pkg
23-
Pkg.pkg"add Revise, CairoMakie, PlutoUI, Quantikz, BPGates, QuantumClifford"
23+
Pkg.pkg"add Revise, CairoMakie, PlutoUI, Quantikz, BPGates, QuantumClifford, ProgressLogging"
2424
#using Revise
2525
#Pkg.add(url="https://github.com/QuantumSavory/QEPOptimize.jl.git")
2626
Pkg.develop(path="../")
2727
using CairoMakie
2828
using PlutoUI
29+
using PlutoUI:confirm, Slider
2930
using Quantikz
3031
using QEPOptimize
31-
using QEPOptimize: initialize_pop!, step!, NetworkFidelity
32+
using QEPOptimize: initialize_pop!, step!, NetworkFidelity, Population, EVOLUTION_METRICS
3233
using BPGates
3334
using BPGates: PauliNoise, BellMeasure, CNOTPerm
3435
using QuantumClifford: SparseGate, sCNOT, affectedqubits, BellMeasurement, Reset, sMX, sMZ, sMY
@@ -40,86 +41,140 @@ md"
4041
Entanglement Purification Circuit Generator
4142
"
4243

44+
# ╔═╡ 610c0135-3a8e-4676-aa5f-9ca76546dd98
45+
begin
46+
# to help dealing with variables that should not be changed ever
47+
48+
# Define the population (on its own so it is not regenerated)
49+
const pop = Ref(Population())
50+
51+
# These are here to allow re-definition of the configs' values, without triggering cells (only change the derefrenced value)
52+
# the types are nasty... I know..
53+
54+
const config = Ref{@NamedTuple{num_simulations::Int64, number_registers::Int64, purified_pairs::Int64, code_distance::Int64, pop_size::Int64, noises::Vector{Any}}}()
55+
56+
const init_config = Ref{@NamedTuple{start_ops::Int64, start_pop_size::Int64, num_simulations::Int64, number_registers::Int64, purified_pairs::Int64, code_distance::Int64, pop_size::Int64, noises::Vector{Any}}}()
57+
58+
const step_config = Ref{@NamedTuple{max_ops::Int64, new_mutants::Int64, p_drop::Float64, p_mutate::Float64, p_gain::Float64, evolution_metric::Symbol, max_performance_calcs::Int64, num_simulations::Int64, number_registers::Int64, purified_pairs::Int64, code_distance::Int64, pop_size::Int64, noises::Vector{Any}}}()
59+
60+
const evolution_steps_ref = Ref{Int64}()
61+
62+
nothing;
63+
end
64+
4365
# ╔═╡ 6419143d-dc3a-47f0-8791-004e57b911c1
66+
@bind c confirm(
67+
PlutoUI.combine() do Child
4468
md"""
4569
## Quantum Circuit Parameters
4670
47-
* Number of registers: $(@bind number_registers PlutoUI.Slider(2:6, default=4, show_value=true))
71+
* Number of registers: $(Child("number_registers", PlutoUI.Slider(2:6, default=4, show_value=true)))
72+
73+
* Purified Pairs: $(Child("purified_pairs", PlutoUI.Slider(1:5, default=1, show_value=true)))
4874
49-
* Purified Pairs: $(@bind purified_pairs PlutoUI.Slider(1:5, default=1, show_value=true))
75+
* Maximum Operations: $(Child("max_ops", PlutoUI.Slider(10:5:30, default=15, show_value=true)))
5076
51-
* Maximum Operations: $(@bind max_ops PlutoUI.Slider(10:5:30, default=15, show_value=true))
77+
* Code distance: $(Child("code_distance", PlutoUI.Slider(1:1:6, default=1, show_value=true)))
5278
5379
### Error Parameters
5480
55-
* Network fidelity: $(@bind network_fidelity PlutoUI.Slider(0.:0.002:0.3, default=0.1, show_value=true))
81+
* Network fidelity: $(Child( "network_fidelity", PlutoUI.Slider(0.:0.002:0.3, default=0.1, show_value=true)))
5682
57-
* Gate error X: $(@bind paulix PlutoUI.Slider(0.:0.002:0.1, default=0.01, show_value=true))
83+
* Gate error X: $(Child("paulix",PlutoUI.Slider(0.:0.002:0.1, default=0.01, show_value=true)))
5884
59-
* Gate error Y: $(@bind pauliy PlutoUI.Slider(0.:0.002:0.1, default=0.01, show_value=true))
85+
* Gate error Y: $(Child("pauliy", PlutoUI.Slider(0.:0.002:0.1, default=0.01, show_value=true)))
6086
61-
* Gate error Z: $(@bind pauliz PlutoUI.Slider(0.:0.002:0.1, default=0.01, show_value=true))
87+
* Gate error Z: $(Child( "pauliz",PlutoUI.Slider(0.:0.002:0.1, default=0.01, show_value=true)))
6288
6389
## Simulation Parameters
6490
65-
* Number of Simulations: $(@bind num_simulations PlutoUI.Slider(100:100:5000, default=1000, show_value=true))
91+
* Number of Simulations: $(Child("num_simulations", PlutoUI.Slider(100:100:5000, default=1000, show_value=true)))
6692
67-
* Max performance calculations per circuit: $(@bind max_perf_calcs PlutoUI.Slider(1:1:50, default=10, show_value=true))
93+
* Max performance calculations per circuit: $(Child("max_perf_calcs", PlutoUI.Slider(1:1:50, default=10, show_value=true)))
6894
69-
* Population Size: $(@bind pop_size PlutoUI.Slider(10:10:100, default=20, show_value=true))
95+
* Population Size: $( Child("pop_size", PlutoUI.Slider(10:10:100, default=20, show_value=true)))
7096
71-
* Initial Operations: $(@bind start_ops PlutoUI.Slider(5:20, default=10, show_value=true))
72-
* Initial Population Size: $(@bind start_pop_size PlutoUI.Slider(100:100:2000, default=1000, show_value=true))
97+
* Initial Operations: $(Child( "start_ops", PlutoUI.Slider(5:20, default=10, show_value=true)))
98+
* Initial Population Size: $(Child( "start_pop_size", PlutoUI.Slider(100:100:2000, default=1000, show_value=true)))
7399
74100
### Evolution Parameters
75101
76-
* Number of Evolution Steps: $(@bind evolution_steps PlutoUI.Slider(50:150, default=80, show_value=true))
102+
* Evolution metric: $(Child("evolution_metric", PlutoUI.Select([:logical_qubit_fidelity => "Logical qubit fidelity",:purified_pairs_fidelity => "Purified pairs fidelity" ,:average_marginal_fidelity => "Average marginal fidelity"])))
77103
78-
* New Mutants: $(@bind new_mutants PlutoUI.Slider(5:1:30, default=10, show_value=true))
104+
* Number of Evolution Steps: $(Child("evolution_steps", PlutoUI.Slider(10:150, default=50, show_value=true)))
79105
80-
* Drop Probability: $(@bind p_drop PlutoUI.Slider(0.0:0.05:0.5, default=0.1, show_value=true))
106+
* New Mutants: $(Child( "new_mutants", PlutoUI.Slider(5:5:30, default=10, show_value=true)))
81107
82-
* Mutation Probability: $(@bind p_mutate PlutoUI.Slider(0.0:0.05:0.5, default=0.1, show_value=true))
108+
* Drop Probability: $(Child("p_drop", PlutoUI.Slider(0.0:0.05:0.5, default=0.1, show_value=true)))
83109
84-
* Gain Probability: $(@bind p_gain PlutoUI.Slider(0.0:0.05:0.5, default=0.1, show_value=true))
110+
* Mutation Probability: $(Child("p_mutate", PlutoUI.Slider(0.0:0.05:0.5, default=0.1, show_value=true)))
111+
112+
* Gain Probability: $(Child("p_gain", PlutoUI.Slider(0.0:0.05:0.5, default=0.1, show_value=true)))
85113
86114
"""
115+
end; label="Update Config"
116+
)
87117

88-
# ╔═╡ 7419143d-dc3a-47f0-8791-004e57b911c2
118+
# ╔═╡ a892e297-7223-4d1a-b772-5f4ca5c64339
119+
@bind restart_population_trigger PlutoUI.CounterButton("Restart Population")
120+
121+
# ╔═╡ dad1728c-c341-44cc-88e6-d26ca1815a30
122+
@bind run_simulation_trigger PlutoUI.CounterButton("Run simulation")
123+
124+
# ╔═╡ cef70317-fc58-42b3-987b-a454064f0113
89125
begin
90-
config = (;
91-
num_simulations=num_simulations,
92-
number_registers=number_registers,
93-
purified_pairs=purified_pairs,
94-
code_distance=1, # Not needed to change for now
95-
pop_size=pop_size,
96-
noises=[NetworkFidelity(network_fidelity), PauliNoise(paulix, pauliy, pauliz)],
97-
max_performance_calcs=max_perf_calcs
98-
)
126+
config[] = (
127+
num_simulations=c.num_simulations,
128+
number_registers=c.number_registers,
129+
purified_pairs=c.purified_pairs,
130+
code_distance=c.code_distance, # For logical qubit fidelity
131+
pop_size=c.pop_size,
132+
noises=[NetworkFidelity(c.network_fidelity), PauliNoise(c.paulix, c.pauliy, c.pauliz)],
133+
)
99134

100-
init_config = (;
101-
start_ops=start_ops,
102-
start_pop_size=start_pop_size,
103-
config...
135+
init_config[] = (
136+
start_ops=c.start_ops,
137+
start_pop_size=c.start_pop_size,
138+
config[]...
104139
)
105-
106-
step_config = (;
107-
max_ops=max_ops,
108-
new_mutants=new_mutants,
109-
p_drop=p_drop,
110-
p_mutate=p_mutate,
111-
p_gain=p_gain,
112-
config...
140+
141+
step_config[] = (;
142+
max_ops=c.max_ops,
143+
new_mutants=c.new_mutants,
144+
p_drop=c.p_drop,
145+
p_mutate=c.p_mutate,
146+
p_gain=c.p_gain,
147+
evolution_metric=c.evolution_metric,
148+
max_performance_calcs=c.max_perf_calcs,
149+
config[]...
113150
)
114-
115-
pop = Population()
116-
117-
initialize_pop!(pop; init_config...)
151+
152+
evolution_steps_ref[] = c.evolution_steps
118153
end;
119154

155+
# ╔═╡ 3d17bc74-fa91-410c-b060-b15eae7a564b
156+
begin
157+
# Re-generate population
158+
restart_population_trigger
159+
160+
initialize_pop!(pop[]; init_config[]...);
161+
md"Regenerating Population..."
162+
end
120163

121164
# ╔═╡ c09c7bb8-1d08-45da-81ca-0cf1d1985b91
122-
_, fitness_history, transition_counts_matrix, transition_counts_keys = multiple_steps_with_history!(pop, evolution_steps; step_config...);
165+
begin
166+
# Run simulation
167+
run_simulation_trigger
168+
try
169+
# check if values have been set
170+
pop[], evolution_steps_ref[], step_config[];
171+
catch
172+
throw("Config not set")
173+
end
174+
_, fitness_history, transition_counts_matrix, transition_counts_keys = multiple_steps_with_history!(pop[], evolution_steps_ref[]; step_config[]...);
175+
176+
md"""Optimizing..."""
177+
end
123178

124179
# ╔═╡ 451be68d-b0bb-4b1b-b7fa-5c39618f95de
125180
md"
@@ -141,7 +196,7 @@ md"
141196

142197
# ╔═╡ e876ddcf-d2c9-401e-af83-368fbd5ba593
143198
begin
144-
best_circuit = pop.individuals[1]
199+
best_circuit = pop[].individuals[1]
145200
Quantikz.QuantikzOp.(best_circuit.ops)
146201
end
147202

@@ -156,71 +211,94 @@ Fidelity results for this circuit
156211
plot_circuit_analysis(
157212
best_circuit;
158213
num_simulations=fidelity_num_simulations,
159-
config.number_registers,
160-
config.purified_pairs,
161-
noise_sets=[[PauliNoise(paulix, pauliy, pauliz)],[]],
214+
config[].number_registers,
215+
config[].purified_pairs,
216+
noise_sets=[[PauliNoise(c.paulix, c.pauliy, c.pauliz)],[]],
162217
noise_set_labels=["with gate noise", "no gate noise"]
163218
)
164219

165-
# ╔═╡ 55dec933-ace8-4a90-bfc3-3dcd9e23a4cc
220+
221+
# ╔═╡ 402e6b8b-7c13-4ab0-9d40-1b764dba1691
166222
md"
167-
Operations on this circuit:
223+
Choose how to display operations on this circuit:
168224
"
169225

226+
# ╔═╡ 9a1b169a-36f5-4d2e-ad63-a7e184abde66
227+
begin
228+
@bind enabled_output PlutoUI.MultiCheckBox([:print => "Print",:stab_desc => "Stabilizer description"];default=[:print,:stab_desc])
229+
end
230+
231+
# ╔═╡ 23123ce9-58b0-4eb7-8d39-fd56499b3ed2
232+
:print in enabled_output ? md"#### Print" : nothing
233+
170234
# ╔═╡ e19cb382-99ae-4629-8242-83827c9e3631
171235
begin
172-
for g in best_circuit.ops
173-
println(g)
236+
if :print in enabled_output
237+
for g in best_circuit.ops println(g) end
238+
md"""
239+
BPGates.CNOTPerm:
240+
$(@doc BPGates.CNOTPerm)
241+
242+
BPGates.BellMeasure:
243+
$(@doc BPGates.BellMeasure)
244+
245+
Operations on the best circuit:
246+
"""
247+
else
174248
end
175249
end
176250

177-
# ╔═╡ 49894406-6dfe-4aeb-8193-e31731bfab65
178-
@doc BPGates.CNOTPerm
179-
180-
# ╔═╡ e99563b8-2827-4e0a-b7c5-e812fef7c6c5
181-
@doc BPGates.BellMeasure
251+
# ╔═╡ b2f3c15c-1b03-4c4e-9c68-539f96ebd4cb
252+
:stab_desc in enabled_output ? md"#### Stabilizer Description" : nothing
182253

183254
# ╔═╡ c434086a-d9e3-436b-91ad-a7ddef56622d
184255
begin
185-
for g in best_circuit.ops
186-
for qcg in BPGates.toQCcircuit(g)
187-
if isa(qcg, SparseGate)
188-
println(qcg.cliff)
189-
println("on qubit $(qcg.indices...)")
190-
elseif isa(qcg, sCNOT)
191-
println("CNOT on qubits $(affectedqubits(qcg))")
192-
elseif isa(qcg, BellMeasurement)
193-
print("measure ")
194-
for m in qcg.measurements
195-
print(Dict(sMX=>:X, sMY=>:Y, sMZ=>:Z)[typeof(m)])
196-
print(m.qubit)
197-
print(" ")
256+
if :stab_desc in enabled_output
257+
for g in best_circuit.ops
258+
for qcg in BPGates.toQCcircuit(g)
259+
if isa(qcg, SparseGate)
260+
println(qcg.cliff)
261+
println("on qubit $(qcg.indices...)")
262+
elseif isa(qcg, sCNOT)
263+
println("CNOT on qubits $(affectedqubits(qcg))")
264+
elseif isa(qcg, BellMeasurement)
265+
print("measure ")
266+
for m in qcg.measurements
267+
print(Dict(sMX=>:X, sMY=>:Y, sMZ=>:Z)[typeof(m)])
268+
print(m.qubit)
269+
print(" ")
270+
end
271+
println("of parity $(qcg.parity)")
272+
elseif isa(qcg, Reset)
273+
println("new raw Bell pair")
274+
else
275+
println(qcg)
198276
end
199-
println("of parity $(qcg.parity)")
200-
elseif isa(qcg, Reset)
201-
println("new raw Bell pair")
202-
else
203-
println(qcg)
277+
println()
204278
end
205-
println()
206279
end
207280
end
208281
end
209282

210283
# ╔═╡ Cell order:
211284
# ╟─8fc5cb18-70cc-4846-a62b-4cda69df12b0
212-
# ╟─353e15de-0a9b-4107-a265-28953e1deee2
285+
# ╠═353e15de-0a9b-4107-a265-28953e1deee2
286+
# ╟─610c0135-3a8e-4676-aa5f-9ca76546dd98
213287
# ╟─6419143d-dc3a-47f0-8791-004e57b911c1
214-
# ╟─7419143d-dc3a-47f0-8791-004e57b911c2
288+
# ╟─a892e297-7223-4d1a-b772-5f4ca5c64339
289+
# ╟─dad1728c-c341-44cc-88e6-d26ca1815a30
290+
# ╟─cef70317-fc58-42b3-987b-a454064f0113
291+
# ╟─3d17bc74-fa91-410c-b060-b15eae7a564b
215292
# ╟─c09c7bb8-1d08-45da-81ca-0cf1d1985b91
216293
# ╟─451be68d-b0bb-4b1b-b7fa-5c39618f95de
217-
# ╠═988e9e99-cf93-46a3-be59-11c11e316b07
294+
# ╟─988e9e99-cf93-46a3-be59-11c11e316b07
218295
# ╟─1b6a9400-9d3b-42f1-a83f-c16f8134cb93
219296
# ╟─e876ddcf-d2c9-401e-af83-368fbd5ba593
220297
# ╟─4ab68db5-70cd-45e1-90bb-9fbb2830a3e4
221298
# ╟─81aa21b4-50f0-4695-a9d0-fd998b0c0cc1
222-
# ╟─55dec933-ace8-4a90-bfc3-3dcd9e23a4cc
299+
# ╟─402e6b8b-7c13-4ab0-9d40-1b764dba1691
300+
# ╟─9a1b169a-36f5-4d2e-ad63-a7e184abde66
301+
# ╟─23123ce9-58b0-4eb7-8d39-fd56499b3ed2
223302
# ╟─e19cb382-99ae-4629-8242-83827c9e3631
224-
# ╠═49894406-6dfe-4aeb-8193-e31731bfab65
225-
# ╠═e99563b8-2827-4e0a-b7c5-e812fef7c6c5
226-
# ╠═c434086a-d9e3-436b-91ad-a7ddef56622d
303+
# ╟─b2f3c15c-1b03-4c4e-9c68-539f96ebd4cb
304+
# ╟─c434086a-d9e3-436b-91ad-a7ddef56622d

0 commit comments

Comments
 (0)