- You are running into basic python issues: trying to call a function with a list
[r]
instead of a float parameter. Also, the bit_flip channel then needs to be applied on a qubit. A potential fix is here:
import cirq
alice, bob, charlie = cirq.LineQubit.range(3)
rho_13 = cirq.Circuit(
cirq.H(alice),
cirq.CNOT(alice, charlie),
# you need a probability to have the channel defined
# then you'll need to apply the channel to a qubit
cirq.bit_flip(p=0.6)(charlie),
cirq.
measure(alice,charlie),
)
This is also fraught with Python issues. You are trying to create a circuit - but then passing in a for loop as an argument? cirq.final_density_matrix
should not be part of the Circuit construction arguments for sure. Measurement can be part of the circuit but let's deal with that later as you have a question about that too.
Summing states together only makes sense in the density matrix representation. From your three last questions (Producing |GHZ><GHZ| State in Cirq, Multiple Bipartite Entangled State in Cirq and this one) I'm gathering that you would like to put together a state that represents a mixture between the GHZ state and 4 states. So we'll have to
- create the density matrix for each of them,
- multiply them with the required probabilities
- sum them together.
You need to tell us more about what kind of separable state you would like. |000><000| is one of the simplest separable ones - as it is $|0\rangle\langle0| \otimes|0\rangle\langle0|\otimes|0\rangle\langle0|$ - I'm going to assume that that's good enough. But any state that is the result of only local operations (i.e. one qubit operations) should be good enough.
Measurement is not required for your state preparation. If you want to measure your final state, I would add that at the end. Let's cover that as well.
There are two major ways that I can think of to solve this:
- using density matrices directly
- using mixtures of unitaries
Here is an example for both - at the end the final density matrix is exactly the same.
from typing import Union, Sequence, Tuple, Any
import cirq
import numpy as np
from cirq.type_workarounds import NotImplementedType
# ======== Density matrix based method ============
a, b, c = cirq.LineQubit.range(3)
GHZ_circuit = cirq.Circuit(cirq.H(a),
cirq.CNOT(a, b),
cirq.CNOT(b, c))
GHZ = cirq.final_density_matrix(GHZ_circuit)
def density_matrix_bipartite_entangled(i, j, qs):
circuit = biparty_entangle_circuit(i, j, qs)
return cirq.final_density_matrix(circuit, qubit_order=qs)
def biparty_entangle_circuit(i, j, qs):
return cirq.Circuit(cirq.H(qs[i]), cirq.CNOT(qs[i], qs[j]))
qs = [a, b, c]
rho01 = density_matrix_bipartite_entangled(0, 1, qs)
rho02 = density_matrix_bipartite_entangled(0, 2, qs)
rho12 = density_matrix_bipartite_entangled(1, 2, qs)
# creates the |+> ⊗ |1> ⊗ |0> state
circuit_separable = cirq.Circuit(cirq.H(a), cirq.X(b))
rho_separable = cirq.final_density_matrix(circuit_separable, qubit_order=qs)
p, q, r, s = 0.5, 0.3, 0.2, 0.1
assert 0 <= q + r + s <= 1
assert 0 <= p <= 1
rho = q * rho01 + r * rho02 + s * rho12 + (1 - q - r - s) * rho_separable
state = p * GHZ + (1 - p) * rho
print(f"final state: \n {state}")
print(cirq.sample_density_matrix(state, indices=[0, 1, 2], repetitions=10))
# ======== Mixture based method ============
class MixtureGate(cirq.Gate):
def __init__(self, p, q, r, s):
self.p = p
self.q = q
self.r = r
self.s = s
def _num_qubits_(self) -> int:
return 3
def _mixture_(self) -> Union[Sequence[Tuple[float, Any]],
NotImplementedType]:
p, q, r, s = self.p, self.q, self.r, self.s
rho01_gate = biparty_entangle_circuit(0, 1, qs).unitary(
qubits_that_should_be_present=qs)
rho02_gate = biparty_entangle_circuit(0, 2, qs).unitary(
qubits_that_should_be_present=qs)
rho12_gate = biparty_entangle_circuit(1, 2, qs).unitary(
qubits_that_should_be_present=qs)
separable_gate = circuit_separable.unitary(
qubits_that_should_be_present=qs)
return [
(p, GHZ_circuit.unitary()),
((1 - p) * q, rho01_gate),
((1 - p) * r, rho02_gate),
((1 - p) * s, rho12_gate),
((1 - p) * (1 - q - r - s), separable_gate),
]
final_circuit = cirq.Circuit(
MixtureGate(p, q, r, s)(a, b, c)
)
circuit_based_state = cirq.final_density_matrix(final_circuit)
print(circuit_based_state)
# we can do measurements here as well
final_circuit.append(cirq.measure(a, b, c))
r = cirq.DensityMatrixSimulator().run(program=final_circuit, repetitions=10)
print("Measurement results: ", r)
## They are the same, yay!
assert np.allclose(circuit_based_state, state)