How to create a random pure state and create its density matrix not using numpy

How to create a random state vector which is a valid quantum state by not using np.array(). Is there any direct library function drawn in pennylane?

Hello @SUDHIR_KUMAR_SAHOO

To create an arbitrary random state, you can use the StatePrep function in PennyLane. But since you don’t want to use np.array, you could also do a rotation qml.Rot, which will prepare an arbitrary 1-qubit state. By choosing the parameters of qml.Rot randomly, you can create a random state. But be careful! In order for the states to be uniformly distributed in state space, you need the Haar measure, so check that out!

Creating a truly random state is not a basic technique. Do check our tutorials on the Haar measure and Unitary Designs to learn more.

And if you want the density matrix from a state vector, the best way to obtain it is qml.math.dm_from_state_vector. Note that if you use the default_mixed device, all states you prepare will be encoded in a density matrix by default!

Hope this helps!

Alvaro

1 Like

My problem state is I want to prepare a Mixed state density matrix \rho = p|\psi><\psi| + (1 - p)/2\times \mathrm{I}_2, where p is the probability of pure state. After that I want to add (N-1) ancilla such that density matrix becomes \sigma = \rho \otimes |0><0|^{\otimes (N-1)}.

I want to implement this in pennylane. Is this the correct way to this

import pennylane as qml
from pennylane import numpy as np

# Number of qubits
num_qubits = 1

# Initialize a quantum device
dev = qml.device("default.qubit", wires=num_qubits)

# Define a random quantum state vector
random_state = np.random.normal(size=(2**num_qubits,)) + 1j*np.random.normal(size=(2**num_qubits,))
normalized_state = random_state / np.linalg.norm(random_state)

nr_wires = (N-1)
rho = np.zeros((2 ** nr_wires, 2 ** nr_wires))
rho[0, 0] = 1  # initialize the pure state density matrix for the |0><0| state

dev = qml.device("default.mixed", wires=nr_wires)
@qml.qnode(dev)
def circuit():
    qml.QubitDensityMatrix(rho, wires = [for wire in nr_wires])
    return qml.state()

# Apply the state vector to the quantum device
@qml.qnode(dev)
def circuit():
    qml.QubitStateVector(normalized_state, wires=list(range(num_qubits)))
    state = qml.state()
    density_mat = np.outer(state, np.conj(state).T)
    sig = (p*density_mat + ((1- p)/2 )*np.eye(2))

# Run the circuit to prepare the state
circuit()

# Print the random pure state
print("Random pure state vector:")
print(normalized_state)

Hey @SUDHIR_KUMAR_SAHOO,

You’re close :slight_smile:. There’s a couple things worth addressing. With your first circuit,

rho[0, 0] = 1  # initialize the pure state density matrix for the |0><0| state

dev = qml.device("default.mixed", wires=nr_wires)
@qml.qnode(dev)
def circuit():
    qml.QubitDensityMatrix(rho, wires = [for wire in nr_wires])
    return qml.state()

you can just return qml.density_matrix() here because, by default, all QNodes will start in the zero state :slight_smile:.

@qml.qnode(dev)
def circuit():
    return qml.density_matrix(wires= [...]) # put the right wires there

Your second circuit,

@qml.qnode(dev)
def circuit():
    qml.QubitStateVector(normalized_state, wires=list(range(num_qubits)))
    state = qml.state()
    density_mat = np.outer(state, np.conj(state).T)
    sig = (p*density_mat + ((1- p)/2 )*np.eye(2))

won’t work because QNodes must end with a measurement process. I recommend doing all of that processing outside of a QNode (i.e., the outer calculation and sig), maybe in a different function that returns those two numpy arrays, and then calling that result in a QNode.

Let me know if that puts you on the right path!

1 Like