Skip to content

Commit ac54061

Browse files
committed
new port quantum information
1 parent ebcb99e commit ac54061

File tree

1 file changed

+374
-0
lines changed

1 file changed

+374
-0
lines changed
Lines changed: 374 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,374 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Porting Yao.jl with QuantumInformation.jl\n",
8+
"### GiggleLiu"
9+
]
10+
},
11+
{
12+
"cell_type": "markdown",
13+
"metadata": {},
14+
"source": [
15+
"# overview\n",
16+
"\n",
17+
" [`Yao`](https://github.com/QuantumBFS/Yao.jl) is a powerful tool for quantum circuit based simulation, but it does not support many density matrix related operations. This is why we need to port `Yao.jl` with [`QuantumInformation (QI)`](https://github.com/QuantumBFS/QuantumInformation.jl) sometimes (e.g. for computing entanglement entropy).\n",
18+
" \n",
19+
"* `Yao.jl` Documentation: https://quantumbfs.github.io/Yao.jl/latest/ (paper is comming out)\n",
20+
"* `QuantumInformation.jl` paper: https://arxiv.org/abs/1806.11464\n",
21+
" \n",
22+
"### `Yao` provides\n",
23+
"* high performance quantum circuit based simulation\n",
24+
" * parameter management\n",
25+
" * gradients\n",
26+
" * batched regiser\n",
27+
"* operator matrix representation and arithmatics\n",
28+
"* [quantum algorithms](https://github.com/QuantumBFS/QuAlgorithmZoo.jl)\n",
29+
"* [GPU support](https://github.com/QuantumBFS/CuYao.jl)\n",
30+
"\n",
31+
"### `QI` provides\n",
32+
"\n",
33+
"* Compute entropy from density matrices\n",
34+
"* Quantum channels, four types of channel representations\n",
35+
" * Kraus Operator\n",
36+
" * Super operator\n",
37+
" * Dynamic matrices\n",
38+
" * Stinespring representation\n",
39+
"* Compute norm, distance and distingushability between \"states\" (density matrices)\n",
40+
" * Hilbert–Schmidt norm and distance\n",
41+
" * trace norm and *distance*\n",
42+
" * diamond norm\n",
43+
" * Bures distane and Bures angles\n",
44+
" * *fidelity* and superfidelity\n",
45+
" * KL-divergence\n",
46+
" * JS-distance\n",
47+
"* Compute the amount of entanglement\n",
48+
" * negativity\n",
49+
" * positive partial trace\n",
50+
" * concurrence\n",
51+
"* POVM measurements"
52+
]
53+
},
54+
{
55+
"cell_type": "code",
56+
"execution_count": 16,
57+
"metadata": {},
58+
"outputs": [],
59+
"source": [
60+
"import Yao\n",
61+
"using Yao: ArrayReg, ρ, mat, ConstGate, purify, exchange_sysenv, @bit_str, statevec\n",
62+
"import QuantumInformation; const QI = QuantumInformation\n",
63+
"using QuantumInformation: ket\n",
64+
"using LinearAlgebra\n",
65+
"using Test"
66+
]
67+
},
68+
{
69+
"cell_type": "markdown",
70+
"metadata": {},
71+
"source": [
72+
"Obtain reduced density matrices in Yao\n",
73+
"-------------------------\n",
74+
"The memory layout of `Yao` register and `QI` ket are similar, their basis are both [little endian](https://en.wikipedia.org/wiki/Endianness), despite they have different representation powers\n",
75+
"\n",
76+
"* `Yao` support batch,\n",
77+
"* `QI` is not limited to qubits.\n",
78+
"\n",
79+
"\n",
80+
"`Yao` does not have much operations defined on density matrices, but purified states with environment,\n",
81+
"On the other side, most operations in `QI` are defined on **(density) matrices**, they can be easily obtained in `Yao`."
82+
]
83+
},
84+
{
85+
"cell_type": "code",
86+
"execution_count": 17,
87+
"metadata": {},
88+
"outputs": [
89+
{
90+
"data": {
91+
"text/plain": [
92+
"\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m"
93+
]
94+
},
95+
"execution_count": 17,
96+
"metadata": {},
97+
"output_type": "execute_result"
98+
}
99+
],
100+
"source": [
101+
"# construct a product state, notice the indexing in `QI` starts from `1`\n",
102+
"@test QI.ket(3, 1<<4) ≈ statevec(ArrayReg(bit\"0010\"))\n",
103+
"\n",
104+
"# join two registers, notice little endian convension is used here.\n",
105+
"reg = join(ArrayReg(bit\"10\"), ArrayReg(bit\"11\"))\n",
106+
"v = QI.:⊗(QI.ket(0b10+1,1<<2), QI.ket(0b11+1,1<<2))\n",
107+
"@test statevec(reg) ≈ v"
108+
]
109+
},
110+
{
111+
"cell_type": "code",
112+
"execution_count": 18,
113+
"metadata": {
114+
"scrolled": true
115+
},
116+
"outputs": [
117+
{
118+
"data": {
119+
"text/plain": [
120+
"16×16 Array{Complex{Float64},2}:\n",
121+
" 0.0668399+0.0im … 0.0048149+0.00800254im \n",
122+
" -0.00683079+0.00430075im 0.00271044+0.013467im \n",
123+
" -0.00405524-0.00233655im 0.00489161-0.00506099im \n",
124+
" 0.0041184-0.00690317im -0.00724508+0.00433365im \n",
125+
" 0.000248112-0.00614303im -0.00169715-0.0060107im \n",
126+
" -0.00638715+0.00343611im … -0.00346919+0.0104737im \n",
127+
" -0.0032589-0.00594789im -0.00502371+0.00889227im \n",
128+
" 0.0053714-0.00448422im 0.000149836+0.00490488im \n",
129+
" -0.00485418+0.00190183im -0.00707738-0.0117206im \n",
130+
" -0.00185245-0.0113168im -0.00100021+0.00456715im \n",
131+
" 0.000202351+0.00648573im … 9.29962e-5-0.00362312im \n",
132+
" 0.0038004-0.00408768im 0.00290617+0.0109155im \n",
133+
" -0.00488166-0.00699333im -0.00471523+0.000137239im\n",
134+
" 0.00485705+0.00532262im 0.00956895-0.00457732im \n",
135+
" 0.00756613-0.00569826im 0.0032851+0.0014402im \n",
136+
" 0.0048149-0.00800254im … 0.0786938+0.0im "
137+
]
138+
},
139+
"execution_count": 18,
140+
"metadata": {},
141+
"output_type": "execute_result"
142+
}
143+
],
144+
"source": [
145+
"# convert a Yao register to density matrix in QI\n",
146+
"reg2dm(reg::ArrayReg{1}) = reg |> ρ |> Matrix\n",
147+
"\n",
148+
"# e.g. obtain a reduced denstiy matrix for subsystem 1,2,3,4\n",
149+
"reg = Yao.rand_state(10)\n",
150+
"freg = Yao.focus!(reg, 1:4) # make qubits 1-4 active\n",
151+
"reg2dm(freg)"
152+
]
153+
},
154+
{
155+
"cell_type": "markdown",
156+
"metadata": {},
157+
"source": [
158+
"One can also convert a density matrix to a a quantum state through **purification**"
159+
]
160+
},
161+
{
162+
"cell_type": "code",
163+
"execution_count": 19,
164+
"metadata": {},
165+
"outputs": [
166+
{
167+
"data": {
168+
"text/plain": [
169+
"\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m"
170+
]
171+
},
172+
"execution_count": 19,
173+
"metadata": {},
174+
"output_type": "execute_result"
175+
}
176+
],
177+
"source": [
178+
"# e.g. purify a state and recover it\n",
179+
"reg = Yao.rand_state(6) |> Yao.focus!(1:4)\n",
180+
"reg_p = purify(reg |> ρ; nbit_env=2)\n",
181+
"@test Yao.fidelity(reg, reg_p)[] ≈ 1"
182+
]
183+
},
184+
{
185+
"cell_type": "markdown",
186+
"metadata": {},
187+
"source": [
188+
"entanglement & state distance\n",
189+
"----------------\n"
190+
]
191+
},
192+
{
193+
"cell_type": "code",
194+
"execution_count": 20,
195+
"metadata": {},
196+
"outputs": [
197+
{
198+
"data": {
199+
"text/plain": [
200+
"\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m"
201+
]
202+
},
203+
"execution_count": 20,
204+
"metadata": {},
205+
"output_type": "execute_result"
206+
}
207+
],
208+
"source": [
209+
"reg1 = Yao.rand_state(10)\n",
210+
"freg1 = Yao.focus!(reg1, 1:4)\n",
211+
"reg2 = Yao.rand_state(6)\n",
212+
"freg2 = Yao.focus!(reg2, 1:4)\n",
213+
"dm1, dm2 = freg1 |> reg2dm, freg2 |> reg2dm\n",
214+
"\n",
215+
"# trace distance between two registers (different by a factor 2)\n",
216+
"@test Yao.tracedist(freg1, freg2)[]/2 ≈ QI.trace_distance(dm1, dm2)"
217+
]
218+
},
219+
{
220+
"cell_type": "code",
221+
"execution_count": 21,
222+
"metadata": {},
223+
"outputs": [
224+
{
225+
"name": "stdout",
226+
"output_type": "stream",
227+
"text": [
228+
"QI.vonneumann_entropy(dm1) = 2.6568839293081608\n",
229+
"QI.vonneumann_entropy(dm2) = 1.3245543916726097\n"
230+
]
231+
},
232+
{
233+
"data": {
234+
"text/plain": [
235+
"1.3245543916726097"
236+
]
237+
},
238+
"execution_count": 21,
239+
"metadata": {},
240+
"output_type": "execute_result"
241+
}
242+
],
243+
"source": [
244+
"# get the entanglement entropy between system and env\n",
245+
"@show QI.vonneumann_entropy(dm1)\n",
246+
"@show QI.vonneumann_entropy(dm2)"
247+
]
248+
},
249+
{
250+
"cell_type": "code",
251+
"execution_count": 22,
252+
"metadata": {},
253+
"outputs": [
254+
{
255+
"data": {
256+
"text/plain": [
257+
"1.5694621854109723"
258+
]
259+
},
260+
"execution_count": 22,
261+
"metadata": {},
262+
"output_type": "execute_result"
263+
}
264+
],
265+
"source": [
266+
"# KL-divergence (or relative entropy)\n",
267+
"QI.kl_divergence(dm2, dm1)"
268+
]
269+
},
270+
{
271+
"cell_type": "markdown",
272+
"metadata": {},
273+
"source": [
274+
"Note: you can defined many distances and entropies in a similar way, we don't enumerate it."
275+
]
276+
},
277+
{
278+
"cell_type": "markdown",
279+
"metadata": {},
280+
"source": [
281+
"Quantum Operations/Quantum Gates\n",
282+
"------------------------\n",
283+
"\n",
284+
"A quantum gate in `Yao` is equivalent to a unitary channel in `QI`, matrix representations of blocks in `Yao` can be used to construct channels."
285+
]
286+
},
287+
{
288+
"cell_type": "code",
289+
"execution_count": 23,
290+
"metadata": {},
291+
"outputs": [
292+
{
293+
"data": {
294+
"text/plain": [
295+
"QuantumInformation.KrausOperators{Array{Complex{Float64},2}}\n",
296+
" dimensions: (2, 2)\n",
297+
" Complex{Float64}[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im]\n",
298+
" Complex{Float64}[0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im]\n",
299+
" Complex{Float64}[0.0 + 0.0im 1.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im]"
300+
]
301+
},
302+
"execution_count": 23,
303+
"metadata": {},
304+
"output_type": "execute_result"
305+
}
306+
],
307+
"source": [
308+
"# construct a Kraus Operator\n",
309+
"QI.KrausOperators([Matrix(ConstGate.P0), Matrix(ConstGate.P1), Matrix(ConstGate.Pu)])"
310+
]
311+
},
312+
{
313+
"cell_type": "code",
314+
"execution_count": 24,
315+
"metadata": {},
316+
"outputs": [
317+
{
318+
"data": {
319+
"text/plain": [
320+
":(#= In[24]:9 =# @test (copy(reg) |> Yao.chain(b1, b2)) |> reg2dm ≈ (c2 ∘ c1)(reg |> reg2dm))"
321+
]
322+
},
323+
"execution_count": 24,
324+
"metadata": {},
325+
"output_type": "execute_result"
326+
}
327+
],
328+
"source": [
329+
"# applying a rotation gate\n",
330+
"b1 = Yao.put(2,2=>Yao.Rx(0.3π))\n",
331+
"c1 = QI.UnitaryChannel(mat(b1))\n",
332+
"b2 = Yao.put(2,2=>Yao.Ry(0.3π))\n",
333+
"c2 = QI.UnitaryChannel(mat(b2))\n",
334+
"\n",
335+
"reg = Yao.rand_state(2)\n",
336+
"@test copy(reg) |> b1 |> reg2dm ≈ c1(reg |> reg2dm)\n",
337+
":@test copy(reg) |> Yao.chain(b1,b2) |> reg2dm ≈ (c2∘c1)(reg |> reg2dm)"
338+
]
339+
},
340+
{
341+
"cell_type": "code",
342+
"execution_count": null,
343+
"metadata": {},
344+
"outputs": [],
345+
"source": []
346+
},
347+
{
348+
"cell_type": "code",
349+
"execution_count": null,
350+
"metadata": {},
351+
"outputs": [],
352+
"source": []
353+
}
354+
],
355+
"metadata": {
356+
"@webio": {
357+
"lastCommId": null,
358+
"lastKernelId": null
359+
},
360+
"kernelspec": {
361+
"display_name": "Julia 1.3.0",
362+
"language": "julia",
363+
"name": "julia-1.3"
364+
},
365+
"language_info": {
366+
"file_extension": ".jl",
367+
"mimetype": "application/julia",
368+
"name": "julia",
369+
"version": "1.3.0"
370+
}
371+
},
372+
"nbformat": 4,
373+
"nbformat_minor": 2
374+
}

0 commit comments

Comments
 (0)