forked from qiskit-community/MicroQiskit
-
Notifications
You must be signed in to change notification settings - Fork 1
/
microqiskit.py
141 lines (141 loc) · 4.4 KB
/
microqiskit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import random
from math import cos,sin,pi
r2=0.70710678118
class QuantumCircuit:
def __init__(self,n,m=0):
self.num_qubits=n
self.num_clbits=m
self.name = ''
self.data=[]
def __add__(self,self2):
self3=QuantumCircuit(max(self.num_qubits,self2.num_qubits),max(self.num_clbits,self2.num_clbits))
self3.data=self.data+self2.data
self3.name = self.name
return self3
def initialize(self,k):
self.data[:] = []
self.data.append(('init',[e for e in k]))
def x(self,q):
self.data.append(('x',q))
def rx(self,theta,q):
self.data.append(('rx',theta,q))
def h(self,q):
self.data.append(('h',q))
def cx(self,s,t):
self.data.append(('cx',s,t))
def crx(self,theta,s,t):
self.data.append(('crx',theta,s,t))
def measure(self,q,b):
assert b<self.num_clbits, 'Index for output bit out of range.'
assert q<self.num_qubits, 'Index for qubit out of range.'
self.data.append(('m',q,b))
def rz(self,theta,q):
self.h(q)
self.rx(theta,q)
self.h(q)
def ry(self,theta,q):
self.rx(pi/2,q)
self.rz(theta,q)
self.rx(-pi/2,q)
def z(self,q):
self.rz(pi,q)
def y(self,q):
self.rz(pi,q)
self.x(q)
def simulate(qc,shots=1024,get='counts',noise_model=[]):
def superpose(x,y):
return [r2*(x[j]+y[j])for j in range(2)],[r2*(x[j]-y[j])for j in range(2)]
def turn(x,y,theta):
theta = float(theta)
return [x[0]*cos(theta/2)+y[1]*sin(theta/2),x[1]*cos(theta/2)-y[0]*sin(theta/2)],[y[0]*cos(theta/2)+x[1]*sin(theta/2),y[1]*cos(theta/2)-x[0]*sin(theta/2)]
k = [[0,0] for _ in range(2**qc.num_qubits)]
k[0] = [1.0,0.0]
if noise_model:
if type(noise_model)==float:
noise_model = [noise_model]*qc.num_qubits
outputnum_clbitsap = {}
for gate in qc.data:
if gate[0]=='init':
if type(gate[1][0])==list:
k = [e for e in gate[1]]
else:
k = [[e,0] for e in gate[1]]
elif gate[0]=='m':
outputnum_clbitsap[gate[2]] = gate[1]
elif gate[0] in ['x','h','rx']:
j = gate[-1]
for i0 in range(2**j):
for i1 in range(2**(qc.num_qubits-j-1)):
b0=i0+2**(j+1)*i1
b1=b0+2**j
if gate[0]=='x':
k[b0],k[b1]=k[b1],k[b0]
elif gate[0]=='h':
k[b0],k[b1]=superpose(k[b0],k[b1])
else:
theta = gate[1]
k[b0],k[b1]=turn(k[b0],k[b1],theta)
elif gate[0] in ['cx','crx']:
if gate[0]=='cx':
[s,t] = gate[1:]
else:
theta = gate[1]
[s,t] = gate[2:]
[l,h] = sorted([s,t])
for i0 in range(2**l):
for i1 in range(2**(h-l-1)):
for i2 in range(2**(qc.num_qubits-h-1)):
b0=i0+2**(l+1)*i1+2**(h+1)*i2+2**s
b1=b0+2**t
if gate[0]=='cx':
k[b0],k[b1]=k[b1],k[b0]
else:
k[b0],k[b1]=turn(k[b0],k[b1],theta)
if get=='statevector':
return k
else:
probs = [e[0]**2+e[1]**2 for e in k]
if noise_model:
for j in range(qc.num_qubits):
p_meas = noise_model[j]
for i0 in range(2**j):
for i1 in range(2**(qc.num_qubits-j-1)):
b0=i0+2**(j+1)*i1
b1=b0+2**j
p0 = probs[b0]
p1 = probs[b1]
probs[b0] = (1-p_meas)*p0 + p_meas*p1
probs[b1] = (1-p_meas)*p1 + p_meas*p0
if get=='probabilities_dict':
return {('{0:0'+str(qc.num_qubits)+'b}').format(j):p for j,p in enumerate(probs)}
elif get in ['counts', 'memory']:
m = [False for _ in range(qc.num_qubits)]
for gate in qc.data:
for j in range(qc.num_qubits):
assert not ((gate[-1]==j) and m[j]), 'Incorrect or missing measure command.'
m[j] = (gate==('m',j,j))
m=[]
for _ in range(shots):
cumu=0
un=True
r=random.random()
for j,p in enumerate(probs):
cumu += p
if r<cumu and un:
raw_out=('{0:0'+str(qc.num_qubits)+'b}').format(j)
out_list = ['0']*qc.num_clbits
for bit in outputnum_clbitsap:
out_list[qc.num_clbits-1-bit] = raw_out[qc.num_qubits-1-outputnum_clbitsap[bit]]
out = ''.join(out_list)
m.append(out)
un=False
if get=='memory':
return m
else:
counts = {}
for out in m:
if out in counts:
counts[out] += 1
else:
counts[out] = 1
return counts