Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
test_decomposition.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 """
3 Created on Fri Jun 26 14:42:56 2020
4 Copyright 2020 Peter Rakyta, Ph.D.
5 
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see http://www.gnu.org/licenses/.
20 
21 @author: Peter Rakyta, Ph.D.
22 """
23 
25 
26 
27 
28 # cerate unitary q-bit matrix
29 from scipy.stats import unitary_group
30 import numpy as np
31 from squander import utils
32 
33 try:
34  from mpi4py import MPI
35  MPI_imported = True
36 except ModuleNotFoundError:
37  MPI_imported = False
38 
39 
41  """This is a test class of the python iterface to the decompsition classes of the QGD package"""
42 
44  r"""
45  This method is called by pytest.
46  Test to create an instance of class N_Qubit_Decomposition.
47 
48  """
49 
50  from squander import N_Qubit_Decomposition
51 
52  # the number of qubits spanning the unitary
53  qbit_num = 3
54 
55  # determine the soze of the unitary to be decomposed
56  matrix_size = int(2**qbit_num)
57 
58  # creating a random unitary to be decomposed
59  Umtx = unitary_group.rvs(matrix_size)
60 
61  # creating an instance of the C++ class
62  decomp = N_Qubit_Decomposition( Umtx.conj().T, optimize_layer_num=False, initial_guess="random" )
63 
65  r"""
66  This method is called by pytest.
67  Test to decompose a 3-qubit unitary
68 
69  """
70 
71  from squander import N_Qubit_Decomposition
72 
73  # the number of qubits spanning the unitary
74  qbit_num = 3
75 
76  # determine the soze of the unitary to be decomposed
77  matrix_size = int(2**qbit_num)
78 
79  # creating a random unitary to be decomposed
80  Umtx = unitary_group.rvs(matrix_size)
81 
82  # creating an instance of the C++ class
83  decomp = N_Qubit_Decomposition( Umtx )
84 
85  # start the decomposition
86  decomp.Start_Decomposition()
87 
88  decomp.List_Gates()
89 
91  r"""
92  This method is called by pytest.
93  Test to decompose a 2-qubit unitary and retrive the corresponding Qiskit circuit
94 
95  """
96 
97  from squander import N_Qubit_Decomposition
98 
99  # the number of qubits spanning the unitary
100  qbit_num = 2
101 
102  # determine the soze of the unitary to be decomposed
103  matrix_size = int(2**qbit_num)
104 
105  # creating a random unitary to be decomposed
106  Umtx = unitary_group.rvs(matrix_size)
107 
108  # creating an instance of the C++ class
109  decomp = N_Qubit_Decomposition( Umtx.conj().T )
110 
111  # set the number of block to be optimized in one shot
112  decomp.set_Optimization_Blocks( 20 )
113 
114  # setting the verbosity of the decomposition
115  decomp.set_Verbose( 3 )
116 
117  # setting the debugfile name. If it is not set, the program will not debug.
118  decomp.set_Debugfile( "debugfile.txt" )
119 
120  # start the decomposition
121  decomp.Start_Decomposition()
122 
123  # get the decomposing operations
124  quantum_circuit = decomp.get_Qiskit_Circuit()
125 
126  # print the list of decomposing operations
127  decomp.List_Gates()
128 
129  # print the quantum circuit
130  print(quantum_circuit)
131 
132  import numpy.linalg as LA
133 
134  # test the decomposition of the matrix
135 
136  # the unitary matrix from the result object
137  decomposed_matrix = np.asarray( utils.get_unitary_from_qiskit_circuit( quantum_circuit ) )
138  product_matrix = np.dot(Umtx,decomposed_matrix.conj().T)
139  phase = np.angle(product_matrix[0,0])
140  product_matrix = product_matrix*np.exp(-1j*phase)
141 
142  product_matrix = np.eye(matrix_size)*2 - product_matrix - product_matrix.conj().T
143  # the error of the decomposition
144  decomposition_error = (np.real(np.trace(product_matrix)))/2
145 
146  print('The error of the decomposition is ' + str(decomposition_error))
147 
148  assert( decomposition_error < 1e-3 )
149 
150 
151 
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...