Skip to content

Commit 24ecc7a

Browse files
author
changsookim
committed
Merge branch 'master' into router_sabre
2 parents 5e25ecf + 434989e commit 24ecc7a

File tree

14 files changed

+108
-108
lines changed

14 files changed

+108
-108
lines changed

doc/source/api-reference/qibo.rst

+3-2
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,8 @@ factor results in the mitigated Pauli expectation value :math:`\langle O\rangle_
473473
.. math::
474474
\langle O\rangle_{ideal} = \frac{\langle O\rangle_{noisy}}{\lambda}
475475
476-
.. autofunction:: qibo.models.error_mitigation.apply_randomized_readout_mitigation
476+
This process can be implemented with the aforementioned
477+
:func:`qibo.models.error_mitigation.apply_randomized_readout_mitigation`.
477478

478479

479480
Zero Noise Extrapolation (ZNE)
@@ -2382,7 +2383,7 @@ Hellinger fidelity
23822383
Hellinger shot error
23832384
""""""""""""""""""""
23842385

2385-
.. autofunction:: qibo.quantum_info.hellinger_fidelity
2386+
.. autofunction:: qibo.quantum_info.hellinger_shot_error
23862387

23872388

23882389
Haar integral

doc/source/code-examples/examples.rst

-2
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,6 @@ For example, we can draw the QFT circuit for 5-qubits:
347347
# new plot function based on matplotlib
348348
from qibo.ui import plot_circuit
349349

350-
%matplotlib inline
351-
352350
# create a 5-qubits QFT circuit
353351
c = QFT(5)
354352
c.add(gates.M(qubit) for qubit in range(2))

examples/shor/functions.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,9 @@ def quantum_order_finding_semiclassical(N, a):
393393
circuit.add(gates.U1(q_reg, -angle))
394394
circuit.add(gates.H(q_reg))
395395
results.append(circuit.add(gates.M(q_reg, collapse=True)))
396+
circuit.add(gates.M(q_reg))
396397

397-
circuit() # execute
398+
circuit(nshots=1) # execute
398399
s = sum(int(r.symbols[0].outcome()) * (2**i) for i, r in enumerate(results))
399400
print(f"The quantum circuit measures s = {s}.\n")
400401
return s

src/qibo/backends/abstract.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ def execute_circuit(
193193
def execute_circuits(
194194
self, circuits, initial_states=None, nshots=None
195195
): # pragma: no cover
196-
"""Execute multiple :class:`qibo.models.circuit.Circuit`s in parallel."""
196+
"""Execute multiple :class:`qibo.models.circuit.Circuit` in parallel."""
197197
raise_error(NotImplementedError)
198198

199199
@abc.abstractmethod

src/qibo/backends/clifford.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ def calculate_frequencies(self, samples):
9090
return collections.Counter(dict(zip(res, counts)))
9191

9292
def zero_state(self, nqubits: int):
93-
"""Construct the zero state |00...00>.
93+
"""Construct the zero state :math`\\ket{00...00}`.
9494
9595
Args:
96-
nqubits (int): Number of qubits.
96+
nqubits (int): number of qubits.
9797
9898
Returns:
99-
(ndarray): Symplectic matrix for the zero state.
99+
ndarray: Symplectic matrix for the zero state.
100100
"""
101101
identity = self.np.eye(nqubits)
102102
symplectic_matrix = self.np.zeros(

src/qibo/gates/channels.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,11 @@ def to_choi(self, nqubits: Optional[int] = None, order: str = "row", backend=Non
4848
of the Kraus channel :math:`\\{K_{\\alpha}\\}_{\\alpha}`.
4949
5050
.. math::
51-
\\mathcal{E} = \\sum_{\\alpha} \\, |K_{\\alpha}\\rangle\\rangle
52-
\\langle\\langle K_{\\alpha}|
51+
\\mathcal{E} = \\sum_{\\alpha} \\, |K_{\\alpha})(K_{\\alpha}| \\, ,
52+
53+
where :math:`|K_{\\alpha})` is the vectorization of the Kraus operator
54+
:math:`K_{\\alpha}`.
55+
For a definition of vectorization, see :func:`qibo.quantum_info.vectorization`.
5356
5457
Args:
5558
nqubits (int, optional): total number of qubits to be considered

src/qibo/gates/measurements.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,26 @@ class M(Gate):
1717
If the qubits to measure are held in an iterable (eg. list) the ``*``
1818
operator can be used, for example ``gates.M(*[0, 1, 4])`` or
1919
``gates.M(*range(5))``.
20-
register_name (str): Optional name of the register to distinguish it
20+
register_name (str, optional): Optional name of the register to distinguish it
2121
from other registers when used in circuits.
2222
collapse (bool): Collapse the state vector after the measurement is
2323
performed. Can be used only for single shot measurements.
2424
If ``True`` the collapsed state vector is returned. If ``False``
2525
the measurement result is returned.
26-
basis (:class:`qibo.gates.Gate`, str, list): Basis to measure.
26+
basis (:class:`qibo.gates.Gate` or str or list, optional): Basis to measure.
2727
Can be either:
2828
- a qibo gate
2929
- the string representing the gate
3030
- a callable that accepts a qubit, for example: ``lambda q: gates.RX(q, 0.2)``
31-
- a list of the above, if a different basis will be used for each
32-
measurement qubit.
33-
Default is Z.
34-
p0 (dict): Optional bitflip probability map. Can be:
31+
- a list of the above, if a different basis will be used for each measurement qubit.
32+
Defaults is to :class:`qibo.gates.Z`.
33+
p0 (dict, optional): bitflip probability map. Can be:
3534
A dictionary that maps each measured qubit to the probability
3635
that it is flipped, a list or tuple that has the same length
3736
as the tuple of measured qubits or a single float number.
3837
If a single float is given the same probability will be used
3938
for all qubits.
40-
p1 (dict): Optional bitflip probability map for asymmetric bitflips.
39+
p1 (dict, optional): bitflip probability map for asymmetric bitflips.
4140
Same as ``p0`` but controls the 1->0 bitflip probability.
4241
If ``p1`` is ``None`` then ``p0`` will be used both for 0->1 and
4342
1->0 bitflips.

src/qibo/models/error_mitigation.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -658,24 +658,24 @@ def apply_randomized_readout_mitigation(
658658
nshots (int, optional): number of shots. Defaults to :math:`10000`.
659659
ncircuits (int, optional): number of randomized circuits. Each of them uses
660660
``int(nshots / ncircuits)`` shots. Defaults to 10.
661-
qubit_map (list, optional): the qubit map. If None, a list of range of circuit's qubits is used.
662-
Defaults to ``None``.
661+
qubit_map (list, optional): the qubit map. If ``None``, a list of range of circuit's
662+
qubits is used. Defaults to ``None``.
663663
seed (int or :class:`numpy.random.Generator`, optional): Either a generator of random
664664
numbers or a fixed seed to initialize a generator. If ``None``, initializes
665665
a generator with a random seed. Default: ``None``.
666666
backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used
667667
in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`.
668668
Defaults to ``None``.
669669
670-
Return:
670+
Returns:
671671
:class:`qibo.measurements.CircuitResult`: the state of the input circuit with
672672
mitigated frequencies.
673673
674674
675-
Reference:
675+
References:
676676
1. Ewout van den Berg, Zlatko K. Minev et al,
677677
*Model-free readout-error mitigation for quantum expectation values*.
678-
`arXiv:2012.09738 [quant-ph] <https://arxiv.org/abs/2012.09738>`_.
678+
`arXiv:2012.09738 [quant-ph] <https://arxiv.org/abs/2012.09738>`_.
679679
"""
680680
from qibo import Circuit # pylint: disable=import-outside-toplevel
681681
from qibo.quantum_info import ( # pylint: disable=import-outside-toplevel

src/qibo/quantum_info/basis.py

+21-19
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ def pauli_basis(
2828
vectorize (bool, optional): If ``False``, returns a nested array with
2929
all Pauli matrices. If ``True``, retuns an array where every
3030
row is a vectorized Pauli matrix. Defaults to ``False``.
31-
sparse (bool, optional) If ``True``, retuns Pauli basis in a sparse
32-
representation. Default is ``False``.
31+
sparse (bool, optional): If ``True``, retuns Pauli basis in a sparse
32+
representation. Defaults to ``False``.
3333
order (str, optional): If ``"row"``, vectorization of Pauli basis is
3434
performed row-wise. If ``"column"``, vectorization is performed
3535
column-wise. If ``"system"``, system-wise vectorization is
3636
performed. If ``vectorization=False``, then ``order=None`` is
37-
forced. Default is ``None``.
37+
forced. Defaults to ``None``.
3838
pauli_order (str, optional): corresponds to the order of 4 single-qubit
39-
Pauli elements. Default is "IXYZ".
39+
Pauli elements. Defaults to ``"IXYZ"``.
4040
backend (:class:`qibo.backends.abstract.Backend`, optional): backend
4141
to be used in the execution. If ``None``, it uses
4242
:class:`qibo.backends.GlobalBackend`. Defaults to ``None``.
@@ -148,15 +148,12 @@ def comp_basis_to_pauli(
148148
The unitary :math:`U` is given by
149149
150150
.. math::
151-
U = \\sum_{k = 0}^{d^{2} - 1} \\, \\ketbra{k}{P_{k}} \\,\\, ,
151+
U = \\sum_{k = 0}^{d^{2} - 1} \\, |k)(P_{k}| \\,\\, ,
152152
153-
where :math:`\\ket{P_{k}}` is the system-vectorization of the :math:`k`-th
154-
Pauli operator :math:`P_{k}`, and :math:`\\ket{k}` is the computational
155-
basis element.
156-
157-
When converting a state :math:`\\ket{\\rho}` to its Pauli-Liouville
158-
representation :math:`\\ket{\\rho'}`, one should use ``order="system"``
159-
in :func:`vectorization`.
153+
where :math:`|P_{k})` is the vectorization of the :math:`k`-th
154+
Pauli operator :math:`P_{k}`, and :math:`|k)` is the vectorization
155+
of the :math:`k`-th computational basis element.
156+
For a definition of vectorization, see :func:`qibo.quantum_info.vectorization`.
160157
161158
Example:
162159
.. code-block:: python
@@ -174,13 +171,13 @@ def comp_basis_to_pauli(
174171
normalize (bool, optional): If ``True``, converts to the
175172
Pauli basis. Defaults to ``False``.
176173
sparse (bool, optional): If ``True``, returns unitary matrix in
177-
sparse representation. Default is ``False``.
174+
sparse representation. Defaults to ``False``.
178175
order (str, optional): If ``"row"``, vectorization of Pauli basis is
179176
performed row-wise. If ``"column"``, vectorization is performed
180177
column-wise. If ``"system"``, system-wise vectorization is
181-
performed. Default is ``"row"``.
178+
performed. Defaults to ``"row"``.
182179
pauli_order (str, optional): corresponds to the order of 4 single-qubit
183-
Pauli elements. Default is "IXYZ".
180+
Pauli elements. Defaults to ``"IXYZ"``.
184181
backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be
185182
used in the execution. If ``None``, it uses
186183
:class:`qibo.backends.GlobalBackend`. Defaults to ``None``.
@@ -237,20 +234,25 @@ def pauli_to_comp_basis(
237234
The unitary :math:`U` is given by
238235
239236
.. math::
240-
U = \\sum_{k = 0}^{d^{2} - 1} \\, \\ketbra{P_{k}}{b_{k}} \\, .
237+
U = \\sum_{k = 0}^{d^{2} - 1} \\, |P_{k})(b_{k}| \\, ,
238+
239+
where :math:`|P_{k})` is the vectorization of the :math:`k`-th
240+
Pauli operator :math:`P_{k}`, and :math:`|k)` is the vectorization
241+
of the :math:`k`-th computational basis element.
242+
For a definition of vectorization, see :func:`qibo.quantum_info.vectorization`.
241243
242244
Args:
243245
nqubits (int): number of qubits.
244246
normalize (bool, optional): If ``True``, converts to the
245247
Pauli basis. Defaults to ``False``.
246248
sparse (bool, optional): If ``True``, returns unitary matrix in
247-
sparse representation. Default is ``False``.
249+
sparse representation. Defaults to ``False``.
248250
order (str, optional): If ``"row"``, vectorization of Pauli basis is
249251
performed row-wise. If ``"column"``, vectorization is performed
250252
column-wise. If ``"system"``, system-wise vectorization is
251-
performed. Default is ``"row"``.
253+
performed. Defaults to ``"row"``.
252254
pauli_order (str, optional): corresponds to the order of 4 single-qubit
253-
Pauli elements. Default is "IXYZ".
255+
Pauli elements. Defaults to ``"IXYZ"``.
254256
backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be
255257
used in the execution. If ``None``, it uses
256258
:class:`qibo.backends.GlobalBackend`. Defaults to ``None``.

src/qibo/quantum_info/clifford.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -297,16 +297,16 @@ def frequencies(self, binary: bool = True, registers: bool = False):
297297
of times each measured value/bitstring appears.
298298
299299
If ``binary`` is ``True``
300-
the keys of the `Counter` are in binary form, as strings of
301-
:math:`0`s and :math`1`s.
300+
the keys of the :class:`collections.Counter` are in binary form,
301+
as strings of :math:`0` and :math`1`.
302302
If ``binary`` is ``False``
303-
the keys of the ``Counter`` are integers.
303+
the keys of the :class:`collections.Counter` are integers.
304304
If ``registers`` is ``True``
305-
a `dict` of `Counter` s is returned where keys are the name of
306-
each register.
305+
a `dict` of :class:`collections.Counter` is returned where keys are
306+
the name of each register.
307307
If ``registers`` is ``False``
308-
a single ``Counter`` is returned which contains samples from all
309-
the measured qubits, independently of their registers.
308+
a single :class:`collections.Counter` is returned which contains samples
309+
from all the measured qubits, independently of their registers.
310310
"""
311311
measured_qubits = self.measurement_gate.target_qubits
312312
freq = self._backend.calculate_frequencies(self.samples(False))

src/qibo/quantum_info/entropies.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def classical_relative_entropy(prob_dist_p, prob_dist_q, base: float = 2, backen
7878
7979
For probabilities :math:`\\mathbf{p}` and :math:`\\mathbf{q}`, it is defined as
8080
81-
..math::
81+
.. math::
8282
D(\\mathbf{p} \\, \\| \\, \\mathbf{q}) = \\sum_{x} \\, \\mathbf{p}(x) \\,
8383
\\log\\left( \\frac{\\mathbf{p}(x)}{\\mathbf{q}(x)} \\right) \\, .
8484
@@ -680,7 +680,7 @@ def relative_renyi_entropy(
680680
This is known as the `min-relative entropy <https://arxiv.org/abs/1310.7178>`_.
681681
682682
.. note::
683-
Function raises ``NotImplementedError`` when ``target`` :math:`sigma`
683+
Function raises ``NotImplementedError`` when ``target`` :math:`\\sigma`
684684
is a pure state and :math:`\\alpha > 1`. This is due to the fact that
685685
it is not possible to calculate :math:`\\sigma^{1 - \\alpha}` when
686686
:math:`\\alpha > 1` and :math:`\\sigma` is a projector, i.e. a singular matrix.

src/qibo/quantum_info/superoperator_transformations.py

+22-16
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,17 @@
1414

1515

1616
def vectorization(state, order: str = "row", backend=None):
17-
"""Returns state :math:`\\rho` in its Liouville
18-
representation :math:`|\\rho\\rangle\\rangle`.
17+
"""Returns state :math:`\\rho` in its Liouville representation :math:`|\\rho)`.
1918
2019
If ``order="row"``, then:
2120
2221
.. math::
23-
|\\rho\\rangle\\rangle = \\sum_{k, l} \\, \\rho_{kl} \\, \\ket{k} \\otimes \\ket{l}
22+
|\\rho) = \\sum_{k, l} \\, \\rho_{kl} \\, \\ket{k} \\otimes \\ket{l}
2423
2524
If ``order="column"``, then:
2625
2726
.. math::
28-
|\\rho\\rangle\\rangle = \\sum_{k, l} \\, \\rho_{kl} \\, \\ket{l} \\otimes \\ket{k}
27+
|\\rho) = \\sum_{k, l} \\, \\rho_{kl} \\, \\ket{l} \\otimes \\ket{k}
2928
3029
Args:
3130
state: state vector or density matrix.
@@ -88,12 +87,12 @@ def vectorization(state, order: str = "row", backend=None):
8887

8988
def unvectorization(state, order: str = "row", backend=None):
9089
"""Returns state :math:`\\rho` from its Liouville
91-
representation :math:`|\\rho\\rangle\\rangle`. This operation is
90+
representation :math:`|\\rho)`. This operation is
9291
the inverse function of :func:`vectorization`, i.e.
9392
9493
.. math::
9594
\\begin{align}
96-
\\rho &= \\text{unvectorization}(|\\rho\\rangle\\rangle) \\nonumber \\\\
95+
\\rho &= \\text{unvectorization}(|\\rho)) \\nonumber \\\\
9796
&= \\text{unvectorization}(\\text{vectorization}(\\rho)) \\nonumber
9897
\\end{align}
9998
@@ -152,9 +151,9 @@ def to_choi(channel, order: str = "row", backend=None):
152151
"""Converts quantum ``channel`` :math:`U` to its Choi representation :math:`\\Lambda`.
153152
154153
.. math::
155-
\\Lambda = | U \\rangle\\rangle \\langle\\langle U | \\, ,
154+
\\Lambda = | U ) ( U | \\, ,
156155
157-
where :math:`| \\cdot \\rangle\\rangle` is the :func:`qibo.quantum_info.vectorization`
156+
where :math:`| \\cdot )` is the :func:`qibo.quantum_info.vectorization`
158157
operation.
159158
160159
Args:
@@ -376,7 +375,9 @@ def choi_to_kraus(
376375
377376
.. math::
378377
\\Lambda = \\sum_{\\alpha} \\, \\lambda_{\\alpha}^{2} \\,
379-
|\\tilde{K}_{\\alpha}\\rangle\\rangle \\langle\\langle \\tilde{K}_{\\alpha}| \\, .
378+
|\\tilde{K}_{\\alpha})(\\tilde{K}_{\\alpha}| \\, .
379+
380+
where :math:`|\\cdot)` is the :func:`qibo.quantum_info.vectorization` operation.
380381
381382
This is the spectral decomposition of :math:`\\Lambda`, Hence, the set
382383
:math:`\\{\\lambda_{\\alpha}, \\, \\tilde{K}_{\\alpha}\\}_{\\alpha}`
@@ -385,7 +386,7 @@ def choi_to_kraus(
385386
386387
.. math::
387388
K_{\\alpha} = \\lambda_{\\alpha} \\,
388-
\\text{unvectorization}(|\\tilde{K}_{\\alpha}\\rangle\\rangle) \\, .
389+
\\text{unvectorization}(|\\tilde{K}_{\\alpha})) \\, .
389390
390391
If :math:`\\mathcal{E}` is not CP, then spectral composition is replaced by
391392
a singular value decomposition (SVD), i.e.
@@ -638,7 +639,11 @@ def kraus_to_choi(kraus_ops, order: str = "row", backend=None):
638639
of quantum channel to its Choi representation :math:`\\Lambda`.
639640
640641
.. math::
641-
\\Lambda = \\sum_{\\alpha} \\, |K_{\\alpha}\\rangle\\rangle \\langle\\langle K_{\\alpha}|
642+
\\Lambda = \\sum_{\\alpha} \\, |K_{\\alpha})( K_{\\alpha}|
643+
644+
where :math:`|K_{\\alpha})` is the vectorization of the Kraus operator
645+
:math:`K_{\\alpha}`.
646+
For a definition of vectorization, see :func:`qibo.quantum_info.vectorization`.
642647
643648
Args:
644649
kraus_ops (list): List of Kraus operators as pairs ``(qubits, Ak)``
@@ -757,10 +762,11 @@ def kraus_to_chi(
757762
of quantum channel to its :math:`\\chi`-matrix representation.
758763
759764
.. math::
760-
\\chi = \\sum_{\\alpha} \\, |c_{\\alpha}\\rangle\\rangle \\langle\\langle c_{\\alpha}|,
765+
\\chi = \\sum_{\\alpha} \\, |c_{\\alpha})( c_{\\alpha}|,
761766
762-
where :math:`|c_{\\alpha}\\rangle\\rangle \\cong |K_{\\alpha}\\rangle\\rangle`
763-
in Pauli-Liouville basis.
767+
where :math:`|c_{\\alpha}) \\cong |K_{\\alpha})` in Pauli-Liouville basis,
768+
and :math:`| \\cdot )` is the :func:`qibo.quantum_info.vectorization`
769+
operation.
764770
765771
Args:
766772
kraus_ops (list): List of Kraus operators as pairs ``(qubits, Ak)``
@@ -2130,8 +2136,6 @@ def _reshuffling(super_op, order: str = "row", backend=None):
21302136
Returns:
21312137
ndarray: Choi (Liouville) representation of the quantum channel.
21322138
"""
2133-
super_op = backend.cast(super_op)
2134-
21352139
if not isinstance(order, str):
21362140
raise_error(TypeError, f"order must be type str, but it is type {type(order)}.")
21372141

@@ -2150,6 +2154,8 @@ def _reshuffling(super_op, order: str = "row", backend=None):
21502154

21512155
backend = _check_backend(backend)
21522156

2157+
super_op = backend.cast(super_op, dtype=super_op.dtype)
2158+
21532159
dim = np.sqrt(super_op.shape[0])
21542160

21552161
if (

0 commit comments

Comments
 (0)