Skip to content

Commit

Permalink
Merge pull request #10 from arnavdas88/master
Browse files Browse the repository at this point in the history
Docs Updated
  • Loading branch information
sumeetkhatri authored Jan 3, 2024
2 parents f222921 + 58fcbdf commit d4ff44a
Show file tree
Hide file tree
Showing 11 changed files with 438 additions and 74 deletions.
Binary file added docs/_static/_imgs/partial_trace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/_imgs/quantum_channel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@

"external_links": [
{"name": "Numpy", "url": "https://numpy.org/numpy-tutorials/"},
{"name": "Book", "url": "https://sumeetkhatri.files.wordpress.com/2021/08/sc_22aug2021.pdf"}
# {"name": "Principles of Quantum Communication Theory: A Modern Approach", "url": "https://sumeetkhatri.files.wordpress.com/2021/08/sc_22aug2021.pdf"}
{"name": "Book", "url": "https://sumeetkhatri.files.wordpress.com/2023/01/pqct-khatri-wilde.pdf"}
# {"name": "Principles of Quantum Communication Theory: A Modern Approach", "url": "https://sumeetkhatri.files.wordpress.com/2023/01/pqct-khatri-wilde.pdf"}
],

# "analytics_id": "G-XXXXXXXXXX", # Provided by Google in your dashboard
Expand Down
66 changes: 27 additions & 39 deletions docs/guide/beginnersguide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ predicted about the system’s behavior.
.. _state: https://en.wikipedia.org/wiki/Quantum_state
.. _quantum system: states.md#quantum-systems
.. _density operator: https://en.wikipedia.org/wiki/Density_matrix#Definition_and_motivation
.. _Hilbert space: general-functions.md#firstheading
.. _Hilbert space: https://en.wikipedia.org/wiki/Hilbert_space
.. _evolution in time: https://en.wikipedia.org/wiki/Quantum_channel#Time_evolution

The qubit is perhaps the most fundamental quantum system
Expand Down Expand Up @@ -142,13 +142,11 @@ and can be imported as such.
Bell States
***********
A `Bell state`_ is defined as a `maximally entangled quantum state`_ of two qubits.
A `Bell state`_ is defined as a `maximally entangled quantum state <maximally-entangled-state>`_ of two qubits.
It can be described as one of four entangled two qubit quantum states,
known collectively as the four "`Bell state`_".

.. _Bell state: https://en.wikipedia.org/wiki/Bell_state
.. _maximally entangled quantum state: https://github.com/arnavdas88/QuTIpy-Tutorials/blob/main/modules/states.md#maximally-entangled-state



:math:`\displaystyle |\phi^{+}\rangle \equiv |\phi_{0, 0}\rangle = \frac{1}{\sqrt{2}} (|0, 0\rangle + |1, 1\rangle)`
Expand All @@ -169,11 +167,9 @@ To generates a :math:`d`-dimensional Bell State with :math:`0 \leq z`, :math:`x
.. code-block:: python
>>> from qutipy.states import Bell
>>>
>>> # This will create a Bell State for a 2 dimensional system.
>>> # The resultant matrix will be of shape 4x4.
>>> bell_state = Bell(d=2, z=1, x=1)
>>>
>>> bell_state.shape
(2, 2)
Expand All @@ -193,10 +189,8 @@ For Density Matrix,
>>> # Import the random_density_matrix definition
>>> from qutipy.states import random_density_matrix
>>>
>>> # Let's create a random density matrix of shape 3 x 3
>>> A = random_density_matrix(dim = 3)
>>>
>>> # The shape of A will be `dim x dim`, i.e. 3 x 3
>>> A.shape
(3, 3)
Expand All @@ -208,19 +202,15 @@ State Vectors can be generated directly as well using the definition ``random_st
>>> # Import the random_density_matrix definition
>>> from qutipy.states import random_state_vector
>>>
>>> # Let's create a pure random state vector of shape 3 x 1
>>> A = random_state_vector(dim = 3)
>>>
>>> # The shape of A will be 3 x 1
>>> A.shape
(3, 1)
>>>
>>> # One can also define the Schmidt rank like this:
>>> A = random_state_vector(dim = [2, 4], rank = 2)
>>> # In this case, the random_state_vector generates the state_vector for 2 systems,
>>> # one with dimension 2 and one with dimension 4.
>>>
>>> # The shape of A will be 8 x 1
>>> A.shape
(8, 1)
Expand All @@ -243,10 +233,8 @@ QuTIpy ships a definition ``qutipy.gates.RandomUnitary`` that generates a Random
.. code-block:: python
>>> from qutipy.gates import RandomUnitary
>>>
>>> # Creates a random unitary of shape 2 x 2
>>> random_unitary = RandomUnitary(2)
>>>
>>> random_unitary.shape
(2, 2)
Expand Down Expand Up @@ -300,7 +288,6 @@ To define :math:`X = \sigma_x( 111 )` using numpy, one need to define the entire
.. code:: python
>>> import numpy as np
>>>
>>> # Define Pauli-X for [ 1 1 1 ] using numpy
>>> X = np.array([
>>> [0, 0, 0, 0, 0, 0, 0, 1],
Expand All @@ -318,7 +305,6 @@ These kind of definition for :math:`X = \sigma_x( 111 )` can be obtained easily
.. code:: python
>>> from qutipy.Pauli import generate_nQubit_Pauli_X
>>>
>>> # Define Pauli-X for [ 1 1 1 ] using qutipy
>>> X = generate_nQubit_Pauli_X([1, 1, 1])
Expand Down Expand Up @@ -353,14 +339,11 @@ implemented as such,
.. code-block:: python
>>> from qutipy.channels import depolarizing_channel, apply_channel
>>>
>>> # The first element of the channel is the Kraus Operator
>>> kraus_op = depolarizing_channel(0.2)[0]
>>>
>>> # Suppose `density_matrix` is a 2 x 2 density matrix,
>>> # say, density_matrix = random_density_matrix(dim = 2)
>>> evolved_density_matrix = apply_channel(kraus_op, density_matrix)
>>>
>>> evolved_density_matrix.shape
(2, 2)
Expand All @@ -370,18 +353,15 @@ to visualize the channel with the `Choi Representation` of the `Kraus Operator`,
.. code-block:: python
>>> from qutipy.channels import choi_representation
>>>
>>> # We represent the Kraus Operator, as Choi representation that will be
>>> # a 4 x 4 matrix, representing the operator.
>>> representation = choi_representation(kraus_op, 2)
>>>
>>> # representation = array(
>>> # [[□, □, □, □],
>>> # [□, □, □, □],
>>> # [□, □, □, □],
>>> # [□, □, □, □]]
>>> # )
>>>
>>> representation.shape
(4, 4)
Expand All @@ -390,52 +370,60 @@ For starters, a `random quantum channel` can be created with the definition ``qu
.. code-block:: python
>>> from qutipy.channels import random_quantum_channel
>>>
>>> # Here we get the Kraus Operator for a Random Quantum Channel
>>> kraus_op = random_quantum_channel(2, 2, return_as="kraus")
>>>
>>> # Suppose `density_matrix` is a 2 x 2 density matrix,
>>> # say, density_matrix = random_density_matrix(dim = 2)
>>> evolved_density_matrix = apply_channel(kraus_op, density_matrix)
>>>
>>> evolved_density_matrix.shape
(2, 2)
Pauli Channel
*************

Pauli channel is one of the most common channel, which can be easily implimentd with QuTIpy.
Pauli channel is one of the most common channel, where the kraus operator are proportional to
that of the the pauli operators, i.e.

.. math::
\rho 7 → p_I \rho + p_X X\rho X + p_Y Y\rho Y + p_ZZ\rho Z
where :math:`p_I, p_X, p_Y , p_Z \ge 0, p_I + p_X + p_Y + p_Z = 1`

.. code-block:: python
>>> from qutipy.channels import Pauli_channel
>>>
>>> # Here we get the Kraus Operator for a Random Quantum Channel
>>> # Here we define the Kraus Operator for the Pauli Quantum Channel
>>> kraus_op, _, _ = Pauli_channel(px=0.16, py=0.04, pz=0.16)
>>>
>>> # Suppose `density_matrix` is a 2 x 2 density matrix,
>>> # say, density_matrix = random_density_matrix(dim = 2)
>>> # Suppose exists a `density_matrix` of dimension 2, i.e. a 2 x 2 density matrix,
>>> # let's assume the density_matrix for, `density_matrix = random_density_matrix(dim = 2)`
>>> # then we can apply the pauli channel on the state as follows,
>>> evolved_density_matrix = apply_channel(kraus_op, density_matrix)
>>>
>>> evolved_density_matrix.shape
(2, 2)
Amplitude Damping Channel
*************************

Amplitude Damping channel is one of the most common channels.
Amplitude Damping channel is one of the most common channels. The amplitude damping
channel with decay parameter :math:`\gamma \in [0, 1]` is the channel :math:`\mathcal{A}_\gamma` given by
:math:`\mathcal{A}_\gamma(\rho) = A_1 \rho A_1^{\dagger} + A_2 \rho A_2^{\dagger}`, with the two Kraus
operators :math:`A_1` and :math:`A_2` defined as,

.. math::
A_1 = \sqrt{\gamma}|0\rangle\langle 1|, \\
A_2 = |0\rangle\langle 0| + \sqrt{1-\gamma}|1\rangle\langle 1|
It is straightforward to verify that :math:`A_1^{\dagger} A_1 + A_2^{\dagger} A_2 = \mathbb{1}`, so that :math:`\mathcal{A}_\gamma` is indeed trace preserving.

.. code-block:: python
>>> from qutipy.channels import amplitude_damping_channel
>>>
>>> # Here we get the Kraus Operator for a Random Quantum Channel
>>> # Here we generate the Kraus Operator for Amplitude Damping Quantum Channel
>>> kraus_op = amplitude_damping_channel(0.2)
>>>
>>> # Suppose `density_matrix` is a 2 x 2 density matrix,
>>> # say, density_matrix = random_density_matrix(dim = 2)
>>> # Suppose exists a `density_matrix` of dimension 2, i.e. a 2 x 2 density matrix,
>>> # let's assume the density_matrix for, `density_matrix = random_density_matrix(dim = 2)`
>>> # then we can apply the amplitude damping channel on the state as follows,
>>> evolved_density_matrix = apply_channel(kraus_op, density_matrix)
>>>
>>> evolved_density_matrix.shape
(2, 2)
17 changes: 16 additions & 1 deletion docs/guide/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,25 @@ Examples

Lorem ipsum
-----------
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus sed viverra tellus in hac habitasse platea dictumst. Consectetur lorem donec massa sapien faucibus et molestie ac. Est ullamcorper eget nulla facilisi etiam dignissim diam quis enim. Hac habitasse platea dictumst vestibulum rhoncus est pellentesque. Magnis dis parturient montes nascetur. Feugiat nisl pretium fusce id velit ut tortor pretium. Amet mattis vulputate enim nulla aliquet porttitor lacus luctus. Ultricies lacus sed turpis tincidunt id aliquet risus feugiat in. Interdum consectetur libero id faucibus nisl tincidunt eget nullam non. Nec feugiat in fermentum posuere urna nec. Bibendum enim facilisis gravida neque. Et netus et malesuada fames ac. Sit amet est placerat in. Aliquam sem et tortor consequat id porta nibh. Tincidunt nunc pulvinar sapien et ligula. Aenean pharetra magna ac placerat vestibulum lectus mauris ultrices. Lectus sit amet est placerat in egestas erat imperdiet sed. Leo vel fringilla est ullamcorper eget nulla facilisi. Ultrices eros in cursus turpis massa tincidunt.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Lacus sed viverra tellus in hac habitasse platea dictumst.
Consectetur lorem donec massa sapien faucibus et molestie ac. Est ullamcorper eget nulla facilisi
etiam dignissim diam quis enim. Hac habitasse platea dictumst vestibulum rhoncus est pellentesque.
Magnis dis parturient montes nascetur. Feugiat nisl pretium fusce id velit ut tortor pretium. Amet
mattis vulputate enim nulla aliquet porttitor lacus luctus. Ultricies lacus sed turpis tincidunt
id aliquet risus feugiat in. Interdum consectetur libero id faucibus nisl tincidunt eget nullam
non. Nec feugiat in fermentum posuere urna nec. Bibendum enim facilisis gravida neque. Et netus et
malesuada fames ac. Sit amet est placerat in. Aliquam sem et tortor consequat id porta nibh.
Tincidunt nunc pulvinar sapien et ligula. Aenean pharetra magna ac placerat vestibulum lectus
mauris ultrices. Lectus sit amet est placerat in egestas erat imperdiet sed. Leo vel fringilla est
ullamcorper eget nulla facilisi. Ultrices eros in cursus turpis massa tincidunt.


Ornare massa
------------

`Quantum Channels <examples/qutipy-doc-example-quantum-channels>`_

Ornare massa eget egestas purus viverra. Donec et odio pellentesque diam volutpat. Nisi porta lorem mollis aliquam ut porttitor leo a. Tempor nec feugiat nisl pretium fusce. Rhoncus est pellentesque elit ullamcorper dignissim cras. Penatibus et magnis dis parturient montes nascetur ridiculus mus mauris. Nunc consequat interdum varius sit amet mattis vulputate enim. Bibendum est ultricies integer quis auctor. Porttitor eget dolor morbi non arcu. Dolor sed viverra ipsum nunc aliquet. Sapien et ligula ullamcorper malesuada proin libero nunc consequat. Ut ornare lectus sit amet est placerat in.

Amet est placerat
Expand Down
141 changes: 141 additions & 0 deletions docs/guide/examples/quantum_channels.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
.. QuTIpy documentation master file, created by
sphinx-quickstart on Thu Jun 9 22:10:58 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
.. _qutipy-doc-example-quantum-channels:

.. meta::
:description lang=en:
New to QuTIpy? Check out the Absolute Beginner’s Guide. It contains an
introduction to QuTIpy’s main concepts and links to additional tutorials.

Quantum Channels
================


Quantum communication is an evolving field at the intersection of quantum mechanics and information theory.
It leverages the principles of quantum physics to enable secure and efficient data transmission.

Quantum Channel
---------------

A quantum channel (often represented as :math:`\mathcal{N}`) is a fundamental concept in quantum information theory. In classical communication,
information is transmitted through a noisy channel, introducing errors. Similarly, in quantum communication,
a quantum channel models the physical process through which a quantum state is sent from one location to
another, potentially introducing errors, noise, or decoherence.


Suppose 2 minions **Tim** (left) and **Dave** (right) want to communicate with each other, and have a quantum
channel :math:`\mathcal{N}`, pre-eshtablished. Suppose **Tim** wants to send a information represented by the
quantum state :math:`\rho` to **Dave**. This transfer of information through the quantum channel :math:`\mathcal{N}`
will add noise, distortion and errors to the quantum state, transforming the quantum state :math:`\rho` to :math:`\sigma`

.. figure:: ../../_static/_imgs/quantum_channel.png


Mathematical Representation
---------------------------

Mathematically, a quantum channel is represented as a completely positive, trace-preserving (CPTP) map.
In this example, we focus on an amplitude damping channel, which models the loss of quantum information.
The amplitude damping channel is described by a Kraus operator, and it's action on a quantum state :math:`\rho`
is given by :math:`\sigma = \mathcal{N} ( \rho )`, i.e. :math:`\sigma = \mathcal{N} ( \rho ) = \sum\limits_{i=0}^{r}{K_i \rho K_i^\dagger}` or,
:math:`\sigma = K_1 \rho K_1^\dagger + K_2 \rho K_2^\dagger` in case of an amplitude damping channel.


Where:

* :math:`\sigma`: Transformed quantum state after the channel.
* :math:`\rho`: Original quantum state.
* :math:`K`: Kraus operator representing the amplitude damping channel.
* :math:`K^\dagger`: The conjugate transpose of :math:`K`.

QuTIpy Implementation
---------------------

We utilize several QuTIpy functions and modules in this example:

* :code:`qutipy.channels.amplitude_damping_channel(γ)`: Creates an amplitude damping channel with damping parameter :math:`\gamma`.
* :code:`qutipy.states.random_density_matrix(n)`: Generates a random density matrix representing an initial quantum state with n qubits.
* :code:`qutipy.pauli.nQubit_Pauli_coeff(rho, i)`: Calculates the coefficients of the Pauli matrices for the quantum state :math:`\rho`.
* :code:`qutipy.channels.apply_channel(K, rho)`: Applies the quantum channel :math:`K` to the quantum state :math:`\rho`.
* :code:`qutipy.fidelities.fidelity(rho1, rho2)`: Computes the fidelity between two quantum states :math:`\rho_1` and :math:`\rho_2`.

To simulate the above example of Tim and Dave, we will start with importing the required functionalities from qutipy package.

.. code:: python
>>> from qutipy.channels import amplitude_damping_channel, apply_channel
>>> from qutipy.states import random_density_matrix
>>> from qutipy.pauli import nQubit_Pauli_coeff
>>> from qutipy.fidelities import fidelity
>>> import numpy as np
Once the required modules are imported, we can start creating the required components like the
quantum channel and the quantum state. We start with creating our quantum channel first,

.. code:: python
>>> # Create an amplitude damping channel with a damping parameter of 0.2.
>>> # K = (K_1, K_2) for amplitude damping.
>>> K = amplitude_damping_channel(0.2)
The above code creates the kraus operator :math:`K` for the amplitude damping channel, which looks like this:

.. math::
K_0 = \begin{bmatrix} 1 && 0 \\ 0 && 0.89442719 \end{bmatrix} \\
K_1 = \begin{bmatrix} 0 && 0.44721360 \\ 0 && 0 \end{bmatrix}
Now that we have our quantum channel :math:`\mathcal{N}` represented by the kraus operator :math:`K`, we can jump
in creating some quantum states to transfer through the channel.

.. code:: python
>>> # Generate a random density matrix representing an initial quantum state with 2 qubits.
>>> rho = random_density_matrix(2)
>>> # Calculate the coefficients of the Pauli matrices for ρ.
>>> coefficient = nQubit_Pauli_coeff(rho, 1)
>>> # Verify that the coefficient is equal to 1, indicating a valid quantum state.
>>> np.testing.assert_almost_equal(coefficient[0], 1)
Here :math:`\rho` is some density matrix in 2 dimension, which looks like this:

.. math::
\rho = \begin{bmatrix} 0.20384195 && 0.10963633+0.1308432j \\ 0.10963633-0.1308432j && 0.79615805 \end{bmatrix}
We have also calculated the pauli coefficient of :math:`\rho` (which should be near to :math:`1.` ), in order to verify
that the density matrix :math:`\rho` represents a valid quantum state. Now that we have our kraus operator :math:`K` and
the quantum state :math:`\rho`, we can start applying the quantum channel over the quantum state.

.. code:: python
# Apply the amplitude damping channel K to the quantum state ρ.
sigma = apply_channel(K, rho)
# Calculate the Pauli coefficients for the transformed state σ.
transformed_coefficient = nQubit_Pauli_coeff(sigma, 1)
# Verify that the transformed coefficient is still 1 due to the channel being trace-preserving.
np.testing.assert_almost_equal(transformed_coefficient[0], coefficient[0])
# Check if the transformed coefficients for the rest of the Pauli matrices are different from the original coefficients.
assert transformed_coefficient[1:] != coefficient[1:]
# Calculate the fidelity between the original state ρ and the transformed state σ.
print("Fidelity : ", fidelity(rho, sigma))
Here :math:`\sigma` represents transformed density matrix due to the amplitude damping acting on :math:`\rho`. It
looks something like:

.. math::
\sigma = \begin{bmatrix} 0.36307356 && 0.09806171+0.11702972j \\ 0.09806171-0.11702972j && 0.63692644 \end{bmatrix}
It is clear that :math:`\rho \ne \sigma` but as the amplitude damping channel is trace-preserving, we can verify
that :math:`coeff_{\rho} \approx coeff_{\sigma} \approx 1`. We can also check that closeness of the quantum state
:math:`\rho` to the quantum state :math:`\sigma` by measuring their **fidelity**, which must be :math:`\approx 1`,
verifying that both :math:`\rho` and :math:`\sigma` nearly represent the same quantum state.
Loading

0 comments on commit d4ff44a

Please sign in to comment.