
Welcome to LibKet¶
LibKet (pronounced lib-ket) is a lightweight expression template library that allows you to develop quantum algorithms as backend-agnostic generic expressions and execute them on different quantum simulator and hardware backends without changing your code.
Supported quantum hardware backends
Supported quantum simulator backends
All you need to get started is a C++14 (or better) compiler and, optionally, Python 3.x to execute quantum algorithms directly from within LibKet.
User Documentation¶
Installation Guide¶
LibKet is designed as header-only C++ library with minimal external dependencies. All you need to get started is a C++14 (or better) compiler and, optionally, Python 3.x to execute quantum algorithms directly from within LibKet. Instructions on how to install prerequisites, download LibKet, and configure and build it can be found below.
Installing prerequisites¶
LibKet uses standard C++14 code and has minimal requirements, which are as follows:
C/C++compiler that supports the C++14 standard (or better);
CMake configuration tools version 3.x (or better);
Python version 3.x (or better) header and library files (optional);
Doxygen documentation tool (optional);
Sphinx documentation tool (optional)
These prerequisites can be installed as follows:
Linux RedHat/CentOS 7.x (or better)¶
First, install the basic development tools
sudo yum update
sudo yum group install "Development Tools"
Next, install CMake3 and Doxygen (optional) and Python 3.x (optional). If you have RedHat/CentOS 7.7 or better, you can simply run
sudo yum install cmake3 doxygen git python3 python3-devel python3-libs
Releases prior to 7.7 do not provide Python 3.x and require to install it from a third-party repository such as [IUS](https://ius.io/setup) or [EPEL](https://fedoraproject.org/wiki/EPEL).
If you are running RedHat/CentOS 8.x or better you are done here. The GCC version that is shipped with RedHat/CentOS 7.x is too old to compile LibKet and needs to be updated from the Software Collections
sudo yum install centos-release-scl
sudo yum install devtoolset-7
From now on, GCC v7.x can be used by running
scl enable devtoolset-7 bash
Linux Ubuntu 18.x (or better)¶
All prerequisites can be installed by running the following oneliner
sudo apt-get update
sudo apt install build-essential cmake doxygen git python3-dev python3-pip --fix-missing
macOS¶
The easiest way to get started under macOS is to install the XCode Command Line Tools by opening a Terminal in /Applications/Utilities/ and running the one-liner
xcode-select --install
Afterwards, install the package manager homebrew by running
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Once that is done you can install the prerequisites as follows
brew update
brew install cmake doxygen gcc python
Note that the QX simulator does not run under Apple Silicon (M1). Moreover, some Python packages might not install correctly. We are working on a one-liner installation procedure.
Windows 10¶
The easiest way to get started under Windows 10 is to install the Windows 10 Linux subsystem and a Linux distribution of your choice and compile and run LibKet inside the Linux subsystem. In our experience, Ubuntu Linux works fine.
Note that LibKet does not compile under Microsoft Visual Studio 2017 or 2019. We are working on a native port.
Downloading LibKet¶
Stable version¶
The latest stable version of the LibKet code can be obtained from GitLab as:
https://gitlab.com/mmoelle1/LibKet/-/archive/master/LibKet-master.zip
https://gitlab.com/mmoelle1/LibKet/-/archive/master/LibKet-master.tar.gz
https://gitlab.com/mmoelle1/LibKet/-/archive/master/LibKet-master.tar.bz2
https://gitlab.com/mmoelle1/LibKet/-/archive/master/LibKet-master.tar
If you are interested in a specific version you can download zip files of specific releases.
A better way to obtain the latest revision from GitLab and additionally have the convenience to receive updates of the code is to use Git.
On Linux/macOS, you may checkout the latest revision using
git clone https://gitlab.com/mmoelle1/LibKet.git
or
git clone git@gitlab.com:mmoelle1/LibKet.git
On Windows, you can use GitHub Windows client or any other Git client.
Developer version¶
If you are interested in trying out the development version of the LibKet code switch to the develop branch once you the initial cloning of the Git repository succeeded
cd LibKet
git checkout --track origin/develop
Configuring and building LibKet¶
Assuming that LibKet has been downloaded to the source folder
LibKet
the following sequence of commands will compile all
examples with the common Quantum Assembly Language (CQASM) v1.0 (cQASMv1) backend enabled and
execute the program tutorial01_simple
.
cd LibKet
mkdir build
cd build
cmake .. -DLIBKET_WITH_EXAMPLES=ON -DLIBKET_WITH_CQASM=ON
make
...
[100%] Built
./examples/tutorial01_simple
Please note that the so-compiled tutorials try to establish a connection with the remote QI-Simulator. Details on how to configure LibKet for the QI-backend can be found in LibKet Activating additional quantum backends
The following configuration options can be used with the cmake
-D
flag:
Configuration Command |
Description |
---|---|
LIBKET_BUILD_COVERAGE |
Build LibKet with code coverage |
LIBKET_BUILD_DOCS |
Enable generation of Doxyen and Sphinx Docs |
LIBKET_BUILD_C_API |
Build the C API library |
LIBKET_BUILD_PYTHON_API |
Build the Python API library |
LIBKET_BUILD_EXAMPLES |
Build the example and tutorial programs |
LIBKET_BUILD_UNITTESTS |
Build unit tests |
LIBKET_BUILTIN_OPENQL |
Use built-in OpenQL Simulator |
LIBKET_BUILTIN_QUEST |
Use built-in QuEST Simulator |
LIBKET_BUILTIN_QX |
Use built-in QX Simulator |
LIBKET_BUILTIN_UNITTESTS |
Use built-in UnitTests++ |
LIBKET_L2R_EVALUATION |
Enable left-to-right evaluation |
LIBKET_GEN_PROFILING |
Enable generation of profiling data |
LIBKET_OPTIMIZE_GATES |
Enable optimization of gates, e.g. H(H(q0)) = I(q0) |
LIBKET_PROF_COMPILE |
Enable profiling of compilation |
LIBKET_USE_PCH |
Enable use of precompiled headers |
LIBKET_WITH_AQASM |
Enable support for Atos QASM |
LIBKET_WITH_CIRQ |
Enable support for Cirq used by Google |
LIBKET_WITH_CQASM |
Enable support for Common QASM used by QuTech’s QX simulator |
LIBKET_WITH_MPI |
Enable support for MPI |
LIBKET_WITH_OPENMP |
Enable support for OpenMP |
LIBKET_WITH_OPENQASM |
Enable support for OpenQASM used by IBMs Qiskit framework |
LIBKET_WITH_OPENQL |
Enable support for OpenQL used by QuTech’s OpenQL simulator |
LIBKET_WITH_QASM |
Enable support for Qasm2circ LaTeX export |
LIBKET_WITH_QUEST |
Enable support for Quantum exact simulation toolkit by University of Oxford, UK |
LIBKET_WITH_QUIL |
Enable support for Quantum instruction set architecture used by Rigetti |
LIBKET_WITH_QX |
Enable support for QuTech’s QX simulator |
Activating additional quantum backends¶
LibKet supports the following quantum computing backends
backend name |
description |
note |
---|---|---|
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
6 |
|
|
6 |
|
|
5 |
|
|
6 |
|
|
6 |
For using the full functionality of the
AQASM
backend you need to have access to a Quantum Learning Maching (QLM). This is proprietary software. Further information will come soon.For using the full functionality of the
Cirq
backend you need to have thecirq
Python package installed. This can be done by running either of the following commands:pip3 install cirq # installs Cirq in the global environment make install-cirq-venv # installs Cirq in a virtual environment make install-cirq # installs Cirq in the global environment
When using the CMake approach (
make
) the default location of the Python virtual environment is$PYTHON_VENV_DIR/venv/cirq-$CIRQ_VERSION
, where$PYTHON_VENV_DIR
andCIRQ_VERSION
are environment variables. If not given then the virtual environment is installed in the CMake project binary directory and/or without version number.For using the full functionality of the
cQASMv1
backend you need to have thequantuminspire
Python package installed (see above for an explanation of the following commands).pip3 install quantuminspire make install-quantuminspire-venv make install-quantuminspire
In order to execute the quantum kernels on QuTech’s Quantum Inspire (QI) cloud platform, you are required to have a user account, which can be created free-of-charge here. Once you created a free user account it suffices to set the following environment variables:
Bash
export QI_USERNAME=<your username> export QI_PASSWORD=<your password>
Csh/Tcsh
setenv QI_USERNAME <your username> setenv QI_PASSWORD <your password>
LibKet will use this information to establish the connection with the remote QI simulator.
For using the full functionality of the
openQASMv2
backend you need to have theqiskit
Python package installed (see above for an explanation of the following commands).pip3 install qiskit make install-qiskit-venv make install-qiskit
For using the full functionality of the
Quil
backend you need to have thepyquil
Python package installed (see above for an explanation of the following commands).pip3 install pyquil make install-pyquil-venv make install-pyquil
In addition, you need to have the Forest SDK installed which includes the Rigetti quil compiler and the Rigetti quantum virtual machine. The CMake targets only point you to the website but do not install the Forest SDK.
Prerequisites for these backends are bundled with LibKet as Git submodules and do not have to be installed separately. It is, however, still possible to install them externally, e.g., system-wide and request LibKet to use them by passing the following arguments to CMake, e.g.
cmake .. -DLIBKET_BUILTIN_OPENQL=OFF -DOPENQL_INCLUDE_PATH=<path to OpenQL include files> cmake .. -DLIBKET_BUILTIN_QUEST=OFF -DQUEST_INCLUDE_PATH=<path to QuEST include files> cmake .. -DLIBKET_BUILTIN_QX=OFF -DQX_INCLUDE_PATH=<path to QX include files>
LibKet makes use of the UnitTest++ framework for unit testing. Like the above, it is bundled with LibKet as Git submodule but can be overwritten as follows
cmake .. -DLIBKET_BUILTIN_UNITTESTS=OFF -DUNITTESTPP_INCLUDE_PATH=<path to UnitTest++ include files>
Docker images¶
The quickest way to explore LibKet without going through all installation steps is by trying one of the pre-build images for Docker or its daemonless counterpart Podman.
Once you have installed one of these tools, getting started with LibKet is as easy as running the following one-liner in your terminal
docker run --rm -ti mmoelle1/libket:qx
or
podman run --rm -ti mmoelle1/libket:qx
Please check the full online documentation for additional configuration options.
Generating the LibKet documentation¶
Libket supports the generation of project documentations with Doxygen
and Sphinx. Make sure to set the -DLIBKET_BUILD_DOCS=ON
flag
when configuring cmake
.
If Doxygen is available on your system, you can generate and open the Doxygen HTML pages by executing
cd build
make Doxygen
...
Built target Doxygen
firefox doc/doxygen/html/index.html
If Sphinx is available on your system, you can generate and open the Sphinx HTML pages by executing
cd build
make Sphinx
...
Built target Sphinx
firefox doc/sphinx/index.html
If you want to generate both documentations simply type
cd build
make docs
Next read Components.
Basics¶
The LibKet basiscs will cover the creation of simple generic quantum expressions, executing these expressions on different quantum backends and explaination of some quantum visualisation tools.
Generic Quantum Expressions¶
This section will cover the basics of creating a generic quantum expression in LibKet, selecting qubits with filters and applying gates to selected qubits. LibKet’s main components are
Read this page for a quick overview of the different components.
Initialization¶
In order to work with an quantum expression, first an empty expression needs to be created. This can simply be done with:
auto expr = init();
Which creates an empty expression object. Notice that the number of qubits does not need to be specified yet and will be derived from the quantum device setup later.
Filters¶
Filters let you restrict the set of qubits to which an action such as a quantum gate or expression is applied. Filters operate relative to the input expression and can be combined to filter chains.
Filter functions¶
LibKet provides the following filter functions
all([expr])
resets all previous filters and selects all qubitsqubit<q>([expr])
selects theq
-th qubitsqureg<q,length>([expr])
selects all qubits betweenq
andq+length-1
range<qbegin,qend>([expr])
selects all qubits betweenqbegin
andqend
select<q0,q1,...>([expr])
selects individual qubitsq0
,q1
, …shift<offset>([expr])
shifts the selected qubits by a positive or negativeoffset
For a detailed description check the Library.
Here and below [expr]
means that the function can be called with
and without an expression expr
as will become clear from the
following example.
Example
The following code snippet illustrates how to combine multiple filters to a filter chain that, though overly complicated, selects the first qubit. Note that counting starts at 0 as it is common practice in C/C++
auto f0 = select<0,4,2,6>(); // selects q0, q4, q2, q6
auto f1 = range<1,2>(f0); // selects q4, q2
auto f2 = qubit<1>(f1); // selects q2
Filter classes¶
An alternative way to create filters is by instantiating objects of
filter classes and applying them using their operator()
.
Example
With this approach the above example code reads
auto f0 = QFilterSelect<0,4,2,6>(); // selects q0, q4, q2, q6
auto f1 = QFilterSelectRange<1,2>()(f0); // selects q4, q2
auto f2 = QBit<1>()(f1); // selects q2
Filter classes and functions can be combined since the functions are aliases that return an instance of the corresponding filter class.
Filter Concatenations¶
Filters can be concatenated into a new filter by using thd <<
operator:
auto f0 = select<0,2>(); // selects q0, q2
auto f1 = select<1,3>(); // selects q1, q3
auto f2 = f0<<f1; // selects q0, q2, q1, q3
Gates¶
Gates apply to all qubits of the current filter chain in a single-instruction multiple-data (SIMD) like fashion. That is, a single-qubit gate like the Hadamard (H) gate when applied to an \(n\)-qubit register is applied to each single qubit individually
Unary (One qubit) Gates¶
This gate set includes all one-qubit operations, such as Pauli operations, arbitrary rotations around the X-, Y- or Z-axis and measurements. Examples are:
auto e0 = h([expr]); //Applies a Hadamard gate to all qubits in [expr]
auto e1 = rz([theta], [expr]); //Applies a Z-rotation to all qubits in [expr] by angle [theta]
Binary (Two qubit) Gates¶
This gate set includes all two-gubit operations, such as CNOT, CPHASE or other controlled rotations. Examples are:
auto e0 = cnot(sel<0>(), sel<1>([expr])); //CNOT gate on qubit 0 (control) and qubit 1 (target) in [expr]
auto e1 = cphase([theta], sel<0>(), sel<1>([expr])); //CPhase gate on qubit 0 (control) and qubit 1 (target) in [expr] by angle [theta]
Ternary (Three qubit) Gates¶
This gate set includes all three-gubit operations, such as the TOFFOLI gate:
auto e0 = ccnot(sel<0>(), sel<1>(), sel<2>([expr])); //Toffoli gate on qubit 0, 1 (control) and qubit 2 (target) in [expr]
Example¶
With this convention in mind we are ready to write our first quantum algorithm
auto e0 = init();
auto e1 = sel<0,2>(e0);
auto e2 = h(e1);
auto e3 = all(e2);
auto e4 = cnot(sel<0,2>(), sel<1,4>(e3));
auto e5 = measure(all(e4));
which corresponds to the following quantum circuit
This image shows the circuit created with the above line of code
In LibKet we have provided as standard implementation of many of the quantum gates commonly used in quantum algorithms. For all gates, see the Library section Gates.
Circuits¶
Certain quantum circuits are used in the implementation of many quantum algorithms. To make it easier to implement large quantum algorithms some of these circuits are standardly implemented in LibKet. This way the user can create a large quantum circuit with just a single line of code!
Example: Quantum Fourier Transform
The code below can be used to apply the Quantum Fourier Transform on qubits 0 to n.
auto expr = qft(range<0,n>(init()));
This generates the following circuit for \(n = 5\):
This image shows the circuit created with the above line of code
Apart from QFT LibKet also has a standard implementation of other quantum circuits. See section Circuits for all available circuits currently implemented in LibKet.
Devices¶
With the succesful creation of a quantum expression, it can now be executed on a quantum device. This is where the power of LibKet shows, by reinterpeting the generic quantum expression to a the device specific quantum assembly language. For all quantum devices see the Library section Devices.
A quantum device can be initialised with the QDevice<QDeviceType, Qubits>
class. The generic
quantum expression can then we loaded onto the device (Note: The number of qubits used in the quantum
expression must not exceed the number of qubits set to the QDevice
). Then the device can evaluate
the quantum expression for a given number of shots. Here an example is given to evaluate a quantum expression
on the QuEST simulator of 4 qubits for 2048 shots:
QQDevice<QDeviceType::quest, 4> device; // Initalize quantum device (QuEST simulator for 4 qubits)
device(expr); // Load generic quantum expression to device
device.eval(2048); // Evaluate the quantum kernel for 2048 shots
Result retrieval (Python based)¶
Retrieving the results differs slightly from device to device. For Python oriented backends (AQASM, Cirq, cQASM, OpenQASM, Quil) results put in a JSON object. The following code snippet shows how the result is loaded into a JSON object and results are printed to standard output:
utils::json result = device.eval(shots);
std::cout << "Job ID : " << device.get<QResultType::id>(result) << std::endl;
std::cout << "Time stamp : " << device.get<QResultType::timestamp>(result) << std::endl;
std::cout << "Histogram : " << device.get<QResultType::histogram>(result) << std::endl;
std::cout << "Duration : " << device.get<QResultType::duration>(result).count() << std::endl;
std::cout << "Best : " << device.get<QResultType::best>(result) << std::endl;
Alternatively, the entire content of the JSON object can be dumped to the output with:
std::cout << result << std::endl; //Print without formatting
std::cout << result.dump(2) << std::endl; //Use pretty print with indent 2
Result retrieval (QuEST & QX)¶
The QuEST and QX simulators can simulate the state of a quantum register and return an exact result of the qubit states. It can also determine the probabilities of a quantum states and simulate a measurement distribution. The following code print the results for a QuEST or QX device. An example output is given for \(H\lvert0\rangle\)
QuEST example:
auto expr = h(init());
//QuEST Simulator
QDevice<QDeviceType::quest, 1> quest;
quest(expr);
quest.eval(1);
std::cout << quest.reg() << std::endl; //Returns exact quantum state
std::cout << quest.probabilities() << std::endl; //Returns probalities of quantum states
std::cout << quest.creg() << std::endl; //Returns a classical measurement
Output:
--------------[quantum state]--------------
(+0.70710678,+0.00000000) |0> +
(+0.70710678,+0.00000000) |1> +
-------------------------------------------
0.500000000000000,0.500000000000000
0
QX example:
auto expr = h(init());
//QX Simulator
QDevice<QDeviceType::qx, 1> qx;
qx(expr);
qx.eval(1);
qx.reg().dump(); //Prints execution time, quantum state and measurement data
Output:
[+] executing circuit '' (1 iter) ...
[+] circuit execution time: 0.000235529 sec.
--------------[quantum state]--------------
[p = +0.5000000] (+0.7071068,+0.0000000) |0> +
[p = +0.5000000] (+0.7071068,+0.0000000) |1> +
-------------------------------------------
[>>] measurement averaging (ground state) : | +0.00000000 |
-------------------------------------------
[>>] measurement prediction : | X |
-------------------------------------------
[>>] measurement register : | 0 |
-------------------------------------------
Visualization¶
The show()
function
Filters and all other components generate an abstract syntax tree (AST) that
represents the quantum expression. If you are interested how this AST
looks like or you want to debug your expression use the
show<depth>(expr)
function. Only one level of the AST is printed by default.
Qasm2Circ
The qasm2tex_visualizer
device can load an expression and output a LaTeX file
which in combination with the xyqcirc.tex file
can create a LaTeX image of the quantum circuit. Example:
QDevice<QDeviceType::qasm2tex_visualizer, nqubits> device;
device(expr);
device.to_file("filename");
Other LaTeX Parsers
The Qiskit, Cirq and IBMQ devices provide a LaTeX parser that can convert the quantum expression to a LaTeX code string. This string can then be printed to the standard output:
std::cout device.to_latex() << std::endl;
Terminal Visualisation
The Qiskit, Cirq and IBMQ devices also provide a terminal ASCII art visualisation of the quantum expression. This can be directly printed on the command-line interface, negating the need for a LaTeX interpreter
std::cout device.print_circuit() << std::endl;
Next read Components.
Advanced¶
Static For Loop¶
Since quantum expressions are evaluated at compile time, it is not possible to generate an
expression with a runtime for-loop. However, in order to build larger quantum circuits, using
a for loop will become a necessaty. Looping over quantum expressions can thus be done with the
static_for()
function. The generic interface of the static_for()
function reads:
template<index_t for_start,
index_t for_end,
index_t for_step,
template<index_t start, index_t end, index_t step, index_t index> class functor,
typename functor_return_type,
typename... functor_types>
inline auto
static_for(functor_return_type&& functor_return_arg,
functor_types&&... functor_args)
Below is a small example on how to use the static_for()
function. First, a functor
needs to be created, which represents the loop’s body:
template<index_t start, index_t end, index_t step, index_t index>
struct ftor
{
template<typename Expr>
inline constexpr auto operator()(Expr&& expr) noexcept
{
// Returns the controlled phase shift gate with angle
// theta = pi/2^(index+1) between qubits index and index+1
return crk<index+1>(sel<index> (gototag<0>()),
sel<index+1>(gototag<0>(expr))
);
}
};
To loop through this functor (at compile time) we call the utils::static_for<start, end, step, body>(...)
function as follows.
Note the usefulness of the tag/gototag mechanism to restore the original filter settings easily.
auto expr = utils::static_for<0,4,1,ftor>(tag<0>(init()));
This then generates the following 6 qubit circuit with only one line of code! Notice that the end
index is set to 4 and is thus also included in the loop, similar to the regular for(int i=start; i<=end; i+=step){}
Generated circuit by the static_for loop
Computational offloading¶
LibKet’s computation offloading model is very similar to that of CUDA to ease the transition from GPU- to quantum-accelerated computing. The device.eval(...)
is just one of three ways to run a quantum expression, which we will refer to as quantum kernel, on a quantum device.
LibKet::utils::json device.eval(...)
:This function offloads the quantum computation to the quantum device and returns the evaluated result as JSON object once the quantum computation has completed. Exceptions are the QuEST and QX simulators where a reference to the internal state vector is returned.
LibKet::QJob* device.execute(...)
Offloads the quantum computation to the quantum device and returns a QJob pointer once the quantum computation has completed.
LibKet::QJob* device.execute_async(...)
Offloads the quantum computation to the quantum device and returns a QJob pointer immediately.
The execute()
and execute_async()
have a similar interface as the eval()
function:
QJob<QJobType::CXX>* execute(std::size_t shots = [default from ctor],
std::function<void(QDevice_QuEST*)> ftor_init = NULL,
std::function<void(QDevice_QuEST*)> ftor_before = NULL,
std::function<void(QDevice_QuEST*)> ftor_after = NULL,
QStream<QJobType::CXX>* stream = NULL)
Notice that different functors are optional parameters, which will be elaborated on in the next section. The QJob objects supports the following functionality
QObj* wait()
: waits for the job to complete (blocking)bool query()
: returns true if the job completed and false otherwise (non-blocking)utils::json get()
: returns the result as JSON object after completion (blocking)
Let’s conclude these exection options with an example. Here an expression is executed asychronously for 20 shots on the Qiskit QASM simulator. The results are retreived with the get()
function, which waits for the qpu to finish execution and return results.
QDevice<QDeviceType::qiskit_qasm_simulator, 2> qpu;
qpu(expr);
auto job = qpu.execute_async(20);
result = job->get();
std::cout << result.dump(2) << std::endl;
Execution Scripts¶
The optional hooks ftor_init
, ftor_before
, and ftor_after
make it possible to inject user-defined code at three different locations of the execution process:
script_init
This functor is performed before any other code of the execution process. It can be used for importing additional Python modules.
script_before
This functor is performed just before sending the instructions to the quantum device. It can be used to pre-process the quantum circuit, e.g., to perform user-specific optimizations on the raw quantum circuit, before it runs through the backend-specific pipeline
script_after
Performed just after receiving the result from the quantum device. It can be used to post-process the raw results received from the quantum device, e.g., to generate histograms or other types of visualizations
Let’s inject a simple statement after the execution that collects the histogram data of the experiment using Qiskit’s get_count()
function.
auto job = qiskit.execute_async(20,
/* init_script */
"",
/* before_script */
"",
/* after_script */
"counts = result.get_counts(qc)\n"
"return json.dumps(counts)\n"
);
std::cout << job->get().dump(2) << std::endl;
It should be noted that the code injections are idented automatically and must not have trailing \t
’s. Each line must end with \n
.
Parameterized circuits [WIP]¶
The creating of parameteterized circuits is still under development. When finished, LibKet will be able to support platforms that use parameterised circuits, such as Qiskit Runtime.
Library¶
Filters¶
- group filters
Quantum filters are used to select a subset of qubits of a LibKet::QExpression object to which a particular quantum gate is applied. The following code creates a quantum filter that selects the first three qubits:
auto filter = QFilterSelectRange<0,2>();
The same can be achieved using wrapper functions:
auto filter = filters::range<0,2>();
Quantum filters can be combined to a quantum filter chain. The following code creates a quantum filter that selects the first three even qubits and shifts them by +1 afterwards:
auto filter = filters::shift<1>(filters::sel<0,2,4>());
Quantum filter chains can also be created by creating individual LibKet::filters::QFilter objects and using their LibKet::filters::QFilter::operator()
auto filter = QFilterShift<1>() ( QFilterSelect<0,2,4>() );
LibKet provides the following quantum filters (with wrapper functions):
LibKet::filters::QFilterSelect (LibKet::filters::sel)
LibKet::filters::QFilterSelectAll (LibKet::filters::all)
LibKet::filters::QFilterShift (LibKet::filters::shift)
LibKet::filters::QFilterSelectRange (LibKet::filters::range)
LibKet::filters::QRegister (LibKet::filters::qureg)
LibKet::filters::QBit (LibKet::filters::qubit)
All quantum filters are implemented as expression templates so that, when multiple filters are combined to a filter chain, a single LibKet::filters::QFilter object is created at compile time.
-
template<typename _expr, bool = std::is_base_of<filters::QFilter, typename std::decay<_expr>::type>::value>
struct getFilter¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/QFilter.hpp>
Type trait extracts the filter from an expression.
-
template<typename _expr, bool = std::is_base_of<filters::QFilter, typename std::decay<_expr>::type>::value>
struct getPreviousFilter¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/QFilter.hpp>
Type trait extracts the previous filter from an expression.
-
class QFilter : public LibKet::QBase¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/QFilter.hpp>
Filter base class.
The Quantum filter base class is the base class of all Quantum filter classes. It is used to identify a generic type
T
as Quantum filter, e.g.template <typename T bool is_filter(T t) { return std::is_base_of<QFilter, typename std::decay<T>::type>::value; }
Subclassed by LibKet::filters::QFilterSelectAll
Gates¶
Initialisation¶
- group init
Functions
-
inline constexpr auto init() noexcept¶
Init gate creator.
This overload of the LibKet::gates::init() function can be used as the inner-most gate in a quantum expression
Be careful with using the initialization gate as terminal in quantum expressions that serve as sub-expressions. The following code creates two sub-expressions both using the initialization gate as terminal and creates them to another expression. The so-defined quantum expression is likely invalid since it re-initializes the quantum expr within the algorithm
auto expr1 = gates::hadamard( gates::init() ); auto expr2 = gates::hadamard( gates::init() ); auto expr3 = expr1( expr2 );
Warning
-
class QInit : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Init.hpp>
Init gate class.
The Init gate class implements the initialization gate for an arbitrary number of quantum bits
-
inline constexpr auto init() noexcept¶
- group prep_x
Functions
-
inline constexpr auto prep_x() noexcept¶
Prep_X gate creator.
This overload of the LibKet::gates::prep_x() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::prep_x();
-
class QPrep_X : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Prep_X.hpp>
Prep_X class.
The Prep_X class implements the initialization of an arbitrary number of quantum bits in the X-basis. Striktly speaking, Prep_X is not a quantum gate.
By using Prep_X, qubits will be initialized in the x-basis in the \(\left|+\right> = \frac{\left|0\right> + \left|1\right>}{\sqrt{2}}\) state
-
inline constexpr auto prep_x() noexcept¶
- group prep_y
Functions
-
inline constexpr auto prep_y() noexcept¶
Prep_Y gate creator.
This overload of the LibKet::gates::prep_y() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::prep_y();
-
class QPrep_Y : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Prep_Y.hpp>
Prep_Y class.
The Prep_Y class implements the initialization of an arbitrary number of quantum bits in the Y-basis. Striktly speaking, Prep_Y is not a quantum gate.
By using Prep_Y, qubits will be initialized in the y-basis in the \(\left|+i\right> = \frac{\left|0\right> + i\left|1\right>}{\sqrt{2}}\) state
-
inline constexpr auto prep_y() noexcept¶
- group prep_z
Functions
-
inline constexpr auto prep_z() noexcept¶
Prep_Z gate creator.
This overload of the LibKet::gates::prep_z() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::prep_z();
-
class QPrep_Z : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Prep_Z.hpp>
Prep_Z class.
The Prep_Z class implements the initialization of an arbitrary number of quantum bits in the Z-basis. Striktly speaking, Prep_Z is not a quantum gate.
By using Prep_Z, qubits will be initialized in the z-basis in the \(\left|0\right>\) .
-
inline constexpr auto prep_z() noexcept¶
- group reset
Functions
-
inline constexpr auto reset() noexcept¶
Reset gate creator.
This overload of the LibKet::gates::reset() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::reset();
-
class QReset : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Reset.hpp>
Reset class.
The Reset class implements the initialization of an arbitrary number of quantum bits in the Z-basis. Striktly speaking, Reset is not a quantum gate.
-
inline constexpr auto reset() noexcept¶
Measurements¶
- group measure
Functions
-
inline constexpr auto measure() noexcept¶
Measure gate creator.
This overload of the LibKet::gates::measure() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::measure();
-
class QMeasure : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Measure.hpp>
Measure class.
The Measure class implements the measurement of an arbitrary number of quantum bits in the Z-basis. Striktly speaking, measure is not a quantum gate.
-
inline constexpr auto measure() noexcept¶
- group measure_x
Functions
-
inline constexpr auto measure_x() noexcept¶
Measure_X gate creator.
This overload of the LibKet::gates::measure_x() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::measure_x();
-
class QMeasure_X : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Measure_X.hpp>
Measure_X class.
The Measure_X class implements the measurement of an arbitrary number of quantum bits in the Z-basis. Striktly speaking, Measure_X is not a quantum gate.
-
inline constexpr auto measure_x() noexcept¶
- group measure_y
Functions
-
inline constexpr auto measure_y() noexcept¶
Measure_Y gate creator.
This overload of the LibKet::gates::measure_y() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::measure_y();
-
class QMeasure_Y : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Measure_Y.hpp>
Measure_Y class.
The Measure_Y class implements the measurement of an arbitrary number of quantum bits in the Z-basis. Striktly speaking, Measure_y is not a quantum gate.
-
inline constexpr auto measure_y() noexcept¶
- group measure_z
Functions
-
inline constexpr auto measure_z() noexcept¶
Measure_Z gate creator.
This overload of the LibKet::gates::measure_z() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::measure_z();
-
class QMeasure_Z : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Measure_Z.hpp>
Measure_Z class.
The Measure_Z class implements the measurement of an arbitrary number of quantum bits in the Z-basis. Striktly speaking, Measure_z is not a quantum gate.
-
inline constexpr auto measure_z() noexcept¶
Single Qubit Gates¶
- group pauli_x
Functions
-
inline constexpr auto pauli_x() noexcept¶
Pauli_X gate creator.
This overload of the LibKet::gates::pauli_x() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::pauli_x();
-
class QPauli_X : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Pauli_X.hpp>
Pauli_X gate class.
The Pauli_X gate class implements the quantum Pauli_X gate for an arbitrary number of quantum bits.
The Pauli_X gate is a single-qubit operation that maps the basis state \(\left|0\right>\) to \(\left|1\right>\) and \(\left|1\right>\) to \(\left|0\right>\).
The Pauli_X gate is a single-qubit rotation through \(\pi\) radians around the x-axis.
The unitary matrix reads
\[\begin{split} X = \begin{pmatrix} 0 & 1\\ 1 & 0 \end{pmatrix} \end{split}\]
-
inline constexpr auto pauli_x() noexcept¶
- group pauli_y
Functions
-
inline constexpr auto pauli_y() noexcept¶
Pauli_Y gate creator.
This overload of the LibKet::gates::pauli_y() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::pauli_y();
-
class QPauli_Y : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Pauli_Y.hpp>
Pauli_Y gate class.
The Pauli_Y gate class implements the quantum Pauli_Y gate for an arbitrary number of quantum bits.
The Pauli_Y gate is a single-qubit operation that maps the basis state \(\left|0\right>\) to \(-i\left|1\right>\) and \(\left|1\right>\) to \(i\left|0\right>\).
The Pauli-Y gate is a single-qubit rotation through \(\pi\) radians around the y-axis.
The unitary matrix reads
\[\begin{split} Y = \begin{pmatrix} 0 & -i\\ i & 0 \end{pmatrix} \end{split}\]
-
inline constexpr auto pauli_y() noexcept¶
- group pauli_z
Functions
-
inline constexpr auto pauli_z() noexcept¶
Pauli_Z gate creator.
This overload of the LibKet::gates::pauli_z() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::pauli_z();
-
class QPauli_Z : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Pauli_Z.hpp>
Pauli_Z gate class.
The Pauli_Z gate class implements the quantum Pauli_Z gate for an arbitrary number of quantum bits.
The Pauli_Z gate is a single-qubit operation that maps the basis state \(\left|0\right>\) to \(\left|0\right>\) and \(\left|1\right>\) to \(-\left|1\right>\).
The Pauli_Z gate is a single-qubit rotation through \(\pi\) radians around the z-axis.
The unitary matrix reads
\[\begin{split} Z = \begin{pmatrix} 1 & 0\\ 0 & -1 \end{pmatrix} \end{split}\]
-
inline constexpr auto pauli_z() noexcept¶
- group identity
Functions
-
inline constexpr auto identity() noexcept¶
Identity gate creator.
This overload of the LibKet::gates::identity() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::identity( );
-
class QIdentity : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Identity.hpp>
Identity gate class.
The Identity gate class implements the quantum identity gate for an arbitrary number of quantum bits
The identity gate is a single-qubit operation that leaves the basis state \(\left|0\right>\) and \(\left|1\right>\) unchanged.
The unitary matrix reads
\[\begin{split} I = \begin{pmatrix} 1 & 0\\ \ 0 & 1 \end{pmatrix} \end{split}\]
-
inline constexpr auto identity() noexcept¶
- group hadamard
Functions
-
inline constexpr auto hadamard() noexcept¶
Hadamard gate creator.
This overload of the LibKet::gates::hadamard() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::hadamard();
-
class QHadamard : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Hadamard.hpp>
Hadamard gate class.
The Hadamard gate class implements the quantum Hadamard gate for an arbitrary number of quantum bits.
The Hadamard gate is a single-qubit operation that maps the basis state \(\left|0\right>\) to \(\frac{\left|0\right>+\left|1\right>}{\sqrt{2}}\) and \(\left|1\right>\) to \(\frac{\left|0\right>-\left|1\right>}{\sqrt{2}}\), thus creating an equal superposition of the two basis states.
The unitary matrix reads
\[\begin{split} H = \frac{1}{\sqrt{2}} \begin{pmatrix} 1 & 1\\ 1 & -1 \end{pmatrix} \end{split}\]
-
inline constexpr auto hadamard() noexcept¶
- group s
-
Functions
-
inline constexpr auto s() noexcept¶
\(S\) gate creator
This overload of the LibKet::gates::gate_s() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::s();
-
class QS : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_S.hpp>
\(S\) gate class
The \(S\) gate class implements the quantum \(S\) gate gate for an arbitrary number of quantum bits.
The \(S\) gate is a single-qubit operation that maps the basis state \(\left|0\right>\) to \(\left|0\right>\) and \(\left|1\right>\) to \(i\left|1\right>\).
The \(S\) gate is also known as the phase gate or the Z90 gate, because it represents a 90-degree rotation around the z-axis.
The \(S\) gate is related to the \(T\) gate by the relationship \(S=T^{2}\).
The unitary matrix reads
\[\begin{split} S = \begin{pmatrix} 1 & 0\\ 0 & i \end{pmatrix} \end{split}\]
-
inline constexpr auto s() noexcept¶
- group sdag
Functions
-
inline constexpr auto sdag() noexcept¶
\(S\)-dagger gate creator
This overload of the LibKet::gates::gate_sdag() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::sdag();
-
class QSdag : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Sdag.hpp>
\(S\)-dagger gate class
The \(S\)-dagger gate class implements the quantum \(S\)-dagger gate for an arbitrary number of quantum bits.
The \(S\)-dagger gate is a single-qubit operation that maps the basis state \(\left|0\right>\) to \(\left|0\right>\) and \(\left|1\right>\) to \(-i\left|1\right>\).
The \(S^{\dagger}\) gate is also defined as the conjugate transpose of the \(S\) gate.
The unitary matrix reads
\[\begin{split} S^{\dagger} = \begin{pmatrix} 1 & 0\\ \ 0 & -i \end{pmatrix} \end{split}\]
-
inline constexpr auto sdag() noexcept¶
- group rotate_x90
Functions
-
inline constexpr auto rotate_x90() noexcept¶
Rotate_X90 gate creator.
This overload of the LibKet::gate:rotate_x90() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::rotate_x90();
-
class QRotate_X90 : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Rotate_X90.hpp>
Rotate_X90 gate class.
The Rotate_X90 gate class implements the quantum Rotate_X90 gate for an arbitrary number of quantum bits.
The Rotate_X90 gate is a single-qubit rotation through angle \(\frac{\pi}{2}\) (radians) around the x-axis.
The unitary matrix reads
\[\begin{split} R_{x}\left(\frac{\pi}{2}\right) = \begin{pmatrix} \frac{1}{\sqrt{2}} & -i\frac{1}{\sqrt{2}}\\ -i\frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \end{pmatrix} \end{split}\]
-
inline constexpr auto rotate_x90() noexcept¶
- group rotate_mx90
Functions
-
inline constexpr auto rotate_mx90() noexcept¶
Rotate_MX90 gate creator.
This overload of the LibKet::gate:rotate_mx90() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::rotate_mx90();
-
class QRotate_MX90 : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Rotate_MX90.hpp>
Rotate_MX90 gate class.
The Rotate_MX90 gate class implements the quantum Rotate_MX90 gate for an arbitrary number of quantum bits.
The Rotate_MX90 gate is a single-qubit rotation through angle \(-\frac{\pi}{2}\) (radians) around the x-axis.
The unitary matrix reads
\[\begin{split} R_{x}\left(-\frac{\pi}{2}\right) = \begin{pmatrix} \frac{1}{\sqrt{2}} & i\frac{1}{\sqrt{2}}\\ i\frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \end{pmatrix} \end{split}\]
-
inline constexpr auto rotate_mx90() noexcept¶
- group rotate_y90
Functions
-
inline constexpr auto rotate_y90() noexcept¶
Rotate_Y90 gate creator.
This overload of the LibKet::gate:rotate_y90() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::rotate_y90();
-
class QRotate_Y90 : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Rotate_Y90.hpp>
Rotate_Y90 gate class.
The Rotate_Y90 gate class implements the quantum Rotate_Y90 gate for an arbitrary number of quantum bits.
The Rotate_Y90 gate is a single-qubit rotation through angle \(\frac{\pi}{2}\) (radians) around the y-axis.
The unitary matrix reads
\[\begin{split} R_{y}(\frac{\pi}{2}) = \begin{pmatrix} \frac{1}{\sqrt{2}} & -\frac{1}{\sqrt{2}}\\ \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \end{pmatrix} \end{split}\]
-
inline constexpr auto rotate_y90() noexcept¶
- group rotate_my90
Functions
-
inline constexpr auto rotate_my90() noexcept¶
Rotate_MY90 gate creator.
This overload of the LibKet::gate:rotate_my90() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::rotate_my90();
-
class QRotate_MY90 : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Rotate_MY90.hpp>
Rotate_MY90 gate class.
The Rotate_MY90 gate class implements the quantum Rotate_MY90 gate for an arbitrary number of quantum bits.
The Rotate_MY90 gate is a single-qubit rotation through angle \(-\frac{\pi}{2}\) (radians) around the y-axis.
The unitary matrix reads
\[\begin{split} R_{y}\left(-\frac{\pi}{2}\right) = \begin{pmatrix} \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}}\\ -\frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \end{pmatrix} \end{split}\]
-
inline constexpr auto rotate_my90() noexcept¶
- group sqrtnot
Functions
-
template<typename _tol = QConst_M_ZERO_t>
inline constexpr auto sqrt_not() noexcept¶ Square-root-of-NOT gate creator.
This overload of the LibKet::gates::sqrt_not() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto qcirc = gates::sqrt_not();
-
template<typename _tol = QConst_M_ZERO_t>
class QSqrt_Not : public LibKet::gates::QGate¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Sqrt_Not.hpp>
Square-root-of-NOT gate class.
The Quantum square root of NOT gate class implements the square root of NOT gate for an arbitrary number of qubits.
The square root of NOT gate (or square root of Pauli_X, \(\sqrt{X}\)) acts on a single qubit. It maps the basis state \(\left|0\right>\) to \(\frac{(1+i)\left|0\right> + (1-i)\left|1\right>}{2}\) and \(\left|1\right>\) to \(\frac{(1-i)\left|0\right> + (1+i)\left|1\right>}{2}\).
The unitary matrix reads
\[\begin{split} \sqrt{X} = \frac{1}{2} \begin{pmatrix} 1+i & 1-i\\ \ 1-i & 1+i \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t>
- group t
Functions
-
inline constexpr auto t() noexcept¶
\(T\) gate creator
This overload of the LibKet::gate:gate_t() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::t();
-
class QT : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_T.hpp>
\(T\) gate class
The \(T\) gate class implements the quantum \(T\) gate gate for an arbitrary number of quantum bits.
The \(T\) gate is a single-qubit operation that maps the basis state \(\left|0\right>\) to \(\left|0\right>\) and \(\left|1\right>\) to \(\exp(i\frac{\pi}{4})\left|1\right>\).
The \(T\) gate is related to the \(S\) gate by the relationship \(S=T^{2}\).
The unitary matrix reads
\[\begin{split} T = \begin{pmatrix} 1 & 0\\ 0 & \exp(i\frac{\pi}{4}) \end{pmatrix} \end{split}\]
-
inline constexpr auto t() noexcept¶
- group tdag
Functions
-
inline constexpr auto tdag() noexcept¶
\(T\)-dagger gate creator
This overload of the LibKet::gate:gate_tdag() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::tdag();
-
class QTdag : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Tdag.hpp>
\(T\)-dagger gate class
The \(T\)-dagger gate class implements the quantum \(T\)-dagger gate for an arbitrary number of quantum bits.
The \(T\)-dagger is a single-qubit operation that maps the basis state \(\left|0\right>\) to \(\left|0\right>\) and \(\left|1\right>\) to \(\exp(-i\frac{\pi}{4})\left|1\right>\).
The \(T^{\dagger}\) gate is also defined as the conjugate transpose of the \(T\) gate
The unitary matrix reads
\[\begin{split} T^{\dagger} = \begin{pmatrix} 1 & 0 \\ 0 & \exp(-i\frac{\pi}{4}) \end{pmatrix} \end{split}\]
-
inline constexpr auto tdag() noexcept¶
- group barrier
Functions
-
inline constexpr auto barrier() noexcept¶
Barrier gate creator.
This overload of the LibKet::gates::barrier() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr1 = gates::hadamard( gates::barrier() );
If the so-defined expression is used as sub-expression then the synchronization gate ensures that no optimization takes place. In the following example, the double application of the Hadamard gate would be eliminated without the barrier inbetween the two gates
auto expr2 = expr1( gates::hadamard() );
- Returns
UnaryQGate object
-
class QBarrier : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Barrier.hpp>
Barrier gate class.
The quantum synchronization gate ensures that quantum expression optimization does not proceed beyond the synchronization barrier.
The following code creates a quantum expression consisting of three Hadamard gates applied consecutively, which by the built-in optimization of quantum expressions yields a single Hadamard gate
auto expr = gates::hadamard( gates::hadamard( gates::hadamard() ) ); // same as auto expr = gates::hadamard();
To prevent the built-in optimization from taking place, the quantum synchronization gate can be inserted between the gates
auto expr = gates::hadamard( gates::barrier ( gates::hadamard( gates::barrier ( gates::hadamard() ) ) ) );
-
inline constexpr auto barrier() noexcept¶
- group u2
-
template<typename _functor, typename _tol = QConst_M_ZERO_t>
class QUnitary2 : public LibKet::gates::QGate¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Unitary2.hpp>
\(2\times 2\) unitary gate class
The \(2\times2\) unitary gate accepts an arbitrary \(2\times 2\) unitary matrix \(U\) as input and performs the ZYZ decomposition of \(U\)
\[ U = \exp(i\Phi) R_z(\alpha)R_y(\beta)R_z(\gamma) \]with \(\Phi,\alpha,\beta,\gamma\) are rotation angles.
-
template<typename _functor, typename _tol = QConst_M_ZERO_t>
- group u2dag
-
template<typename _functor, typename _tol = QConst_M_ZERO_t>
class QUnitary2dag¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Unitary2.hpp>
\(2\times 2\) unitary gate (conjugate transpose) class
The \(2\times2\) unitary gate (conjugate transpose) accepts an arbitrary \(2\times 2\) unitary matrix \(U\) as input and performs the ZYZ decomposition of the conjugate transpose of \(U\)
\[ U^\dagger = \exp(i\Phi) R_z(-\gamma)R_y(-\beta)R_z(-\alpha) \]with \(\Phi,\alpha,\beta,\gamma\) are rotation angles.
-
template<typename _functor, typename _tol = QConst_M_ZERO_t>
Parameterized Single Qubit Gates¶
- group rotate_x
Functions
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
inline constexpr auto rotate_x(_angle) noexcept¶ Rotate_X gate creator.
This overload of the LibKet::gates::rotate_x() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::rotate_x();
-
template<typename _angle, typename _tol = QConst_M_ZERO_t>
class QRotate_X : public LibKet::gates::QGate¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Rotate_X.hpp>
Rotate_X gate class.
The Rotate_X gate class implements the quantum Rotate_X gate for an arbitrary number of quantum bits.
The Rotate_X gate is a single-qubit rotation through angle \(\theta\) (radians) around the x-axis.
The unitary matrix reads
\[\begin{split} R_{x}(\theta) = \begin{pmatrix} \cos(\frac{\theta}{2}) & -i\sin(\frac{\theta}{2})\\ -i\sin(\frac{\theta}{2}) & \cos(\frac{\theta}{2}) \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
- group rotate_xdag
Functions
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
inline constexpr auto rotate_xdag(_angle) noexcept¶ Rotate_Xdag gate creator.
This overload of the LibKet::gates::rotate_xdag() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::rotate_xdag();
-
template<typename _angle, typename _tol = QConst_M_ZERO_t>
class QRotate_Xdag¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Rotate_X.hpp>
Rotate_Xdag gate class.
The Rotate_Xdag gate class implements the inverse quantum Rotate_X gate for an arbitrary number of quantum bits.
The \(R_{x}^{\dagger}(\theta)\) gate is defined as the conjugate transpose of the Rotate_X gate.
The unitary matrix reads
\[\begin{split} R_{x}^{\dagger}(\theta) = \begin{pmatrix} \cos(\frac{\theta}{2}) & i\sin(\frac{\theta}{2})\\ i\sin(\frac{\theta}{2}) & \cos(\frac{\theta}{2}) \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
- group rotate_y
Functions
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
inline constexpr auto rotate_y(_angle) noexcept¶ Rotate_Y gate creator.
This overload of the LibKet::gates::rotate_y() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::rotate_y();
-
template<typename _angle, typename _tol = QConst_M_ZERO_t>
class QRotate_Y : public LibKet::gates::QGate¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Rotate_Y.hpp>
Rotate_Y gate class.
The Rotate_Y gate class implements the quantum Rotate_Y gate for an arbitrary number of quantum bits.
The Rotate_Y gate is a single-qubit rotation through angle \(\theta\) (radians) around the y-axis.
The unitary matrix reads
\[\begin{split} R_{y}(\theta) = \begin{pmatrix} \cos(\frac{\theta}{2}) & -\sin(\frac{\theta}{2})\\ \sin(\frac{\theta}{2}) & \cos(\frac{\theta}{2}) \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
- group rotate_ydag
Functions
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
inline constexpr auto rotate_ydag(_angle) noexcept¶ Rotate_Ydag gate creator.
This overload of the LibKet::gates::rotate_ydag() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::rotate_ydag();
-
template<typename _angle, typename _tol = QConst_M_ZERO_t>
class QRotate_Ydag¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Rotate_Y.hpp>
Rotate_Ydag gate class.
The Rotate_Ydag gate class implements the inverse quantum Rotate_Y gate for an arbitrary number of quantum bits.
The \(R_{y}^{\dagger}(\theta)\) gate is defined as the conjugate transpose of the Rotate_Y gate.
The unitary matrix reads
\[\begin{split} R_{y}^{\dagger}(\theta) = \begin{pmatrix} \cos(\frac{\theta}{2}) & \sin(\frac{\theta}{2})\\ -\sin(\frac{\theta}{2}) & \cos(\frac{\theta}{2}) \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
- group rotate_z
Functions
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
inline constexpr auto rotate_z(_angle) noexcept¶ Rotate_Z gate creator.
This overload of the LibKet::gates::rotate_z() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::rotate_z();
-
template<typename _angle, typename _tol = QConst_M_ZERO_t>
class QRotate_Z : public LibKet::gates::QGate¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Rotate_Z.hpp>
Rotate_Z gate class.
The Rotate_Z gate class implements the quantum Rotate_Z gate for an arbitrary number of quantum bits.
The Rotate_Z gate is a single-qubit rotation through angle \(\theta\) (radians) around the z-axis.
The unitary matrix reads
\[\begin{split} R_{z}(\theta) = \begin{pmatrix} \exp(-i\frac{\theta}{2}) & 0\\ 0 & \exp(i\frac{\theta}{2}) \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
- group rotate_zdag
Functions
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
inline constexpr auto rotate_zdag(_angle) noexcept¶ Rotate_Zdag gate creator.
This overload of the LibKet::gates::rotate_zdag() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::rotate_zdag();
-
template<typename _angle, typename _tol = QConst_M_ZERO_t>
class QRotate_Zdag¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Rotate_Z.hpp>
Rotate_Zdag gate class.
The Rotate_Zdag gate class implements the inverse quantum Rotate_Z gate for an arbitrary number of quantum bits.
The \(R_{z}^{\dagger}(\theta) \) gate is defined as the conjugate transpose of the Rotate_Z gate.
The unitary matrix reads
\[\begin{split} R_{z}^{\dagger}(\theta)= \begin{pmatrix} \exp(i\frac{\theta}{2}) & 0\\ 0 & \exp(-i\frac{\theta}{2}) \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
- group phase
-
Functions
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
inline constexpr auto phase(_angle) noexcept¶ Phase gate creator.
This overload of the LibKet::gates::phase() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::phase();
-
template<typename _angle, typename _tol = QConst_M_ZERO_t>
class QPhase : public LibKet::gates::QGate¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Phase.hpp>
PHASE gate class.
The PHASE gate class implements the quantum phase gate for an arbitrary number of quantum bits.
The PHASE gate is a single-qubit operation that maps the basis state \(\left|0\right>\) to \(\left|0\right>\) and \(\left|1\right>\) to \(\exp(i\theta)\left|1\right>\).
The unitary matrix reads
\[\begin{split} \text{PHASE} = \begin{pmatrix} 1 & 0\\ 0 & \exp(i\theta) \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
- group phasedag
Functions
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
inline constexpr auto phasedag(_angle) noexcept¶ Phasedag gate creator.
This overload of the LibKet::gates::phasedag() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::phasedag();
-
template<typename _angle, typename _tol = QConst_M_ZERO_t>
class QPhasedag¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Phase.hpp>
PHASEdag gate class.
The PHASEdag gate class implements the inverse quantum phase gate for an arbitrary number of quantum bits.
The PHASEdag gate is a single-qubit operation that maps the basis state \(\left|0\right>\) to \(\left|0\right>\) and \(\left|1\right>\) to \(\exp(-i\theta)\left|1\right>\).
The unitary matrix reads
\[\begin{split} \text{PHASE}^{\dagger} = \begin{pmatrix} 1 & 0\\ 0 & \exp(-i\theta) \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
Two Qubit Gates¶
- group cnot
Functions
-
inline constexpr auto cnot() noexcept¶
CNOT (controlled-X) gate creator.
This overload of the LibKet::gates::CNOT() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::cnot();
-
class QCNOT : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_CNOT.hpp>
CNOT (controlled-X) gate class.
The CNOT (controlled-X) gate class implements the quantum CNOT gate for an arbitrary number of quantum bits.
The CNOT (controlled-X) gate is a two-qubit operation, where the first qubit is usually referred to as the control qubit and the second qubit as the target qubit. It maps the basis state \(\left|00\right>\) to \(\left|00\right>\), \(\left|01\right>\) to \(\left|01\right>\), \(\left|10\right>\) to \(\left|11\right>\) and \(\left|11\right>\) to \(\left|10\right>\).
The CNOT (controlled-X) gates leaves the control qubit unchanged and performs a Pauli-X gate on the target qubit only when the control qubit is in state \(\left|1\right>\).
The unitary matrix reads
\[\begin{split} \text{CNOT} = \begin{pmatrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 0 & 1\\ 0 & 0 & 1 & 0 \end{pmatrix} \end{split}\]
-
inline constexpr auto cnot() noexcept¶
- group cy
Functions
-
inline constexpr auto cy() noexcept¶
CY (controlled-Y) gate creator.
This overload of the LibKet::gates::cy() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::cy();
-
class QCY : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_CY.hpp>
CY (controlled-Y) gate class.
The CY (controlled-Y) gate class implements the quantum controlled-Y gate for an arbitrary number of quantum bits
The CY (controlled-Y) gate is a two-qubit operation, where the first qubit is usually referred to as the control qubit and the second qubit as the target qubit. It maps the basis state \(\left|00\right>\) to \(\left|00\right>\), \(\left|01\right>\) to \(\left|01\right>\), \(\left|10\right>\) to \(i\left|11\right>\) and \(\left|11\right>\) to \(-i\left|10\right>\).
The CY (controlled-Y) gates leaves the control qubit unchanged and performs a Pauli-Y gate on the target qubit only when the control qubit is in state \(\left|1\right>\).
The unitary matrix reads
\[\begin{split} \text{CY} = \begin{pmatrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 0 & -i\\ 0 & 0 & i & 0 \end{pmatrix} \end{split}\]
-
inline constexpr auto cy() noexcept¶
- group cz
Functions
-
inline constexpr auto cz() noexcept¶
CZ (controlled-Z) gate creator.
This overload of the LibKet::gates::cz() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::cz();
-
class QCZ : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_CZ.hpp>
CZ (controlled-Z) gate class.
The CZ (controlled-Z) gate class implements the quantum controlled-Z gate for an arbitrary number of quantum bits
The CZ (controlled-Z) gate is a two-qubit operation, where the first qubit is usually referred to as the control qubit and the second qubit as the target qubit. It maps the basis state \(\left|00\right>\) to \(\left|00\right>\), \(\left|01\right>\) to \(\left|01\right>\), \(\left|10\right>\) to \(\left|10\right>\) and \(\left|11\right>\) to \(-\left|11\right>\).
The CZ (controlled-Z) gates leaves the control qubit unchanged and performs a Pauli-Z gate on the target qubit only when the control qubit is in state \(\left|1\right>\).
The unitary matrix reads
\[\begin{split} \text{CZ} = \begin{pmatrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & -1 \end{pmatrix} \end{split}\]
-
inline constexpr auto cz() noexcept¶
- group swap
Functions
-
class QSwap : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Swap.hpp>
Swap gate class.
The LibKet SWAP gate class implements the quantum swap gate for an arbitrary number of quantum bits.
The SWAP gate is a two-qubit operation that maps the basis state \(\left|00\right>\) to \(\left|00\right>\), \(\left|01\right>\) to \(\left|10\right>\), \(\left|10\right>\) to \(\left|01\right>\) and \(\left|11\right>\) to \(\left|11\right>\).
The SWAP gate swaps the state of the two qubits involved in the operation.
The unitary matrix reads
\[\begin{split} \text{SWAP} = \begin{pmatrix} 1 & 0 & 0 & 0\\ \ 0 & 0 & 1 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 0 & 1 \end{pmatrix} \end{split}\]
-
class QSwap : public LibKet::gates::QGate¶
- group sqrtswap
Functions
-
inline constexpr auto sqrt_swap() noexcept¶
Square-root-of-swap gate creator.
This overload of the LibKet::gate:sqrt_swap() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::sqrt_swap();
-
class QSqrt_Swap : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_Sqrt_Swap.hpp>
Swap gate class.
The Square root of SWAP gate class implements the quantum square root of SWAP gate for an arbitrary number of quantum bits.
The square root of SWAP gate (or square root of SWAP, \(\sqrt{\text{SWAP}}\)) is two qubit operation which implements the square root of SWAP gate.
The unitary matrix reads
\[\begin{split} \sqrt{\text{SWAP}} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \frac{1+i}{2} & \frac{1-i}{2} & 0 \\ 0 & \frac{1-i}{2} & \frac{1+i}{2} & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \end{split}\]
-
inline constexpr auto sqrt_swap() noexcept¶
- group cu2
Unnamed Group
Functions
-
template<typename _functor, typename _tol = QConst_M_ZERO_t>
inline constexpr auto cunitary2() noexcept¶ \(2\times 2\) controlled unitary gate creator
This overload of the LibKet::gates::cunitary2() function can be used as terminal, i.e. the inner-most gate in a quantum expression
struct CU2_ftor { inline auto operator()() const noexcept { return arma::vec{ 1.0/sqrt(2.0), -1.0/sqrt(2.0), 1.0/sqrt(2.0), 1.0/sqrt(2.0)}; } }; auto expr = gates::cunitary2<CU2_ftor>();
-
template<typename _functor, typename _tol = QConst_M_ZERO_t>
class QCUnitary2 : public LibKet::gates::QGate¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_CUnitary2.hpp>
\(2\times 2\) controlled unitary gate class
The \(2\times2\) controlled unitary gate accepts an arbitrary \(2\times 2\) unitary matrix \(U\) as input and performs the controlled ZYZ decomposition of \(U\)
\[ U = \exp(i\Phi) R_z(\alpha)R_y(\beta)R_z(\gamma) \]with \(\Phi,\alpha,\beta,\gamma\) are rotation angles.
-
template<typename _functor, typename _tol = QConst_M_ZERO_t>
- group cu2dag
Functions
-
template<typename _functor, typename _tol = QConst_M_ZERO_t>
inline constexpr auto cunitary2dag() noexcept¶ \(2\times 2\) controlled unitary gate (conjugate transpose) creator
This overload of the LibKet::gates::cunitary2dag() function can be used as terminal, i.e. the inner-most gate in a quantum expression
struct CU2_ftor { inline auto operator()() const noexcept return arma::vec{ 1.0/sqrt(2.0), -1.0/sqrt(2.0), 1.0/sqrt(2.0), 1.0/sqrt(2.0)}; }; auto expr = gates::cunitary2dag<CU2_ftor>();
-
template<typename _functor, typename _tol = QConst_M_ZERO_t>
class QCUnitary2dag¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_CUnitary2.hpp>
\(2\times 2\) controlled unitary gate (conjugate transpose) class
The \(2\times2\) controlled unitary gate (conjugate transpose) accepts an arbitrary \(2\times 2\) unitary matrix \(U\) as input and performs the ZYZ decomposition of the conjugate transpose of \(U\)
\[ U^\dagger = \exp(i\Phi) R_z(-\gamma)R_y(-\beta)R_z(-\alpha) \]with \(\Phi,\alpha,\beta,\gamma\) are rotation angles.
-
template<typename _functor, typename _tol = QConst_M_ZERO_t>
Parameterized Two Qubit Gates¶
- group cphase
Functions
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
inline constexpr auto cphase(_angle) noexcept¶ CPHASE (controlled phase shift) gate creator.
This overload of the LibKet::gates::cphase() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::cphase();
-
template<typename _angle, typename _tol = QConst_M_ZERO_t>
class QCPhase : public LibKet::gates::QGate¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_CPhase.hpp>
CPHASE (controlled phase shift) gate class.
The CPHASE (controlled phase shift) gate class implements the quantum controlled phase shift gate for an arbitrary number of quantum bits
The CPHASE (controlled phase shift) gate is a two-qubit operation, where the first qubit is usually referred to as the control qubit and the second qubit as the target qubit. It maps the basis state \(\left|00\right>\) to \(\left|00\right>\), \(\left|01\right>\) to \(\left|01\right>\), \(\left|10\right>\) to \(\left|10\right>\) and \(\left|11\right>\) to \(\exp(i\theta)\left|11\right>\).
The CPHASE (controlled phase shift) gates leaves the control qubit unchanged and performs a Phase gate on the target qubit only when the control qubit is in state \(\left|1\right>\).
The unitary matrix reads
\[\begin{split} \text{CPHASE} = \begin{pmatrix} 1 & 0 & 0 & 0\\ \ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & \exp(i\theta) \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
- group cphasedag
Functions
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
inline constexpr auto cphasedag(_angle) noexcept¶ CPHASEDAG (inverse controlled phase shift) gate creator.
This overload of the LibKet::gates::cphasedag() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::cphasedag();
-
template<typename _angle, typename _tol = QConst_M_ZERO_t>
class QCPhasedag¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_CPhase.hpp>
CPHASEDAG (inverse controlled phase shift) gate class.
The CPHASEDAG (inverse controlled phase shift) gate class implements the quantum controlled phase shift gate for an arbitrary number of quantum bits
The CPHASEDAG (inverse controlled phase shift) gate is a two-qubit operation, where the first qubit is usually referred to as the control qubit and the second qubit as the target qubit. It maps the basis state \(\left|00\right>\) to \(\left|00\right>\), \(\left|01\right>\) to \(\left|01\right>\), \(\left|10\right>\) to \(\left|10\right>\) and \(\left|11\right>\) to \(\exp(-i\theta)\left|11\right>\).
The \(\text{CPHASE}^{\dagger}\) (inverse controlled phase shift) gate is also defined as the conjugate transpose of the CPHASE gate.
The unitary matrix reads
\[\begin{split} \text{CPHASE}^{\dagger} = \begin{pmatrix} 1 & 0 & 0 & 0\\ \ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & \exp(-i\theta) \end{pmatrix} \end{split}\]
-
template<typename _tol = QConst_M_ZERO_t, typename _angle>
- group cphasek
Functions
-
template<std::size_t k, typename _tol = QConst_M_ZERO_t>
inline constexpr auto cphasek() noexcept¶ CPHASEK (controlled phase shift with \(\pi/2^k\) angle) gate creator.
This overload of the LibKet::gates::cphasek() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::cphasek();
-
template<std::size_t k, typename _tol = QConst_M_ZERO_t>
class QCPhaseK : public LibKet::gates::QGate¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_CPhaseK.hpp>
CPHASEK (controlled phase shift with \(\pi/2^k\) angle) gate class.
The CPHASEK (controlled phase shift with \(\pi/2^k\) angle) gate class implements the quantum controlled phase shift with \(\pi/2^k\) angle gate for an arbitrary number of quantum bits
The CPHASEK (controlled phase shift with \(\pi/2^k\) angle) gate is a two-qubit operation, where the first qubit is usually referred to as the control qubit and the second qubit as the target qubit. It maps the basis state \(\left|00\right>\) to \(\left|00\right>\), \(\left|01\right>\) to \(\left|01\right>\), \(\left|10\right>\) to \(\left|10\right>\) and \(\left|11\right>\) to \(\exp(\frac{2 \pi i}{2^{k}})\left|11\right>\).
The CPHASEK (controlled phase shift with \(\pi/2^k\) angle) gates leaves the control qubit unchanged and performs a Phase gate on the target qubit only when the control qubit is in state \(\left|1\right>\).
The unitary matrix reads
\[\begin{split} \text{CPHASEK} = \begin{pmatrix} 1 & 0 & 0 & 0\\ \ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & \exp(\frac{2 \pi i}{2^{k}}) \end{pmatrix} \end{split}\]
-
template<std::size_t k, typename _tol = QConst_M_ZERO_t>
- group cphasekdag
Functions
-
template<std::size_t k, typename _tol = QConst_M_ZERO_t>
inline constexpr auto cphasekdag() noexcept¶ CPHASEKDAG (inverse controlled phase shift with \(\pi/2^k\) angle) gate creator.
This overload of the LibKet::gates::cphasekdag() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::cphasekdag();
-
template<std::size_t k, typename _tol = QConst_M_ZERO_t>
class QCPhaseKdag¶ - #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_CPhaseK.hpp>
CPHASEKDAG (inverse controlled phase shift with \(\pi/2^k\) angle) gate class.
The CPHASEKDAG (inverse controlled phase shift with \(\pi/2^k\) angle) gate class implements the quantum controlled phase shift with \(\pi/2^k\) angle gate for an arbitrary number of quantum bits
The CPHASEKDAG (inverse controlled phase shift with \(\pi/2^k\) angle) gate is a two-qubit operation, where the first qubit is usually referred to as the control qubit and the second qubit as the target qubit. It maps the basis state \(\left|00\right>\) to \(\left|00\right>\), \(\left|01\right>\) to \(\left|01\right>\), \(\left|10\right>\) to \(\left|10\right>\) and \(\left|11\right>\) to \(\exp(-\frac{2 \pi i}{2^{k}})\left|11\right>\).
The CPHASEKDAG (inverse controlled phase shift with \(\pi/2^k\) angle) gates leaves the control qubit unchanged and performs a Phase gate on the target qubit only when the control qubit is in state \(\left|1\right>\).
The \(\text{CPHASEK}^{\dagger}\) (inverse controlled phase shift with \(\pi/2^k\) angle) is also defined as the conjugate transpose of the CPHASEK gate.
The unitary matrix reads
\[\begin{split} \text{CPHASEK}^{\dagger} = \begin{pmatrix} 1 & 0 & 0 & 0\\ \ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & \exp(-\frac{2 \pi i}{2^{k}}) \end{pmatrix} \end{split}\]
-
template<std::size_t k, typename _tol = QConst_M_ZERO_t>
Three Qubit Gates¶
- group ccnot
Functions
-
inline constexpr auto ccnot() noexcept¶
CCNOT (Toffoli) gate creator.
This overload of the LibKet::gates::ccnot() function can be used as terminal, i.e. the inner-most gate in a quantum expression
auto expr = gates::ccnot();
-
class QCCNOT : public LibKet::gates::QGate¶
- #include </home/docs/checkouts/readthedocs.org/user_builds/libket/checkouts/latest/libket/gates/QGate_CCNOT.hpp>
CCNOT (Toffoli) gate class.
The CCNOT (Toffoli) gate class implements the quantum CCNOT (Toffoli) gate for an arbitrary number of quantum bits
The CCNOT (Toffoli) gate is a three-qubit operation, where the first qubit and the second qubit are usually referred to as the control qubits and the third qubit as the target qubit. It maps the basis state \(\left|000\right>\) to \(\left|000\right>\), \(\left|001\right>\) to \(\left|001\right>\), \(\left|010\right>\) to \(\left|010\right>\), \(\left|011\right>\) to \(\left|011\right>\), \(\left|100\right>\) to \(\left|100\right>\), \(\left|101\right>\) to \(\left|101\right>\), \(\left|110\right>\) to \(\left|111\right>\) and \(\left|110\right>\) to \(\left|110\right>\)
The CCNOT (Toffoli) gates leaves the control qubit unchanged and performs a Pauli-X gate on the target qubit only when both the control qubits are in state \(\left|1\right>\).
The unitary matrix reads
\[\begin{split} \text{CCNOT} = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \end{pmatrix} \end{split}\]
-
inline constexpr auto ccnot() noexcept¶
Circuits¶
Quantum Fourier Transform¶
The code below can be used to apply the Quantum Fourier Transform on qubits 0 to n.
auto expr = qft(range<0,n>(init()));
This generates the following circuit for \(n = 5\):
This image shows the circuit created with the above line of code
Inverse QFT is called using function qftdag()
.
AllSwap¶
The LibKet AllSwap circuit swaps all qubits in a given selection. The LibKet AllSwap circuit can be applied to the first n qubits of your register as follows:
auto expr = allswap(range<0,n>(init()));
This creates the following circuit for n = 5:
This image shows the circuit created with the above line of code
Arbitrary Control¶
The Arbitrary control circuit allows controlled unitary qubit gates (e.g. cx, cy, cz, cphase, etc) to be controlled by multiple qubits. For every \(N\) control qubits, \(N-1\) ancilla qubits are needed. The following code snippet constructs a cnot gate controlled by qubits 0 to 3.
auto expr = arb_ctrl<>(cx(), //Control gate
sel<0,1,2,3>(), //Control qubits
sel<7>(), //Target qubits
sel<4,5,6>(init()) //Ancilla qubits
);
This generates the following circuit:
Arbitrary Control circuit for cnot gate
Quantum Phase Estimation¶
Oracle¶
Devices¶
Atos QLM¶
This class executes quantum circuits on the Atos Quantum Learning Machine (QLM) simulator. It adopts Atos’ AQASM quantum assembly language: Atos Website
Available QDevices in LibKet:
atos_qlm_feynman_simulator /**< Atos QLM Feynman integral path simulator */
atos_qlm_linalg_simulator /**< Atos QLM Linear algebra-based simulator */
atos_qlm_stabs_simulator /**< Atos QLM Stabilizer-based simulator */
atos_qlm_mps_simulator /**< Atos QLM Matrix product state-based simulator */
Cirq¶
This class executes quantum circuits locally on the Cirq simulator, a Python software library for writing, manipulating, and optimizing quantum circuits, and then running them on quantum computers and quantum simulators. It adopts the Cirq quantum assembly language. Cirq provides useful features such as dealing with today’s noisy intermediate-scale quantum computers: Cirq Website
Available QDevices in LibKet:
cirq_simulator /**< Cirq simulator */
cirq_simulator_simulator /**< Cirq simulator (name demangling) */
cirq_bristlecone_simulator /**< Cirq Bristlecone simulator */
cirq_foxtail_simulator /**< Cirq Foxtail simulator */
cirq_sycamore_simulator /**< Cirq Sycamore simulator */
cirq_sycamore23_simulator /**< Cirq Sycamore23 simulator */
Qiskit¶
Qiskit is another python basesd open-source SDK for working with quantum computers and simulators at the level of pulses, circuits and application modules: Qiskit Website
Available QDevices in LibKet:
qiskit_almaden_simulator /**< Qiskit 20-qubit local simulator */
qiskit_armonk_simulator /**< Qiskit 1-qubit local simulator */
qiskit_athens_simulator /**< Qiskit 5-qubit local simulator */
qiskit_belem_simulator /**< Qiskit 5-qubit local simulator */
qiskit_boeblingen_simulator /**< Qiskit 20-qubit local simulator */
qiskit_bogota_simulator /**< Qiskit 5-qubit local simulator */
qiskit_brooklyn_simulator /**< Qiskit 65-qubit local simulator */
qiskit_burlington_simulator /**< Qiskit 5-qubit local simulator */
qiskit_cairo_simulator /**< Qiskit 27-qubit local simulator */
qiskit_cambridge_simulator /**< Qiskit 28-qubit local simulator */
qiskit_casablanca_simulator /**< Qiskit 7-qubit local simulator */
qiskit_dublin_simulator /**< Qiskit 27-qubit local simulator */
qiskit_essex_simulator /**< Qiskit 5-qubit local simulator */
qiskit_guadalupe_simulator /**< Qiskit 16-qubit local simulator */
qiskit_hanoi_simulator /**< Qiskit 27-qubit local simulator */
qiskit_jakarta_simulator /**< Qiskit 7-qubit local simulator */
qiskit_johannesburg_simulator /**< Qiskit 20-qubit local simulator */
qiskit_kolkata_simulator /**< Qiskit 27-qubit local simulator */
qiskit_lagos_simulator /**< Qiskit 7-qubit local simulator */
qiskit_lima_simulator /**< Qiskit 5-qubit local simulator */
qiskit_london_simulator /**< Qiskit 5-qubit local simulator */
qiskit_manhattan_simulator /**< Qiskit 65-qubit local simulator */
qiskit_manila_simulator /**< Qiskit 5-qubit local simulator */
qiskit_melbourne_simulator /**< Qiskit 15-qubit local simulator */
qiskit_montreal_simulator /**< Qiskit 27-qubit local simulator */
qiskit_mumbai_simulator /**< Qiskit 27-qubit local simulator */
qiskit_nairobi_simulator /**< Qiskit 7-qubit local simulator */
qiskit_ourense_simulator /**< Qiskit 5-qubit local simulator */
qiskit_paris_simulator /**< Qiskit 27-qubit local simulator */
qiskit_peekskill_simulator /**< Qiskit 27-qubit local simulator */
qiskit_poughkeepsie_simulator /**< Qiskit 20-qubit local simulator */
qiskit_quito_simulator /**< Qiskit 5-qubit local simulator */
qiskit_rochester_simulator /**< Qiskit 53-qubit local simulator */
qiskit_rome_simulator /**< Qiskit 5-qubit local simulator */
qiskit_rueschlikon_simulator /**< Qiskit 16-qubit local simulator */
qiskit_santiago_simulator /**< Qiskit 5-qubit local simulator */
qiskit_singapore_simulator /**< Qiskit 20-qubit local simulator */
qiskit_sydney_simulator /**< Qiskit 27-qubit local simulator */
qiskit_tenerife_simulator /**< Qiskit 5-qubit local simulator */
qiskit_tokyo_simulator /**< Qiskit 20-qubit local simulator */
qiskit_toronto_simulator /**< Qiskit 27-qubit local simulator */
qiskit_valencia_simulator /**< Qiskit 5-qubit local simulator */
qiskit_vigo_simulator /**< Qiskit 5-qubit local simulator */
qiskit_yorktown_simulator /**< Qiskit 5-qubit local simulator */
qiskit_washington_simulator /**< Qiskit 127-qubit local simulator */
qiskit_perth_simulator /**< Qiskit 7-qubit local simulator */
qiskit_pulse_simulator /**< Qiskit pulse local simulator */
qiskit_qasm_simulator /**< Qiskit universal local simulator */
qiskit_statevector_simulator /**< Qiskit statevector local simulator */
qiskit_unitary_simulator /**< Qiskit density matrix local simulator */
qiskit_aer_density_matrix_simulator /**< Qiskit Aer density matrix local simulator */
qiskit_aer_extended_stabilizer_simulator /**< Qiskit Aer extended stabilizer local simulator */
qiskit_aer_matrix_product_state_simulator /**< Qiskit Aer matrix product state local simulator */
qiskit_aer_simulator /**< Qiskit Aer local simulator */
qiskit_aer_stabilizer_simulator /**< Qiskit Aer stabilizer local simulator */
qiskit_aer_statevector_simulator /**< Qiskit Aer statevector local simulator */
qiskit_aer_superop_simulator /**< Qiskit Aer superop local simulator */
qiskit_aer_unitary_simulator /**< Qiskit Aer unitary local simulator */
IBMQ¶
This class executes quantum circuits remotely on physical quantum devices made accessible through IBM’s Quantum Experience cloud services. It adopts the OpenQASM v2.0 quantum assembly language: IBMQ Website
Available QDevices in LibKet:
// IBM-Q Experience
ibmq_almaden_simulator /**< IBM-Q 20-qubit remote simulator */
ibmq_armonk_simulator /**< IBM-Q 1-qubit remote simulator */
ibmq_athens_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_belem_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_boeblingen_simulator /**< IBM-Q 20-qubit remote simulator */
ibmq_bogota_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_brooklyn_simulator /**< IBM-Q 65-qubit remote simulator */
ibmq_burlington_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_cairo_simulator /**< IBM-Q 27-qubit remote simulator */
ibmq_cambridge_simulator /**< IBM-Q 28-qubit remote simulator */
ibmq_casablanca_simulator /**< IBM-Q 7-qubit remote simulator */
ibmq_dublin_simulator /**< IBM-Q 27-qubit remote simulator */
ibmq_essex_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_guadalupe_simulator /**< IBM-Q 16-qubit remote simulator */
ibmq_hanoi_simulator /**< IBM-Q 27-qubit remote simulator */
ibmq_jakarta_simulator /**< IBM-Q 7-qubit remote simulator */
ibmq_johannesburg_simulator /**< IBM-Q 20-qubit remote simulator */
ibmq_kolkata_simulator /**< IBM-Q 27-qubit remote simulator */
ibmq_lagos_simulator /**< IBM-Q 7-qubit remote simulator */
ibmq_lima_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_london_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_manhattan_simulator /**< IBM-Q 65-qubit remote simulator */
ibmq_manila_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_melbourne_simulator /**< IBM-Q 15-qubit remote simulator */
ibmq_montreal_simulator /**< IBM-Q 27-qubit remote simulator */
ibmq_mumbai_simulator /**< IBM-Q 27-qubit remote simulator */
ibmq_nairobi_simulator /**< IBM-Q 7-qubit remote simulator */
ibmq_ourense_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_paris_simulator /**< IBM-Q 27-qubit remote simulator */
ibmq_peekskill_simulator /**< IBM-Q 27-qubit remote simulator */
ibmq_poughkeepsie_simulator /**< IBM-Q 20-qubit remote simulator */
ibmq_quito_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_rochester_simulator /**< IBM-Q 53-qubit remote simulator */
ibmq_rome_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_rueschlikon_simulator /**< IBM-Q 16-qubit remote simulator */
ibmq_santiago_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_singapore_simulator /**< IBM-Q 20-qubit remote simulator */
ibmq_sydney_simulator /**< IBM-Q 27-qubit remote simulator */
ibmq_tenerife_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_tokyo_simulator /**< IBM-Q 20-qubit remote simulator */
ibmq_toronto_simulator /**< IBM-Q 27-qubit remote simulator */
ibmq_valencia_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_vigo_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_yorktown_simulator /**< IBM-Q 5-qubit remote simulator */
ibmq_washington_simulator /**< IBM-Q 127-qubit remote simulator */
ibmq_perth_simulator /**< IBM-Q 7-qubit remote simulator */
ibmq_qasm_simulator /**< IBM-Q universal remote simulator */
ibmq_almaden /**< IBM-Q 20-qubit processor */
ibmq_armonk /**< IBM-Q 1-qubit processor */
ibmq_athens /**< IBM-Q 5-qubit processor */
ibmq_belem /**< IBM-Q 5-qubit processor */
ibmq_boeblingen /**< IBM-Q 20-qubit processor */
ibmq_bogota /**< IBM-Q 5-qubit processor */
ibmq_brooklyn /**< IBM-Q 65-qubit processor */
ibmq_cairo /**< IBM-Q 27-qubit processor */
ibmq_burlington /**< IBM-Q 5-qubit processor */
ibmq_cambridge /**< IBM-Q 28-qubit processor */
ibmq_casablanca /**< IBM-Q 7-qubit processor */
ibmq_dublin /**< IBM-Q 27-qubit processor */
ibmq_essex /**< IBM-Q 5-qubit processor */
ibmq_guadalupe /**< IBM-Q 16-qubit processor */
ibmq_hanoi /**< IBM-Q 27-qubit processor */
ibmq_jakarta /**< IBM-Q 7-qubit processor */
ibmq_johannesburg /**< IBM-Q 20-qubit processor */
ibmq_kolkata /**< IBM-Q 27-qubit processor */
ibmq_lagos /**< IBM-Q 7-qubit processor */
ibmq_lima /**< IBM-Q 5-qubit processor */
ibmq_london /**< IBM-Q 5-qubit processor */
ibmq_manhattan /**< IBM-Q 65-qubit processor */
ibmq_manila /**< IBM-Q 5-qubit processor */
ibmq_melbourne /**< IBM-Q 15-qubit processor */
ibmq_montreal /**< IBM-Q 27-qubit processor */
ibmq_mumbai /**< IBM-Q 27-qubit processor */
ibmq_nairobi /**< IBM-Q 7-qubit processor */
ibmq_ourense /**< IBM-Q 5-qubit processor */
ibmq_paris /**< IBM-Q 27-qubit processor */
ibmq_peekskill /**< IBM-Q 27-qubit processor */
ibmq_poughkeepsie /**< IBM-Q 20-qubit processor */
ibmq_quito /**< IBM-Q 5-qubit processor */
ibmq_rochester /**< IBM-Q 53-qubit processor */
ibmq_rome /**< IBM-Q 5-qubit processor */
ibmq_rueschlikon /**< IBM-Q 16-qubit processor */
ibmq_santiago /**< IBM-Q 5-qubit processor */
ibmq_singapore /**< IBM-Q 20-qubit processor */
ibmq_sydney /**< IBM-Q 27-qubit processor */
ibmq_tenerife /**< IBM-Q 5-qubit processor */
ibmq_tokyo /**< IBM-Q 20-qubit processor */
ibmq_toronto /**< IBM-Q 27-qubit processor */
ibmq_valencia /**< IBM-Q 5-qubit processor */
ibmq_vigo /**< IBM-Q 5-qubit processor */
ibmq_yorktown /**< IBM-Q 5-qubit processor */
ibmq_washington /**< IBM-Q 127-qubit processor */
ibmq_perth /**< IBM-Q 7-qubit processor */
Quantum Inspire¶
This class executes quantum circuits remotely on the Quantum-Inspire simulator made accessible through QuTech’s Quantum-Inspire cloud services. It adopts the commonQASM v1.0 quantum assembly language. The goal of Quantum Inspire is to provide users access to various technologies to perform quantum computations and insights in principles of quantum computing and access to the community: Quantum Inpsire Website
Available QDevices in LibKet:
qi_26_simulator /**< Quantum Inspire 26-qubit simulator */
qi_34_simulator /**< Quantum Inspire 34-qubit simulator */
qi_spin2 /**< Quantum Inspire spin-2 processor (2 qubits) */
qi_starmon5 /**< Quantum Inspire starmon-5 processor (5 qubits) */
Rigetti¶
This class executes quantum circuits remotely on physical quantum devices made accessible through Rigetti’s Quantum Cloud Service (QCS). It adopts Rigetti’s Quantum Instruction Language. Rigetti builds quantum computers and the superconducting quantum processors that power them: Rigetti Website
Available QDevices in LibKet:
rigetti_aspen_8_simulator /**< Rigetti Aspen-8 simulator */
rigetti_aspen_9_simulator /**< Rigetti Aspen-9 simulator */
rigetti_aspen_10_simulator /**< Rigetti Aspen-10 simulator */
rigetti_9q_square_simulator /**< Rigetti 9Q-square simulator */
rigetti_aspen_8 /**< Rigetti Aspen-8 processor */
rigetti_aspen_9 /**< Rigetti Aspen-9 processor */
rigetti_aspen_10 /**< Rigetti Aspen-10 processor */
QuEST¶
The Quantum Exact Simulation Toolkit is a high performance simulator of quantum circuits, state-vectors and density matrices. QuEST implements multiple useful feathuers such as multithreading, GPU acceleration and distribution: QuEST Website
Available QDevices in LibKet:
quest /**< QuEST simulator */
QX¶
The QX Simulator is a universal quantum computer simulator developped at QuTech by Nader Khammassi. The QX allows quantum algorithm designers to simulate the execution of their quantum circuits on a quantum computer. It adopts a low-level quantum assembly language Quantum Code: QX Website
Available QDevices in LibKet:
qx /**< QX simulator */
OpenQL¶
This class compiles the quantum circuit using the OpenQL backend. It adopts the OpenQL quantum assembly language. OpenQL is a framework for high-level quantum programming in C++/Python. The framework provides a compiler for compiling and optimizing quantum code. The compiler produces the intermediate quantum assembly language and the compiled micro-code for various target platforms: OpenQL website
Available QDevices in LibKet:
openql_cc_light_compiler /**< OpenQL compiler for CC-Light */
openql_cc_light17_compiler /**< OpenQL compiler for CC-Light17 */
openql_qx_compiler /**< OpenQL compiler for QX simulator */
Tutorials¶
These set of tutorials provide more insight in the workings of LibKet for different commonly used quantum circuits, backends and advanced operations. All tutorial code can be found in the LibKet examples folder. If not mentioned otherwise, all expressions are evaluated for 1024 shots on all active backends. This section is complemantary material to the example code and as such the tutorials are best followed with code and documenation side to side.
Tutorial 1: Bell state
This tutorial shows how to create a simple LibKet expression, the Bell circuit.
Bell state circuit
Tutorial 2: Quantum Teleportation
This tutorial implements the quantum teleportation circuit, which teleports the state of the first qubit to the third qubit by using measurements taken from the first two qubits.
Quantum Teleportation circuit
Tutorial 3: Advanced
This tutorial shows the use of more advanced filters and gates to create this arbitrary circuit. The circuit itselfs serves no real purpose, but is rather an example of how LibKet handles filters and gate functors.
Advanced circuit
Tutorial 4: Static_for with graph
This tutorial shows how to implement the static_for
function in combination with the LibKet graph class. Here the static_for
loop is used to apply a cnot gate between every connected node in the graph. The ring graph with five nodes is represented as a list of edges. From this, it follows that the static_for loop should iterate over all edges in this list and apply a cnot function between two nodes that are connected, where the first node is the control and the second node the target qubit.
Static_for circuit
Tutorial 5: QPU execution
In this tutorial, three methods of retrieving QPU results are shown:
Asynchronous execution
Synchronous execution
Evaluation
Both asynchronous and synchrounous execution return a pointer to the quantum job. The asynchronous option does not interrupt the code exection and the QPU execution will run in the background, so you can run code while the quantum expression is being evaluated. The synchronous option waits until the QPU has finished evaluating the quantum expression before contuing with the main code. For both methods, results can be retreived using the job->get()
function.
The evaluation method is similar to the sychronous execution, but directly returns results in JSON format instead of the QObj
pointer. The circuit belows shows the simple quantum expression used in this tutorial:
Simple quantum expression
Tutorial 6: Quantum Fourier Transform
Here, the LibKet circuit QFT is used to construct a QFT circuit with allswap at the end. The Quantum Fourier Tranform. More information on the QFT can be found here. The inverse QFT can be applied by using the QFTdag()
circuit.
QFT circuit for 6 qubits
Tutorial 7: Arbitrary Control Circuit
The following circuit implements the arbitrary control circuit. It takes four parameters: A controlled binary gate, a filter for the control qubits, a filter for the ancilla qubits and a filter for the target qubit. This example implements a 4-qubit controlled X-gate. The first four qubits are used a control for the target qubit \(q_4\). For every \(N\) control qubits, \(N-1\) ancilla qubits are needed, in this case the last three qubits.
Arbitrary Control circuit for cnot gate
Tutorial 8: Allswap
The Allswap circuit creates a quantum expression where the qubit order in a given selection is flipped.
Allswap circuit
Tutorial 9: QAOA
This tutorial shows the implementation of a QAOA circuit for the Maximum Cut problem on arbitrary graph. More information on the QAOA can be found here. This toturial shows some more advance use of the static_for()
function. The circuit is constructed for a singe QAOA iteration (\(p=1\)). This tutorial only shows how to create the QAOA circuit. For the QAOA to function, an classical optimizer is needed to optimize parameters \(\beta\) and \(\gamma\).
QAOA circuit for MaxCut
Tutorial 10: Hook
This tutorial illustrates the usage of the hook gate, which is able to reference another LibKet expression or create an expression from a cQASM string.
Circuit created with the Hook function
Tutorial 11: Just-In-Time Compilation
Using Just-In-Time Compilation, LibKet is able to use command line inputs for compile-time expresions. In this tutorial, a LibKet expression can be entered via the command line and will be processed later on in program.
Tutorial 12: Execution Scripts
he optional ftor_init
, ftor_before
, and ftor_after
make it possible to inject user-defined code at three different locations of the execution process. In this tutorial, a simple statement after the execution collects the histogram data of the experiment using Qiskit’s get_count()
function, generates a histogram plot and saves it to a file named ‘histogram.png’ in the build folder.
The init script imports the necessary packages for the qiksit visualization. After execution, the after script gets the counts and plots the histogram. It should be noted that the code injections are idented automatically and must not have trailing \t
’s. Each line must end with \n
.
Simple quantum expression for scripts tutorial
Tutorial 13: Unitary decomposition
This tutorial illustrates the basic usage of the built-in decomposition of a controlled 2x2 unitary gate into native gates. The unitary gate accepts an arbitrary 2x2 unitary matrix \(U\) as input and performs the ZYZ decomposition of \(U\). For example the following unitary matrix is used:
The decomposition created the following quantum circuit:
ZYZ decomposition of the unitary matrix
Tutorial 14: Controlled unitary decomposition
This tutorial implementes the controlled unitary decomposition, which is similar the the previous tutorial on the decomposed unitary. In this case, a control qubit is incluced to form a binary gate which controls the rotations of the unitary. For example the following unitary matrix is used:
The controlled decomposition created the following quantum circuit:
ZYZ decomposition of the unitary matrix
Tutorial 15: Quantum Program
The quantum program allows for a linear approach to constructing a quantum expression, as often seen in QASM languages. Here, qubit gates and operations are added sequantially and are translated to a quantum expression.
Circuit created by using the QProgram
Tutorial 16: HHL Algorithm
This tutorial shows the implementation of the Harrow-Hassidim-Lloyd (HHL) algorithm (see link). This algorithm is used to solve Linear systems of the form:
where A is an \(N_{b}×N_{b}\) Hermitian matrix and \(\vec{x}\) and \(\vec{b}\) are \(N_b\)-dimensional vectors. In this example, \(A\) and \(\vec{b}\) are set to:
The controlled unitary evolution is computed to be:
Which results in the following circuit example:
HHL Algorithm for a 2x2 matrix A and 2x1 vector b
The output result indeed confirms the expected ratio found in the HHL paper, which should be around \(prob(b_0)\) : \(prob(b_1)\) = 1 : 9.
API documentation¶
C++ API:¶
For the full API documentation, visit: C++ API
C API:¶
Python API:¶
Release Notes¶
[WIP]
Frequently Asked Questions¶
Why the name LibKet?
The acronym LibKet stands for Quantum Expression Template Library and is an allusion to the famous bra-ket notation since the Dutch spelling of the word Quantum is Kwantum.
Can you add support for the quantum device X?
Sure, as long as there exists either a Python package or a C/C++ API that allows to communicate with the quantum device, we can add support for it. Just let us know which quantum device you would like to see supported in LibKet by creating a feature request.
I think I found a bug in LibKet. How can I report it?
Please create an bug report describing the bug, your specific setup (operating system and compiler versions) and the steps to reproduce the bug. We will take care it is fixed.
I developed a bugfix/new feature. How can I contribute it?
Please fork the LibKet repository, commit your changes there, and create a merge request.
I used LibKet for my research. How can I cite it?
Please use the folloginw BibTeX entry to cite LibKet
@InProceedings{10.1007/978-3-030-50433-5_35, author = {M{\"o}ller, Matthias and Schalkers, Merel}, editor = {Krzhizhanovskaya, Valeria V. and Z{\'a}vodszky, G{\'a}bor and Lees, Michael H. and Dongarra, Jack J. and Sloot, Peter M. A. and Brissos, S{\'e}rgio and Teixeira, Jo{\~a}o}, title = {LibKet: A Cross-Platform Programming Framework for Quantum-Accelerated Scientific Computing}, booktitle = {Computational Science -- ICCS 2020}, year = {2020}, publisher = {Springer International Publishing}, address = {Cham}, pages = {451--464}, isbn = {978-3-030-50433-5}, doi = {10.1007/978-3-030-50433-5_35}, url = {https://doi.org/10.1007/978-3-030-50433-5_35} }
I like LibKet. Can I contribute to its further development?
That’s nice to hear. Sure, you are more than welcome to contribute to the developmet of LibKet. Please contact us by email (m.moller@tudelft.nl) or slack to discuss possible collaborations.