Skip to content

Commit

Permalink
Release v0.15.0
Browse files Browse the repository at this point in the history
Main changes:

e0943d9 Override `optimal_detuning_off` on stored calls (#588)
3e40319 Deprecate legacy serializer + Improve error messages (#585)
9e05982 Adding register_is_from_calibrated_layout and is_calibrated_layout to Device (#586)
c08dfa8 Adding dmm config and modulation to sequence (#564)
5270944 Clarify the Conventions in Pulser (#573)
2315989 Give access to all EOM block parameters and allow for phase drift correction (#566)
d5ac020 Adding  DetuningMap, DMM (#539)
f56a19f Remove expired deprecations in pulser-pasqal
  • Loading branch information
HGSilveri authored Sep 27, 2023
2 parents 41fee7c + 5090ec6 commit c2175d8
Show file tree
Hide file tree
Showing 69 changed files with 5,467 additions and 1,464 deletions.
2 changes: 1 addition & 1 deletion VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.14.1
0.15.0
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# For generating documentation.
Sphinx
Sphinx < 7
sphinx-rtd-theme # documentation theme
sphinx_autodoc_typehints == 1.21.3
nbsphinx
Expand Down
22 changes: 21 additions & 1 deletion docs/source/apidoc/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ The register classes allow for the creation of arbitrary registers.
Register layout
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A ``RegisterLayout`` is used to define a register from a set of traps. It is
intended to be given to the user by the hardware provided as a way of showing
intended to be given to the user by the hardware provider as a way of showing
which layouts are already available on a given device. In turn, the user
can create a ``Register`` by selecting the traps on which to place atoms, or
even a ``MappableRegister``, which allows for the creation of sequences whose
register can be defined at build time.

.. autoclass:: pulser.register.register_layout.RegisterLayout
:members:
:inherited-members:

.. autoclass:: pulser.register.mappable_reg.MappableRegister
:members:
Expand All @@ -51,6 +52,17 @@ Special cases
:members:
:show-inheritance:

DetuningMap
-------------------

A ``DetuningMap`` is associated to a ``DMM`` in a ``Sequence``. It links a set
of weights to a set of trap coordinates. It is intended to be defined by the user
from a ``RegisterLayout``, a ``Register`` or a ``MappableRegister`` using
``define_detuning_map``.

.. autoclass:: pulser.register.weight_maps.DetuningMap
:members:
:inherited-members:

Pulse
-------------------
Expand Down Expand Up @@ -114,6 +126,9 @@ Available Channels
:members:
:show-inheritance:

.. autoclass:: pulser.channels.dmm.DMM
:members:
:show-inheritance:

EOM Mode Configuration
^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -129,3 +144,8 @@ Sampler
.. automodule:: pulser.sampler.samples
:members:

Result
------------------
.. automodule:: pulser.result
:members:
:show-inheritance:
13 changes: 10 additions & 3 deletions docs/source/apidoc/simulation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,20 @@ Simulation Results

Depending on the types of noise involved in a simulation, the results are returned
as an instance of :class:`SimulationResults`, namely :class:`CoherentResults`
(when the results can still be represented as a state vector or a density matrix, before being measured)
or :class:`NoisyResults` (when they can only be represented as a probability
distribution over the basis states).
(when each result can still be represented as a :class:`QutipResult` i.e. a state vector
or a density matrix, before being measured) or :class:`NoisyResults` (when each of them can only
be represented as :class:`SampledResult` i.e. a probability distribution over the basis states).

Both classes feature methods for processing and displaying the results stored
within them.

QutipResult
^^^^^^^^^^^^^^^^

.. autoclass:: pulser_simulation.qutip_result.QutipResult
:members:
:inherited-members:

CoherentResults
^^^^^^^^^^^^^^^^

Expand Down
246 changes: 246 additions & 0 deletions docs/source/conventions.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
****************************************
Conventions
****************************************

States and Bases
####################################

Bases
*******
A basis refers to a set of two eigenstates. The transition between
these two states is said to be addressed by a channel that targets that basis. Namely:

.. list-table::
:align: center
:widths: 50 35 35
:header-rows: 1

* - Basis
- Eigenstates
- ``Channel`` type
* - ``ground-rydberg``
- :math:`|g\rangle,~|r\rangle`
- ``Rydberg``
* - ``digital``
- :math:`|g\rangle,~|h\rangle`
- ``Raman``
* - ``XY``
- :math:`|0\rangle,~|1\rangle`
- ``Microwave``



Qutrit state
******************

The qutrit state combines the basis states of the ``ground-rydberg`` and ``digital`` bases,
which share the same ground state, :math:`|g\rangle`. This qutrit state comes into play
in the digital approach, where the qubit state is encoded in :math:`|g\rangle` and
:math:`|h\rangle` but then the Rydberg state :math:`|r\rangle` is accessed in multi-qubit
gates.

The qutrit state's basis vectors are defined as:

.. math:: |r\rangle = (1, 0, 0)^T,~~|g\rangle = (0, 1, 0)^T, ~~|h\rangle = (0, 0, 1)^T.

Qubit states
**************

.. warning::
There is no implicit relationship between a state's vector representation and its
associated measurement value. To see the measurement value of a state for each
measurement basis, see :ref:`SPAM` .

When using only the ``ground-rydberg`` or ``digital`` basis, the qutrit state is not
needed and is thus reduced to a qubit state. This reduction is made simply by tracing-out
the extra basis state, so we obtain

* ``ground-rydberg``: :math:`|r\rangle = (1, 0)^T,~~|g\rangle = (0, 1)^T`
* ``digital``: :math:`|g\rangle = (1, 0)^T,~~|h\rangle = (0, 1)^T`

On the other hand, the ``XY`` basis uses an independent set of qubit states that are
labelled :math:`|0\rangle` and :math:`|1\rangle` and follow the standard convention:

* ``XY``: :math:`|0\rangle = (1, 0)^T,~~|1\rangle = (0, 1)^T`

Multi-partite states
*************************

The combined quantum state of multiple atoms respects their order in the ``Register``.
For a register with ordered atoms ``(q0, q1, q2, ..., qn)``, the full quantum state will be

.. math:: |q_0, q_1, q_2, ...\rangle = |q_0\rangle \otimes |q_1\rangle \otimes |q_2\rangle \otimes ... \otimes |q_n\rangle

.. note::
The atoms may be labelled arbitrarily without any inherent order, it's only the
order with which they are stored in the ``Register`` (as returned by
``Register.qubit_ids``) that matters .

.. _SPAM:

State Preparation and Measurement
####################################

.. list-table:: Initial State and Measurement Conventions
:align: center
:widths: 60 40 75
:header-rows: 1

* - Basis
- Initial state
- Measurement
* - ``ground-rydberg``
- :math:`|g\rangle`
- |
| :math:`|r\rangle \rightarrow 1`
| :math:`|g\rangle,|h\rangle \rightarrow 0`
* - ``digital``
- :math:`|g\rangle`
- |
| :math:`|h\rangle \rightarrow 1`
| :math:`|g\rangle,|r\rangle \rightarrow 0`
* - ``XY``
- :math:`|0\rangle`
- |
| :math:`|1\rangle \rightarrow 1`
| :math:`|0\rangle \rightarrow 0`
Measurement samples order
***************************

Measurement samples are returned as a sequence of 0s and 1s, in
the same order as the atoms in the ``Register`` and in the multi-partite state.

For example, a four-qutrit state :math:`|q_0, q_1, q_2, q_3\rangle` that's
projected onto :math:`|g, r, h, r\rangle` when measured will record a count to
sample

* ``0101``, if measured in the ``ground-rydberg`` basis
* ``0010``, if measured in the ``digital`` basis

Hamiltonians
####################################

Independently of the mode of operation, the Hamiltonian describing the system
can be written as

.. math:: H(t) = \sum_i \left (H^D_i(t) + \sum_{j<i}H^\text{int}_{ij} \right),

where :math:`H^D_i` is the driving Hamiltonian for atom :math:`i` and
:math:`H^\text{int}_{ij}` is the interaction Hamiltonian between atoms :math:`i`
and :math:`j`. Note that, if multiple basis are addressed, there will be a
corresponding driving Hamiltonian for each transition.


Driving Hamiltonian
*********************

The driving Hamiltonian describes the coherent excitation of an individual atom
between two energies levels, :math:`|a\rangle` and :math:`|b\rangle`, with
Rabi frequency :math:`\Omega(t)`, detuning :math:`\delta(t)` and phase :math:`\phi(t)`.

.. figure:: files/two_level_ab.png
:align: center
:width: 200
:alt: The energy levels for the driving Hamiltonian.

The coherent excitation is driven between a lower energy level, :math:`|a\rangle`, and a higher energy level,
:math:`|b\rangle`, with Rabi frequency :math:`\Omega(t)` and detuning :math:`\delta(t)`.

.. warning::
In this form, the Hamiltonian is **independent of the state vector representation of each basis state**,
but it still assumes that :math:`|b\rangle` **has a higher energy than** :math:`|a\rangle`.

.. math:: H^D(t) / \hbar = \frac{\Omega(t)}{2} e^{-i\phi(t)} |a\rangle\langle b| + \frac{\Omega(t)}{2} e^{i\phi(t)} |b\rangle\langle a| - \delta(t) |b\rangle\langle b|

Pauli matrix form
---------------------

A more conventional representation of the driving Hamiltonian uses Pauli operators
instead of projectors. However, this form now **depends on the state vector definition**
of :math:`|a\rangle` and :math:`|b\rangle`.

Pulser's state-vector definition
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In Pulser, we consistently define the state vectors according to their relative energy.
In this way we have, for any given basis, that

.. math:: |b\rangle = (1, 0)^T,~~|a\rangle = (0, 1)^T

Thus, the Pauli and excited state occupation operators are defined as

.. math::
\hat{\sigma}^x = |a\rangle\langle b| + |b\rangle\langle a|, \\
\hat{\sigma}^y = i|a\rangle\langle b| - i|b\rangle\langle a|, \\
\hat{\sigma}^z = |b\rangle\langle b| - |a\rangle\langle a| \\
\hat{n} = |b\rangle\langle b| = (1 + \sigma_z) / 2
and the driving Hamiltonian takes the form

.. math::
H^D(t) / \hbar = \frac{\Omega(t)}{2} \cos\phi(t) \hat{\sigma}^x
- \frac{\Omega(t)}{2} \sin\phi(t) \hat{\sigma}^y
- \delta(t) \hat{n}
Alternative state-vector definition
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Outside of Pulser, the alternative definition for the basis state
vectors might be taken:

.. math:: |a\rangle = (1, 0)^T,~~|b\rangle = (0, 1)^T

This changes the operators and Hamiltonian definitions,
as rewriten below with highlighted differences.

.. math::
\hat{\sigma}^x = |a\rangle\langle b| + |b\rangle\langle a|, \\
\hat{\sigma}^y = \textcolor{red}{-}i|a\rangle\langle b| \textcolor{red}{+}i|b\rangle\langle a|, \\
\hat{\sigma}^z = \textcolor{red}{-}|b\rangle\langle b| \textcolor{red}{+} |a\rangle\langle a| \\
\hat{n} = |b\rangle\langle b| = (1 \textcolor{red}{-} \sigma_z) / 2
.. math::
H^D(t) / \hbar = \frac{\Omega(t)}{2} \cos\phi(t) \hat{\sigma}^x
\textcolor{red}{+}\frac{\Omega(t)}{2} \sin\phi(t) \hat{\sigma}^y
- \delta(t) \hat{n}
.. note::
A common case for the use of this alternative definition arises when
trying to reconcile the basis states of the ``ground-rydberg`` basis
(where :math:`|r\rangle` is the higher energy level) with the
computational-basis state-vector convention, thus ending up with

.. math:: |0\rangle = |g\rangle = |a\rangle = (1, 0)^T,~~|1\rangle = |r\rangle = |b\rangle = (0, 1)^T


Interaction Hamiltonian
*************************

The interaction Hamiltonian depends on the states involved in the sequence.
When working with the ``ground-rydberg`` and ``digital`` bases, atoms interact
when they are in the Rydberg state :math:`|r\rangle`:

.. math:: H^\text{int}_{ij} = \frac{C_6}{R_{ij}^6} \hat{n}_i \hat{n}_j

where :math:`\hat{n}_i = |r\rangle\langle r|_i` (the projector of
atom :math:`i` onto the Rydberg state), :math:`R_{ij}^6` is the distance
between atoms :math:`i` and :math:`j` and :math:`C_6` is a coefficient
depending on the specific Rydberg level of :math:`|r\rangle`.

On the other hand, with the two Rydberg states of the ``XY``
basis, the interaction Hamiltonian takes the form

.. math:: H^\text{int}_{ij} = \frac{C_3}{R_{ij}^3} (\hat{\sigma}_i^{+}\hat{\sigma}_j^{-} + \hat{\sigma}_i^{-}\hat{\sigma}_j^{+})

where :math:`C_3` is a coefficient that depends on the chosen Ryberg states
and

.. math:: \hat{\sigma}_i^{+} = |1\rangle\langle 0|_i,~~~\hat{\sigma}_i^{-} = |0\rangle\langle 1|_i

.. note:: The definitions given for both interaction Hamiltonians are independent of the chosen state vector convention.
Binary file added docs/source/files/two_level_ab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ computers and simulators, check the pages in :doc:`review`.
:caption: Fundamental Concepts

review
conventions

.. toctree::
:maxdepth: 2
Expand All @@ -86,6 +87,7 @@ computers and simulators, check the pages in :doc:`review`.
tutorials/reg_layouts
tutorials/interpolated_wfs
tutorials/serialization
tutorials/dmm
tutorials/slm_mask
tutorials/output_mod_eom
tutorials/virtual_devices
Expand Down
4 changes: 2 additions & 2 deletions docs/source/intro_rydberg_blockade.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"from pulser_simulation import Simulation\n",
"from pulser_simulation import QutipEmulator\n",
"\n",
"data = []\n",
"distances = np.linspace(6.5, 14, 7)\n",
Expand All @@ -175,7 +175,7 @@
" seq.target(\"atom1\", \"ryd\")\n",
" seq.add(pi_pulse, \"ryd\")\n",
"\n",
" sim = Simulation(seq)\n",
" sim = QutipEmulator.from_sequence(seq)\n",
"\n",
" res = sim.run() # Returns a SimulationResults instance\n",
" data.append(\n",
Expand Down
4 changes: 2 additions & 2 deletions docs/source/review.rst
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ In the analog simulation approach, the laser field acts on the entire array
of atoms. This creates a **global** Hamiltonian of the form

.. math::
H = \frac{\hbar\Omega(t)}{2} \sum_i \sigma_i^x - \frac{\hbar\delta(t)}{2} \sum_i
\sigma_i^z + \sum_{i<j} U_{ij} n_i n_j
H = \sum_i \left( \frac{\hbar\Omega(t)}{2} \sigma_i^x - \frac{\hbar\delta(t)}{2}
\sigma_i^z + \sum_{j<i} U_{ij} n_i n_j \right)
Through the continuous manipulation of :math:`\Omega(t)` and :math:`\delta(t)`,
one has a very high degree of control over the system's dynamics and properties.
Expand Down
3 changes: 3 additions & 0 deletions docs/source/tutorials/dmm.nblink
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"path": "../../../tutorials/advanced_features/Local addressability with DMM.ipynb"
}
Loading

0 comments on commit c2175d8

Please sign in to comment.