def entropy_stationary(steps, d): for _ in range(steps): phi = q.rand_super_bcsz(int(np.sqrt(d))) vals, vecs = np.linalg.eig(phi.data.todense()) idx = np.where(np.isclose(vals, 1.))[0] rho = unres(vecs[:, idx]) rho = q.Qobj(rho/np.trace(rho)) q.entropy_vn(rho)
def entropy_stationary(steps, d): for _ in range(steps): phi = q.rand_super_bcsz(int(np.sqrt(d))) vals, vecs = np.linalg.eig(phi.data.todense()) idx = np.where(np.isclose(vals, 1.))[0] rho = unres(vecs[:, idx]) rho = q.Qobj(rho / np.trace(rho)) q.entropy_vn(rho)
def create_states(): print('\n') n_max = 10 lmd = np.sqrt(0.01/1.01) # Test creating states state_all = [TMSS(lmd, n_max), PS(lmd, n_max), PA(lmd, n_max), PSA(lmd, n_max), PAS(lmd, n_max), PCS(lmd, n_max, (0.7, 0.7))] for item in state_all: name = item.state_name state = item.state print("State: {}".format(item.state_name)) print("Aver N: {:f} (numerical), {:f} (analytical)".format(item.num, item.exact_num if item.state_name != 'PCS' else 0)) print("Entropy of entanglement: {:f}\n".format(item.entanglement)) # Test two-mode mixing input1 = qu.ket2dm(qu.tensor(qu.basis(2, 0), qu.basis(2, 1))) tm_mix_op = tm_mix(0.1, 2) output1 = tm_mix_op * input1 * tm_mix_op.dag() print(input1) print(output1) # Test two-mode squeezing s = np.arctanh(lmd) input2 = qu.ket2dm(qu.tensor(qu.basis(n_max, 0), qu.basis(n_max, 0))) tm_sqz_op = tm_sqz(s, n_max) output2 = tm_sqz_op * input2 * tm_sqz_op.dag() print("\nEntropy of entanglement: {}".format(qu.entropy_vn(output2.ptrace(1))))
def __init__(self, l, n_max, rs): """ States obtained by a coherent superposition operation of photon subtraction and addition on two-mode squeezed state l: double float state parameter, for TMSS l = tanh(s), where s is the squeezed para n_max: positive int photon truncation number as we are doing numerical calculation i.e. photon numbers can be in [0, n_max - 1] rt: int list, optional superposition factors used when state == "PCS" Parameters ---------- rs: a list of int define the superposition factor """ super().__init__(l, n_max) self.state_name = "PCS" self.rs = rs self.state = self.__create_state(l, n_max, rs) self.a_num = qu.expect(qu.num(self.n_max), self.state.ptrace(0)) self.b_num = qu.expect(qu.num(self.n_max), self.state.ptrace(1)) self.num = self.a_num + self.b_num self.entanglement = qu.entropy_vn(self.state.ptrace(1))
def entropy_renyi(rho, alpha): """ Calculate Renyi entropy of the density matrix with given index (Currently limited to 2-level systems) Parameters ---------- dm: qobj/array-like Input density matrix alpha: Renyi index alpha Returns ------- ent_rn: Renyi Entropy """ if rho.type != 'oper': raise TypeError("Input must be a density matrix") qi = rho.eigenenergies() if alpha == 1: ent_rn = entropy_vn(rho, 2) elif alpha >= 0: ent_rn = (1 / (1 - alpha)) * log2(sum(qi**alpha)) else: raise ValueError("alpha must be a non-negative number") return ent_rn
def test_dm_entropy(self): for cut in self.cuts: for name, state in self.states.items(): with self.subTest(cut=cut, state=name): ddm = reduced_density_matrix(state, cut) dy_EE = entanglement_entropy(state, cut) qtp_state = qtp.Qobj(vectonumpy(state), dims=[[2] * self.L, [1] * self.L]) dm = qtp_state * qtp_state.dag() if cut > 0: dm = dm.ptrace(list(range(cut))) else: # qutip breaks when you ask it to trace out everything # maybe I should submit a pull request to them dm = None if dm is not None: r, msg = check_allclose(dm.full(), ddm) self.assertTrue(r, msg=msg) qtp_EE = qtp.entropy_vn(dm) else: r, msg = check_allclose(ddm, np.array([[1. + 0.0j]])) self.assertTrue(r, msg=msg) qtp_EE = 0 r, msg = check_close(qtp_EE, dy_EE) self.assertTrue(r, msg=msg)
def entropy_renyi(rho,alpha): """ Calculate Renyi entropy of the density matrix with given index (Currently limited to 2-level systems) Parameters ---------- dm: qobj/array-like Input density matrix alpha: Renyi index alpha Returns ------- ent_rn: Renyi Entropy """ if rho.type != 'oper': raise TypeError("Input must be a density matrix") qi = rho.eigenenergies() if alpha == 1: ent_rn = entropy_vn(rho,2) elif alpha >= 0: ent_rn = ( 1/(1-alpha) ) * log2 ( sum( qi**alpha ) ) else: raise ValueError("alpha must be a non-negative number") return ent_rn
def __init__(self, l, n_max): super().__init__(l, n_max) self.state_name = "PAS" self.state = qu.Qobj(np.sum([(n + 1) ** 2 * l ** n * qu.tensor(qu.basis(n_max, n + 1), qu.basis(n_max, n + 1)) for n in np.arange(n_max - 1)[::-1]])).unit() self.num = qu.expect(qu.num(self.n_max), self.state.ptrace(0)) * 2 self.exact_num = 2 * (l**8 + 26 * l**6 + 66 * l**4 + 26 * l**2 + 1) / (- l**8 - 10 * l**6 + 10 * l**2 + 1) self.entanglement = qu.entropy_vn(self.state.ptrace(0))
def density_to_purevec(density): entropy = qt.entropy_vn(density) if fuzzy(entropy, 0): U, S, V = np.linalg.svd(density.full()) s = S.tolist() for i in range(len(s)): if fuzzy(s[i], 1): return qt.Qobj(np.conjugate(V[i]))
def __init__(self, l, n_max): super().__init__(l, n_max) self.state_name = "TMSS" self.state = qu.Qobj(np.sum([l ** n * qu.tensor(qu.basis(n_max, n), qu.basis(n_max, n)) for n in np.arange(n_max)[::-1]])).unit() self.num = qu.expect(qu.num(self.n_max), self.state.ptrace(0)) * 2 self.exact_num = l ** 2 / (- l ** 2 + 1) * 2 self.entanglement = qu.entropy_vn(self.state.ptrace(0))
def test_EntropyMutual(): "Mutual information" # verify mutual information = S(A)+S(B) for pure state rhos = [rand_dm(25, dims=[[5, 5], [5, 5]], pure=True) for k in range(10)] for r in rhos: assert_equal(abs(entropy_mutual(r, [0], [1]) - ( entropy_vn(ptrace(r, 0)) + entropy_vn(ptrace(r, 1)))) < 1e-13, True) # check component selection rhos = [rand_dm(8, dims=[[2, 2, 2], [2, 2, 2]], pure=True) for k in range(10)] for r in rhos: assert_equal(abs(entropy_mutual(r, [0, 2], [1]) - (entropy_vn( ptrace(r, [0, 2])) + entropy_vn(ptrace(r, 1)))) < 1e-13, True)
def separable(whole, dims, piece_index): whole_copy = whole.copy() whole_copy.dims = [[dims], [1] * len(dims)] reduction = whole_copy.ptrace(piece_index) entropy = qt.entropy_vn(reduction) if entropy < 0.0001 and entropy > -0.9999: return True else: return False
def are_separable(self, pieces): seps = [] for piece in pieces: entropy = qt.entropy_vn(piece) if entropy < 0.001 and entropy > -0.001: seps.append(True) else: seps.append(False) return seps
def test_EntropyLinear(): "Linear entropy" # test_ entropy_vn = 0 for pure state psi = rand_ket(10) assert_equal(abs(entropy_linear(psi)) <= 1e-13, True) # test_ linear entropy always less than or equal to VN entropy rhos = [rand_dm(6) for k in range(10)] for k in rhos: assert_equal(entropy_linear(k) <= entropy_vn(k), True)
def test_EntropyLinear(): "Entropy: Linear entropy" # test_ entropy_vn = 0 for pure state psi = rand_ket(10) assert_equal(abs(entropy_linear(psi)) <= 1e-13, True) # test_ linear entropy always less than or equal to VN entropy rhos = [rand_dm(6) for k in range(10)] for k in rhos: assert_equal(entropy_linear(k) <= entropy_vn(k), True)
def test_EntropyVN(): "von-Neumann entropy" # verify that entropy_vn gives correct binary entropy a = np.linspace(0, 1, 20) for k in range(len(a)): # a*|0><0| x = a[k] * ket2dm(basis(2, 0)) # (1-a)*|1><1| y = (1 - a[k]) * ket2dm(basis(2, 1)) rho = x + y # Von-Neumann entropy (base 2) of rho out = entropy_vn(rho, 2) if k == 0 or k == 19: assert_equal(out, -0.0) else: assert_(abs(-out - a[k] * np.log2(a[k]) - (1. - a[k]) * np.log2((1. - a[k]))) < 1e-12) # test_ entropy_vn = 0 for pure state psi = rand_ket(10) assert_equal(abs(entropy_vn(psi)) <= 1e-13, True)
def test_EntropyVN(): "Entropy: von-Neumann entropy" # verify that entropy_vn gives correct binary entropy a = np.linspace(0, 1, 20) for k in range(len(a)): # a*|0><0| x = a[k] * ket2dm(basis(2, 0)) # (1-a)*|1><1| y = (1 - a[k]) * ket2dm(basis(2, 1)) rho = x + y # Von-Neumann entropy (base 2) of rho out = entropy_vn(rho, 2) if k == 0 or k == 19: assert_equal(out, -0.0) else: assert_( abs(-out - a[k] * np.log2(a[k]) - (1. - a[k]) * np.log2((1. - a[k]))) < 1e-12) # test_ entropy_vn = 0 for pure state psi = rand_ket(10) assert_equal(abs(entropy_vn(psi)) <= 1e-13, True)
def test_EntropyMutual(): "Entropy: Mutual information" # verify mutual information = S(A)+S(B) for pure state rhos = [rand_dm(25, dims=[[5, 5], [5, 5]], pure=True) for k in range(10)] for r in rhos: assert_equal( abs( entropy_mutual(r, [0], [1]) - (entropy_vn(ptrace(r, 0)) + entropy_vn(ptrace(r, 1)))) < 1e-13, True) # check component selection rhos = [ rand_dm(8, dims=[[2, 2, 2], [2, 2, 2]], pure=True) for k in range(10) ] for r in rhos: assert_equal( abs( entropy_mutual(r, [0, 2], [1]) - (entropy_vn(ptrace(r, [0, 2])) + entropy_vn(ptrace(r, 1)))) < 1e-13, True)
def entropy_entg(rho, base=2): """ Calculates the entropy of entanglement of a density matrix Parameters: ----------- rho : qobj/array-like Input density matrix base: Base of log Returns: -------- ent_entg: Entropy of Entanglement """ if rho.type == 'ket': rho = ket2dm(rho) if rho.type != 'oper': raise TypeError("Input must be density matrix") rhopartial = ptrace(rho,0) ent_entg = entropy_vn(rhopartial,base) return ent_entg
def entropy_entg(rho, base=2): """ Calculates the entropy of entanglement of a density matrix Parameters: ----------- rho : qobj/array-like Input density matrix base: Base of log Returns: -------- ent_entg: Entropy of Entanglement """ if rho.type == 'ket': rho = ket2dm(rho) if rho.type != 'oper': raise TypeError("Input must be density matrix") rhopartial = ptrace(rho, 0) ent_entg = entropy_vn(rhopartial, base) return ent_entg
def dist_kl(rho, sgm): """ Calculates the Kullback-Leibler distance (a.k.a. relative entropy) between DMs rho and sgm representing two-level systems. Parameters ---------- rho : qobj/array-like First density operator. sgm : qobj/array-like Second density operator. Returns ------- kldist : float Relative Entropy between rho and sgm. """ if rho.type != 'oper' or sgm.type != 'oper': raise TypeError("Inputs must be density matrices..") ent_vn = entropy_vn(rho, 2) r_eigs = rho.eigenenergies() s_eigs = sgm.eigenenergies() # too small negtive values may give trouble s_eigs = np.round(s_eigs, 8) kldist = -ent_vn for pj, qj in zip(r_eigs, s_eigs): if qj == 0: pass else: kldist -= pj * log2(qj) kldist = abs(kldist) return kldist
def dist_kl(rho, sgm): """ Calculates the Kullback-Leibler distance (a.k.a. relative entropy) between DMs rho and sgm representing two-level systems. Parameters ---------- rho : qobj/array-like First density operator. sgm : qobj/array-like Second density operator. Returns ------- kldist : float Relative Entropy between rho and sgm. """ if rho.type != 'oper' or sgm.type != 'oper': raise TypeError("Inputs must be density matrices..") ent_vn = entropy_vn(rho,2) r_eigs = rho.eigenenergies() s_eigs = sgm.eigenenergies() # too small negtive values may give trouble s_eigs = np.round(s_eigs,8) kldist = -ent_vn for pj, qj in zip(r_eigs,s_eigs): if qj==0: pass else: kldist -= pj * log2(qj) kldist = abs(kldist) return kldist
def __init__(self, l, n_max): """ Photon subtracted state |PS> = a b |TMSS> Parameters ---------- l: double float state parameter, for TMSS l = tanh(s), where s is the squeezed para n_max: positive int photon truncation number as we are doing numerical calculation i.e. photon numbers can be in [0, n_max - 1] Return ------ qutip.Qobj() a qutip object, a photon subtracted state in bra form """ super().__init__(l, n_max) self.state_name = "PS" self.state = qu.Qobj(np.sum([(n + 1) * l ** n * qu.tensor(qu.basis(n_max, n), qu.basis(n_max, n)) for n in np.arange(n_max)[::-1]])).unit() self.num = qu.expect(qu.num(self.n_max), self.state.ptrace(0)) * 2 self.exact_num = 4 * l ** 2 * (l ** 2 + 2) / (1 - l ** 4) self.entanglement = qu.entropy_vn(self.state.ptrace(0))
def test_binary(self, p): dm = qutip.qdiags([p, 1 - p], 0) expected = 0 if p in [0, 1 ] else p * np.log2(p) + (1 - p) * np.log2(1 - p) assert abs(-qutip.entropy_vn(dm, 2) - expected) < 1e-12
psi0=qt.basis(2*N,0) output = qt.mesolve(H, psi0, t, [qt.tensor(np.sqrt(0.05*omega)*qt.destroy(2),qt.qeye(N))], []) Energy=np.zeros(10000) Ergotropy=np.zeros(10000) v=eigenvectors(HB) EntropyB=np.zeros(10000) for i in range(0,10000): A=np.array(output.states[i]) FinalRho=np.trace(A.reshape(2,N,2,N), axis1=0, axis2=2) Rho_f=np.zeros((N,N)) for j in range(0,N): Rho_f=eigenvalues(FinalRho)[N-1-j]*v[:,j]+Rho_f Energy[i-1]=np.real(np.matrix.trace(omega*np.dot(np.array(HB),FinalRho))) Ergotropy[i-1]=-np.real(np.matrix.trace(omega*np.dot(np.array(HB),(Rho_f-FinalRho)))) EntropyB[i-1]=qt.entropy_vn(qt.Qobj(FinalRho),2) plt.figure() plt.plot(t,Energy/omega,label="Energy/omega") plt.plot(t,Ergotropy/omega,label="Ergotropy/omega") plt.xlabel("Time") plt.title("Anaharmonicities") plt.legend() plt.figure() plt.plot(t,EntropyB) plt.xlabel("Time") plt.title("Entropy") plt.legend() plt.show()
def disp_subsystems(state): for i in range(len(state.dims[0])): p = state.ptrace(i) print("%d: e: %.3f | %s\n%s" % (i, qt.entropy_vn(p), to_xyz(p), p.full())) print()
n = len(state.dims[0]) d = state.dims[0][0] j = (d - 1) / 2 dt = 0.01 H = qt.tensor(qt.identity(d), qt.rand_herm(d**(n - 1))) H.dims = [state.dims[0], state.dims[0]] U = (-1j * H * dt).expm() states = [pov(state, i) for i in range(n)] ################################################################################################ vdms = [[VisualDensityMatrix(states[i].ptrace(j), pos=[2*j, 3*n-3*i, 0])\ for j in range(n)] for i in range(n)] ventropies = [[vp.label(text="%.3f" % (qt.entropy_vn(states[i].ptrace(j))),\ pos=vp.vector(2*j, 3*n-3*i-1.5, 0))\ for j in range(n)] for i in range(n)] ################################################################################################ input() while True: state = U * state states = [pov(state, i) for i in range(n)] for i in range(n): for j in range(n): pt = states[i].ptrace(j) vdms[i][j].update(pt) ventropies[i][j].text = "%.3f" % (qt.entropy_vn( states[i].ptrace(j)))
def test_pure_state(self): assert abs(qutip.entropy_vn(qutip.rand_ket(10))) < 1e-12
def test_less_than_von_neumann(self): dm = qutip.rand_dm(10) assert qutip.entropy_linear(dm) <= qutip.entropy_vn(dm)
def test_pure_state_additive(self): # Verify mutual information = S(A) + S(B) for pure states. dm = qutip.rand_dm(25, dims=[[5, 5], [5, 5]], pure=True) expect = (qutip.entropy_vn(dm.ptrace(0)) + qutip.entropy_vn(dm.ptrace(1))) assert abs(qutip.entropy_mutual(dm, [0], [1]) - expect) < 1e-13
def test_component_selection(self): dm = qutip.rand_dm(8, dims=[[2, 2, 2], [2, 2, 2]], pure=True) expect = (qutip.entropy_vn(dm.ptrace([0, 2])) + qutip.entropy_vn(dm.ptrace(1))) assert abs(qutip.entropy_mutual(dm, [0, 2], [1]) - expect) < 1e-13
def mixed_separable(part): entropy = qt.entropy_vn(part) if entropy < 0.0001 and entropy > -0.9999: return True else: return False