This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
toffoli_synthesis.py
54 lines (42 loc) · 2.21 KB
/
toffoli_synthesis.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
"""Optimize a 3-qubit circuit to be a toffoli gate."""
import numpy as np
from scipy.stats import unitary_group
from qfactor import Gate, optimize, get_distance
# The next two lines start qfactor's logger.
import logging
logging.getLogger( "qfactor" ).setLevel( logging.INFO )
# We will optimize towards the toffoli unitary.
toffoli = np.array( [ [ 1, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 1, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 1, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 1, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 1, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 0, 0, 0, 0, 0, 0, 1, 0 ] ] )
# Start with the circuit structure
# and an initial guess for the gate's unitaries.
# Here we use randomly generated unitaries for initial guess.
circuit = [ Gate( unitary_group.rvs(4), (1, 2) ),
Gate( unitary_group.rvs(4), (0, 2) ),
Gate( unitary_group.rvs(4), (1, 2) ),
Gate( unitary_group.rvs(4), (0, 2) ),
Gate( unitary_group.rvs(4), (0, 1) ) ]
# Note: the Gate object also has an optional boolean parameter "fixed"
# If "fixed" is set to true, that gate's unitary will not change.
# Call the optimize function
ans = optimize( circuit, toffoli, # <--- These are the only required args
diff_tol_a = 1e-12, # Stopping criteria for distance change
diff_tol_r = 1e-6, # Relative criteria for distance change
dist_tol = 1e-12, # Stopping criteria for distance
max_iters = 100000, # Maximum number of iterations
min_iters = 1000, # Minimum number of iterations
slowdown_factor = 0 ) # Larger numbers slowdown optimization
# to avoid local minima
# The result "ans" is another circuit object (list[Gate])
# with the gate's unitaries changed from the input circuit.
print( "Circuit: ", ans )
print( "Final Distance: ", get_distance( ans, toffoli ) )
# If you would like to convert the unitary operations to native gates,
# you should use the KAK decomposition for 2 qubit unitaries, or
# qsearch or qfast for 3+ qubit unitaries.