# Creating a parameterized Operator in Qiskit

I'm trying to run a VQE for a specific custom Anzats. The Anzats is built up of an unitary matrix $$U_H$$, which I'm trying to created in this way:

from qiskit import *
from qiskit.circuit import Parameter
from qiskit.quantum_info import Operator
import math as m

u_circuit = QuantumCircuit(2)

# This does not work
theta = Parameter('θ')

U_H = Operator([
[m.cos(2 * theta) - 1j * m.sin(2 * theta), 0, 0, 0],
[0, m.cos(2 * theta), -1j * m.sin(2 * theta), 0],
[0, -1j * m.sin(2 * theta), m.cos(2 * theta), 0],
[0, 0, 0, m.cos(2 * theta) - 1j * m.sin(2 * theta)]
])

u_circuit.unitary(U_H, [0, 1], label='U_H(θ)')

U_H_gate = u_circuit.to_gate(label='U_H(θ)')


However, for the VQE to work, the circuit needs to be parameterized, and because of that, so does the unitary gate U_H. Unfortunately, I'm not able to parameterize my variable θ in my operator that I later transform into a 2-qubit gate. Also I can't find a way to bind theta so that it only exists between $$0$$ and $$2\pi$$. Whenever I try to build a circuit using this function to generate the gates in the Ansatz, I get the following error:

ParameterExpression with unbound parameters ({Parameter(θ)}) cannot be cast to a float.


Does anyone know how I can create a parameterized circuit consisting of parameterized gates of the form described by the matrix the U_H operator, where theta ranges from $$0$$ to $$2\pi$$?

If I follow this correctly, the problem is that operator does not currently support parameters. This is a reported issue https://github.com/Qiskit/qiskit-terra/issues/4751

Your unitary matrix is $$U_H=\begin{pmatrix} \cos{\small(2\theta)}-i\sin{\small(2\theta)} & 0 & 0 & 0\\ 0 & \cos{\small(2\theta)} & -i\sin{\small(2\theta)} & 0\\ 0 & -i\sin{\small(2\theta)} & \cos{\small(2\theta)} & 0\\ 0 & 0 & 0 & cos{\small(2\theta)}-i\sin{\small(2\theta)} \\ \end{pmatrix}$$

That is, $$U_H=\begin{pmatrix} e^{-2i\theta} & 0 & 0 & 0\\ 0 & \cos{\small(-2\theta)} & i\sin{\small(-2\theta)} & 0\\ 0 & i\sin{\small(-2\theta)} & \cos{\small(-2\theta)} & 0\\ 0 & 0 & 0 & e^{-2i\theta} \\ \end{pmatrix}$$ Up to a global phase of $$e^{-i\theta}$$, this unitary is equivalent to $$\exp \left({\small 2i\theta}(XX + YY + ZZ) \right)$$.

Now $$XX$$, $$YY$$, and $$ZZ$$ are mutually commute. So, $$U_H\simeq\exp ({\small 2i\theta}XX)\exp ({\small 2i\theta}YY)\exp ({\small 2i\theta}ZZ)$$

Which can be implemented by using the parameterized gates $$R_{XX}$$, $$R_{YY}$$, and $$R_{ZZ}$$ as follows:

def U_H(theta):
circuit = QuantumCircuit(2)

# Global phase:
circuit.x(0)
circuit.u(np.pi, -theta, np.pi - theta, 0)

circuit.rxx(2 * theta, 0, 1)
circuit.ryy(2 * theta, 0, 1)
circuit.rzz(2 * theta, 0, 1)
return circuit.to_gate(label = '$$U_H$$')

theta = Parameter('θ')
circ = QuantumCircuit(2)
circ.append(U_H(theta), [0, 1])
bound_circuit = circ.bind_parameters({ theta: np.pi / 16 })


Could you try this as an alternative?

from qiskit import QuantumCircuit
from qiskit.circuit import Parameter, Gate

class UHGate(Gate):
def __init__(self, theta, label=None):
super().__init__('U', 2, [theta], label=label)

def _define(self):
qc = QuantumCircuit(2)
qc.unitary(self.to_matrix(), [0, 1])

self.definition = qc

def to_matrix(self):
t = float(self.params)
a = np.exp(-2j * t)
c = np.cos(2 * t)
s = -1j * np.sin(2 * t)

return np.array([[a, 0, 0, 0],
[0, c, s, 0],
[0, s, c, 0],
[0, 0, 0, a]])

t = Parameter('θ')
qc = QuantumCircuit(2)
qc.append(UHGate(t), [0, 1])


The idea is to 'delay' the building of the unitary gate to the point where you have available the values of the unbound parameters.

Another option is to manually decompose the unitary operator into 1 and 2-qubit gates that Qiskit natively supports and can be parameterized.