 # Using mixed states as input

Hi all, I’ve seen a couple of questions regarding circuits with mixed state initialization, but I have some further questions. I would like to use `QubitDensityMatrix` to implement my mixed state as input however, I realised a couple of problems that I could not solve. It seems like `QubitDensityMatrix` is only available for “default.mixed” devices. I’ve seen here that mixed states are also available in “cirq.mixedsimulator” device but `qml.device("cirq.mixedsimulator", wires=2).operations` does not have `QubitDensityMatrix`. I want to use it in TensorFlow because, for some reason, I can not take the gradient of my expectation value if I use `scipy.linalg.expm` to construct my hamiltonian. Here is a simplified example;

Imagine that I have a trainable function which creates my Hamiltonian, and I need to take the gradient of the expectation value wrt the parameters of this function and quantum network. Here is some code

``````from scipy.linalg import expm

dev = qml.device("default.mixed", wires = 2)

rho = np.zeros((2**2,2**2), dtype=np.complex128)
rho[0,0] = 1.
state = np.random.uniform(0.1, 1,(2**2, 1))
state /= np.linalg.norm(state)
energy = -3.
phi = np.random.uniform(0, 1,(2,))

@qml.qnode(dev)
def circuit(rho: np.ndarray, phi: np.ndarray):
qml.QubitDensityMatrix(rho, wires=range(2))
qml.RY(phi, 0)
qml.RY(phi, 1)
qml.CNOT(wires=[0,1])
return qml.density_matrix(wires=range(2))

def cost(rho, phi,state, energy):
Hamiltonian = energy * (state @ np.conj(state).T)
density = circuit(rho, phi)
return np.real(np.trace(density @ expm(-Hamiltonian)))

g=grads(rho, phi, state, energy)
``````

Here since my Hamiltonian is an ArrayBox, this code crushes. But without ` expm(-Hamiltonian)`, I get a result.

The reason why I didn’t use `qml.expval(qml.Hermitian(Hamiltonian, wires=range(2)))` is because I again got an Arraybox-related issue where this time, somewhere in the code, it’s trying to take conjugate of the matrix which does not exist since its an ArrayBox. Note that this works if I run `cost(rho, phi, state, energy)` without gradient. My only issue is with the gradient. So I thought the simplest workaround would be to externalize the gradients to TensorFlow.

Is there any workaround that I can use? In the worst-case scenario, is there a generic algorithm to build a gate structure that creates a mixed state input?

Thanks

Hey @jackaraz! Thanks for the question. To your code example, I was able to get your code working by ensuring that `requires_grad` is specified in every argument that you’re passing to your cost function. Specifically:

``````rho = np.zeros((2**2,2**2), dtype=np.complex128, requires_grad=False)
rho[0,0] = 1.
state = np.random.uniform(0.1, 1,(2**2, 1), requires_grad=False)
state /= np.linalg.norm(state)
energy = -3.
phi = np.random.uniform(0, 1,(2,), requires_grad=True)
``````

Thanks @isaacdevlugt; I also managed to utilize tensorflow. Once the interface of the circuit is set to “tf” it seems to work with the “default.mixed” device.

But on a side note, if you know a reference on how to write a gate structure to embed a random multi-qubit mixed state density matrix on a quantum circuit, I would very much like to learn.

Having consulted a few people internally at Xanadu, it depends on what you mean by “random”. Here are a few resources:

https://qutip.org/docs/4.0.2/guide/guide-random.html

I think the simplest thing you can do is to create a random pure state with twice as many qubits and trace over half of the system (I’m trivializing a little here…).

Let us know if any of this helps!

1 Like