def test_qOpSizeMismatchWithNoiseModel(self): ''' An exception gets thrown if the dimensions of the Kraus operators don't match the dimensions of the ``qOp`` when calling ``qOp.set_noise_model()``. ''' twoQubitOperator = qOp().kron(qOp()) self.assertRaises(WrongShapeError, twoQubitOperator.set_noise_model, damping_map(0.5))
def test_mul_with_qOp_preserves_first_qOp_noise_model(self): ''' Checks that after multiplication, the resulting `qOp` has the same noise model as the first operand. ''' op1 = qOp(kraus_ops=damping_map(0.3)) op2 = qOp() np.testing.assert_array_equal((op1 * op2)._qOp__noise_model, damping_map(0.3)) self.assertEqual((op2 * op1)._qOp__noise_model, None)
def test_set_noise_model(self): ''' Verifies that setting a noise model succeeds. ''' self.test_op.set_noise_model(damping_map(0.2)) some_op = qOp(np.eye(2), damping_map(0.2)) list_of_kraus_ops = [ np.array([[1, 0], [0, np.sqrt(0.8)]]), np.array([[0, np.sqrt(0.2)], [0, 0]]), ] np.testing.assert_array_equal( some_op._qOp__noise_model.getKrausOperators(), list_of_kraus_ops) np.testing.assert_array_equal( self.test_op._qOp__noise_model.getKrausOperators(), list_of_kraus_ops)
def ROT_Z(theta=0): return qOp([[np.exp(-1j * theta / 2.0), 0], [0, np.exp(1j * theta / 2.0)]])
def ROT_Y(theta=0): return qOp([[np.cos(theta / 2.0), -np.sin(theta / 2.0)], [np.sin(theta / 2.0), np.cos(theta / 2.0)]])
def ROT_X(theta=0): return qOp([[np.cos(theta / 2.0), -1j * np.sin(theta / 2.0)], [-1j * np.sin(theta / 2.0), np.cos(theta / 2.0)]])
def PHASE(theta=0): return qOp([[1, 0], [0, np.exp(1j * theta)]])
============ Pre-defined ``qOp`` objects are provided implementing the common static gates ``X``, ``Y``, ``Z``, ``I``, ``H``, ``S`` (phase), and ``T`` (pi/8). Parametric gates ================ Common parametric gates (such as rotation operators) are implemented here as functions returning a ``qOp`` object. ''' import numpy as np from pypsqueak.api import qOp # Pauli Gates X = qOp([[0, 1], [1, 0]]) Y = qOp([[0, -1j], [1j, 0]]) Z = qOp([[1, 0], [0, -1]]) I = qOp() # Hadamard gate H = qOp([[1 / np.sqrt(2), ((-1)**i) * 1 / np.sqrt(2)] for i in range(2)]) # PHASE gate def PHASE(theta=0): return qOp([[1, 0], [0, np.exp(1j * theta)]])
# Prep a qReg in the |1> state qubit = qReg() X.on(qubit) # Send it through an amp decay channel with 0.3 chance of decay. if len(sys.argv) > 1 and int(sys.argv[1]) > 0: n_runs = int(sys.argv[1]) else: n_runs = 1000 if len(sys.argv) > 2 and float(sys.argv[2]) >= 0 and float(sys.argv[2]) <= 1: prob = float(sys.argv[2]) else: prob = 0.3 noisy_channel = qOp(kraus_ops=damping_map(prob)) zeros = 0 ones = 0 print("Sending the state |1> through a noisy channel {} times with amplitude decay probability={}...".format(n_runs, prob)) for i in range(n_runs): noisy_channel.on(qubit) result = qubit.measure(0) if result == 0: zeros += 1 # Reset qReg to |1> for next run. X.on(qubit) else: # No need to reset qReg ones += 1
def setUp(self): # Test register and operator self.test_reg = qReg() self.test_op = qOp()
if len(sys.argv) > 1 and int(sys.argv[1]) > 0: n_trials = int(sys.argv[1]) else: n_trials = 2000 if len(sys.argv) > 2 and float(sys.argv[2]) <= 1 and float(sys.argv[2]) >= 0: prob = float(sys.argv[2]) else: prob = 0.1 theory_success = (1 - prob)**3 + 3 * prob * (1 - prob)**2 theory_failure = 1 - theory_success successes = 0 failures = 0 noisy_channel = qOp(np.eye(2), kraus_ops=b_flip_map(prob)) # Check that we are getting the correct statistics out of our noisy channel. print("Initialized noisy channel with {:.1f}% chance of bit flip.".format( 100 * prob)) print("Probing channel with single qubit {} times...".format(n_trials)) flip_amount = 0 for i in range(n_trials): register = qReg() noisy_channel.on(register) if not np.array_equal([1, 0], register.dump_state()): flip_amount += 1 flip_percent = 100 * flip_amount / n_trials print("Bit flip occured ({:.1f} +/- {:.1f})% of the time.\n".format( flip_percent, 0.5 * flip_percent / np.sqrt(n_trials)))