-
Notifications
You must be signed in to change notification settings - Fork 127
/
Copy pathmulti_state_discrimination.py
151 lines (116 loc) · 5.28 KB
/
multi_state_discrimination.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
142
143
144
145
146
147
148
149
150
151
# This code is part of Qiskit.
#
# (C) Copyright IBM 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""Multi state discrimination experiment."""
from typing import Dict, List, Optional, Sequence
from qiskit import QuantumCircuit
from qiskit.circuit import Gate
from qiskit.providers import Backend
from qiskit.providers.options import Options
from qiskit.pulse import ScheduleBlock
from qiskit.qobj.utils import MeasLevel, MeasReturnType
from qiskit_experiments.framework import BaseExperiment
from qiskit_experiments.warnings import qubit_deprecate
from qiskit_experiments.library.characterization import MultiStateDiscriminationAnalysis
class MultiStateDiscrimination(BaseExperiment):
r"""An experiment that discriminates between the first :math:`n` energy states.
# section: overview
The experiment creates :math:`n` circuits that prepare, respectively, the energy states
:math:`|0\rangle,\cdots,|n-1\rangle`. For, e.g., :math:`n=4` the circuits are of the form
.. parsed-literal::
Circuit preparing :math:`|0\rangle`
░ ┌─┐
q: ─░─┤M├
░ └╥┘
meas: ════╩═
...
Circuit preparing :math:`|3\rangle`
┌───┐┌─────┐┌─────┐ ░ ┌─┐
q: ┤ X ├┤ x12 ├┤ x23 ├─░─┤M├
└───┘└─────┘└─────┘ ░ └╥┘
meas: ═══════════════════════╩═
# section: analysis_ref
:class:`MultiStateDiscriminationAnalysis`
# section: reference
`Qiskit Textbook\
<https://qiskit.org/textbook/ch-quantum-hardware/accessing_higher_energy_states.html>`_
"""
@classmethod
def _default_run_options(cls) -> Options:
"""Default option values for the experiment :meth:`run` method."""
options = super()._default_run_options()
options.meas_level = MeasLevel.KERNELED
options.meas_return = MeasReturnType.SINGLE
return options
@classmethod
def _default_experiment_options(cls) -> Options:
"""Default values for the number of states if none is given.
Experiment Options:
n_states (int): The number of states to discriminate.
schedules (dict): A dictionary of the schedules for the gates in the experiment. Each key is
a gate name of the form ``xii+1`` which should implement an x-rotation between level
``i`` and ``i+1``.
"""
options = super()._default_experiment_options()
options.n_states = 2
options.schedules = None
return options
@qubit_deprecate()
def __init__(
self,
physical_qubits: Sequence[int],
backend: Optional[Backend] = None,
n_states: Optional[int] = None,
schedules: Optional[Dict[str, ScheduleBlock]] = None,
):
"""Setup an experiment to prepare different energy states on a given qubit.
Args:
physical_qubits: A single-element sequence containing the qubit on which to run the
experiment.
backend: Optional, the backend to run the experiment on.
n_states: The number of energy levels to prepare.
schedules: The schedules of the x gates between neighboring energy levels.
"""
super().__init__(
physical_qubits, analysis=MultiStateDiscriminationAnalysis(), backend=backend
)
self.experiment_options.schedules = schedules
if n_states is not None:
self.set_experiment_options(n_states=n_states)
def circuits(self) -> List[QuantumCircuit]:
"""
Create the circuits for the multi state discrimination experiment.
Returns:
A list of circuits preparing the different energy states.
"""
circuits = []
for level in range(self.experiment_options.n_states):
circuit = QuantumCircuit(1)
# Prepare |1>
if level >= 1:
circuit.x(0)
# Prepare higher energy states
if level >= 2:
for idx in range(1, level):
gate_name = f"x{idx}{idx + 1}"
gate = Gate(name=gate_name, num_qubits=1, params=[])
circuit.append(gate, (0,))
if self.experiment_options.schedules is not None:
circuit.add_calibration(
gate_name,
self._physical_qubits,
self.experiment_options.schedules[gate_name],
)
# label the circuit
circuit.metadata = {"label": str(level)}
circuit.measure_all()
circuits.append(circuit)
return circuits