Skip to content

Commit

Permalink
Preparing 0.4.1 (#217)
Browse files Browse the repository at this point in the history
* Temporary upper bound on JAX version <=0.4.6 and update to DynamicsBackend tutorial (#210)

* Add links of API reference to tutorials and userguides (#212)

* Fix multiset ordering bug in perturbation module (#211)

Co-authored-by: Ian Hincks <[email protected]>

* Bump Sphinx Theme to 1.11 (#215)

* Bump Sphinx Theme to 1.11

* Also activate jquery

* Bug fix: Measurement properties automatic padding for DynamicsBackend initialization (#209)

Co-authored-by: Daniel Puzzuoli <[email protected]>

* bounding ipython version for compatibility with python 3.8 (#216)

* Update deploy_documentation.sh to deploy in ecosystem (#219)

* Bound Diffrax version (#226)

* Bounding diffrax and equinox versions. The latest versions require
the latest version of JAX, but due to an unresolved bug in JAX,
Dynamics is only compatible with jax<=0.4.6. This commit also
adds a release note stating exactly what versions of these packages
will work with the latest version of dynamics.

* Upgrade to qiskit_sphinx_theme 1.12 (#224)

* Update links to repo and documentation (#227)

* updating minor comments in pulse sim tutorial to remove confusion (#228)

* adding max step size argument to dynamics_backend tutorial, with explanation (#229)

* fixing typo

---------

Co-authored-by: Kento Ueda <[email protected]>
Co-authored-by: Ian Hincks <[email protected]>
Co-authored-by: Eric Arellano <[email protected]>
Co-authored-by: Arthur Strauss <[email protected]>
Co-authored-by: Luciano Bello <[email protected]>
  • Loading branch information
6 people authored Jun 9, 2023
1 parent 27cf27c commit 807edf9
Show file tree
Hide file tree
Showing 31 changed files with 493 additions and 147 deletions.
1 change: 1 addition & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: Docs Publish
on:
workflow_dispatch:
push:
tags:
- "*"
Expand Down
2 changes: 1 addition & 1 deletion CITATION.bib
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ @misc{qiskit_dynamics_2021
year = {2021},
publisher = {GitHub},
journal = {GitHub repository},
url = {https://github.com/Qiskit/qiskit-dynamics}
url = {https://github.com/Qiskit-Extensions/qiskit-dynamics}
}
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ as:
fixes:
- |
Fixes a race condition in the function ``foo()``. Refer to
`#12345 <https://github.com/Qiskit/qiskit-dynamics/issues/12345>` for more
`#12345 <https://github.com/Qiskit-Extensions/qiskit-dynamics/issues/12345>` for more
details.
```

Expand Down
67 changes: 32 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@

**This repo is still in the early stages of development, there will be breaking API changes**

Qiskit Dynamics is an open-source project for building, transforming, and solving
time-dependent quantum systems in Qiskit.

The goal of Qiskit Dynamics is to provide access to different numerical
methods for solving differential equations, and to automate common processes typically performed by hand,
e.g. applying frame transformations or rotating wave approximations to system and control Hamiltonians.

Qiskit Dynamics can be configured to use either
[NumPy](https://github.com/numpy/numpy) or [JAX](https://github.com/google/jax)
as the backend for array operations. [NumPy](https://github.com/numpy/numpy) is the default,
and [JAX](https://github.com/google/jax) is an optional dependency.
[JAX](https://github.com/google/jax) provides just-in-time compilation, automatic differentiation,
and GPU execution, and therefore is well-suited to tasks involving repeated
evaluation of functions with different parameters; E.g. simulating a model of a quantum system
over a range of parameter values, or optimizing the parameters of control sequence.

Reference documentation may be found [here](https://qiskit.org/documentation/dynamics/),
including [tutorials](https://qiskit.org/documentation/dynamics/tutorials),
[user guide](https://qiskit.org/documentation/dynamics/userguide),
and [API reference](https://qiskit.org/documentation/dynamics/apidocs).
Qiskit Dynamics is an open-source project for building, transforming, and solving time-dependent
quantum systems in Qiskit.

The goal of Qiskit Dynamics is to provide access to different numerical methods for solving
differential equations, and to automate common processes typically performed by hand, e.g. applying
frame transformations or rotating wave approximations to system and control Hamiltonians.

Qiskit Dynamics can be configured to use either [NumPy](https://github.com/numpy/numpy) or
[JAX](https://github.com/google/jax) as the backend for array operations.
[NumPy](https://github.com/numpy/numpy) is the default, and [JAX](https://github.com/google/jax) is
an optional dependency. [JAX](https://github.com/google/jax) provides just-in-time compilation,
automatic differentiation, and GPU execution, and therefore is well-suited to tasks involving
repeated evaluation of functions with different parameters; E.g. simulating a model of a quantum
system over a range of parameter values, or optimizing the parameters of control sequence.

Reference documentation may be found [here](https://qiskit.org/ecosystem/dynamics/), including
[tutorials](https://qiskit.org/ecosystem/dynamics/tutorials/index.html),
[user guide](https://qiskit.org/ecosystem/dynamics/userguide/index.html),
[API reference](https://qiskit.org/ecosystem/dynamics/apidocs/index.html), and
[Discussions](https://qiskit.org/ecosystem/dynamics/discussions/index.html).

## Installation

Expand All @@ -46,25 +46,22 @@ Installing JAX with GPU support must be done manually, for instructions refer to

## Contribution Guidelines

If you'd like to contribute to Qiskit Dynamics, please take a look at our
[contribution guidelines](CONTRIBUTING.md). This project adheres to Qiskit's
[code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to
uphold this code.

We use [GitHub issues](https://github.com/Qiskit/qiskit-dynamics/issues) for
tracking requests and bugs. Please
[join the Qiskit Slack community](https://qisk.it/join-slack)
and use our [#qiskit-dynamics](https://qiskit.slack.com/archives/C03E7UVCDEV) channel for discussion and
simple questions.
For questions that are more suited for a forum we use the Qiskit tag in the
If you'd like to contribute to Qiskit Dynamics, please take a look at our
[contribution guidelines](CONTRIBUTING.md). This project adheres to Qiskit's
[code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.

We use [GitHub issues](https://github.com/Qiskit-Extensions/qiskit-dynamics/issues) for tracking
requests and bugs. Please [join the Qiskit Slack community](https://qisk.it/join-slack) and use our
[#qiskit-dynamics](https://qiskit.slack.com/archives/C03E7UVCDEV) channel for discussion and simple
questions. For questions that are more suited for a forum we use the Qiskit tag in the
[Stack Exchange](https://quantumcomputing.stackexchange.com/questions/tagged/qiskit).

## Authors and Citation

Qiskit Dynamics is the work of
[many people](https://github.com/Qiskit/qiskit-dynamics/graphs/contributors) who contribute
to the project at different levels. If you use Qiskit, please cite as per the included
[BibTeX file](https://github.com/Qiskit/qiskit-dynamics/blob/main/CITATION.bib).
Qiskit Dynamics is the work of
[many people](https://github.com/Qiskit-Extensions/qiskit-dynamics/graphs/contributors) who
contribute to the project at different levels. If you use Qiskit, please cite as per the included
[BibTeX file](https://github.com/Qiskit-Extensions/qiskit-dynamics/blob/main/CITATION.bib).

## License

Expand Down
9 changes: 3 additions & 6 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@

# pylint: disable=invalid-name

"""
Sphinx documentation builder
"""

# General options:

project = 'Qiskit Dynamics'
Expand All @@ -25,7 +21,7 @@
# The short X.Y version
version = ''
# The full version, including alpha/beta/rc tags
release = '0.4.0'
release = '0.4.1'

extensions = [
'sphinx.ext.napoleon',
Expand All @@ -39,7 +35,8 @@
'reno.sphinxext',
'sphinx.ext.intersphinx',
'nbsphinx',
'sphinxcontrib.bibtex'
'sphinxcontrib.bibtex',
"qiskit_sphinx_theme",
]
templates_path = ["_templates"]

Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ just-in-time compilation, automatic differentiation, and GPU execution of Qiskit
This package is still in the early stages of development and it is very likely
that there will be breaking API changes in future releases.
If you encounter any bugs please open an issue on
`Github <https://github.com/Qiskit/qiskit-dynamics/issues>`_
`Github <https://github.com/Qiskit-Extensions/qiskit-dynamics/issues>`_


.. toctree::
Expand Down
6 changes: 3 additions & 3 deletions docs/tutorials/Lindblad_dynamics_simulation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ In the sections below we define a model, solve the dynamics and plot
some observables using the following steps:

1. Define the number of qubits and precompute some matrix operators.
2. Define all relevant parameters and setup a ``Solver`` instance with the model of the system,
2. Define all relevant parameters and setup a :class:`Solver` instance with the model of the system,
consisting of the Hamiltonian and the jump operators of the Lindblad dissipator.
3. Define the initial state and other parameters for the initial value problem,
and evolve the system state.
Expand Down Expand Up @@ -110,7 +110,7 @@ used in the rest of this tutorial.
2. Setup the solver
-------------------

In this section we setup a ``Solver`` class that stores and manipulates
In this section we setup a :class:`Solver` class that stores and manipulates
the model to be solved. In the following, we will set :math:`\hbar=1`
and set the driving amplitude to be :math:`\nu_x \equiv 1`. This sets the
time units, with the other frequency
Expand All @@ -119,7 +119,7 @@ these free parameters, and then create the Hamiltonian matrix and the
list of dissipator operators. We build the full Hamiltonian matrix by
summing all single-qubit and two-qubit terms. Since there are no
time-dependent terms, and we do not plan to take partial derivatives of
parameters, we do not use the ``Signal`` class in this tutorial. See the other tutorials for various
parameters, we do not use the :class:`Signal` class in this tutorial. See the other tutorials for various
generalizations of this approach supported with ``qiskit-dynamics``.

.. jupyter-execute::
Expand Down
15 changes: 8 additions & 7 deletions docs/tutorials/Rabi_oscillations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ decoherence terms modeled by using a Lindblad master equation.
In the sections below we define a model, solve the dynamics and plot the
qubit oscillations using the following steps:

1. Define all relevant parameters and setup a ``Solver`` instance with the Hamiltonian model of
the system.
1. Setup a :class:`.Solver` with the Hamiltonian model
2. Define the initial state and simulation times, and evolve the system state.
3. Plot the qubit state as a function of time and discuss the results.
4. Solve again the the model with jump operators for the Lindblad dissipator, and plot the results.
Expand All @@ -20,7 +19,9 @@ In the first step below, we model the time evolution of a qubit’s state
taken as a two-level system, using the Schrödinger equation with a
Hamiltonian containing a diagonal term of frequency :math:`\nu_z` and a
transverse term of amplitude :math:`\nu_x` and harmonic driving
frequency :math:`\nu_d`,
frequency :math:`\nu_d` (see how the Hamiltonians are derived on
`Qiskit Textbook page on Introduction to Transmon Physics
<https://qiskit.org/textbook/ch-quantum-hardware/transmon-physics.html>`_),

.. math:: H = \frac{1}{2} \times 2 \pi \nu_z {Z} + 2 \pi \nu_x \cos(2 \pi \nu_d t){X},

Expand All @@ -33,8 +34,8 @@ where :math:`\{X,Y,Z\}` are the Pauli matrices (also written as
In the following, we will set :math:`\hbar=1` and fix some arbitrary
time units, with all frequency parameters scaled accordingly. Below, we
first set a few values for these frequency parameters, and then setup the
``Solver`` class instance that stores and manipulates the model to be
solved, using matrices and ``Signal`` instances. For the
:class:`.Solver` class instance that stores and manipulates the model to be
solved, using matrices and :class:`.Signal` instances. For the
time-independent :math:`z` term we set the signal to a constant, while
for the trasverse driving term we setup a harmonic signal.

Expand Down Expand Up @@ -144,8 +145,8 @@ particular this is a realization of the :math:`X` gate.

plot_qubit_dynamics(sol, t_eval, X, Y, Z)

4. Redefine the model with damping and decoherence.
---------------------------------------------------
4. Redefine the model with damping and decoherence
--------------------------------------------------

Now we add to our simulation an environment modeled as a memory-less
(Markovian) bath, solving the Lindblad master equation with the same
Expand Down
17 changes: 8 additions & 9 deletions docs/tutorials/dynamics_backend.rst
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,16 @@ differential equation. The full list of allowable ``solver_options`` are the arg
:func:`.solve_ode`.

Note that, to enable the internal automatic jit-compilation, we choose a JAX integration method.
Furthermore, note that in the solver options we set the max step size to the pulse sample width
``dt`` via the ``"hmax"`` argument for the method ``"jax_odeint"``. This is important for preventing
variable step solvers from accidentally stepping over pulses in schedules with long idle times.

.. jupyter-execute::

from qiskit_dynamics import DynamicsBackend

# Consistent solver option to use throughout notebook
solver_options = {"method": "jax_odeint", "atol": 1e-6, "rtol": 1e-8}
solver_options = {"method": "jax_odeint", "atol": 1e-6, "rtol": 1e-8, "hmax": dt}

backend = DynamicsBackend(
solver=solver,
Expand Down Expand Up @@ -318,8 +321,9 @@ To enable running of the single qubit experiments, we add the following to the `
backend.
- Add definitions of ``RZ`` gates as phase shifts. These instructions control the phase of the drive
channels, as well as any control channels acting on a given qubit.
- Add a ``CX`` gate which applies to all qubits. While this tutorial will not be utilizing it, this
ensures that validation steps checking that the device is fully connected will pass.
- Add a ``CX`` gate between qubits :math:`(0, 1)` and :math:`(1, 0)`. While this tutorial will not
be utilizing it, this ensures that validation steps checking that the device is fully connected
will pass.

.. jupyter-execute::

Expand All @@ -336,7 +340,7 @@ To enable running of the single qubit experiments, we add the following to the `
target.add_instruction(XGate(), properties={(0,): None, (1,): None})
target.add_instruction(SXGate(), properties={(0,): None, (1,): None})

target.add_instruction(CXGate())
target.add_instruction(CXGate(), properties={(0, 1): None, (1, 0): None})

# Add RZ instruction as phase shift for drag cal
phi = Parameter("phi")
Expand Down Expand Up @@ -472,11 +476,6 @@ values for the single qubit gates calibrated above.

from qiskit_experiments.library import CrossResonanceHamiltonian

backend.target.add_instruction(
instruction=CrossResonanceHamiltonian.CRPulseGate(width=Parameter("width")),
properties={(0, 1): None, (1, 0): None}
)

cr_ham_experiment = CrossResonanceHamiltonian(
qubits=(0, 1),
flat_top_widths=np.linspace(0, 5000, 17),
Expand Down
33 changes: 15 additions & 18 deletions docs/tutorials/qiskit_pulse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ground state we expect that this second pulse will not have any effect
on the qubit. This situation is simulated with the following steps:

1. Create the pulse schedule
2. Converting pulse schedules to Signals
2. Converting pulse schedules to a :class:`.Signal`
3. Create the system model, configured to simulate pulse schedules
4. Simulate the pulse schedule using the model

Expand All @@ -48,30 +48,27 @@ First, we use the pulse module in Qiskit to create a pulse schedule.
# Sample rate of the backend in ns.
dt = 1 / 4.5

# Define gaussian envelope function to have a pi rotation.
amp = 1.
area = 1
sig = area*0.399128/r/amp
# Define gaussian envelope function to approximately implement an sx gate.
amp = 1. / 1.75
sig = 0.6985/r/amp
T = 4*sig
duration = int(T / dt)
beta = 2.0

# The 1.75 factor is used to approximately get a sx gate.
# Further "calibration" could be done to refine the pulse amplitude.
with pulse.build(name="sx-sy schedule") as xp:
pulse.play(pulse.Drag(duration, amp / 1.75, sig / dt, beta), pulse.DriveChannel(0))
with pulse.build(name="sx-sy schedule") as sxp:
pulse.play(pulse.Drag(duration, amp, sig / dt, beta), pulse.DriveChannel(0))
pulse.shift_phase(np.pi/2, pulse.DriveChannel(0))
pulse.play(pulse.Drag(duration, amp / 1.75, sig / dt, beta), pulse.DriveChannel(0))
pulse.play(pulse.Drag(duration, amp, sig / dt, beta), pulse.DriveChannel(0))

xp.draw()
sxp.draw()


2. Convert the pulse schedule to a ``Signal``
---------------------------------------------
2. Convert the pulse schedule to a :class:`.Signal`
---------------------------------------------------

Qiskit Dynamics has functionality for converting pulse schedule to instances
of ``Signal``. This is done using the pulse instruction to signal
converter ``InstructionToSignals``. This converter needs to know the
of :class:`.Signal`. This is done using the pulse instruction to signal
converter :class:`.InstructionToSignals`. This converter needs to know the
sample rate of the arbitrary waveform generators creating the signals,
i.e. ``dt``, as well as the carrier frequency of the signals,
i.e. ``w``. The plot below shows the envelopes and the signals resulting
Expand All @@ -87,7 +84,7 @@ virtual ``Z`` gate is applied.

converter = InstructionToSignals(dt, carriers={"d0": w})

signals = converter.get_signals(xp)
signals = converter.get_signals(sxp)
fig, axs = plt.subplots(1, 2, figsize=(14, 4.5))
for ax, title in zip(axs, ["envelope", "signal"]):
signals[0].draw(0, 2*T, 2000, title, axis=ax)
Expand All @@ -101,7 +98,7 @@ virtual ``Z`` gate is applied.
3. Create the system model
--------------------------

We now setup a ``Solver`` instance with the desired Hamiltonian information,
We now setup a :class:`.Solver` instance with the desired Hamiltonian information,
and configure it to simulate pulse schedules. This requires specifying
which channels act on which operators, channel carrier frequencies, and sample width ``dt``.
Additionally, we setup this solver in the rotating frame and perform the
Expand Down Expand Up @@ -146,7 +143,7 @@ and in this case should produce identical behavior.
# Start the qubit in its ground state.
y0 = Statevector([1., 0.])

%time sol = hamiltonian_solver.solve(t_span=[0., 2*T], y0=y0, signals=xp, atol=1e-8, rtol=1e-8)
%time sol = hamiltonian_solver.solve(t_span=[0., 2*T], y0=y0, signals=sxp, atol=1e-8, rtol=1e-8)


.. jupyter-execute::
Expand Down
12 changes: 6 additions & 6 deletions docs/userguide/how_to_configure_simulations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ Here we walk through some of these options, covering:
rotating frame to preserve sparsity


Throughout this guide we work at the level of the ``Solver`` interface,
Throughout this guide we work at the level of the :class:`.Solver` interface,
and consider Hamiltonian dynamics for simplicity, however all of the
considerations have their analogs for Lindblad dynamics.

1. How-to set up a simulation in a rotating frame, and its potential benefits
-----------------------------------------------------------------------------

Here we show how to perform a simulation in a rotating frame by setting the
optional ``rotating_frame`` argument when instantiating a ``Solver``, and demonstrate how a
optional ``rotating_frame`` argument when instantiating a :class:`.Solver`, and demonstrate how a
well-chosen frame operator :math:`F = -iH_0` can reduce solving time.
See the :ref:`Rotating frames section of the Models API documentation <Rotating frames>`
for details on rotating frames.
Expand Down Expand Up @@ -74,7 +74,7 @@ First, construct the components of the model:
# total simulation time
T = 1. / r

Construct a ``Solver`` for the model as stated, without entering a rotating frame, and solve,
Construct a :class:`.Solver` for the model as stated, without entering a rotating frame, and solve,
timing the solver.

.. jupyter-execute::
Expand All @@ -87,7 +87,7 @@ timing the solver.
y0 = np.eye(dim, dtype=complex)
%time results = solver.solve(t_span=[0., T], y0=y0, signals=[drive_signal], atol=1e-10, rtol=1e-10)

Next, define a ``Solver`` in the rotating frame of the static
Next, define a :class:`.Solver` in the rotating frame of the static
Hamiltonian by setting the ``rotating_frame`` kwarg, and solve, again timing the solver.

.. jupyter-execute::
Expand Down Expand Up @@ -151,7 +151,7 @@ reducing the number of RHS calls required to solve with a given accuracy.
---------------------------------------------------------------------------

Next we show how to perform a simulation with the rotating wave approximation (RWA)
by setting the ``rwa_cutoff_freq`` argument at ``Solver`` instantiation, and show
by setting the ``rwa_cutoff_freq`` argument at :class:`.Solver` instantiation, and show
how it results in further speed ups at the expense of solution accuracy. See the API
documentation for the :meth:`~qiskit_dynamics.models.rotating_wave_approximation` function
for specific details about the RWA.
Expand Down Expand Up @@ -201,7 +201,7 @@ with extra emphasis on the following:
:ref:`evaluation modes section of the Models API documentation <evaluation modes>`,
when using a sparse evaluation mode, to preserve sparsity, it is recommended to
only use *diagonal* rotating frames, which can be specified as a 1d array to the
``rotating_frame`` kwarg of ``Solver`` instantiation.
``rotating_frame`` kwarg of :class:`.Solver` instantiation.

For this section we use JAX as it is more performant. See the
:ref:`userguide on using JAX <how-to use jax>` for a more detailed
Expand Down
Loading

0 comments on commit 807edf9

Please sign in to comment.