Metadata-Version: 2.1
Name: pyquest
Version: 0.0.1
Summary: A Python interface for QuEST.
Home-page: https://github.com/rrmeister/pyQuEST
Author: Richard Meister
Author-email: Richard Meister <richardm.tug@gmail.com>
License: MIT License
        
        Copyright (c) 2022 Richard Meister
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: homepage, https://github.com/rrmeister/pyQuEST
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Environment :: Console
Classifier: Environment :: GPU :: NVIDIA CUDA
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: C++
Classifier: Programming Language :: Cython
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: ./LICENCE.txt
Requires-Dist: numpy >=1.20

# pyQuEST

A Python interface for the Quantum Exact Simulation Toolkit (QuEST) written mainly in Cython.

## Getting started
After cloning the repository

```console
$ git clone -b develop --recursive https://github.com/rrmeister/pyQuEST
$ cd pyQuEST
```

it is recommended to create a virtual environment, e.g. with `venv`.

```console
$ python3 -m venv .
$ source bin/activate
```

To configure the QuEST backend for multithreading, GPU usage, float precision, etc., have a look at the QuEST build documentation.

The package can then be installed using pip.

```console
$ pip3 install .
```

## Usage
After successful installation, we can test pyQuEST by importing it and having a look at the environment it is running in.

```python
In [1]: import pyquest

In [2]: pyquest.env
Out[2]: QuESTEnvironment(cuda=False, openmp=False, mpi=False, num_threads=1, num_ranks=1, precision=2)
```

The `QuESTEnvironment` class is automatically instantiated once upon module import and never needs to be called by the user. It contains internals and can return information about the execution environment, as above.

### Example
The most important classes are `Register` representing a quantum register, and the operators which can be applied to it. Let's create such a register with 3 qubits and look at its contents.

```python
In [3]: from pyquest import Register

In [4]: from pyquest.unitaries import *

In [5]: reg = Register(3)

In [6]: reg[:]
Out[6]: array([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])
```

Like in QuEST, the state is automatically initialised to the all-zero product state. To apply some gates to it, first import some unitaries and the `Circuit` class.

```python
In [7]: from pyquest.unitaries import H, X, Ry

In [8]: from pyquest import Circuit
```

The operators are constructed from their classes with their target qubits, then any additional parameters (like a rotation angle), and then the control qubits as a keyword-only argument, e.g. `Ry(0, .2, controls=[1])` creates a rotation operator about the y-axis of the Bloch sphere by 0.2 radians on qubit 0, controlled by qubit 1. A single operator can be applied to a register `reg` with `reg.apply_operator(X(1))`. To apply multiple operators at once, first collect them into a `Circuit`.

```python
In [9]: circ = Circuit([H(0), X(2, controls=[0]), Ry(1, .23, controls=[2])])

In [10]: reg.apply_circuit(circ)

In [11]: reg[:]
Out[11]:
array([0.70710678+0.j, 0.        +0.j, 0.        +0.j, 0.        +0.j,
       0.        +0.j, 0.70243619+0.j, 0.        +0.j, 0.08113816+0.j])
```

Multiplying two registers together will return their inner product. For example, the expectation value of `X(1)` is

```python
In [12]: temp = Register(copy_reg=reg)

In [13]: temp.apply_operator(X(1))

In [14]: reg * temp
Out[14]: (0.11398876176759418+0j)
```

A measurement can be performed with

```python
In [15]: from pyquest.gates import M

In [16]: reg.apply_operator(M(1))
Out[16]: [0]
```

Remember that measurements are destructive.

```python
In [17]: reg[:]
Out[17]:
array([0.70944592+0.j, 0.        +0.j, 0.        +0.j, 0.        +0.j,
       0.        +0.j, 0.70475988+0.j, 0.        +0.j, 0.        +0.j])
```

A register can also be directly modified, but may then end up in an invalid state if not properly normalised.
```python
In [18]: reg[:] = 0

In [19]: reg[:]
Out[19]: array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])

In [20]: reg[4] = 1j

In [21]: reg[:]
Out[21]: array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j])
```

For further details on which operators are available and all methods of `Register` and `Circuit`, for now check out the documentation in the source files.

## Development
If you want to contribute to the project or just play around with the source, you can use an editable install

```console
$ pip3 install -e .
```

but this temporarily re-installs the build requirements every time the project is compiled and clutters the `pyquest` source directory with build artifacts. It is therefore a good idea to simply install the build requirements manually

```console
$ pip3 install -r build_requirements.txt
```

and then call

```console
$ python3 setup.py build
```

to build pyQuEST in the `_skbuild/<os_id>/cmake-install/pyquest` folder, or use

```console
$ python3 setup.py install
```
to install the package without telling `pip` about it. This is really only recommended in a virtual environment.
