Qiskit DemoDays presentation Demoday20230615
(15th June 2023)
Jupyter notebook demo
Qiskit Medium blog
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
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.
pip install qiskit-symb
git clone https://github.com/SimoneGasperini/qiskit-symb.git
cd qiskit-symb
pip install -e .
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()
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()
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.
Simone Gasperini |