def _rewrite_basis(self, basis, evect, **options): from sympy.physics.quantum.represent import represent j = sympify(self.j) jvals = self.jvals if j.is_number: if j == int(j): start = j**2 else: start = (2*j-1)*(2*j+1)/4 vect = represent(self, basis=basis, **options) result = Add(*[vect[start+i] * evect(j,j-i,*jvals) for i in range(2*j+1)]) if options.get('coupled') is False: return uncouple(result) return result else: # TODO: better way to get angles of rotation mi = symbols('mi') angles = represent(self.__class__(0,mi),basis=basis)[0].args[3:6] if angles == (0,0,0): return self else: state = evect(j, mi, *jvals) lt = Rotation.D(j, mi, self.m, *angles) result = lt * state return Sum(lt * state, (mi,-j,j))
def test_QubitBra(): assert Qubit(0).dual_class() == QubitBra assert QubitBra(0).dual_class() == Qubit assert represent(Qubit(1,1,0), nqubits=3).H ==\ represent(QubitBra(1,1,0), nqubits=3) assert Qubit(0,1)._eval_innerproduct_QubitBra(QubitBra(1,0)) == Integer(0) assert Qubit(0,1)._eval_innerproduct_QubitBra(QubitBra(0,1)) == Integer(1)
def test_scalar_numpy(): if not np: skip("numpy not installed or Python too old.") assert represent(Integer(1), format='numpy') == 1 assert represent(Float(1.0), format='numpy') == 1.0 assert represent(1.0+I, format='numpy') == 1.0+1.0j
def test_entropy(): up = JzKet(S(1)/2, S(1)/2) down = JzKet(S(1)/2, -S(1)/2) d = Density((up, 0.5), (down, 0.5)) # test for density object ent = entropy(d) assert entropy(d) == 0.5*log(2) assert d.entropy() == 0.5*log(2) np = import_module('numpy', min_module_version='1.4.0') if np: #do this test only if 'numpy' is available on test machine np_mat = represent(d, format='numpy') ent = entropy(np_mat) assert isinstance(np_mat, np.matrixlib.defmatrix.matrix) assert ent.real == 0.69314718055994529 assert ent.imag == 0 scipy = import_module('scipy', __import__kwargs={'fromlist': ['sparse']}) if scipy and np: #do this test only if numpy and scipy are available mat = represent(d, format="scipy.sparse") assert isinstance(mat, scipy_sparse_matrix) assert ent.real == 0.69314718055994529 assert ent.imag == 0
def test_RaisingOp(): assert Dagger(ad) == a assert Commutator(ad, a).doit() == Integer(-1) assert Commutator(ad, N).doit() == Integer(-1)*ad assert qapply(ad*k) == (sqrt(k.n + 1)*SHOKet(k.n + 1)).expand() assert qapply(ad*kz) == (sqrt(kz.n + 1)*SHOKet(kz.n + 1)).expand() assert qapply(ad*kf) == (sqrt(kf.n + 1)*SHOKet(kf.n + 1)).expand() assert ad.rewrite('xp').doit() == \ (Integer(1)/sqrt(Integer(2)*hbar*m*omega))*(Integer(-1)*I*Px + m*omega*X) assert ad.hilbert_space == ComplexSpace(S.Infinity) for i in range(ndim - 1): assert ad_rep_sympy[i + 1,i] == sqrt(i + 1) if not np: skip("numpy not installed or Python too old.") ad_rep_numpy = represent(ad, basis=N, ndim=4, format='numpy') for i in range(ndim - 1): assert ad_rep_numpy[i + 1,i] == float(sqrt(i + 1)) if not np: skip("numpy not installed or Python too old.") if not scipy: skip("scipy not installed.") else: sparse = scipy.sparse ad_rep_scipy = represent(ad, basis=N, ndim=4, format='scipy.sparse', spmatrix='lil') for i in range(ndim - 1): assert ad_rep_scipy[i + 1,i] == float(sqrt(i + 1)) assert ad_rep_numpy.dtype == 'float64' assert ad_rep_scipy.dtype == 'float64'
def fidelity(state1, state2): """ Computes the fidelity [1]_ between two 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 sympy.physics.quantum.dagger import Dagger >>> from sympy.physics.quantum.spin import JzKet >>> from sympy.physics.quantum.density import Density, fidelity >>> from sympy.physics.quantum.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 References ========== .. [1] https://en.wikipedia.org/wiki/Fidelity_of_quantum_states """ 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 test_cnot_gate(): """Test the CNOT gate.""" circuit = CNotGate(1,0) assert represent(circuit, nqubits=2) ==\ Matrix([[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]]) circuit = circuit*Qubit('111') assert matrix_to_qubit(represent(circuit, nqubits=3)) ==\ apply_operators(circuit)
def test_swap_gate(): """Test the SWAP gate.""" swap_gate_matrix = Matrix(((1, 0, 0, 0), (0, 0, 1, 0), (0, 1, 0, 0), (0, 0, 0, 1))) assert represent(SwapGate(1, 0).decompose(), nqubits=2) == swap_gate_matrix assert qapply(SwapGate(1, 3) * Qubit("0010")) == Qubit("1000") nqubits = 4 for i in range(nqubits): for j in range(i): assert represent(SwapGate(i, j), nqubits=nqubits) == represent(SwapGate(i, j).decompose(), nqubits=nqubits)
def test_scalar_scipy_sparse(): if not np: skip("numpy not installed or Python too old.") if not scipy: skip("scipy not installed.") assert represent(Integer(1), format='scipy.sparse') == 1 assert represent(Float(1.0), format='scipy.sparse') == 1.0 assert represent(1.0+I, format='scipy.sparse') == 1.0+1.0j
def test_one_qubit_commutators(): """Test single qubit gate commutation relations.""" for g1 in (IdentityGate, X, Y, Z, H, T, S): for g2 in (IdentityGate, X, Y, Z, H, T, S): e = Commutator(g1(0),g2(0)) a = matrix_to_zero(represent(e, nqubits=1, format='sympy')) b = matrix_to_zero(represent(e.doit(), nqubits=1, format='sympy')) assert a == b e = Commutator(g1(0),g2(1)) assert e.doit() == 0
def test_swap_gate(): """Test the SWAP gate.""" swap_gate_matrix = Matrix(((1,0,0,0),(0,0,1,0),(0,1,0,0),(0,0,0,1))) assert represent(SwapGate(1,0).decompose(), nqubits=2) == swap_gate_matrix assert apply_operators(SwapGate(1,3)*Qubit('0010')) == Qubit('1000') nqubits = 4 for i in range(nqubits): for j in range(i): assert represent(SwapGate(i,j), nqubits=nqubits) ==\ represent(SwapGate(i,j).decompose(), nqubits=nqubits)
def test_cnot_gate(): """Test the CNOT gate.""" circuit = CNotGate(1, 0) assert represent(circuit, nqubits=2) == Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]) circuit = circuit * Qubit("111") assert matrix_to_qubit(represent(circuit, nqubits=3)) == qapply(circuit) circuit = CNotGate(1, 0) assert Dagger(circuit) == circuit assert Dagger(Dagger(circuit)) == circuit assert circuit * circuit == 1
def test_one_qubit_anticommutators(): """Test single qubit gate anticommutation relations.""" for g1 in (IdentityGate, X, Y, Z, H): for g2 in (IdentityGate, X, Y, Z, H): e = AntiCommutator(g1(0), g2(0)) a = matrix_to_zero(represent(e, nqubits=1, format="sympy")) b = matrix_to_zero(represent(e.doit(), nqubits=1, format="sympy")) assert a == b e = AntiCommutator(g1(0), g2(1)) a = matrix_to_zero(represent(e, nqubits=2, format="sympy")) b = matrix_to_zero(represent(e.doit(), nqubits=2, format="sympy")) assert a == b
def bures_angle(state1, state2): """ Computes the Bures angle [1], [2] between two 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.physics.quantum import TensorProduct, Ket, Dagger >>> from sympy.physics.quantum.density import bures_angle >>> from sympy import Matrix >>> from math import sqrt >>> # define qubits |0>, |1>, |00>, and |11> >>> q0 = Matrix([1,0]) >>> q1 = Matrix([0,1]) >>> q00 = TensorProduct(q0,q0) >>> q11 = TensorProduct(q1,q1) >>> # create set of maximally entangled Bell states >>> phip = 1/sqrt(2) * ( q00 + q11 ) >>> phim = 1/sqrt(2) * ( q00 - q11 ) >>> # create the corresponding density matrices for the Bell states >>> phip_dm = phip * Dagger(phip) >>> phim_dm = phim * Dagger(phim) >>> # calculates the Bures angle between two orthogonal states (yields: 0) >>> print bures_angle(phip_dm, phim_dm) 1.0 >>> # calculates the Bures angle between two identitcal states (yields: 1) >>> print bures_angle(phip_dm, phip_dm) 0.0 References ========== .. [1] http://en.wikipedia.org/wiki/Bures_metric .. [2] Quantum Computation and Quantum Information. M. Nielsen, I. Chuang, Cambridge University Press, (2001) (Eq. 9.82, pg 413). """ 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") # the pi/2 is for normalization return acos( fidelity(state1, state2) ) / (pi/2)
def test_UGate_OneQubitGate_combo(): v, w, f, g = symbols('v w f g') uMat1 = ImmutableMatrix([[v, w], [f, g]]) cMat1 = Matrix([[v, w + 1, 0, 0], [f + 1, g, 0, 0], [0, 0, v, w + 1], [0, 0, f + 1, g]]) u1 = X(0) + UGate(0, uMat1) assert represent(u1, nqubits=2) == cMat1 uMat2 = ImmutableMatrix([[1/sqrt(2), 1/sqrt(2)], [I/sqrt(2), -I/sqrt(2)]]) cMat2_1 = Matrix([[1/2 + I/2, 1/2 - I/2], [1/2 - I/2, 1/2 + I/2]]) cMat2_2 = Matrix([[1, 0], [0, I]]) u2 = UGate(0, uMat2) assert represent(H(0)*u2, nqubits=1) == cMat2_1 assert represent(u2*H(0), nqubits=1) == cMat2_2
def test_OracleGate(): v = OracleGate(1, lambda qubits: qubits == IntQubit(0)) assert qapply(v*IntQubit(0)) == -IntQubit(0) assert qapply(v*IntQubit(1)) == IntQubit(1) nbits = 2 v = OracleGate(2, return_one_on_two) assert qapply(v*IntQubit(0, nbits)) == IntQubit(0, nqubits=nbits) assert qapply(v*IntQubit(1, nbits)) == IntQubit(1, nqubits=nbits) assert qapply(v*IntQubit(2, nbits)) == -IntQubit(2, nbits) assert qapply(v*IntQubit(3, nbits)) == IntQubit(3, nbits) assert represent(OracleGate(1, lambda qubits: qubits == IntQubit(0)), nqubits=1) == \ Matrix([[-1, 0], [0, 1]]) assert represent(v, nqubits=2) == Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
def test_UGate(): a, b, c, d = symbols("a,b,c,d") uMat = Matrix([[a, b], [c, d]]) # Test basic case where gate exists in 1-qubit space u1 = UGate((0,), uMat) assert represent(u1, nqubits=1) == uMat assert qapply(u1 * Qubit("0")) == a * Qubit("0") + c * Qubit("1") assert qapply(u1 * Qubit("1")) == b * Qubit("0") + d * Qubit("1") # Test case where gate exists in a larger space u2 = UGate((1,), uMat) u2Rep = represent(u2, nqubits=2) for i in range(4): assert u2Rep * qubit_to_matrix(IntQubit(i, 2)) == qubit_to_matrix(qapply(u2 * IntQubit(i, 2)))
def qubit_to_matrix(qubit, format='sympy'): """Converts an Add/Mul of Qubit objects into it's matrix representation This function is the inverse of ``matrix_to_qubit`` and is a shorthand for ``represent(qubit)``. """ return represent(qubit, format=format)
def _rewrite_basis(self, basis, evect, **options): from sympy.physics.quantum.represent import represent j = sympify(self.j) if j.is_number: vect = represent(self, basis=basis, **options) return Add(*[vect[i] * evect(j,j-i) for i in range(2*j+1)]) else: # TODO: better way to get angles of rotation mi = symbols('mi') angles = represent(self.__class__(0,mi),basis=basis)[0].args[3:6] if angles == (0,0,0): return self else: state = evect(j, mi) lt = Rotation.D(j, mi, self.m, *angles) return Sum(lt * state, (mi,-j,j))
def test_apply_represent_equality(): gates = [ HadamardGate(int(3 * random.random())), XGate(int(3 * random.random())), ZGate(int(3 * random.random())), YGate(int(3 * random.random())), ZGate(int(3 * random.random())), PhaseGate(int(3 * random.random())), ] circuit = Qubit( int(random.random() * 2), int(random.random() * 2), int(random.random() * 2), int(random.random() * 2), int(random.random() * 2), int(random.random() * 2), ) for i in range(int(random.random() * 6)): circuit = gates[int(random.random() * 6)] * circuit mat = represent(circuit, nqubits=6) states = qapply(circuit) state_rep = matrix_to_qubit(mat) states = states.expand() state_rep = state_rep.expand() assert state_rep == states
def test_superposition_of_states(): assert qapply(CNOT(0, 1)*HadamardGate(0)*(1/sqrt(2)*Qubit('01') + 1/sqrt(2)*Qubit('10'))).expand() == (Qubit('01')/2 + Qubit('00')/2 - Qubit('11')/2 + Qubit('10')/2) assert matrix_to_qubit(represent(CNOT(0, 1)*HadamardGate(0) *(1/sqrt(2)*Qubit('01') + 1/sqrt(2)*Qubit('10')), nqubits=2)) == \ (Qubit('01')/2 + Qubit('00')/2 - Qubit('11')/2 + Qubit('10')/2)
def test_QubitBra(): qb = Qubit(0) qb_bra = QubitBra(0) assert qb.dual_class() == QubitBra assert qb_bra.dual_class() == Qubit qb = Qubit(1, 1, 0) qb_bra = QubitBra(1, 1, 0) assert represent(qb, nqubits=3).H == represent(qb_bra, nqubits=3) qb = Qubit(0, 1) qb_bra = QubitBra(1,0) assert qb._eval_innerproduct_QubitBra(qb_bra) == Integer(0) qb_bra = QubitBra(0, 1) assert qb._eval_innerproduct_QubitBra(qb_bra) == Integer(1)
def test_format_numpy(): for test in _tests: lhs = represent(test[0], basis=A, format='numpy') rhs = to_numpy(test[1]) if isinstance(lhs, numpy_ndarray): assert (lhs == rhs).all() else: assert lhs == rhs
def test_format_scipy_sparse(): for test in _tests: lhs = represent(test[0], basis=A, format='scipy.sparse') rhs = to_scipy_sparse(test[1]) if isinstance(lhs, scipy_sparse_matrix): assert np.linalg.norm((lhs-rhs).todense()) == 0.0 else: assert lhs == rhs
def test_ugate(): """Test the general UGate.""" a,b,c,d = symbols('abcd') uMat = Matrix([[a,b],[c,d]]) # Test basic case where gate exists in 1-qubit space u1 = UGate((0,), uMat) assert represent(u1, nqubits = 1) == uMat assert apply_operators(u1*Qubit('0')) == a*Qubit('0') + c*Qubit('1') assert apply_operators(u1*Qubit('1')) == b*Qubit('0') + d*Qubit('1') # Test case where gate exists in a larger space u2 = UGate((1,), uMat) u2Rep = represent(u2, nqubits=2) for i in range(4): assert u2Rep*qubit_to_matrix(IntQubit(i,2)) ==\ qubit_to_matrix(apply_operators(u2*IntQubit(i,2)))
def qubit_to_matrix(qubit, format='sympy'): """Coverts an Add/Mul of Qubit objects into it's matrix representation This function is the inverse of ``matrix_to_qubit`` and is a shorthand for ``represent(qubit)``. """ from sympy.physics.quantum.gate import Z return represent(qubit, format=format)
def _rewrite_basis(self, basis, evect_cls, *args): j = self.j size, mvals = m_values(j) result = 0 vect = represent(self, basis=basis) for p in range(size): me = vect[p] me *= evect_cls.__new__(evect_cls, j, mvals[p]) result += me return result
def test_RkGate(): x = Symbol('x') assert RkGate(1,x).k == x assert RkGate(1,x).targets == (1,) assert RkGate(1,1) == ZGate(1) assert RkGate(2,2) == PhaseGate(2) assert RkGate(3,3) == TGate(3) assert represent(RkGate(0,x), nqubits =1) ==\ Matrix([[1,0],[0,exp(2*I*pi/2**x)]])
def test_UGate_CGate_combo(): a, b, c, d = symbols("a,b,c,d") uMat = Matrix([[a, b], [c, d]]) cMat = Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, a, b], [0, 0, c, d]]) # Test basic case where gate exists in 1-qubit space. u1 = UGate((0,), uMat) cu1 = CGate(1, u1) assert represent(cu1, nqubits=2) == cMat assert qapply(cu1 * Qubit("10")) == a * Qubit("10") + c * Qubit("11") assert qapply(cu1 * Qubit("11")) == b * Qubit("10") + d * Qubit("11") assert qapply(cu1 * Qubit("01")) == Qubit("01") assert qapply(cu1 * Qubit("00")) == Qubit("00") # Test case where gate exists in a larger space. u2 = UGate((1,), uMat) u2Rep = represent(u2, nqubits=2) for i in range(4): assert u2Rep * qubit_to_matrix(IntQubit(i, 2)) == qubit_to_matrix(qapply(u2 * IntQubit(i, 2)))
def test_represent(): x, y = symbols('x y') d = Density([XKet(), 0.5], [PxKet(), 0.5]) assert (represent(0.5*(PxKet()*Dagger(PxKet()))) + represent(0.5*(XKet()*Dagger(XKet())))) == represent(d) # check for kets with expr in them d_with_sym = Density([XKet(x*y), 0.5], [PxKet(x*y), 0.5]) assert (represent(0.5*(PxKet(x*y)*Dagger(PxKet(x*y)))) + represent(0.5*(XKet(x*y)*Dagger(XKet(x*y))))) == \ represent(d_with_sym) # check when given explicit basis assert (represent(0.5*(XKet()*Dagger(XKet())), basis=PxOp()) + represent(0.5*(PxKet()*Dagger(PxKet())), basis=PxOp())) == \ represent(d, basis=PxOp())
def run_circuit(self, circuit): """Run a circuit and return object Args: circuit (dict): JSON that describes the circuit Returns: dict: A dictionary of results which looks something like:: { "data":{ 'classical_state': 0, 'counts': {'11': 1}, 'quantum_state': array([sqrt(2)/2, 0, 0, sqrt(2)/2], dtype=object)}, "status": --status (string)-- } Raises: SimulatorError: if an error occurred. """ ccircuit = circuit['compiled_circuit'] self._number_of_qubits = ccircuit['header']['number_of_qubits'] self._number_of_cbits = ccircuit['header']['number_of_clbits'] self._quantum_state = 0 self._classical_state = 0 cl_reg_index = [] # starting bit index of classical register cl_reg_nbits = [] # number of bits in classical register cbit_index = 0 for cl_reg in ccircuit['header']['clbit_labels']: cl_reg_nbits.append(cl_reg[1]) cl_reg_index.append(cbit_index) cbit_index += cl_reg[1] if circuit['config']['seed'] is None: random.seed(random.getrandbits(32)) else: random.seed(circuit['config']['seed']) actual_shots = self._shots self._quantum_state = Qubit(*tuple([0] * self._number_of_qubits)) self._classical_state = 0 # Do each operation in this shot for operation in ccircuit['operations']: if 'conditional' in operation: # not related to sympy mask = int(operation['conditional']['mask'], 16) if mask > 0: value = self._classical_state & mask while (mask & 0x1) == 0: mask >>= 1 value >>= 1 if value != int(operation['conditional']['val'], 16): continue if operation['name'] in ['U', 'u1', 'u2', 'u3']: qubit = operation['qubits'][0] opname = operation['name'].upper() opparas = operation['params'] _sym_op = SympyQasmSimulator.get_sym_op( opname, tuple([qubit]), opparas) _applied_quantum_state = _sym_op * self._quantum_state self._quantum_state = qapply(_applied_quantum_state) # Check if CX gate elif operation['name'] in ['id']: logger.info( 'Identity gate is ignored by sympy-based qasm simulator.') elif operation['name'] in ['CX', 'cx']: qubit0 = operation['qubits'][0] qubit1 = operation['qubits'][1] opname = operation['name'].upper() if 'params' in operation: opparas = operation['params'] else: opparas = None q0q1tuple = tuple([qubit0, qubit1]) _sym_op = SympyQasmSimulator.get_sym_op( opname, q0q1tuple, opparas) self._quantum_state = qapply(_sym_op * self._quantum_state) # Check if measure elif operation['name'] == 'measure': logger.info( 'The statement measure is ignored by sympy-based qasm simulator.' ) elif operation['name'] == 'reset': logger.info( 'The statement reset is ignored by sympy-based qasm simulator.' ) elif operation['name'] == 'barrier': logger.info( 'The statement barrier is ignored by sympy-based qasm simulator.' ) else: backend = globals()['__configuration']['name'] err_msg = '{0} encountered unrecognized operation "{1}"' raise SimulatorError(err_msg.format(backend, operation['name'])) outcomes = [] matrix_form = represent(self._quantum_state) shape_n = matrix_form.shape[0] list_form = [matrix_form[i, 0] for i in range(shape_n)] pdist = [ SympyQasmSimulator._conjugate_square(matrix_form[i, 0]) for i in range(shape_n) ] norm_pdist = [float(i) / sum(pdist) for i in pdist] for _ in range(actual_shots): _classical_state_observed = np.random.choice(np.arange(0, shape_n), p=norm_pdist) outcomes.append( bin(_classical_state_observed)[2:].zfill( self._number_of_cbits)) # Return the results counts = dict(Counter(outcomes)) # data['quantum_state']: consistent with other backends. data = { 'counts': self._format_result(counts, cl_reg_index, cl_reg_nbits), 'quantum_state': np.asarray(list_form), 'classical_state': self._classical_state } return {'data': data, 'status': 'DONE'}
k = SHOKet('k') kz = SHOKet(0) kf = SHOKet(1) k3 = SHOKet(3) b = SHOBra('b') b3 = SHOBra(3) H = Hamiltonian('H') N = NumberOp('N') omega = Symbol('omega') m = Symbol('m') ndim = Integer(4) np = import_module('numpy') scipy = import_module('scipy', __import__kwargs={'fromlist': ['sparse']}) ad_rep_sympy = represent(ad, basis=N, ndim=4, format='sympy') a_rep = represent(a, basis=N, ndim=4, format='sympy') N_rep = represent(N, basis=N, ndim=4, format='sympy') H_rep = represent(H, basis=N, ndim=4, format='sympy') k3_rep = represent(k3, basis=N, ndim=4, format='sympy') b3_rep = represent(b3, basis=N, ndim=4, format='sympy') def test_RaisingOp(): assert Dagger(ad) == a assert Commutator(ad, a).doit() == Integer(-1) assert Commutator(ad, N).doit() == Integer(-1) * ad assert qapply(ad * k) == (sqrt(k.n + 1) * SHOKet(k.n + 1)).expand() assert qapply(ad * kz) == (sqrt(kz.n + 1) * SHOKet(kz.n + 1)).expand() assert qapply(ad * kf) == (sqrt(kf.n + 1) * SHOKet(kf.n + 1)).expand() assert ad.rewrite('xp').doit() == \
def is_scalar_sparse_matrix(circuit, nqubits, identity_only, eps=1e-11): """Checks if a given scipy.sparse matrix is a scalar matrix. A scalar matrix is such that B = bI, where B is the scalar matrix, b is some scalar multiple, and I is the identity matrix. A scalar matrix would have only the element b along it's main diagonal and zeroes elsewhere. Parameters ========== circuit : Gate tuple Sequence of quantum gates representing a quantum circuit nqubits : int Number of qubits in the circuit identity_only : bool Check for only identity matrices eps : number The tolerance value for zeroing out elements in the matrix. Values in the range [-eps, +eps] will be changed to a zero. """ if not np or not scipy: pass matrix = represent(Mul(*circuit), nqubits=nqubits, format='scipy.sparse') # In some cases, represent returns a 1D scalar value in place # of a multi-dimensional scalar matrix if (isinstance(matrix, int)): return matrix == 1 if identity_only else True # If represent returns a matrix, check if the matrix is diagonal # and if every item along the diagonal is the same else: # Due to floating pointing operations, must zero out # elements that are "very" small in the dense matrix # See parameter for default value. # Get the ndarray version of the dense matrix dense_matrix = matrix.todense().getA() # Since complex values can't be compared, must split # the matrix into real and imaginary components # Find the real values in between -eps and eps bool_real = np.logical_and(dense_matrix.real > -eps, dense_matrix.real < eps) # Find the imaginary values between -eps and eps bool_imag = np.logical_and(dense_matrix.imag > -eps, dense_matrix.imag < eps) # Replaces values between -eps and eps with 0 corrected_real = np.where(bool_real, 0.0, dense_matrix.real) corrected_imag = np.where(bool_imag, 0.0, dense_matrix.imag) # Convert the matrix with real values into imaginary values corrected_imag = corrected_imag * complex(1j) # Recombine the real and imaginary components corrected_dense = corrected_real + corrected_imag # Check if it's diagonal row_indices = corrected_dense.nonzero()[0] col_indices = corrected_dense.nonzero()[1] # Check if the rows indices and columns indices are the same # If they match, then matrix only contains elements along diagonal bool_indices = row_indices == col_indices is_diagonal = bool_indices.all() first_element = corrected_dense[0][0] # If the first element is a zero, then can't rescale matrix # and definitely not diagonal if (first_element == 0.0 + 0.0j): return False # The dimensions of the dense matrix should still # be 2^nqubits if there are elements all along the # the main diagonal trace_of_corrected = (corrected_dense / first_element).trace() expected_trace = pow(2, nqubits) has_correct_trace = trace_of_corrected == expected_trace # If only looking for identity matrices # first element must be a 1 real_is_one = abs(first_element.real - 1.0) < eps imag_is_zero = abs(first_element.imag) < eps is_one = real_is_one and imag_is_zero is_identity = is_one if identity_only else True return bool(is_diagonal and has_correct_trace and is_identity)
k = SHOKet("k") kz = SHOKet(0) kf = SHOKet(1) k3 = SHOKet(3) b = SHOBra("b") b3 = SHOBra(3) H = Hamiltonian("H") N = NumberOp("N") omega = Symbol("omega") m = Symbol("m") ndim = Integer(4) np = import_module("numpy") scipy = import_module("scipy", import_kwargs={"fromlist": ["sparse"]}) ad_rep_sympy = represent(ad, basis=N, ndim=4, format="sympy") a_rep = represent(a, basis=N, ndim=4, format="sympy") N_rep = represent(N, basis=N, ndim=4, format="sympy") H_rep = represent(H, basis=N, ndim=4, format="sympy") k3_rep = represent(k3, basis=N, ndim=4, format="sympy") b3_rep = represent(b3, basis=N, ndim=4, format="sympy") def test_RaisingOp(): assert Dagger(ad) == a assert Commutator(ad, a).doit() == Integer(-1) assert Commutator(ad, N).doit() == Integer(-1) * ad assert qapply(ad * k) == (sqrt(k.n + 1) * SHOKet(k.n + 1)).expand() assert qapply(ad * kz) == (sqrt(kz.n + 1) * SHOKet(kz.n + 1)).expand() assert qapply(ad * kf) == (sqrt(kf.n + 1) * SHOKet(kf.n + 1)).expand() assert ad.rewrite("xp").doit() == (
def test_qft_represent(): c = QFT(0,3) a = represent(c,nqubits=3) b = represent(c.decompose(),nqubits=3) assert a.evalf(prec=10) == b.evalf(prec=10)
def run_circuit(self, circuit): """Run a circuit and return object. Args: circuit (dict): JSON that describes the circuit Returns: dict: A dictionary of results which looks something like:: { "data":{ 'statevector': array([sqrt(2)/2, 0, 0, sqrt(2)/2], dtype=object)}, "status": --status (string)-- } Raises: SimulatorError: if an error occurred. """ ccircuit = circuit['compiled_circuit'] self._number_of_qubits = ccircuit['header']['number_of_qubits'] self._statevector = 0 self._statevector = Qubit(*tuple([0] * self._number_of_qubits)) for operation in ccircuit['operations']: if 'conditional' in operation: raise SimulatorError('conditional operations not supported ' 'in statevector simulator') if operation['name'] == 'measure' or operation['name'] == 'reset': raise SimulatorError('operation {} not supported by ' 'sympy statevector simulator.'.format( operation['name'])) if operation['name'] in ['U', 'u1', 'u2', 'u3']: qubit = operation['qubits'][0] opname = operation['name'].upper() opparas = operation['params'] _sym_op = StatevectorSimulatorSympy.get_sym_op( opname, tuple([qubit]), opparas) _applied_statevector = _sym_op * self._statevector self._statevector = qapply(_applied_statevector) elif operation['name'] in ['id']: logger.info( 'Identity gate is ignored by sympy-based statevector simulator.' ) elif operation['name'] in ['barrier']: logger.info( 'Barrier is ignored by sympy-based statevector simulator.') elif operation['name'] in ['CX', 'cx']: qubit0 = operation['qubits'][0] qubit1 = operation['qubits'][1] opname = operation['name'].upper() if 'params' in operation: opparas = operation['params'] else: opparas = None q0q1tuple = tuple([qubit0, qubit1]) _sym_op = StatevectorSimulatorSympy.get_sym_op( opname, q0q1tuple, opparas) self._statevector = qapply(_sym_op * self._statevector) else: backend = globals()['__configuration']['name'] err_msg = '{0} encountered unrecognized operation "{1}"' raise SimulatorError(err_msg.format(backend, operation['name'])) matrix_form = represent(self._statevector) shape_n = matrix_form.shape[0] list_form = [matrix_form[i, 0] for i in range(shape_n)] # Return the results data = { 'statevector': np.asarray(list_form), } return {'data': data, 'status': 'DONE'}
def _represent(self, **options): return represent(self.doit(), **options)
def test_compound_gates(): """Test a compound gate representation.""" circuit = YGate(0) * ZGate(0) * XGate(0) * HadamardGate(0) * Qubit('00') answer = represent(circuit, nqubits=2) assert Matrix([I / sqrt(2), I / sqrt(2), 0, 0]) == answer
def test_random_circuit(): c = random_circuit(10, 3) assert isinstance(c, Mul) m = represent(c, nqubits=3) assert m.shape == (8, 8) assert isinstance(m, Matrix)
def test_fidelity(): #test with kets up = JzKet(S(1) / 2, S(1) / 2) down = JzKet(S(1) / 2, -S(1) / 2) updown = (S(1) / sqrt(2)) * up + (S(1) / sqrt(2)) * down #check with matrices up_dm = represent(up * Dagger(up)) down_dm = represent(down * Dagger(down)) updown_dm = represent(updown * Dagger(updown)) assert abs(fidelity(up_dm, up_dm) - 1) < 1e-3 assert fidelity(up_dm, down_dm) < 1e-3 assert abs(fidelity(up_dm, updown_dm) - (S(1) / sqrt(2))) < 1e-3 assert abs(fidelity(updown_dm, down_dm) - (S(1) / sqrt(2))) < 1e-3 #check with density up_dm = Density([up, 1.0]) down_dm = Density([down, 1.0]) updown_dm = Density([updown, 1.0]) assert abs(fidelity(up_dm, up_dm) - 1) < 1e-3 assert abs(fidelity(up_dm, down_dm)) < 1e-3 assert abs(fidelity(up_dm, updown_dm) - (S(1) / sqrt(2))) < 1e-3 assert abs(fidelity(updown_dm, down_dm) - (S(1) / sqrt(2))) < 1e-3 #check mixed states with density updown2 = (sqrt(3) / 2) * up + (S(1) / 2) * down d1 = Density([updown, 0.25], [updown2, 0.75]) d2 = Density([updown, 0.75], [updown2, 0.25]) assert abs(fidelity(d1, d2) - 0.991) < 1e-3 assert abs(fidelity(d2, d1) - fidelity(d1, d2)) < 1e-3 #using qubits/density(pure states) state1 = Qubit('0') state2 = Qubit('1') state3 = (S(1) / sqrt(2)) * state1 + (S(1) / sqrt(2)) * state2 state4 = (sqrt(S(2) / 3)) * state1 + (S(1) / sqrt(3)) * state2 state1_dm = Density([state1, 1]) state2_dm = Density([state2, 1]) state3_dm = Density([state3, 1]) assert fidelity(state1_dm, state1_dm) == 1 assert fidelity(state1_dm, state2_dm) == 0 assert abs(fidelity(state1_dm, state3_dm) - 1 / sqrt(2)) < 1e-3 assert abs(fidelity(state3_dm, state2_dm) - 1 / sqrt(2)) < 1e-3 #using qubits/density(mixed states) d1 = Density([state3, 0.70], [state4, 0.30]) d2 = Density([state3, 0.20], [state4, 0.80]) assert abs(fidelity(d1, d1) - 1) < 1e-3 assert abs(fidelity(d1, d2) - 0.996) < 1e-3 assert abs(fidelity(d1, d2) - fidelity(d2, d1)) < 1e-3 #TODO: test for invalid arguments # non-square matrix mat1 = [[0, 0], [0, 0], [0, 0]] mat2 = [[0, 0], [0, 0]] raises(ValueError, lambda: fidelity(mat1, mat2)) # unequal dimensions mat1 = [[0, 0], [0, 0]] mat2 = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] raises(ValueError, lambda: fidelity(mat1, mat2)) # unsupported data-type x, y = 1, 2 #random values that is not a matrix raises(ValueError, lambda: fidelity(x, y))
def test_superposition_of_states(): state = 1/sqrt(2)*Qubit('01') + 1/sqrt(2)*Qubit('10') state_gate = CNOT(0, 1)*HadamardGate(0)*state state_expanded = Qubit('01')/2 + Qubit('00')/2 - Qubit('11')/2 + Qubit('10')/2 assert qapply(state_gate).expand() == state_expanded assert matrix_to_qubit(represent(state_gate, nqubits=2)) == state_expanded
def test_represent_hadamard(): """Test the representation of the hadamard gate.""" circuit = HadamardGate(0) * Qubit('00') answer = represent(circuit, nqubits=2) # Check that the answers are same to within an epsilon. assert answer == Matrix([1 / sqrt(2), 1 / sqrt(2), 0, 0])
def test_represent_ygate(): """Test the representation of the Y gate.""" circuit = YGate(0) * Qubit('00') answer = represent(circuit, nqubits=2) assert answer[0] == 0 and answer[1] == I and \ answer[2] == 0 and answer[3] == 0
def test_represent_zgate(): """Test the representation of the Z gate.""" circuit = ZGate(0) * Qubit('00') answer = represent(circuit, nqubits=2) assert Matrix([1, 0, 0, 0]) == answer
def test_represent_phasegate(): """Test the representation of the S gate.""" circuit = PhaseGate(0) * Qubit('01') answer = represent(circuit, nqubits=2) assert Matrix([0, I, 0, 0]) == answer
def test_represent_tgate(): """Test the representation of the T gate.""" circuit = TGate(0) * Qubit('01') assert Matrix([0, exp(I * pi / 4), 0, 0]) == represent(circuit, nqubits=2)
def run_circuit(self, circuit): """Run a circuit and return object. Args: circuit (QobjExperiment): Qobj experiment Returns: ExperimentResult: Container for a single experiment:: { "data":{ 'statevector': array([sqrt(2)/2, 0, 0, sqrt(2)/2], dtype=object)}, "status": --status (string)-- } Raises: SympySimulatorError: if an error occurred. """ self._number_of_qubits = circuit.header.number_of_qubits self._statevector = 0 self._statevector = Qubit(*tuple([0] * self._number_of_qubits)) for operation in circuit.instructions: if getattr(operation, 'conditional', None): raise SympySimulatorError( 'conditional operations not supported ' 'in statevector simulator') if operation.name in ('measure', 'reset'): raise SympySimulatorError( 'operation {} not supported by sympy statevector simulator.' .format(operation.name)) if operation.name in ('U', 'u1', 'u2', 'u3'): qubit = operation.qubits[0] opname = operation.name.upper() opparas = getattr(operation, 'params', None) _sym_op = SympyStatevectorSimulator.get_sym_op( opname, tuple([qubit]), opparas) _applied_statevector = _sym_op * self._statevector self._statevector = qapply(_applied_statevector) elif operation.name == 'id': logger.info( 'Identity gate is ignored by sympy-based statevector simulator.' ) elif operation.name == 'barrier': logger.info( 'Barrier is ignored by sympy-based statevector simulator.') elif operation.name in ('CX', 'cx'): qubit0 = operation.qubits[0] qubit1 = operation.qubits[1] opname = operation.name.upper() opparas = getattr(operation, 'params', None) q0q1tuple = tuple([qubit0, qubit1]) _sym_op = SympyStatevectorSimulator.get_sym_op( opname, q0q1tuple, opparas) self._statevector = qapply(_sym_op * self._statevector) else: backend = self.name err_msg = '{0} encountered unrecognized operation "{1}"' raise SympySimulatorError( err_msg.format(backend, operation.name)) matrix_form = represent(self._statevector) shape_n = matrix_form.shape[0] list_form = [matrix_form[i, 0] for i in range(shape_n)] # Build a schema-conformant container of the Experiment results. result = { 'data': { 'statevector': np.asarray(list_form) }, 'success': True, 'shots': 1, 'status': 'DONE', 'header': { 'name': circuit.header.name } } return ExperimentResult(**result)
def test_scalar_scipy_sparse(): assert represent(Integer(1), format='scipy.sparse') == 1 assert represent(Real(1.0), format='scipy.sparse') == 1.0 assert represent(1.0 + I, format='scipy.sparse') == 1.0 + 1.0j
def test_format_sympy(): for test in _tests: lhs = represent(test[0], basis=A, format="sympy") rhs = to_sympy(test[1]) assert lhs == rhs
def test_scalar_numpy(): assert represent(Integer(1), format='numpy') == 1 assert represent(Real(1.0), format='numpy') == 1.0 assert represent(1.0 + I, format='numpy') == 1.0 + 1.0j
def test_scalar_sympy(): assert represent(Integer(1)) == Integer(1) assert represent(Float(1.0)) == Float(1.0) assert represent(1.0 + I) == 1.0 + I
def test_represent_xgate(): """Test the representation of the X gate.""" circuit = XGate(0) * Qubit("00") answer = represent(circuit, nqubits=2) assert Matrix([0, 1, 0, 0]) == answer