Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
test_IBM.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 
34 try:
35  from mpi4py import MPI
36  MPI_imported = True
37 except ModuleNotFoundError:
38  MPI_imported = False
39 
40 
41 
43  """This is a test class of the python iterface to the decompsition classes of the QGD package"""
44 
45 
46 
47  def test_IBM_Chellenge(self):
48  r"""
49  This method is called by pytest.
50  Test to decompose a 4-qubit unitary of the IBM chellenge
51 
52  """
53 
54  from squander import N_Qubit_Decomposition
55  from scipy.io import loadmat
56 
57  # load the unitary from file
58  data = loadmat('data/Umtx.mat')
59  # The unitary to be decomposed
60  Umtx = data['Umtx']
61 
62 
63  # creating a class to decompose the unitary
64  cDecompose = N_Qubit_Decomposition( Umtx.conj().T, optimize_layer_num=True, initial_guess="CLOSE_TO_ZERO" )
65 
66 
67  # set the number of successive identical blocks in the optimalization of disentanglement of the n-th qubits
68  cDecompose.set_Identical_Blocks( {4: 2, 3: 1} )
69 
70  # set the maximal number of layers in the decomposition
71  cDecompose.set_Max_Layer_Num( {4: 9, 3:4} )
72 
73  # set the number of iteration loops in the decomposition
74  cDecompose.set_Iteration_Loops({4: 3, 3: 3, 2: 3})
75 
76  # setting the verbosity of the decomposition
77  #cDecompose.set_Verbose( True )
78 
79  # set the number of block to be optimized in one shot
80  cDecompose.set_Optimization_Blocks( 20 )
81 
82  # starting the decomposition
83  cDecompose.Start_Decomposition()
84 
85  # list the decomposing operations
86  cDecompose.List_Gates()
87 
88  # get the decomposing operations
89  quantum_circuit = cDecompose.get_Qiskit_Circuit()
90 
91  # print the quantum circuit
92  print(quantum_circuit)
93 
94 
95  import numpy.linalg as LA
96 
97  # test the decomposition of the matrix
98  # the unitary matrix from the result object
99  decomposed_matrix = utils.get_unitary_from_qiskit_circuit( quantum_circuit )
100  product_matrix = np.dot(Umtx,decomposed_matrix.conj().T)
101  phase = np.angle(product_matrix[0,0])
102  product_matrix = product_matrix*np.exp(-1j*phase)
103 
104  product_matrix = np.eye(16)*2 - product_matrix - product_matrix.conj().T
105  # the error of the decomposition
106  decomposition_error = (np.real(np.trace(product_matrix)))/2
107 
108  print('The error of the decomposition is ' + str(decomposition_error))
109 
110  assert( decomposition_error < 1e-3 )
111 
112 
113 
115  r"""
116  This method is called by pytest.
117  Test to decompose a 4-qubit unitary of the IBM chellenge
118 
119  """
120 
121  from squander import N_Qubit_Decomposition_adaptive
122  from scipy.io import loadmat
123 
124  # load the unitary from file
125  data = loadmat('data/Umtx.mat')
126  # The unitary to be decomposed
127  Umtx = data['Umtx']
128 
129 
130  # creating a class to decompose the unitary
131  cDecompose = N_Qubit_Decomposition_adaptive( Umtx.conj().T, level_limit_max=5, level_limit_min=0 )
132 
133 
134  # setting the verbosity of the decomposition
135  cDecompose.set_Verbose( 3 )
136 
137  # set initial parameters
138  rng = np.random.default_rng( 42 )
139  num_of_parameters = cDecompose.get_Parameter_Num()
140  parameters = rng.random(num_of_parameters)*2*np.pi
141 
142  cDecompose.set_Optimized_Parameters( parameters )
143 
144  # starting the decomposition
145  cDecompose.Start_Decomposition()
146 
147  # list the decomposing operations
148  cDecompose.List_Gates()
149 
150  # get the decomposing operations
151  quantum_circuit = cDecompose.get_Qiskit_Circuit()
152 
153  # print the quantum circuit
154  print(quantum_circuit)
155 
156  import numpy.linalg as LA
157 
158  # the unitary matrix from the result object
159  decomposed_matrix = utils.get_unitary_from_qiskit_circuit( quantum_circuit )
160  product_matrix = np.dot(Umtx,decomposed_matrix.conj().T)
161  phase = np.angle(product_matrix[0,0])
162  product_matrix = product_matrix*np.exp(-1j*phase)
163 
164  product_matrix = np.eye(16)*2 - product_matrix - product_matrix.conj().T
165  # the error of the decomposition
166  decomposition_error = (np.real(np.trace(product_matrix)))/2
167 
168  print('The error of the decomposition is ' + str(decomposition_error))
169 
170  assert( decomposition_error < 1e-3 )
171 
172 
173 
174 
175 
177  r"""
178  This method is called by pytest.
179  Test to decompose a 4-qubit unitary of the IBM chellenge
180 
181  """
182 
183  from squander import N_Qubit_Decomposition_adaptive
184  from scipy.io import loadmat
185 
186  # load the unitary from file
187  data = loadmat('data/Umtx.mat')
188  # The unitary to be decomposed
189  Umtx = data['Umtx']
190  Umtx = Umtx[0:14,:]
191 
192 
193  # creating a class to decompose the unitary
194  cDecompose = N_Qubit_Decomposition_adaptive( Umtx.conj().T, level_limit_max=5, level_limit_min=0 )
195 
196 
197  # setting the verbosity of the decomposition
198  cDecompose.set_Verbose( 3 )
199 
200  # set initial parameters
201  rng = np.random.default_rng( 42 )
202  num_of_parameters = cDecompose.get_Parameter_Num()
203  parameters = rng.random(num_of_parameters)*2*np.pi
204 
205  cDecompose.set_Optimized_Parameters( parameters )
206 
207  # starting the decomposition
208  cDecompose.Start_Decomposition()
209 
210  # list the decomposing operations
211  cDecompose.List_Gates()
212 
213  # get the decomposing operations
214  quantum_circuit = cDecompose.get_Qiskit_Circuit()
215 
216  # print the quantum circuit
217  print(quantum_circuit)
218 
219  import numpy.linalg as LA
220 
221  # the unitary matrix from the result object
222  decomposed_matrix = utils.get_unitary_from_qiskit_circuit( quantum_circuit )
223  decomposed_matrix = decomposed_matrix[0:14,:]
224  product_matrix = np.dot(Umtx,decomposed_matrix.conj().T)
225  phase = np.angle(product_matrix[0,0])
226  product_matrix = product_matrix*np.exp(-1j*phase)
227 
228  print( product_matrix.shape )
229 
230  product_matrix = np.eye(product_matrix.shape[0])*2 - product_matrix - product_matrix.conj().T
231  # the error of the decomposition
232  decomposition_error = (np.real(np.trace(product_matrix)))/2
233 
234  print('The error of the decomposition is ' + str(decomposition_error))
235 
236  assert( decomposition_error < 1e-3 )
237 
238 
239 
241  r"""
242  This method is called by pytest.
243  Test to decompose a 4-qubit unitary of the IBM chellenge
244 
245  """
246 
247  from squander import N_Qubit_Decomposition_Tree_Search
248  from scipy.io import loadmat
249 
250  # load the unitary from file
251  data = loadmat('data/Umtx.mat')
252  # The unitary to be decomposed
253  Umtx = data['Umtx']
254 
255 
256  # creating a class to decompose the unitary
257  cDecompose = N_Qubit_Decomposition_Tree_Search( Umtx.conj().T )
258 
259 
260  # setting the verbosity of the decomposition
261  cDecompose.set_Verbose( 3 )
262 
263  # starting the decomposition
264  cDecompose.Start_Decomposition()
265 
266  # list the decomposing operations
267  cDecompose.List_Gates()
268 
269  # get the decomposing operations
270  quantum_circuit = cDecompose.get_Qiskit_Circuit()
271 
272  # print the quantum circuit
273  print(quantum_circuit)
274 
275  import numpy.linalg as LA
276 
277  # the unitary matrix from the result object
278  decomposed_matrix = utils.get_unitary_from_qiskit_circuit( quantum_circuit )
279  product_matrix = np.dot(Umtx,decomposed_matrix.conj().T)
280  phase = np.angle(product_matrix[0,0])
281  product_matrix = product_matrix*np.exp(-1j*phase)
282 
283  product_matrix = np.eye(16)*2 - product_matrix - product_matrix.conj().T
284  # the error of the decomposition
285  decomposition_error = (np.real(np.trace(product_matrix)))/2
286 
287  print('The error of the decomposition is ' + str(decomposition_error))
288 
289  assert( decomposition_error < 1e-3 )
290 
291 
292 
293 
295  r"""
296  This method is called by pytest.
297  Test to decompose a 4-qubit unitary of the IBM chellenge
298 
299  """
300 
301  from squander import N_Qubit_Decomposition_Tabu_Search
302  from scipy.io import loadmat
303 
304  # load the unitary from file
305  data = loadmat('data/Umtx.mat')
306  # The unitary to be decomposed
307  Umtx = data['Umtx']
308 
309 
310  # creating a class to decompose the unitary
311  cDecompose = N_Qubit_Decomposition_Tabu_Search( Umtx.conj().T )
312 
313 
314  # setting the verbosity of the decomposition
315  cDecompose.set_Verbose( 3 )
316 
317  # starting the decomposition
318  cDecompose.Start_Decomposition()
319 
320  # list the decomposing operations
321  cDecompose.List_Gates()
322 
323  # get the decomposing operations
324  quantum_circuit = cDecompose.get_Qiskit_Circuit()
325 
326  # print the quantum circuit
327  print(quantum_circuit)
328 
329  import numpy.linalg as LA
330 
331  # the unitary matrix from the result object
332  decomposed_matrix = utils.get_unitary_from_qiskit_circuit( quantum_circuit )
333  product_matrix = np.dot(Umtx,decomposed_matrix.conj().T)
334  phase = np.angle(product_matrix[0,0])
335  product_matrix = product_matrix*np.exp(-1j*phase)
336 
337  product_matrix = np.eye(16)*2 - product_matrix - product_matrix.conj().T
338  # the error of the decomposition
339  decomposition_error = (np.real(np.trace(product_matrix)))/2
340 
341  print('The error of the decomposition is ' + str(decomposition_error))
342 
343  assert( decomposition_error < 1e-3 )
344 
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...