Exemple #1
0
    def test_known_operation_results(self):
        '''
        Verifies the resulting state of several operations.
        '''

        test_results = []
        # Takes |0> to |1>
        some_reg = qReg()
        X.on(some_reg)
        test_results.append(some_reg.dump_state())

        # Takes |0> to |0001>
        some_reg = qReg()
        X.on(some_reg)
        I.on(some_reg, 3)
        test_results.append(some_reg.dump_state())

        # Takes |0> to (1/sqrt(2))(|000> - |100>)
        some_reg = qReg()
        X.on(some_reg, 2)
        H.on(some_reg, 2)
        test_results.append(some_reg.dump_state())

        expected_results = [
            np.array([0, 1]),
            np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
            1 / np.sqrt(2) * np.array([1, 0, 0, 0, -1, 0, 0, 0])
        ]

        for test_pair in zip(test_results, expected_results):
            np.testing.assert_array_almost_equal(test_pair[0], test_pair[1])
Exemple #2
0
    def test_operator_overloading_imul_dereferences_arg(self):
        '''
        Checks that `*=` dereferences the right hand operand.
        '''

        q = qReg()
        p = qReg()

        q *= p

        self.assertTrue(p._qReg__is_dereferenced)
        self.assertFalse(q._qReg__is_dereferenced)
Exemple #3
0
    def test_operator_overloading_imul_on_dereferenced_args_fails(self):
        '''
        Checks that `*=` fails when either involved register is dereferenced.
        '''

        q = qReg()
        p = qReg()
        q *= p
        r = qReg()

        self.assertRaises(IllegalRegisterReference, q.__imul__, p)
        self.assertRaises(IllegalRegisterReference, p.__imul__, r)
Exemple #4
0
    def test_mult_checks_both_regs_for_dereference(self):
        '''
        Verifies that multiplication checks whether both argument registers are
        dereferenced.
        '''

        a = qReg()
        b = a * qReg()

        self.assertRaises(IllegalRegisterReference, a.__mul__, b)
        self.assertRaises(IllegalRegisterReference, b.__mul__, a)
        self.assertRaises(IllegalRegisterReference, a.__imul__, b)
        self.assertRaises(IllegalRegisterReference, b.__imul__, a)
def deutschJozsa(input_register, black_box):
    # Take |input_reg> to |input_reg>|1>
    input_register *= qReg()
    X.on(input_register, 0)

    # Prep qubits 1 to n in the Hadamard state.
    for i in range(1, n + 1):
        H.on(input_register, i)

    # Flip the answer qubit and apply H.
    H.on(input_register, 0)

    # Query the oracle.
    black_box.on(input_register, *list(range(n + 1)))

    # Apply H to the qubits 1 through n.
    for i in range(1, n + 1):
        H.on(input_register, i)

    # Measure the first n qubits. If the any of the results
    # are nonzero, the oracle is balanced. Else, it is constant.
    results = []
    for i in range(1, n + 1):
        results.append(input_register.measure(i))

    return results
Exemple #6
0
    def test_measurement_on_five_qubit_state(self):
        register = qReg(5)
        X.on(register, 3)
        X.on(register, 0)
        H.on(register, 1)

        self.assertEqual(register.measure(3), 1)
        self.assertEqual(register.measure(4), 0)
Exemple #7
0
    def test_operator_overloading_imul_fails_for_non_qreg_arg(self):
        '''
        Checks that `*=` throws a TypeError when the right hand operand is
        not a `qReg`.
        '''

        q = qReg()
        self.assertRaises(TypeError, q.__imul__, 4)
Exemple #8
0
    def test_operator_overloading_iadd(self):
        '''
        Tests that `+=` adds one or more qubits to register.
        '''

        q = qReg()
        q += 3

        self.assertEqual(4, len(q))
Exemple #9
0
    def test_operator_overloading_iadd_fails_for_negative_arg(self):
        '''
        Checks that a ValueError is throws for negative right hand operand to
        `+=`.
        '''

        q = qReg()

        self.assertRaises(ValueError, q.__iadd__, -2)
Exemple #10
0
    def test_operator_overloading_iadd_fails_for_nonint(self):
        '''
        Checks that a ValueError is thrown for noninteger right hand operand
        to `+=`.
        '''

        q = qReg()

        self.assertRaises(ValueError, q.__iadd__, 3.2)
Exemple #11
0
    def test_apply_noisy_gate(self):
        '''
        Deterministic verification of application of gate with
        some NoiseModel set (using prob 1 amplitude damping).
        '''

        registerInZeroStateInitially = qReg()
        registerInOneStateInitially = qReg()
        X.on(registerInOneStateInitially)

        self.test_op.set_noise_model(damping_map(1.0))
        self.test_op.on(registerInZeroStateInitially)
        self.test_op.on(registerInOneStateInitially)

        np.testing.assert_array_equal(
            registerInZeroStateInitially.dump_state(), [1, 0])
        np.testing.assert_array_equal(registerInOneStateInitially.dump_state(),
                                      [1, 0])
Exemple #12
0
    def test_qOpFailsWhenAppliedToDereferencedqReg(self):
        '''
        ``IllegalRegisterReference`` is raised when attempting to operate on a
        ``qReg``.
        '''

        q_reg = qReg()
        q_reg._qReg__is_dereferenced = True

        self.assertRaises(IllegalRegisterReference, self.test_op.on, q_reg)
Exemple #13
0
    def test_operator_overloading_misc(self):
        '''
        Tests that several operator overloading methods behave correctly
        for ``qReg`` objects.
        '''

        temp_reg = qReg()
        X.on(temp_reg)
        temp_reg += 1
        self.test_reg *= temp_reg
        state_001 = np.array([0, 1, 0, 0, 0, 0, 0, 0])
        np.testing.assert_array_equal(state_001, self.test_reg.dump_state())

        temp_reg = qReg()
        X.on(temp_reg)
        a_new_reg = self.test_reg * temp_reg
        state_0011 = np.zeros(16)
        state_0011[3] = 1
        np.testing.assert_array_equal(state_0011, a_new_reg.dump_state())
Exemple #14
0
    def test_identity_swap_for_no_targets(self):
        '''
        Verifies that the private ``qOp.__generate_swap()`` retuns identity matrices as
        permutation operators when no nargets are specified.
        '''

        two_qubits = qReg(2)
        permutation, inverse = CNOT._qOp__generate_swap(two_qubits)

        np.testing.assert_array_equal(np.eye(4, 4), permutation)
        np.testing.assert_array_equal(np.eye(4, 4), inverse)
Exemple #15
0
    def test_swap_non_int_input(self):
        '''
        The private ``qOp.__generate_swap()`` method must fail if any of the
        targets are not nonnegative integers.
        '''

        some_reg = qReg()
        some_reg += 3

        self.assertRaises(IndexError, self.test_op._qOp__generate_swap,
                          some_reg, 0, 0.1)
        self.assertRaises(IndexError, self.test_op._qOp__generate_swap,
                          some_reg, 2, 0, -1)
Exemple #16
0
    def test__generateStateTransitionProbabilities(self):
        '''
        Checks that a ``NonUnitaryInputError`` is thrown for nonunitary
        arguments.
        '''
        nonUnitaryMatrix = np.eye(4)
        nonUnitaryMatrix[0, 0] = 0

        twoQubitRegister = qReg(2)

        self.assertRaises(
            NonUnitaryInputError,
            twoQubitRegister._generateStateTransitionProbabilities,
            nonUnitaryMatrix)
Exemple #17
0
    def test_apply_noisy_gate_with_raised_register(self):
        '''
        Deterministic verification of application of gate with
        some NoiseModel set (using prob 1 amplitude damping) where
        qReg needs to be raised.
        '''

        singleQubitInOneStateInitialy = qReg()
        X.on(singleQubitInOneStateInitialy)

        self.test_op.set_noise_model(damping_map(1.0))
        self.test_op.on(singleQubitInOneStateInitialy, 1)

        np.testing.assert_array_equal(
            singleQubitInOneStateInitialy.dump_state(), [0, 1, 0, 0])
Exemple #18
0
    def test_register_dereferencing(self):
        '''
        Verifies that ``qReg`` instances get dereferenced in cases where
        the no-cloning theorem would be violated.
        '''

        # Multiplication operation dereferences register.
        a = qReg()
        X.on(a)
        b = qReg()
        c = a * b
        d = qReg()
        d *= c
        state_010 = np.zeros(8)
        state_010[2] = 1

        # a, b, and c should all be dereferenced. D should be in |0010>
        np.testing.assert_array_equal(state_010, d.dump_state())

        deref = [a, b, c]
        for register in deref:

            # Checks that the dereferenced register is fully dead (i.e. all
            # methods called with or on it raise an exception.
            self.assertRaises(IllegalRegisterReference, register.measure, 0)
            self.assertRaises(IllegalRegisterReference,
                              register.measure_observable, Z)
            self.assertRaises(IllegalRegisterReference, register.peek)
            self.assertRaises(IllegalRegisterReference, register.dump_state)
            self.assertRaises(IllegalRegisterReference, register.__iadd__, 1)
            self.assertRaises(IllegalRegisterReference, register.__mul__,
                              qReg())
            self.assertRaises(IllegalRegisterReference, register.__imul__,
                              qReg())
            self.assertRaises(IllegalRegisterReference, len, register)
            self.assertRaises(IllegalRegisterReference, X.on, register, 0)
Exemple #19
0
    def test_measurement_collapses_register_state(self):
        '''
        Check that a ``qReg`` in the normalized version of the state
        |00> + |10> correctly collapses on measurement of qubit 0 to either
        |00> or |10>.
        '''
        initiallySuperposedRegister = qReg(2)
        H.on(initiallySuperposedRegister, 1)
        measurement_outcome = initiallySuperposedRegister.measure(1)

        if measurement_outcome == 0:
            np.testing.assert_array_equal(
                initiallySuperposedRegister.dump_state(), [1, 0, 0, 0])
        else:
            np.testing.assert_array_equal(
                initiallySuperposedRegister.dump_state(), [0, 0, 1, 0])
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)))

print("With bit flip probability of {:.1f}%:".format(100 * prob))
print("Theoretical transmission success rate: {:.1f}%".format(100 *
                                                              theory_success))
print("Theoretical transmission failure rate: {:.1f}%\n".format(
    100 * theory_failure))

# Now we send an encoded state through our noisy channel n_trials times.
    # are nonzero, the oracle is balanced. Else, it is constant.
    results = []
    for i in range(1, n + 1):
        results.append(input_register.measure(i))

    return results


# Let's try this out a whole bunch of times!
if len(sys.argv) > 1 and int(sys.argv[1]) > 0:
    n_tries = int(sys.argv[1])
else:
    n_tries = 10

zeros = 0
ones = 0

print("Conducting {} trials...".format(n_tries))

for i in range(n_tries):
    input_register = qReg(n)
    oracle_list = make_black_box()
    black_box = qOracle(lambda i: oracle_list[i], n)
    results = deutschJozsa(input_register, black_box)
    if any(results):
        ones += 1
    else:
        zeros += 1
print("Number of zero measurements (constant oracle): {}".format(zeros))
print("Number of one measurements (balanced oracle): {}".format(ones))
Exemple #22
0
import context  # Remove this import if running with pip installed version.

import numpy as np
from pypsqueak.api import qReg, qOp
from pypsqueak.gates import X, I
from pypsqueak.noise import damping_map
import sys

# 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)
Exemple #23
0
 def setUp(self):
     # Test register and operator
     self.test_reg = qReg()
     self.test_op = qOp()