def apply_teleportation_channel(rho,dA=2,dR1=2,dR2=2,dB=2): ''' Applies the d-dimensional teleportation channel to the four-qudit state rho_{AR1R2B}. The channel measures R1 and R2 in the d-dimensional Bell basis and, based on the outcome, applies a 'correction operation' to B. So the output of the channel consists only of the systems A and B. We obtain quantum teleportation by letting rho_{AR1R2B} = psi_{R1} ⊗ Phi_{R2B}^+, so that dA=1. This simulates teleportation of the state psi in the system R1 to the system B. We obtain entanglement swapping by letting rho_{AR1R2B} = Phi_{AR1}^+ ⊗ Phi_{R2B}^+. The result of the channel is then Phi_{AB}^+ ''' X=[matrix_power(discrete_Weyl_X(dB),x) for x in range(dB)] Z=[matrix_power(discrete_Weyl_Z(dB),z) for z in range(dB)] rho_out=np.sum([tensor(eye(dA),dag(Bell_state(dR1,z,x)),Z[z]@X[x])@rho@tensor(eye(dA),Bell_state(dR1,z,x),dag(X[x])@dag(Z[z])) for z in range(dB) for x in range(dB)],0) return rho_out
def discrete_Weyl(d, a, b): ''' Generates the discrete Weyl operator X^aZ^b. ''' return matrix_power(discrete_Weyl_X(d), a) @ matrix_power( discrete_Weyl_Z(d), b)
def generate_nQudit_Z(d,indices): ''' Generates a tensor product of discrete Weyl-Z operators. indices is a list of dits (i.e., each element of the list is a number between 0 and d-1). ''' Z=discrete_Weyl_Z(d) out=1 for index in indices: out=tensor(out,matrix_power(Z,index)) return out
def apply_teleportation_chain_channel(rho, n, dA=2, dR=2, dB=2): ''' Applies the teleportation chain channel to the state rho, which is of the form rho_{A R11 R12 R21 R22 ... Rn1 Rn2 B}. The channel is defined by performing a d-dimensional Bell basis measurement independently on the system pairs Ri1 and Ri2, for 1 <= i <= n; based on the outcome, a 'correction operation' is applied to B. The system pairs Ri1 and Ri2 can be thought of as 'repeaters'. Note that n>=1. For n=1, we get the same channel as in apply_teleportation_channel(). We obtain teleportation by letting dA=1 and letting rho_{A R11 R12 R21 R22 ... Rn1 Rn2 B} = psi_{R11} ⊗ Phi_{R12 R21}^+ ⊗ ... ⊗ Phi_{Rn2 B}^+, so that we have teleportation of the state psi in the system R11 to the system B. We obtain a chain of entanglement swaps by letting rho_{A R11 R12 R21 R22 ... Rn1 Rn2 B} = Phi_{A R11}^+ ⊗ Phi_{R12 R21}^+ ⊗ ... ⊗ Phi_{Rn2 B}^+. ''' indices = list(itertools.product(*[range(dB)] * n)) rho_out = np.array(np.zeros((dA * dB, dA * dB), dtype=complex)) for z_indices in indices: for x_indices in indices: Bell_zx = Bell_state(dB, z_indices[0], x_indices[0]) for j in range(1, n): Bell_zx = tensor(Bell_zx, Bell_state(dB, z_indices[j], x_indices[j])) z_sum = np.mod(sum(z_indices), dB) x_sum = np.mod(sum(x_indices), dB) W_zx = matrix_power(discrete_Weyl_Z(dB), z_sum) @ matrix_power( discrete_Weyl_X(dB), x_sum) rho_out = rho_out + tensor(eye(dA), dag( Bell_zx), W_zx) @ rho @ tensor(eye(dA), Bell_zx, dag(W_zx)) return rho_out
def dephasing_channel(p, d=2): ''' Generates the channel rho -> (1-p)*rho+p*Z*rho*Z. (In the case d=2.) For d>=2, we let p be a list of d probabilities, and we use the discrete Weyl-Z operators to define the channel. For p=1/d, we get the completely dephasing channel. ''' if d == 2: return Pauli_channel(0, 0, p) else: K = [ np.sqrt(p[k]) * matrix_power(discrete_Weyl_Z(d), k) for k in range(d) ] return K
def Bell_state(d, z, x, density_matrix=False): ''' Generates a d-dimensional Bell state with 0 <= z,x <= d-1. These are defined as |Phi_{z,x}> = (Z(z)X(x) ⊗ I)|Phi^+> ''' Bell = MaxEnt_state(d, density_matrix=density_matrix) W_zx = matrix_power(discrete_Weyl_Z(d), z) @ matrix_power( discrete_Weyl_X(d), x) if density_matrix: out = tensor(W_zx, eye(d)) @ Bell @ tensor(dag(W_zx), eye(d)) return out else: out = tensor(W_zx, eye(d)) @ Bell return out