![]() * Initial stab at conditionals Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Removed trailing whitespaces in qasm files Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Update Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Update Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Update Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * update Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * update Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Changed qasm IfStmt to use cond_if * Conditionals now work. Small changes to execute and QCircuitIterator. * fix QBaseEngine * fix to execute_circuit_steps_once_, all unit tests pass. * made iterator_type a value, not a reference * formatting * removed LOGs * Update qengine.hpp * Fix to conditionals, added conditionals to pyqpp. * made measured_d_ a stack in qcircuit.hpp * formatting * Update qcircuit.hpp * Update qcircuit_conditional_step.hpp * Added WHILE and ENDWHILE, extra exception checks * minor update * Update qpp.hpp * Changes to QCircuitConditionalStep * while_pos_ to outer_while_pos_ * updated (c) notice Updated (c) notice * update * Added conditional_if/while examples Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Preparing for Version 6.0 Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Updated README.md Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Minor update Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Fixed typo Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Added Windows CI Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Member var zero-init Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * fixing Windows CI Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * fixing Windows CI Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Finished fixing Windows CI Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Minor stylystic updates to pyqpp Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Spacing Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Minor stylistic update Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Updated CODE_OF_CONDUCT.md Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Update Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Update Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Fix Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Yet more fixes, all tests pass Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * More fixes Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Preparing v6.0 Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * typo Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Preparing for v6.0 Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> * Update qbase_engine.hpp * Version 6.0 Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> --------- Signed-off-by: Vlad Gheorghiu <vsoftco@gmail.com> Co-authored-by: a3moses <a3moses@uwaterloo.ca> |
||
---|---|---|
.. | ||
include/pyqpp | ||
CMakeLists.txt | ||
README.md | ||
qpp_wrapper.cpp |
README.md
Installation instructions
pyqpp is a Python 3
wrapper for Quantum++. pyqpp requires the same dependencies as Quantum++,
and can be installed using pip
pip install git+https://github.com/softwareQinc/qpp
Creating python stubs for IDE autocompletion and static type checking
In case autocompletion (or static type checking via mypy) does not work properly in your editor/IDE, you may need to create python stubs for the package. To do this, execute
mkdir ~/python_stubs
export MYPATH=$MYPATH:~/python_subs # put this in your .profile or .bashrc
. ~/venv/bin/activate
stubgen -p pyqpp -o ~/python_stubs
ln -s ~/python_stubs/pyqpp ~/venv/lib/python3.11/site-packages
In the above, we assumed that your platform is UNIX/UNIX-like, and that you
have pyqpp installed in a virtual environment under ~/venv
. Please modify
accordingly for your system.
Overview
pyqpp includes Bit_circuit
, Dynamic_bitset
, QCircuitT
, QEngineT
,
QNoisyEngineT
, and several other derived Engine classes. Additionally,
pyqpp provides commonly used quantum gates
and states
, and some basic
Eigen operations.
Example:
import numpy as np
from pyqpp import *
print("Qubit teleportation quantum circuit simulation\n")
# quantum circuit with 3 qubits and 2 classical bits
qc = QCircuit(3, 2)
# set the qubit 0 to a random state
U = randU(2)
# apply the gate U with name randU to qubit 0
qc.gate(U, 0, "randU")
# set the MES between qubits 1 and 2
qc.gate(gates.H, 1)
qc.CTRL(gates.X, 1, 2)
# perform the Bell measurement between qubits 0 and 1
qc.CTRL(gates.X, 0, 1)
qc.gate(gates.H, 0)
qc.measure([0, 1])
# apply the classical controls
qc.cCTRL(gates.X, 1, 2)
qc.cCTRL(gates.Z, 0, 2)
# initialize the quantum engine with a circuit
engine = QEngine(qc)
# display the quantum circuit and its corresponding resources
print(qc)
print()
print(qc.get_resources())
print()
# execute the entire circuit
engine.execute()
# display the measurement statistics
print(engine)
print()
# verify that the teleportation was successful
psi_in = np.matmul(U, states.z0)
psi_out = engine.get_state()
print("Teleported state:")
print(dirac(psi_out))
print("Norm difference:\n", norm(psi_out - psi_in))
OpenQASM circuits
Use pyqpp.qasm.read_from_file
to obtain the QCircuit
representation of an
OpenQASM 2.0 file.
Custom Bindings
pyqpp was created using pybind11, see
pyqpp/qpp_wrapper.cpp.
To wrap a custom function, use pybind11::module::def
.
template<typename Func, typename ...Extra>
module &def(const char *name_, Func &&f, const Extra&... extra)
Func
can be a plain C++ function, a function pointer, or a lambda function.
For example, consider the qpp::randU
method
cmat randU(idx D = 2);
which is wrapped as
PYBIND11_MODULE(pyqpp, m) {
...
m.def("randU", &qpp::randU, "Generates a random unitary matrix",
py::arg("D") = 2);
...
}
Template methods
We cannot wrap templated functions; instead, we must explicitly instantiate
them. For example, consider the qpp::norm
method
template <typename Derived>
double norm(const Eigen::MatrixBase<Derived>& A);
One way to wrap this is
PYBIND11_MODULE(pyqpp, m) {
...
m.def("norm", [](const cmat& A) { return qpp::norm(A); }, "Frobenius norm");
m.def("norm", [](const ket& A) { return qpp::norm(A); }, "Frobenius norm");
...
}
This creates the overloaded pyqpp.norm
function, which can accept cmat
or ket
types. To avoid repetition of boilerplate code, we can templatize the
binding:
template<typename T>
void def_norm(pybind11::module &m) {
m.def("norm", [](const T& A) { return qpp::norm(A); }, "Frobenius norm");
}
PYBIND11_MODULE(pyqpp, m) {
...
def_norm<cmat>(m);
def_norm<ket>(m);
...
}