Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quantum-kittens
GitHub Repository: quantum-kittens/platypus
Path: blob/main/frontend/vue/components/MiniComposer/gateUtils.ts
3375 views
1
// eslint-disable-next-line import/named
2
import { multiply, subtract, add, gcd, round } from 'mathjs'
3
4
export enum GateName {
5
UNKNOWN = 'UNKNOWN',
6
ID = 'ID',
7
H = 'H',
8
Z = 'Z',
9
X = 'X',
10
Y = 'Y',
11
T = 'T',
12
S = 'S',
13
RX = 'RX',
14
RZ = 'RZ',
15
RY = 'RY',
16
MEASURE_Z = 'Measure'
17
}
18
19
function neg (m: number[][]) {
20
return multiply(m, -1)
21
}
22
export interface StateMatrix {
23
A: number[][]
24
B: number[][]
25
C: number[][]
26
D: number[][]
27
m: number
28
}
29
30
function reduceSingleElement (numerator: number, denominator: number) {
31
const d = gcd(numerator, denominator)
32
33
return {
34
numerator: round(numerator / d),
35
denominator: round(denominator / d)
36
}
37
}
38
39
export function IdentityState (): StateMatrix {
40
return {
41
A: [[1, 0], [0, 1]],
42
B: [[0, 0], [0, 0]],
43
C: [[0, 0], [0, 0]],
44
D: [[0, 0], [0, 0]],
45
m: 0
46
}
47
}
48
49
export interface QuantumGate {
50
apply (state: StateMatrix): StateMatrix
51
}
52
53
export const Identity: QuantumGate = {
54
apply (state: StateMatrix) {
55
return state
56
}
57
}
58
59
export const XGate: QuantumGate = {
60
apply (state: StateMatrix) {
61
// Integer part
62
const K = [[0, 1], [1, 0]]
63
return {
64
A: multiply(K, state.A),
65
B: multiply(K, state.B),
66
C: multiply(K, state.C),
67
D: multiply(K, state.D),
68
m: state.m
69
}
70
}
71
}
72
73
export const YGate: QuantumGate = {
74
apply (state: StateMatrix) {
75
// Integer part
76
const K = [[0, -1], [1, 0]]
77
78
return {
79
A: neg(multiply(K, state.B)),
80
B: multiply(K, state.A),
81
C: neg(multiply(K, state.D)),
82
D: multiply(K, state.C),
83
m: state.m
84
}
85
}
86
}
87
88
export const ZGate: QuantumGate = {
89
apply (state: StateMatrix) {
90
// Integer part
91
const K = [[1, 0], [0, -1]]
92
93
return {
94
A: multiply(K, state.A),
95
B: multiply(K, state.B),
96
C: multiply(K, state.C),
97
D: multiply(K, state.D),
98
m: state.m
99
}
100
}
101
}
102
103
export const HGate: QuantumGate = {
104
apply (state: StateMatrix) {
105
// Integer part
106
const K = [[1, 1], [1, -1]]
107
108
return {
109
A: multiply(multiply(K, state.C), 2),
110
B: multiply(multiply(K, state.D), 2),
111
C: multiply(K, state.A),
112
D: multiply(K, state.B),
113
m: state.m + 1
114
}
115
}
116
}
117
118
export const SGate: QuantumGate = {
119
apply (state: StateMatrix) {
120
// Integer part
121
const K1 = [[1, 0], [0, 0]]
122
const K2 = [[0, 0], [0, 1]]
123
124
return {
125
A: subtract(multiply(K1, state.A), multiply(K2, state.B)),
126
B: add(multiply(K2, state.A), multiply(K1, state.B)),
127
C: subtract(multiply(K1, state.C), multiply(K2, state.D)),
128
D: add(multiply(K2, state.C), multiply(K1, state.D)),
129
m: state.m
130
}
131
}
132
}
133
134
export const TGate: QuantumGate = {
135
apply (state: StateMatrix) {
136
// Integer part
137
const K1 = [[2, 0], [0, 0]]
138
const K2 = [[0, 0], [0, 1]]
139
140
const K1_A = multiply(K1, state.A)
141
const K1_B = multiply(K1, state.B)
142
const K1_C = multiply(K1, state.C)
143
const K1_D = multiply(K1, state.D)
144
145
const K2_A = multiply(K2, state.A)
146
const K2_B = multiply(K2, state.B)
147
const K2_C = multiply(K2, state.C)
148
const K2_D = multiply(K2, state.D)
149
150
const K2_C_2 = multiply(K2_C, 2)
151
const K2_D_2 = multiply(K2_D, 2)
152
153
return {
154
A: subtract(add(K1_A, K2_C_2), K2_D_2),
155
B: add(add(K1_B, K2_C_2), K2_D_2),
156
C: add(subtract(K2_A, K2_B), K1_C),
157
D: add(add(K2_A, K2_B), K1_D),
158
m: state.m + 1
159
}
160
}
161
}
162
163
export const gateMap = {
164
[GateName.UNKNOWN]: Identity,
165
[GateName.ID]: Identity,
166
[GateName.MEASURE_Z]: Identity,
167
[GateName.H]: HGate,
168
[GateName.X]: XGate,
169
[GateName.Y]: YGate,
170
[GateName.Z]: ZGate,
171
[GateName.T]: TGate,
172
[GateName.S]: SGate,
173
[GateName.RX]: Identity,
174
[GateName.RY]: Identity,
175
[GateName.RZ]: Identity
176
}
177
178
function signedString (n: number, m: number, symbol: string = '') {
179
if (n === 0) {
180
return ''
181
}
182
const { numerator, denominator } = reduceSingleElement(n, Math.pow(2, m))
183
184
const absNumerator = Math.abs(numerator)
185
const sign = numerator > 0 ? '+' : '-'
186
let numeratorTex = ''
187
188
if (symbol) {
189
numeratorTex = `${absNumerator > 1 ? absNumerator : ''}${symbol}`
190
} else {
191
numeratorTex = `${absNumerator}`
192
}
193
194
if (denominator !== 1 && m > 0) {
195
return `${sign}\\frac{${numeratorTex}}{${denominator}}`
196
} else {
197
return `${sign}${numeratorTex}`
198
}
199
}
200
201
function StateMatrixElementToTex (state: StateMatrix, coords: { x: number, y: number }) {
202
const { x, y } = coords
203
const [a, b, c, d] = [state.A[x][y], state.B[x][y], state.C[x][y], state.D[x][y]]
204
const isZero = (a * a + b * b + c * c + d * d) === 0
205
206
if (isZero) {
207
return '0'
208
}
209
210
const aTex = signedString(a, state.m)
211
const bTex = signedString(b, state.m, 'i')
212
const cTex = signedString(c, state.m, '\\sqrt{2}')
213
const dTex = signedString(d, state.m, 'i\\sqrt{2}')
214
215
let tex = `${aTex}${bTex}${cTex}${dTex}`
216
217
if (tex.startsWith('+')) {
218
tex = tex.substring(1)
219
}
220
221
return tex
222
}
223
224
export function StateMatrixToTexMatrix (state: StateMatrix) {
225
return `
226
\\begin{pmatrix}
227
${StateMatrixElementToTex(state, { x: 0, y: 0 })} & ${StateMatrixElementToTex(state, { x: 0, y: 1 })}\\\\
228
${StateMatrixElementToTex(state, { x: 1, y: 0 })} & ${StateMatrixElementToTex(state, { x: 1, y: 1 })}
229
\\end{pmatrix}
230
`
231
}
232
233
function parenthesis (text: string) {
234
return `\\left(${text}\\right)`
235
}
236
237
function valueKetTex (value: string, ket: 0 | 1) {
238
if (value === '0') {
239
return ''
240
}
241
242
const ketTex = `|${ket}\\rangle`
243
if (value === '1') {
244
return ketTex
245
}
246
247
const isMultiElement = value.includes('+') || value.lastIndexOf('-') > 1
248
const valueTex = isMultiElement ? parenthesis(value) : value
249
250
return `${valueTex}${ketTex}`
251
}
252
253
export function StateMatrixToTexKetNotation (state: StateMatrix) {
254
const zeroKetValue = StateMatrixElementToTex(state, { x: 0, y: 0 })
255
const oneKetValue = StateMatrixElementToTex(state, { x: 1, y: 0 })
256
257
const bothKets = zeroKetValue !== '0' && oneKetValue !== '0'
258
259
const zeroKetTex = valueKetTex(zeroKetValue, 0)
260
const oneKetTex = valueKetTex(oneKetValue, 1)
261
262
let joinTex = ''
263
if (bothKets && !oneKetTex.startsWith('-')) {
264
joinTex = '+'
265
}
266
267
return `
268
${zeroKetTex}${joinTex}${oneKetTex}
269
`
270
}
271
272