4 Created on Tue Jun 30 15:44:26 2020 5 Copyright 2020 Peter Rakyta, Ph.D. 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 11 http://www.apache.org/licenses/LICENSE-2.0 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see http://www.gnu.org/licenses/. 22 @author: Peter Rakyta, Ph.D. 31 from squander.decomposition.qgd_N_Qubit_Decomposition_custom_Wrapper
import qgd_N_Qubit_Decomposition_custom_Wrapper
46 def __init__( self, Umtx, initial_guess="RANDOM", config={}, accelerator_num=0 ):
49 self.qbit_num =
int(round( np.log2( len(Umtx) ) ))
52 if not(
type(config)
is dict):
53 print(
"Input parameter config should be a dictionary describing the following hyperparameters:")
57 super(qgd_N_Qubit_Decomposition_custom, self).
__init__(Umtx, self.qbit_num, initial_guess, config=config, accelerator_num=accelerator_num)
75 super(qgd_N_Qubit_Decomposition_custom, self).
Reorder_Qubits(qbit_list)
83 super(qgd_N_Qubit_Decomposition_custom, self).
List_Gates()
99 from squander
import Qiskit_IO
101 squander_circuit = self.get_Circuit()
102 parameters = self.get_Optimized_Parameters()
104 return Qiskit_IO.get_Qiskit_Circuit( squander_circuit, parameters )
118 if parameters
is None:
119 print(
"Optimization_Problem: array of input parameters is None")
139 circuit = cirq.Circuit()
142 q = cirq.LineQubit.range(self.qbit_num)
145 gates = self.get_Gates()
148 for idx
in range(len(gates)-1, -1, -1):
152 if gate.get(
"type") ==
"CNOT":
154 circuit.append(cirq.CNOT(q[self.qbit_num-1-gate.get(
"control_qbit")], q[self.qbit_num-1-gate.get(
"target_qbit")]))
156 if gate.get(
"type") ==
"CRY":
158 print(
"CRY gate needs to be implemented")
160 elif gate.get(
"type") ==
"CZ":
162 circuit.append(cirq.CZ(q[self.qbit_num-1-gate.get(
"control_qbit")], q[self.qbit_num-1-gate.get(
"target_qbit")]))
164 elif gate.get(
"type") ==
"CH":
166 circuit.append(cirq.CH(q[self.qbit_num-1-gate.get(
"control_qbit")], q[self.qbit_num-1-gate.get(
"target_qbit")]))
168 elif gate.get(
"type") ==
"SYC":
170 circuit.append(cirq.google.SYC(q[self.qbit_num-1-gate.get(
"control_qbit")], q[self.qbit_num-1-gate.get(
"target_qbit")]))
172 elif gate.get(
"type") ==
"U3":
173 print(
"Unsupported gate in the Cirq export: U3 gate")
176 elif gate.get(
"type") ==
"RX":
178 circuit.append(cirq.rx(gate.get(
"Theta")).on(q[self.qbit_num-1-gate.get(
"target_qbit")]))
180 elif gate.get(
"type") ==
"RY":
182 circuit.append(cirq.ry(gate.get(
"Theta")).on(q[self.qbit_num-1-gate.get(
"target_qbit")]))
184 elif gate.get(
"type") ==
"RZ":
186 circuit.append(cirq.rz(gate.get(
"Phi")).on(q[self.qbit_num-1-gate.get(
"target_qbit")]))
188 elif gate.get(
"type") ==
"H":
190 circuit.append(cirq.h(q[self.qbit_num-1-gate.get(
"target_qbit")]))
192 elif gate.get(
"type") ==
"X":
194 circuit.append(cirq.x(q[self.qbit_num-1-gate.get(
"target_qbit")]))
196 elif gate.get(
"type") ==
"Y":
198 circuit.append(cirq.y(q[self.qbit_num-1-gate.get(
"target_qbit")]))
200 elif gate.get(
"type") ==
"Z":
202 circuit.append(cirq.z(q[self.qbit_num-1-gate.get(
"target_qbit")]))
205 elif gate.get(
"type") ==
"SX":
207 circuit.append(cirq.sx(q[self.qbit_num-1-gate.get(
"target_qbit")]))
218 from squander
import Qiskit_IO
221 Circuit_Squander, circuit_parameters = Qiskit_IO.convert_Qiskit_to_Squander( qc_in )
224 self.set_Gate_Structure( Circuit_Squander )
225 self.set_Optimized_Parameters( circuit_parameters )
236 super(qgd_N_Qubit_Decomposition_custom, self).
set_Optimizer(optimizer)
255 if not isinstance(Gate_structure, qgd_Circuit) :
256 raise Exception(
"Input parameter Gate_structure should be a an instance of Gates_Block")
def Optimization_Problem(self, parameters=None)
Call to evaluate the cost function.
def set_Cost_Function_Variant(self, costfnc=0)
Call to set the optimizer used in the gate synthesis process.
def Prepare_Gates_To_Export(self)
Call to prepare the circuit to be exported into Qiskit format.
def List_Gates(self)
Call to print the gates decomposing the initial unitary.
def Reorder_Qubits(self, qbit_list)
Call to reorder the qubits in the matrix of the gate.
def get_Optimized_Parameters(self)
Call to get the optimized parameters set in numpy array.
def get_Qiskit_Circuit(self)
Export the unitary decomposition into Qiskit format.
def get_Circuit(self)
Call to retrieve the incorporated quantum circuit (Squander format)
def set_Gate_Structure(self, Gate_structure)
Call to set custom gate structure to used in the decomposition.
def __init__(self, Umtx, initial_guess="RANDOM", config={}, accelerator_num=0)
Constructor of the class.
def get_Cirq_Circuit(self)
Export the unitary decomposition into Qiskit format.
def import_Qiskit_Circuit(self, qc_in)
Call to import initial quantum circuit in QISKIT format to be further comporessed.
A QGD Python interface class for the decomposition of N-qubit unitaries into U3 and CNOT gates...
def Start_Decomposition(self)
Wrapper function to call the start_decomposition method of C++ class N_Qubit_Decomposition.
def set_Optimizer(self, optimizer="BFGS")
Call to set the optimizer used in the gate synthesis process.