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. 33 from squander.gates.gates_Wrapper
import (
71 """Extract scalar value from array or return as is""" 72 return param.item()
if hasattr(param,
'item')
else param
81 from qiskit
import QuantumCircuit
84 circuit = QuantumCircuit(Squander_circuit.get_Qbit_Num() )
86 gates = Squander_circuit.get_Gates()
91 if isinstance( gate, CNOT ):
93 circuit.cx( gate.get_Control_Qbit(), gate.get_Target_Qbit() )
95 elif isinstance( gate, CRY ):
97 parameters_gate = gate.Extract_Parameters( parameters )
98 circuit.cry( parameters_gate[0], gate.get_Control_Qbit(), gate.get_Target_Qbit() )
100 elif isinstance( gate, CRZ ):
102 parameters_gate = gate.Extract_Parameters( parameters )
103 circuit.crz( parameters_gate[0], gate.get_Control_Qbit(), gate.get_Target_Qbit() )
105 elif isinstance( gate, CRX ):
107 parameters_gate = gate.Extract_Parameters( parameters )
108 circuit.crx( parameters_gate[0], gate.get_Control_Qbit(), gate.get_Target_Qbit() )
110 elif isinstance( gate, CP ):
112 parameters_gate = gate.Extract_Parameters( parameters )
113 circuit.cp( parameters_gate[0], gate.get_Control_Qbit(), gate.get_Target_Qbit() )
115 elif isinstance( gate, CZ ):
117 circuit.cz( gate.get_Control_Qbit(), gate.get_Target_Qbit() )
119 elif isinstance( gate, CH ):
121 circuit.ch( gate.get_Control_Qbit(), gate.get_Target_Qbit() )
123 elif isinstance( gate, SYC ):
125 print(
"Unsupported gate in the circuit export: Sycamore gate")
128 elif isinstance( gate, U1 ):
130 parameters_gate = gate.Extract_Parameters( parameters )
131 circuit.p( parameters_gate[0], gate.get_Target_Qbit() )
133 elif isinstance( gate, U2 ):
135 parameters_gate = gate.Extract_Parameters( parameters )
136 circuit.u( np.pi/2, parameters_gate[0], parameters_gate[1], gate.get_Target_Qbit() )
138 elif isinstance( gate, U3 ):
140 parameters_gate = gate.Extract_Parameters( parameters )
141 circuit.u( parameters_gate[0], parameters_gate[1], parameters_gate[2], gate.get_Target_Qbit() )
143 elif isinstance( gate, CU ):
145 parameters_gate = gate.Extract_Parameters( parameters )
146 circuit.cu( parameters_gate[0], parameters_gate[1], parameters_gate[2], parameters_gate[3], gate.get_Control_Qbit(), gate.get_Target_Qbit() )
148 elif isinstance( gate, RX ):
150 parameters_gate = gate.Extract_Parameters( parameters )
151 circuit.rx( parameters_gate[0], gate.get_Target_Qbit() )
153 elif isinstance( gate, RY ):
155 parameters_gate = gate.Extract_Parameters( parameters )
156 circuit.ry( parameters_gate[0], gate.get_Target_Qbit() )
158 elif isinstance( gate, RZ ):
160 parameters_gate = gate.Extract_Parameters( parameters )
161 circuit.rz( parameters_gate[0], gate.get_Target_Qbit() )
163 elif isinstance( gate, R ):
165 parameters_gate = gate.Extract_Parameters( parameters )
166 circuit.r( parameters_gate[0],parameters_gate[1], gate.get_Target_Qbit() )
167 elif isinstance( gate, H ):
169 circuit.h( gate.get_Target_Qbit() )
171 elif isinstance( gate, X ):
173 circuit.x( gate.get_Target_Qbit() )
175 elif isinstance( gate, Y ):
177 circuit.y( gate.get_Target_Qbit() )
179 elif isinstance( gate, Z ):
181 circuit.z( gate.get_Target_Qbit() )
183 elif isinstance( gate, S ):
185 circuit.s( gate.get_Target_Qbit() )
187 elif isinstance( gate, Sdg ):
189 circuit.sdg( gate.get_Target_Qbit() )
191 elif isinstance( gate, SX ):
193 circuit.sx( gate.get_Target_Qbit() )
195 elif isinstance( gate, SXdg ):
197 circuit.sxdg( gate.get_Target_Qbit() )
199 elif isinstance( gate, T ):
201 circuit.t( gate.get_Target_Qbit() )
203 elif isinstance( gate, Tdg ):
205 circuit.tdg( gate.get_Target_Qbit() )
207 elif isinstance(gate, CCX):
209 control_qbits = gate.get_Control_Qbits()
210 circuit.ccx(control_qbits[0], control_qbits[1], gate.get_Target_Qbit())
212 elif isinstance(gate, CSWAP):
214 target_qbits = gate.get_Target_Qbits()
215 circuit.cswap( gate.get_Control_Qbit(), target_qbits[0], target_qbits[1])
217 elif isinstance(gate, SWAP):
219 target_qbits = gate.get_Target_Qbits()
220 circuit.swap(target_qbits[0], target_qbits[1])
222 elif isinstance( gate, RXX ):
224 parameters_gate = gate.Extract_Parameters( parameters )
225 target_qbits = gate.get_Target_Qbits()
226 circuit.rxx( parameters_gate[0], target_qbits[0], target_qbits[1] )
228 elif isinstance( gate, RYY ):
230 parameters_gate = gate.Extract_Parameters( parameters )
231 target_qbits = gate.get_Target_Qbits()
232 circuit.ryy( parameters_gate[0], target_qbits[0], target_qbits[1] )
234 elif isinstance( gate, RZZ ):
236 parameters_gate = gate.Extract_Parameters( parameters )
237 target_qbits = gate.get_Target_Qbits()
238 circuit.rzz( parameters_gate[0], target_qbits[0], target_qbits[1] )
240 elif isinstance( gate, Circuit ):
242 raise ValueError(
"Qiskit export of circuits with subcircuit is not supported. Use Circuit::get_Flat_Circuit prior of exporting circuit.")
246 raise ValueError(
"Unsupported gate in the circuit export.")
258 from squander
import utils
259 from squander.gates.gates_Wrapper
import CR, CROT
261 inv_circuit, inv_parameters = utils.invert_circuit( Squander_circuit, parameters )
268 if any(isinstance(g, (CR, CROT))
for g
in inv_circuit.get_Gates()):
269 cnot_circuit, cnot_parameters = utils.circuit_to_CNOT_basis( inv_circuit, inv_parameters )
280 from qiskit
import QuantumCircuit
281 from qiskit.circuit
import ParameterExpression
287 q_register = qc_in.qubits
290 register_size = qc_in.num_qubits
293 Circuit_Squander = Circuit(register_size)
296 for gate
in qc_in.data:
298 name = gate.operation.name
300 if name ==
'u1' or name ==
'p':
303 qubit = q_register.index( qubits[0] )
305 params = gate.operation.params
308 parameters = parameters + [float(param)]
310 Circuit_Squander.add_U1( qubit )
315 qubit = q_register.index( qubits[0] )
317 params = gate.operation.params
320 parameters = parameters + [float(param)]
322 Circuit_Squander.add_U2( qubit )
324 elif name ==
'u3' or name ==
'u': 327 qubit = q_register.index( qubits[0] )
329 params = gate.operation.params
330 params[0] = params[0]/2
333 parameters = parameters + [float(param)]
335 Circuit_Squander.add_U3( qubit )
340 qubit0 = q_register.index( qubits[0] )
341 qubit1 = q_register.index( qubits[1] )
343 params = gate.operation.params
344 params[0] = params[0]/2
347 parameters = parameters + [float(param)]
349 Circuit_Squander.add_CU( qubit1, qubit0 )
354 qubit0 = q_register.index( qubits[0] )
355 qubit1 = q_register.index( qubits[1] )
356 Circuit_Squander.add_CNOT( qubit1, qubit0 )
361 qubit0 = q_register.index( qubits[0] )
362 qubit1 = q_register.index( qubits[1] )
364 params = gate.operation.params
365 params[0] = params[0]/2
368 parameters = parameters + [float(param)]
370 Circuit_Squander.add_CRY( qubit1, qubit0 )
375 qubit0 = q_register.index( qubits[0] )
376 qubit1 = q_register.index( qubits[1] )
378 params = gate.operation.params
379 params[0] = params[0]/2
382 parameters = parameters + [float(param)]
384 Circuit_Squander.add_CRZ( qubit1, qubit0 )
389 qubit0 = q_register.index( qubits[0] )
390 qubit1 = q_register.index( qubits[1] )
392 params = gate.operation.params
393 params[0] = params[0]/2
396 parameters = parameters + [float(param)]
398 Circuit_Squander.add_CRX( qubit1, qubit0 )
401 elif name ==
"cu1" or name ==
"cp":
404 qubit0 = q_register.index( qubits[0] )
405 qubit1 = q_register.index( qubits[1] )
407 params = gate.operation.params
408 params[0] = params[0]
411 parameters = parameters + [float(param)]
413 Circuit_Squander.add_CP( qubit1, qubit0 )
417 qubit0 = q_register.index( qubits[0] )
418 qubit1 = q_register.index( qubits[1] )
419 Circuit_Squander.add_CZ( qubit1, qubit0 )
423 qubit0 = q_register.index( qubits[0] )
424 qubit1 = q_register.index( qubits[1] )
425 Circuit_Squander.add_CH( qubit1, qubit0 )
429 qubit = q_register.index( qubits[0] )
431 params = gate.operation.params
432 params[0] = params[0]/2
435 parameters = parameters + [float(param)]
437 Circuit_Squander.add_RX( qubit )
441 qubit = q_register.index( qubits[0] )
443 params = gate.operation.params
444 params[0] = params[0]/2
447 parameters = parameters + [float(param)]
449 Circuit_Squander.add_RY( qubit )
453 qubit = q_register.index( qubits[0] )
455 params = gate.operation.params
456 params[0] = params[0]/2
459 parameters = parameters + [float(param)]
461 Circuit_Squander.add_RZ( qubit )
465 qubit = q_register.index( qubits[0] )
467 Circuit_Squander.add_H( qubit )
471 qubit = q_register.index( qubits[0] )
473 Circuit_Squander.add_X( qubit )
477 qubit = q_register.index( qubits[0] )
479 Circuit_Squander.add_Y( qubit )
483 qubit = q_register.index( qubits[0] )
485 Circuit_Squander.add_Z( qubit )
489 qubit = q_register.index( qubits[0] )
491 Circuit_Squander.add_S( qubit )
495 qubit = q_register.index( qubits[0] )
497 Circuit_Squander.add_Sdg( qubit )
501 qubit = q_register.index( qubits[0] )
503 Circuit_Squander.add_SX( qubit )
507 qubit = q_register.index(qubits[0])
510 Circuit_Squander.add_SXdg(qubit)
514 qubit = q_register.index( qubits[0] )
516 Circuit_Squander.add_T( qubit )
520 qubit = q_register.index( qubits[0] )
522 Circuit_Squander.add_Tdg( qubit )
526 qubit = q_register.index( qubits[0] ) 528 params = gate.operation.params 529 params[0] = params[0]/2 532 parameters = parameters + [float(param)]
534 Circuit_Squander.add_R( qubit )
539 qubit0 = q_register.index( qubits[0] )
540 qubit1 = q_register.index( qubits[1] )
541 qubit2 = q_register.index( qubits[2] )
542 Circuit_Squander.add_CCX( qubit2, [qubit1, qubit0] )
544 elif name ==
'cswap':
547 qubit0 = q_register.index( qubits[0] )
548 qubit1 = q_register.index( qubits[1] )
549 qubit2 = q_register.index( qubits[2] )
550 Circuit_Squander.add_CSWAP( [qubit2, qubit1], [qubit0] )
555 qubit0 = q_register.index( qubits[0] )
556 qubit1 = q_register.index( qubits[1] )
557 Circuit_Squander.add_SWAP( [qubit1, qubit0] )
560 qubit0 = q_register.index( qubits[0] )
561 qubit1 = q_register.index( qubits[1] )
563 params = gate.operation.params
564 params[0] = params[0]/2
567 parameters = parameters + [float(param)]
569 Circuit_Squander.add_RXX( [qubit0, qubit1] )
573 qubit0 = q_register.index( qubits[0] )
574 qubit1 = q_register.index( qubits[1] )
576 params = gate.operation.params
577 params[0] = params[0]/2
580 parameters = parameters + [float(param)]
582 Circuit_Squander.add_RYY( [qubit0, qubit1] )
586 qubit0 = q_register.index( qubits[0] )
587 qubit1 = q_register.index( qubits[1] )
589 params = gate.operation.params
590 params[0] = params[0]/2
593 parameters = parameters + [float(param)]
595 Circuit_Squander.add_RZZ( [qubit0, qubit1] )
598 print(f
"convert_Qiskit_to_Squander: Unimplemented gate: {name}")
601 parameters = np.asarray(parameters, dtype=np.float64)
603 return Circuit_Squander, parameters
def convert_Qiskit_to_Squander(qc_in)
Call to import initial quantum circuit in QISKIT format to be further comporessed.
def get_Qiskit_Circuit_inverse(Squander_circuit, parameters)
Export the inverse of a Squander circuit into Qiskit format.
def get_Qiskit_Circuit(Squander_circuit, parameters)
Export the unitary decomposition into Qiskit format.