4
4
5
5
from collections import defaultdict
6
6
import numpy as np
7
- from qiskit import QuantumCircuit , transpiler
8
- from qiskit .qasm import Qasm
9
- from qiskit .providers .builtinsimulators import QasmSimulatorPy
10
- from qiskit .converters import circuits_to_qobj
11
- from qiskit .qobj import qobj_to_dict
7
+ import sympy
12
8
13
9
from quantpy .sympy .executor ._base_quantum_executor import BaseQuantumExecutor
14
10
from quantpy .sympy .executor .simulator .numpy_simulator import NumpySimulator
11
+ import quantpy .sympy
15
12
16
13
def _default_random_sequence (num ):
17
14
import random
@@ -23,95 +20,64 @@ def __init__(self):
23
20
super ().__init__ ()
24
21
self .simulator = None
25
22
26
-
27
23
def execute (self , circuit , ** options ):
28
- """
29
- Execute sympy-circuit with classical simulator
30
- We use numpy simulator as default
31
- @param circuit sympy object to simulate
32
- """
33
- qasm = self .to_qasm (circuit )
34
24
self .simulator = NumpySimulator ()
35
- basis_gates_str = ("," .join (self .simulator .basis_gates )).lower ()
36
- # the following one-line compilation ignores basis_gates, and returnes "u2" for "h".
37
- quantum_circuit = QuantumCircuit .from_qasm_str (qasm )
38
- circuit = transpiler .transpile (quantum_circuit , basis_gates = basis_gates_str , backend = QasmSimulatorPy ())
39
- qobj = circuits_to_qobj (circuit , QasmSimulatorPy ())
40
- json = qobj_to_dict (qobj )["experiments" ][0 ]
41
- self .simulate (json )
42
- return self .simulator .to_coefficients ()
43
-
44
- def simulate (self , circuitJson ):
45
- """
46
- Simulate qasm script with json format
47
- @param circuitJson qasm in json format
48
- """
49
-
50
- sim = self .simulator
51
-
52
- numQubit = circuitJson ["header" ]["n_qubits" ]
53
- sim .initialize (numQubit )
25
+ qubit = circuit .args [- 1 ]
26
+ assert isinstance (qubit , sympy .physics .quantum .qubit .Qubit ), 'Sorry. Now, U*U*U*Qubit format is only supported'
27
+
28
+ self .simulator .initialize (qubit .dimension )
29
+
30
+ # set initial qubit value
31
+ for i , qb in enumerate (reversed (qubit .args )):
32
+ if isinstance (qb , sympy .numbers .One ):
33
+ self .simulator .apply ('x' , i )
34
+
35
+ # main loop
36
+ GATE_TO_STR = {
37
+ sympy .physics .quantum .gate .HadamardGate : 'h' ,
38
+ sympy .physics .quantum .gate .XGate : 'x' ,
39
+ sympy .physics .quantum .gate .YGate : 'y' ,
40
+ sympy .physics .quantum .gate .ZGate : 'z' ,
41
+ sympy .physics .quantum .gate .PhaseGate : 's' ,
42
+ sympy .physics .quantum .gate .TGate : 't' ,
43
+ }
44
+ for gate in reversed (circuit .args [:- 1 ]):
45
+ if isinstance (gate , sympy .physics .quantum .gate .IdentityGate ):
46
+ continue
54
47
55
- if "clbit_labels" in circuitJson [ "header" ]. keys () :
56
- numBit = len ( circuitJson [ "header" ][ "clbit_labels" ])
57
- clbitsArray = np . zeros ( numBit )
48
+ if type ( gate ) in GATE_TO_STR :
49
+ # gate without parameters
50
+ self . simulator . apply ( GATE_TO_STR [ type ( gate )], int ( gate . args [ 0 ]) )
58
51
59
- for operation in circuitJson ["instructions" ]:
52
+ elif isinstance (gate , sympy .physics .quantum .gate .CNotGate ):
53
+ self .simulator .apply ('cx' , int (gate .args [0 ]), int (gate .args [1 ]))
60
54
61
- gateOps = operation ["name" ]
55
+ elif isinstance (gate , sympy .physics .quantum .gate .SwapGate ):
56
+ self .simulator .apply ('cx' , int (gate .args [0 ]), int (gate .args [1 ]))
57
+ self .simulator .apply ('cx' , int (gate .args [1 ]), int (gate .args [0 ]))
58
+ self .simulator .apply ('cx' , int (gate .args [0 ]), int (gate .args [1 ]))
62
59
63
- if not self .simulator .can_simulate_gate (gateOps ):
64
- print (" !!! {} is not supported !!!" .format (gateOps ))
65
- print (operation )
66
- continue
60
+ elif isinstance (gate , sympy .physics .quantum .gate .CGate ):
61
+ control = tuple (gate .args [0 ])[0 ]
62
+ target_gate = gate .args [1 ]
67
63
68
- gateTargets = operation ["qubits" ]
69
-
70
- if "conditional" in operation .keys ():
71
- condition = operation ["conditional" ]
72
- condVal = int (condition ["val" ], 0 )
73
- condMask = int (condition ["mask" ], 0 )
74
- flag = True
75
- for ind in range (numBit ):
76
- if ((condMask >> ind ) % 2 == 1 ):
77
- flag = flag and (condVal % 2 == clbitsArray [ind ])
78
- condVal //= 2
79
- if (not flag ):
64
+ if isinstance (target_gate , sympy .physics .quantum .gate .IdentityGate ):
80
65
continue
81
66
82
- if "memory" in operation .keys ():
83
- measureTargets = operation ["memory" ]
67
+ if type (target_gate ) in GATE_TO_STR :
68
+ # C-"simple" gate
69
+ self .simulator .apply (GATE_TO_STR [type (target_gate )],
70
+ int (target_gate .args [0 ]), control = control )
84
71
85
- if "params" in operation .keys ():
86
- params = operation ["params" ]
87
-
88
- # unparameterized gates
89
- if (gateOps in ["x" , "y" , "z" , "h" , "s" , "t" , "cx" , "cz" , "CX" ]):
90
- if (len (gateTargets ) == 1 ):
91
- sim .apply (gateOps , target = gateTargets [0 ])
92
- elif (len (gateTargets ) == 2 ):
93
- sim .apply (gateOps , target = gateTargets [0 ], control = gateTargets [1 ])
94
- else :
95
- raise ValueError ("Too many target qubits" )
96
-
97
- # measurement
98
- elif (gateOps in ["measure" ]):
99
- trace = sim .trace ()
100
- prob = sim .apply ("M0" , target = gateTargets [0 ], update = False ) / trace
101
- if (np .random .rand () < prob ):
102
- sim .update ()
103
- clbitsArray [measureTargets [0 ]] = 0
72
+ elif isinstance (target_gate , quantpy .sympy .Rk ):
73
+ k = gate .args [1 ].k
74
+ self .simulator .apply ('u' , int (target_gate .args [0 ]), param = (1 , float (k / 2 ), float (k / 2 )))
104
75
else :
105
- sim .apply ("M1" , target = gateTargets [0 ])
106
- clbitsArray [measureTargets [0 ]] = 1
107
- sim .normalize ()
108
-
109
- # generic unitary operation
110
- elif (gateOps in ["U" ]):
111
- sim .apply ("U" , target = gateTargets [0 ], param = params )
112
-
76
+ assert False , '{} it is not a gate operator, nor is a supported operator' .format (repr (gate ))
113
77
else :
114
- raise ValueError ("Op:{} is contained in basis gates, but not supported in simulator" .format (operation ))
78
+ assert False , '{} it is not a gate operator, nor is a supported operator' .format (repr (gate ))
79
+
80
+ return self .simulator .to_coefficients ()
115
81
116
82
def getStateStr (self ):
117
83
"""
0 commit comments