4 Created on Tue Jun 30 15:44:26 2020 5 Copyright (C) 2020 Peter Rakyta, Ph.D. 7 This program is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see http://www.gnu.org/licenses/. 20 @author: Peter Rakyta, Ph.D. 35 if ( path.exists(
'.libs/libqgd.so') ):
36 library_path =
'.libs/libqgd.so' 37 elif ( path.exists(
'lib64/libqgd.so') ):
38 library_path =
'lib64/libqgd.so' 39 elif ( path.exists(
'lib/libqgd.so') ):
40 library_path =
'lib/libqgd.so' 42 print(
"Quantum Gate Decomposer library not found.")
46 _qgd_library = ctypes.cdll.LoadLibrary(library_path)
52 _qgd_library.iface_new_N_Qubit_Decomposition.argtypes = (ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_int, ctypes.c_bool, ctypes.c_int,)
53 _qgd_library.iface_new_N_Qubit_Decomposition.restype = ctypes.c_void_p
54 _qgd_library.iface_start_decomposition.argtypes = (ctypes.c_void_p,)
55 _qgd_library.iface_delete_N_Qubit_Decomposition.argtypes = (ctypes.c_void_p,)
56 _qgd_library.iface_set_identical_blocks.argtypes = (ctypes.c_void_p, ctypes.c_int, ctypes.c_int,)
57 _qgd_library.iface_set_iteration_loops.argtypes = (ctypes.c_void_p, ctypes.c_int, ctypes.c_int,)
58 _qgd_library.iface_set_max_layer_num.argtypes = (ctypes.c_void_p, ctypes.c_int, ctypes.c_int,)
59 _qgd_library.iface_list_operations.argtypes = (ctypes.c_void_p, ctypes.c_int,)
60 _qgd_library.iface_get_operation_num.argtypes = ( ctypes.c_void_p, )
61 _qgd_library.iface_get_operation_num.restype = ctypes.c_int
62 _qgd_library.iface_get_operation.argtypes = ( ctypes.c_void_p, ctypes.c_int, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_double), )
63 _qgd_library.iface_get_operation.restype = ctypes.c_int
64 _qgd_library.iface_set_verbose.argtypes = ( ctypes.c_void_p, ctypes.c_bool, )
65 _qgd_library.iface_set_optimalization_block.argtypes = ( ctypes.c_void_p, ctypes.c_int, )
79 def __init__( self, Umtx, optimize_layer_num=False, initial_guess="zeros" ):
82 self.
qbit_num = int(round( np.log2( len(Umtx) ) ))
88 Umtx_real = np.real(Umtx).reshape(matrix_size*matrix_size)
89 Umtx_imag = np.imag(Umtx).reshape(matrix_size*matrix_size)
92 array_type = ctypes.c_double * (matrix_size*matrix_size)
93 string_length = len(initial_guess)
96 if initial_guess==
"zeros":
98 elif initial_guess==
"random":
100 elif initial_guess==
"close_to_zero":
101 initial_guess_num = 2
103 initial_guess_num = 0
106 self.
c_instance = _qgd_library.iface_new_N_Qubit_Decomposition( array_type(*Umtx_real), array_type(*Umtx_imag), ctypes.c_int(self.
qbit_num), ctypes.c_bool(optimize_layer_num), ctypes.c_int(initial_guess_num) )
114 _qgd_library.iface_delete_N_Qubit_Decomposition( self.c_instance )
125 _qgd_library.iface_start_decomposition( self.c_instance )
133 for qbit
in max_layer_num.keys() :
135 _qgd_library.iface_set_max_layer_num( self.c_instance, ctypes.c_int(qbit), ctypes.c_int(max_layer_num.get(qbit,0)) )
142 for qbit
in iteration_loops.keys() :
144 _qgd_library.iface_set_iteration_loops( self.c_instance, ctypes.c_int(qbit), ctypes.c_int(iteration_loops.get(qbit,3)) )
152 for qbit
in identical_blocks.keys() :
154 _qgd_library.iface_set_identical_blocks( self.c_instance, ctypes.c_int(qbit), ctypes.c_int(identical_blocks.get(qbit,1)) )
162 _qgd_library.iface_list_operations( self.c_instance, ctypes.c_int(start_index) );
170 from qiskit
import QuantumCircuit
173 circuit = QuantumCircuit(self.qbit_num)
178 operation_type = ctypes.c_int()
179 target_qbit = ctypes.c_int()
180 control_qbit = ctypes.c_int()
182 array_type = ctypes.c_double * 3
183 parameters = array_type(*np.array([0,0,0]))
185 number_of_decomposing_operations = _qgd_library.iface_get_operation_num( self.c_instance )
186 op_idx = ctypes.c_int(number_of_decomposing_operations-1)
191 status = _qgd_library.iface_get_operation( self.c_instance, op_idx, ctypes.byref(operation_type), ctypes.byref(target_qbit), ctypes.byref(control_qbit), parameters )
193 if not ( status == 0 ) :
203 if operation_type.value == 1:
205 circuit.cx(control_qbit.value, target_qbit.value)
207 elif operation_type.value == 2:
209 circuit.u3(parameters[0], parameters[1], parameters[2], target_qbit.value)
212 op_idx.value = op_idx.value - 1
223 _qgd_library.iface_set_verbose( self.c_instance, ctypes.c_bool(verbose) )
232 _qgd_library.iface_set_optimalization_block( self.c_instance, ctypes.c_int(optimalization_block) )
def set_max_layer_num(self, max_layer_num)
Set the maximal number of layers used in the subdecomposition of the qbit-th qubit.
def set_iteration_loops(self, iteration_loops)
Set the number of iteration loops during the subdecomposition of the qbit-th qubit.
qbit_num
the number of qubits
def __init__(self, Umtx, optimize_layer_num=False, initial_guess="zeros")
c_instance
the instance of the N_Qubit_Decomposition C class
def set_optimalization_block(self, optimalization_block)
Call to set the number of blocks to be optimized in one shot.
def start_decomposition(self, finalize_decomposition=True)
Start the disentanglig process of the least significant two qubit unitary.
def set_verbose(self, verbose)
Set the verbosity of the N_Qubit_Decomposition class.
def set_identical_blocks(self, identical_blocks)
Set the number of identical successive blocks during the subdecomposition of the qbit-th qubit.
A QGD Python interface class for the decomposition of N-qubit unitaries into U3 and CNOT gates.
def __del__(self)
Destructor of the class.
def list_operations(self, start_index=1)
Lists the operations decomposing the initial unitary.
def get_quantum_circuit(self)
Export the unitary decomposition into Qiskit format.