2020# ╠═╡ show_logs = false
2121begin
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
4041Entanglement 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
4468md"""
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
89125begin
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
118153end ;
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
125180md"
141196
142197# ╔═╡ e876ddcf-d2c9-401e-af83-368fbd5ba593
143198begin
144- best_circuit = pop. individuals[1 ]
199+ best_circuit = pop[] . individuals[1 ]
145200 Quantikz. QuantikzOp.(best_circuit. ops)
146201end
147202
@@ -156,71 +211,94 @@ Fidelity results for this circuit
156211plot_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
166222md"
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
171235begin
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
175249end
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
184255begin
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
208281end
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