Symbolic evaluation of parameterized quantum circuits in Qiskit
Project description
Qiskit DemoDays presentation $\rightarrow$ :link:link,
password: Demoday20230615
(15th June 2023)
Jupyter notebook demo $\rightarrow$ :link:link (15th June 2023)
Qiskit Medium blog $\rightarrow$ :link:link (28th June 2023)
Table of contents
Introduction
The qiskit-symb
package is meant to be a Python tool to enable the symbolic evaluation of parametric quantum states and operators defined in Qiskit by parameterized quantum circuits.
A Parameterized Quantum Circuit (PQC) is a quantum circuit where we have at least one free parameter (e.g. a rotation angle $\theta$). PQCs are particularly relevant in Quantum Machine Learning (QML) models, where the values of these parameters can be learned during training to reach the desired output.
In particular, qiskit-symb
can be used to create a symbolic representation of a parametric quantum statevector, density matrix, or unitary operator directly from the Qiskit quantum circuit. This has been achieved through the re-implementation of some basic classes defined in the qiskit/quantum_info/
module by using sympy as a backend for symbolic expressions manipulation.
Installation
User-mode
pip install qiskit-symb
:warning: The package requires qiskit>=1
. See the official Migration guides if you are used to a prevoius Qiskit version.
Dev-mode
git clone https://github.com/SimoneGasperini/qiskit-symb.git
cd qiskit-symb
pip install -e .
Usage examples
Sympify a Qiskit circuit
Let's get started on how to use qiskit-symb
to get the symbolic representation of a given Qiskit circuit. In particular, in this first basic example, we consider the following quantum circuit:
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter, ParameterVector
y = Parameter('y')
p = ParameterVector('p', length=2)
pqc = QuantumCircuit(2)
pqc.ry(y, 0)
pqc.cx(0, 1)
pqc.u(0, *p, 1)
pqc.draw('mpl')
To get the sympy representation of the unitary matrix corresponding to the parameterized circuit, we just have to create the symbolic Operator
instance and call the to_sympy()
method:
from qiskit_symb.quantum_info import Operator
op = Operator(pqc)
op.to_sympy()
\left[\begin{matrix}\cos{\left(\frac{y}{2} \right)} & - \sin{\left(\frac{y}{2} \right)} & 0 & 0\\0 & 0 & \sin{\left(\frac{y}{2} \right)} & \cos{\left(\frac{y}{2} \right)}\\0 & 0 & e^{i \left(p[0] + p[1]\right)} \cos{\left(\frac{y}{2} \right)} & - e^{i \left(p[0] + p[1]\right)} \sin{\left(\frac{y}{2} \right)}\\e^{i \left(p[0] + p[1]\right)} \sin{\left(\frac{y}{2} \right)} & e^{i \left(p[0] + p[1]\right)} \cos{\left(\frac{y}{2} \right)} & 0 & 0\end{matrix}\right]
If you want then to assign a value to some specific parameter, you can use the subs(<dict>)
method passing a dictionary that maps each parameter to the desired corresponding value:
new_op = op.subs({p: [-1, 2]})
new_op.to_sympy()
\left[\begin{matrix}\cos{\left(\frac{y}{2} \right)} & - \sin{\left(\frac{y}{2} \right)} & 0 & 0\\0 & 0 & \sin{\left(\frac{y}{2} \right)} & \cos{\left(\frac{y}{2} \right)}\\0 & 0 & e^{i} \cos{\left(\frac{y}{2} \right)} & - e^{i} \sin{\left(\frac{y}{2} \right)}\\e^{i} \sin{\left(\frac{y}{2} \right)} & e^{i} \cos{\left(\frac{y}{2} \right)} & 0 & 0\end{matrix}\right]
Lambdify a Qiskit circuit
Given a Qiskit circuit, qiskit-symb
also allows to generate a Python lambda function with actual arguments matching the Qiskit unbound parameters.
Let's consider the following example starting from a ZZFeatureMap
circuit, commonly used as a data embedding ansatz in QML applications:
from qiskit.circuit.library import ZZFeatureMap
pqc = ZZFeatureMap(feature_dimension=3, reps=1)
pqc.draw('mpl')
To get the Python function representing the final parameteric statevector, we just have to create the symbolic Statevector
instance and call the to_lambda()
method:
from qiskit_symb.quantum_info import Statevector
pqc = pqc.decompose()
statevec = Statevector(pqc).to_lambda()
We can now call the lambda-generated function statevec
passing the x
values we want to assign to each parameter. The returned object will be a numpy 2D-array (with shape=(8,1)
in this case) representing the final output statevector psi
.
x = [1.24, 2.27, 0.29]
psi = statevec(*x)
This feature can be useful when, given a Qiskit PQC, we want to run it multiple times with different parameters values. Indeed, we can perform a single symbolic evalutation and then call the lambda generated function as many times as needed, passing different values of the parameters at each iteration.
Contributors
Simone Gasperini |
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file qiskit_symb-0.2.1.tar.gz
.
File metadata
- Download URL: qiskit_symb-0.2.1.tar.gz
- Upload date:
- Size: 20.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.9.20
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0ec94747e6d35b52d888f54ffa712104d4f82921085826b8b4eed0acedb86705 |
|
MD5 | 42535b955d0df1e83cca455d821c2472 |
|
BLAKE2b-256 | 34f3d7a9882de6bed7e9b9a652044c0bfa448265c03d74789a28963c12d2a3c7 |
File details
Details for the file qiskit_symb-0.2.1-py3-none-any.whl
.
File metadata
- Download URL: qiskit_symb-0.2.1-py3-none-any.whl
- Upload date:
- Size: 30.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.9.20
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5df538c7cf27b71d104659470af9f474125036bc0062b5e5b56a35b130056235 |
|
MD5 | ef04eef010b8dc73f3145417e8c1874d |
|
BLAKE2b-256 | 2bbb2c4f903765c190e508857809a9b06b2abae63f99f92f3e4ed6c6ddfb6589 |