def fidelity(state1, state2): """ Computes the fidelity between two quantum states (http://en.wikipedia.org/wiki/Fidelity_of_quantum_states) The arguments provided to this function should be a square matrix or a Density object. If it is a square matrix, it is assumed to be diagonalizable. Parameters: ========== state1, state2 : a density matrix or Matrix Examples: ========= >>> from sympy import S, sqrt >>> from sympsi.dagger import Dagger >>> from sympsi.spin import JzKet >>> from sympsi.density import Density, fidelity >>> from sympsi.represent import represent >>> >>> up = JzKet(S(1)/2,S(1)/2) >>> down = JzKet(S(1)/2,-S(1)/2) >>> amp = 1/sqrt(2) >>> updown = (amp * up) + (amp * down) >>> >>> # represent turns Kets into matrices >>> up_dm = represent(up * Dagger(up)) >>> down_dm = represent(down * Dagger(down)) >>> updown_dm = represent(updown * Dagger(updown)) >>> >>> fidelity(up_dm, up_dm) 1 >>> fidelity(up_dm, down_dm) #orthogonal states 0 >>> fidelity(up_dm, updown_dm).evalf().round(3) 0.707 """ state1 = represent(state1) if isinstance(state1, Density) else state1 state2 = represent(state2) if isinstance(state2, Density) else state2 if (not isinstance(state1, Matrix) or not isinstance(state2, Matrix)): raise ValueError("state1 and state2 must be of type Density or Matrix " "received type=%s for state1 and type=%s for state2" % (type(state1), type(state2))) if ( state1.shape != state2.shape and state1.is_square): raise ValueError("The dimensions of both args should be equal and the " "matrix obtained should be a square matrix") sqrt_state1 = state1**Rational(1, 2) return Tr((sqrt_state1 * state2 * sqrt_state1)**Rational(1, 2)).doit()
def fidelity(state1, state2): """ Computes the fidelity between two quantum states (http://en.wikipedia.org/wiki/Fidelity_of_quantum_states) The arguments provided to this function should be a square matrix or a Density object. If it is a square matrix, it is assumed to be diagonalizable. Parameters: ========== state1, state2 : a density matrix or Matrix Examples: ========= >>> from sympy import S, sqrt >>> from sympsi.dagger import Dagger >>> from sympsi.spin import JzKet >>> from sympsi.density import Density, fidelity >>> from sympsi.represent import represent >>> >>> up = JzKet(S(1)/2,S(1)/2) >>> down = JzKet(S(1)/2,-S(1)/2) >>> amp = 1/sqrt(2) >>> updown = (amp * up) + (amp * down) >>> >>> # represent turns Kets into matrices >>> up_dm = represent(up * Dagger(up)) >>> down_dm = represent(down * Dagger(down)) >>> updown_dm = represent(updown * Dagger(updown)) >>> >>> fidelity(up_dm, up_dm) 1 >>> fidelity(up_dm, down_dm) #orthogonal states 0 >>> fidelity(up_dm, updown_dm).evalf().round(3) 0.707 """ state1 = represent(state1) if isinstance(state1, Density) else state1 state2 = represent(state2) if isinstance(state2, Density) else state2 if (not isinstance(state1, Matrix) or not isinstance(state2, Matrix)): raise ValueError("state1 and state2 must be of type Density or Matrix " "received type=%s for state1 and type=%s for state2" % (type(state1), type(state2))) if (state1.shape != state2.shape and state1.is_square): raise ValueError("The dimensions of both args should be equal and the " "matrix obtained should be a square matrix") sqrt_state1 = state1**Rational(1, 2) return Tr((sqrt_state1 * state2 * sqrt_state1)**Rational(1, 2)).doit()
def entropy(density): """Compute the entropy of a matrix/density object. This computes -Tr(density*ln(density)) using the eigenvalue decomposition of density, which is given as either a Density instance or a matrix (numpy.ndarray, sympy.Matrix or scipy.sparse). Parameters ========== density : density matrix of type Density, sympy matrix, scipy.sparse or numpy.ndarray Examples: ======== >>> from sympsi.density import Density, entropy >>> from sympsi.represent import represent >>> from sympsi.matrixutils import scipy_sparse_matrix >>> from sympsi.spin import JzKet, Jz >>> from sympy import S, log >>> up = JzKet(S(1)/2,S(1)/2) >>> down = JzKet(S(1)/2,-S(1)/2) >>> d = Density((up,0.5),(down,0.5)) >>> entropy(d) log(2)/2 """ if isinstance(density, Density): density = represent(density) # represent in Matrix if isinstance(density, scipy_sparse_matrix): density = to_numpy(density) if isinstance(density, Matrix): eigvals = density.eigenvals().keys() return expand(-sum(e*log(e) for e in eigvals)) elif isinstance(density, numpy_ndarray): import numpy as np eigvals = np.linalg.eigvals(density) return -np.sum(eigvals*np.log(eigvals)) else: raise ValueError( "numpy.ndarray, scipy.sparse or sympy matrix expected")
def entropy(density): """Compute the entropy of a matrix/density object. This computes -Tr(density*ln(density)) using the eigenvalue decomposition of density, which is given as either a Density instance or a matrix (numpy.ndarray, sympy.Matrix or scipy.sparse). Parameters ========== density : density matrix of type Density, sympy matrix, scipy.sparse or numpy.ndarray Examples: ======== >>> from sympsi.density import Density, entropy >>> from sympsi.represent import represent >>> from sympsi.matrixutils import scipy_sparse_matrix >>> from sympsi.spin import JzKet, Jz >>> from sympy import S, log >>> up = JzKet(S(1)/2,S(1)/2) >>> down = JzKet(S(1)/2,-S(1)/2) >>> d = Density((up,0.5),(down,0.5)) >>> entropy(d) log(2)/2 """ if isinstance(density, Density): density = represent(density) # represent in Matrix if isinstance(density, scipy_sparse_matrix): density = to_numpy(density) if isinstance(density, Matrix): eigvals = density.eigenvals().keys() return expand(-sum(e * log(e) for e in eigvals)) elif isinstance(density, numpy_ndarray): import numpy as np eigvals = np.linalg.eigvals(density) return -np.sum(eigvals * np.log(eigvals)) else: raise ValueError( "numpy.ndarray, scipy.sparse or sympy matrix expected")
def _represent(self, **options): return represent(self.doit(), **options)