# Implementing time evolution gate for density matrix in PennyLane circuit

I am trying to create a circuit which time evolves a density matrix $$\hat{\rho}$$ with the parameterized Hamiltonian $$\hat{H}(\theta) = e^{(-i \sum_m \theta_m \Lambda_m)}\hat{H}_ce^{(i \sum_m \theta_m \Lambda_m)}$$ where $$\hat{H}_c$$ is some fixed Hamiltonian and the $$\theta_m$$ and $$\Lambda_m$$ represent the usual parameterization of $$SU(N)$$ with the generalized Gell-Mann matrices (a.k.a. generalized Pauli matrices). The ultimate goal is to perform an optimization w.r.t. the parameters.

Hence, I would like a circuit which simply does $$e^{-i\tau \hat{H}(\theta)} \hat{\rho} e^{i\tau \hat{H}(\theta)}.$$

There are two problems.

1. PennyLane functions like qml.prod and qml.sum return "operators" but not operators that work as gates when placed within a circuit. Hence, I am not sure how to properly define $$\hat{H}(\theta)$$ as a gate.
2. There only seems to be qml.ApproxTimeEvolution() as a native function of PennyLane. But, I would like to implement exact time evolution. I feel like exact time evolution gates must exist since it is not computationally hard to time evolve my state of interest in usual python, QuTip, etc.

Here is my code for computing $$\hat{H}(\theta)$$ as an "operator" that does not work as a gate.

def constructTEO(H, thetas, wireList):
U = qml.SpecialUnitary(thetas, wires = wireList)


Ideally, I would be able to define $$\hat{H}(\theta)$$ and then run the following circuit

@qml.qnode(devRho)
def TE(H, tau, rho):
qml.QubitDensityMatrix(rho, wires=wireList)
qml.TimeEvolution(H, tau)
return qml.state()


where qml.TimeEvolution() is a (currently) fictitious function which implements a gate that exactly time evolves $$\hat{\rho}$$.

The answer turns out to be quite simple. We have used the fact that conjugation commutes with matrix exponentiation to turn the ostensibly complicated time evolution operator into a composition of qml.SpecialUnitary() gates sandwiching a qml.ApproxTimeEvolution() gate. Since these are native gates to PennyLane, there is no need to define a custom gate. The only problem remaining is to get exact time evolution, but this perhaps suffices for now.

@qml.qnode(devRho)
def TE(H, tau, rho):
qml.QubitDensityMatrix(rho, wires=wireList)
$$$$
`