Skip to content
This repository was archived by the owner on Aug 21, 2023. It is now read-only.

Commit bf42d6a

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents a386a9a + f8bdf17 commit bf42d6a

25 files changed

Lines changed: 7977 additions & 4851 deletions

.github/CODEOWNERS

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,2 @@
11
# Fallback codeowners for all files that do not have an explicit rule.
2-
* @jaygambetta @ajavadia
3-
4-
# Codeowners for individual folders
5-
qiskit/* @jaygambetta @ajavadia
6-
7-
qiskit/aqua/**/* @jaygambetta @pistoia
8-
qiskit/artificial_intelligence/**/* @jaygambetta @pistoia
9-
qiskit/chemistry/**/* @jaygambetta @pistoia
10-
qiskit/finance/**/* @jaygambetta @pistoia
11-
qiskit/optimization/**/* @jaygambetta @pistoia
12-
13-
qiskit/aer/* @chriseclectic @jaygambetta @ajavadia
14-
qiskit/ignis/* @dcmckayibm @jaygambetta @ajavadia
15-
qiskit/terra/* @nonhermitian @jaygambetta @ajavadia
2+
* @jaygambetta @nonhermitian

apt.txt

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# QasmSimulator: matrix product state simulation method\n",
8+
"## Simulation methods\n",
9+
"The QasmSimulator has several simulation methods including `statevector`, `stabilizer`, `extended_stabilizer` and `matrix_product_state`. Each of these determines the internal representation of the quantum circuit and the algorithms used to process the quantum operations. They each have advantages and disadvantages, and choosing the best method is a matter of investigation.\n",
10+
"In this tutorial, we focus on the `matrix product state simulation method`.\n"
11+
]
12+
},
13+
{
14+
"cell_type": "markdown",
15+
"metadata": {},
16+
"source": [
17+
"## Matrix product state simulation method\n",
18+
"This simulation method is based on the concept of `matrix product states`. This structure was initially proposed in the paper *Efficient classical simulation of slightly entangled quantum computations* by Vidal in https://arxiv.org/abs/quant-ph/0301063. There are additional papers that describe the structure in more detail, for example *The density-matrix renormalization group in the age of matrix product states* by Schollwoeck https://arxiv.org/abs/1008.3477."
19+
]
20+
},
21+
{
22+
"cell_type": "markdown",
23+
"metadata": {},
24+
"source": [
25+
"A pure quantum state is usually described as a state vector, by the expression $|\\psi\\rangle = \\sum_{i_1=0}^1 {\\ldots} \\sum_{i_n=0}^1 c_{i_1 \\ldots i_n} |i_i\\rangle {\\otimes} {\\ldots} {\\otimes} |i_n\\rangle$.\n",
26+
"\n",
27+
"The state vector representation implies an exponential size representation, regardless of the actual circuit. Every quantum gate operating on this representation requires exponential time and memory.\n",
28+
"\n",
29+
"The matrix product state (MPS) representation offers a local representation, in the form:\n",
30+
"$\\Gamma^{[1]} \\lambda^{[1]} \\Gamma^{[2]} \\lambda^{[2]}\\ldots \\Gamma^{[1]} \\lambda^{[n-1]} \\Gamma^{[n]}$, such that all the information contained in the $c_{i_1 \\ldots i_n}$, can be generated out of the MPS representation..\n"
31+
]
32+
},
33+
{
34+
"cell_type": "markdown",
35+
"metadata": {},
36+
"source": [
37+
"Every $\\Gamma^{[i]}$ is a tensor of complex numbers that represents qubit $i$. Every $\\lambda^{[i]}$ is a matrix of real numbers that is used to normalize the amplitudes of qubits $i$ and $i+1$. Single-qubit gates operate only on the relevant tensor. \n",
38+
"\n",
39+
"Two-qubit gates operate on consecutive qubits $i$ and $i+1$. This involves a tensor-contract operation over $\\lambda^{[i-1]}$, $\\Gamma^{[i-1]}$, $\\lambda^{[i]}$, $\\Gamma^{[i+1]}$ and $\\lambda^{[i+1]}$, that creates a single tensor. We apply the gate to this tensor, and then decompose back to the original structure. This operation may increase the size of the respective tensors. Gates that involve two qubits that are not consecutive, require a series of swap gates to bring the two qubits next to each other and then the reverse swaps. \n",
40+
"\n",
41+
"In the worst case, the tensors may grow exponentially. However, the size of the overall structure remains 'small' for circuits that do not have 'many' two-qubit gates. This allows much more efficient operations in circuits with relatively 'low' entanglement. Characterizing when to use this method over other methods is a subject of current research."
42+
]
43+
},
44+
{
45+
"cell_type": "markdown",
46+
"metadata": {},
47+
"source": [
48+
"## Using the matrix product state simulation method\n",
49+
"The matrix product state simulation method is invoked in the qasm simulator by setting the `simulation_method`. \n",
50+
"Other than that, all operations are controlled by the qasm simulator itself, as in the following example:"
51+
]
52+
},
53+
{
54+
"cell_type": "code",
55+
"execution_count": 1,
56+
"metadata": {
57+
"scrolled": true
58+
},
59+
"outputs": [
60+
{
61+
"name": "stdout",
62+
"output_type": "stream",
63+
"text": [
64+
"{'10': 517, '01': 507}\n"
65+
]
66+
}
67+
],
68+
"source": [
69+
"import numpy as np\n",
70+
"\n",
71+
"# Import Qiskit\n",
72+
"from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister\n",
73+
"from qiskit import Aer, execute\n",
74+
"from qiskit.providers.aer import QasmSimulator\n",
75+
"\n",
76+
"# Construct quantum circuit\n",
77+
"qr = QuantumRegister(2)\n",
78+
"cr = ClassicalRegister(2)\n",
79+
"circ = QuantumCircuit(qr, cr)\n",
80+
"circ.h(qr[0])\n",
81+
"circ.cx(qr[0], qr[1])\n",
82+
"circ.measure(qr, cr)\n",
83+
"\n",
84+
"# Select the QasmSimulator from the Aer provider\n",
85+
"simulator = Aer.get_backend('qasm_simulator')\n",
86+
"\n",
87+
"# Define the simulation method\n",
88+
"backend_opts_mps = {\"method\":\"matrix_product_state\"}\n",
89+
"\n",
90+
"# Execute and get counts, using the matrix_product_state method\n",
91+
"result = execute(circ, simulator, backend_options=backend_opts_mps).result()\n",
92+
"counts = result.get_counts(circ)\n",
93+
"print(counts)"
94+
]
95+
},
96+
{
97+
"cell_type": "markdown",
98+
"metadata": {},
99+
"source": [
100+
"To see the internal state vector of the circuit, we can import the snapshot files:"
101+
]
102+
},
103+
{
104+
"cell_type": "code",
105+
"execution_count": 2,
106+
"metadata": {},
107+
"outputs": [],
108+
"source": [
109+
"from qiskit.extensions.simulator import Snapshot\n",
110+
"from qiskit.extensions.simulator.snapshot import snapshot"
111+
]
112+
},
113+
{
114+
"cell_type": "code",
115+
"execution_count": 3,
116+
"metadata": {},
117+
"outputs": [
118+
{
119+
"name": "stdout",
120+
"output_type": "stream",
121+
"text": [
122+
"[[[0.7071067811865475, 0.0], [0.0, 0.0], [0.0, 0.0], [0.7071067811865475, 0.0]]]\n"
123+
]
124+
}
125+
],
126+
"source": [
127+
"# Construct quantum circuit\n",
128+
"q = QuantumRegister(2)\n",
129+
"c = ClassicalRegister(2)\n",
130+
"circ = QuantumCircuit(q, c)\n",
131+
"circ.h(q[0])\n",
132+
"circ.cx(q[0], q[1])\n",
133+
"\n",
134+
"# Define a snapshot that shows the current state vector\n",
135+
"circ.snapshot('my_sv', snapshot_type='statevector')\n",
136+
"circ.measure(q, c)\n",
137+
"\n",
138+
"# Execute\n",
139+
"job_sim = execute([circ], QasmSimulator(), backend_options=backend_opts_mps)\n",
140+
"result = job_sim.result()\n",
141+
"res = result.results\n",
142+
"\n",
143+
"#print the state vector\n",
144+
"statevector = res[0].data.snapshots.statevector\n",
145+
"print(statevector['my_sv'])"
146+
]
147+
},
148+
{
149+
"cell_type": "code",
150+
"execution_count": 4,
151+
"metadata": {},
152+
"outputs": [
153+
{
154+
"name": "stdout",
155+
"output_type": "stream",
156+
"text": [
157+
"{'10': 529, '01': 495}\n"
158+
]
159+
}
160+
],
161+
"source": [
162+
"print(result.get_counts())"
163+
]
164+
},
165+
{
166+
"cell_type": "markdown",
167+
"metadata": {},
168+
"source": [
169+
"Running circuits using the matrix product state simulation method can be fast, relative to other methods. However, if we generate the state vector during the execution, then the conversion to state vector is, of course, exponential in memory and time, and therefore we don't benefit from using this method. We can benefit if we only do operations that don't require printing the full statevector. For example, if we run a circuit and then take measurement. The circuit below has 200 qubits. We create an `EPR state` involving all these qubits. Although this state is highly entangled, it is handled well by the matrix product state method, because there are effectively only two states. \n",
170+
"\n",
171+
"We can handle more qubits than this, but execution may take a few minutes. Try running a similar circuit with 500 qubits! or maybe even 1000 (you can get a cup of coffee while waiting)."
172+
]
173+
},
174+
{
175+
"cell_type": "code",
176+
"execution_count": 5,
177+
"metadata": {
178+
"scrolled": true
179+
},
180+
"outputs": [
181+
{
182+
"name": "stdout",
183+
"output_type": "stream",
184+
"text": [
185+
"{'00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000': 518, '11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111': 506}\n",
186+
"Time was 38.062061071395874 s\n"
187+
]
188+
}
189+
],
190+
"source": [
191+
"num_qubits = 200\n",
192+
"qr = QuantumRegister(num_qubits)\n",
193+
"cr = ClassicalRegister(num_qubits)\n",
194+
"circ = QuantumCircuit(qr, cr)\n",
195+
"\n",
196+
"# Create EPR state\n",
197+
"circ.h(qr[0])\n",
198+
"for i in range (0,num_qubits-1):\n",
199+
" circ.cx(qr[i], qr[i+1])\n",
200+
"\n",
201+
"# Measure\n",
202+
"circ.measure(qr, cr)\n",
203+
"\n",
204+
"job_sim = execute([circ], QasmSimulator(), backend_options=backend_opts_mps)\n",
205+
"result = job_sim.result()\n",
206+
"print(result.get_counts())\n",
207+
"print(\"Time was {} s\".format(result.time_taken))"
208+
]
209+
}
210+
],
211+
"metadata": {
212+
"kernelspec": {
213+
"display_name": "Python 3",
214+
"language": "python",
215+
"name": "python3"
216+
},
217+
"language_info": {
218+
"codemirror_mode": {
219+
"name": "ipython",
220+
"version": 3
221+
},
222+
"file_extension": ".py",
223+
"mimetype": "text/x-python",
224+
"name": "python",
225+
"nbconvert_exporter": "python",
226+
"pygments_lexer": "ipython3",
227+
"version": "3.6.8"
228+
}
229+
},
230+
"nbformat": 4,
231+
"nbformat_minor": 2
232+
}

0 commit comments

Comments
 (0)