コード例 #1
0
def run_inv(a=11, b=1, param="simulation"):
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(modules=[projectq.libs.math,
                                             projectq.setups.decompositions])
    compilerengines = [AutoReplacer(rule_set),
                       TagRemover(),
                       LocalOptimizer(3),
                       AutoReplacer(rule_set),
                       TagRemover(),
                       LocalOptimizer(3),
                       resource_counter]

    # create a main compiler engine
    a1 = a
    b1 = b
    if a == 0:
        a1 = 1
    if b == 0:
        b1 = 1
    n = max(int(math.log(a1, 2)), int(math.log(b1, 2))) + 1

    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)
        xa = initialisation_n(eng2, a, n + 1)
        xb = initialisation_n(eng2, b, n + 1)
        # b --> phi(b)
        QFT | xb
        phi_adder(eng2, xa, xb)
        with Dagger(eng2):
            QFT | xb
        All(Measure) | xa
        All(Measure) | xb
        eng2.flush()
        print(drawing_engine.get_latex())
    else:
        eng = MainEngine(Simulator(), compilerengines)
        xa = initialisation_n(eng, a, n + 1)
        xb = initialisation_n(eng, b, n + 1)
        # b --> phi(b)
        QFT | xb
        with Dagger(eng):
            phi_adder(eng, xa, xb)
        with Dagger(eng):
            QFT | xb
        All(Measure) | xa
        All(Measure) | xb
        eng.flush()
        n = n+1
        measurements_a = [0] * n
        measurements_b = [0] * n
        for k in range(n):
            measurements_a[k] = int(xa[k])
            measurements_b[k] = int(xb[k])

        return [measurements_a, meas2int(measurements_b), measurements_b]
コード例 #2
0
def ExecuteTeleport(eng, state_creation_function, verbose=False):

    b1, b2 = GetBellPair(eng)

    psi = eng.allocate_qubit()
    if verbose:
        print("Alice : state creation")
    state_creation_function(eng, psi)

    CNOT | (psi, b1)
    if verbose:
        print("Alice : entangled qubit")

    H | psi
    Measure | psi
    Measure | b1
    messageToBob = [int(psi), int(b1)]
    if verbose:
        print("Alice : message {} : Bob.".format(messageToBob))

    with Control(eng, b1):
        X | b2
    with Control(eng, psi):
        Z | b2

    if verbose:
        print("Bob is trying to uncompute the state.")
    with Dagger(eng):
        state_creation_function(eng, b2)

    del b2
    eng.flush()

    if verbose:
        print("Bob successfully arrived at |0>")
コード例 #3
0
def _decompose_QAA(cmd):
    """ Decompose the Quantum Amplitude Apmplification algorithm as a gate. """
    eng = cmd.engine

    # System-qubit is the first qubit/qureg. Ancilla qubit is the second qubit
    system_qubits = cmd.qubits[0]
    qaa_ancilla = cmd.qubits[1]

    # The Oracle and the Algorithm
    Oracle = cmd.gate.oracle
    A = cmd.gate.algorithm

    # Apply the oracle to invert the amplitude of the good states, S_Chi
    Oracle(eng, system_qubits, qaa_ancilla)

    # Apply the inversion of the Algorithm,
    # the inversion of the aplitude of |0> and the Algorithm

    with Compute(eng):
        with Dagger(eng):
            A(eng, system_qubits)
        All(X) | system_qubits
    with Control(eng, system_qubits[0:-1]):
        Z | system_qubits[-1]
    with CustomUncompute(eng):
        All(X) | system_qubits
        A(eng, system_qubits)
    Ph(math.pi) | system_qubits[0]
コード例 #4
0
def adder(eng, xa, xb):

    # On passe de a a phi(a) : QTF
    """
    n = xa.__len__()
    for i in range(n):
        N = n - i - 1
        H | xa[N]
        for k in range(2, N + 2):
            with Control(eng, xa[N-k+1]):
                R((2*math.pi) / (1 << k)) | xa[N]
    """
    QFT | xa
    eng.flush()
    inv_phi_adder(eng, xb, xa)
    eng.flush()
    """
    # add b ->
    for i in range(n):
        N = n - i - 1
        for k in range(1, N+2):
            with Control(eng, xb[N-k+1]):
                R((2*math.pi) / (1 << k)) | xa[N]
    """
    with Dagger(eng):
        QFT | xa
    """
コード例 #5
0
def lcu_oaa(eng,
            list_of_unitaries,
            coefts,
            ctrl,
            sys,
            ctrl_dim,
            sys_dim,
            rounds=1):
    phi = -1 * math.pi
    for i in range(0, rounds):
        cond_phase(eng, ctrl, sys, phi)
        with Dagger(eng):
            lcu_basic(eng, list_of_unitaries, coefts, ctrl, sys, ctrl_dim,
                      sys_dim)
        size = pow(2, ctrl_dim)
        for l in range(1, size):  # -R flips sign of everything except 00..0
            temp = np.binary_repr(i)
            temp = temp.zfill(ctrl_dim)  # pad with zeros for fixed length bin
        with Compute(eng):
            for j in range(0, ctrl_dim):
                if (int(temp[j]) == 0):
                    X | ctrl[j]
        with Control(eng, ctrl):
            Ph(phi) | sys[0]  # flip sign using any one sys qubit
        Uncompute(eng)
        lcu_basic(eng, list_of_unitaries, coefts, ctrl, sys, ctrl_dim, sys_dim)
        print("Amplitudes of ctrl+sys state after {} rounds of OAA:\n".format(
            int(i) + 1))
        print_amplitudes(eng, ctrl + sys, ctrl_dim + sys_dim)
コード例 #6
0
def run_decompose(a=11, param = "draw"):
    if param == "draw":
        drawing_engine = CircuitDrawer()
        eng = MainEngine(drawing_engine)
    else:
        eng = MainEngine()
    [La, n] = int2bit(a)
    xa = eng.allocate_qureg(n)

    # initialisation de a et b
    for i in range(n):
        if La[i]:
            X | xa[i]

    # On passe de a a phi(a) : QTF
    eng.flush()
    qft_decompose(eng, xa)

    eng.flush()
    with Dagger(eng):
        qft_decompose(eng, xa)

    if param != "draw":
        amp_xa = []
        for i in range(1 << n):
            phase_reel = phase(eng.backend.get_amplitude(adapt_binary(bin(i), n), xa)) / (2 * math.pi)
            amp_xa.append(Fraction(phase_reel).limit_denominator(10))
            print(amp_xa)

    All(Measure) | xa
    eng.flush()

    if param == "draw":
        print(drawing_engine.get_latex())
コード例 #7
0
def _decompose_state_preparation(cmd):  # pylint: disable=too-many-locals
    """Implement state preparation based on arXiv:quant-ph/0407010v1."""
    eng = cmd.engine
    if len(cmd.qubits) != 1:
        raise ValueError(
            'StatePreparation does not support multiple quantum registers!')
    num_qubits = len(cmd.qubits[0])
    qureg = cmd.qubits[0]
    final_state = cmd.gate.final_state
    if len(final_state) != 2**num_qubits:
        raise ValueError("Length of final_state is invalid.")
    norm = 0.0
    for amplitude in final_state:
        norm += abs(amplitude)**2
    if norm < 1 - 1e-10 or norm > 1 + 1e-10:
        raise ValueError("final_state is not normalized.")
    with Control(eng, cmd.control_qubits):
        # As in the paper reference, we implement the inverse:
        with Dagger(eng):
            # Cancel all the relative phases
            phase_of_blocks = []
            for amplitude in final_state:
                phase_of_blocks.append(cmath.phase(amplitude))
            for qubit_idx, qubit in enumerate(qureg):
                angles = []
                phase_of_next_blocks = []
                for block in range(2**(len(qureg) - qubit_idx - 1)):
                    phase0 = phase_of_blocks[2 * block]
                    phase1 = phase_of_blocks[2 * block + 1]
                    angles.append(phase0 - phase1)
                    phase_of_next_blocks.append((phase0 + phase1) / 2.0)
                UniformlyControlledRz(angles) | (
                    qureg[(qubit_idx + 1):],  # noqa: E203
                    qubit,
                )
                phase_of_blocks = phase_of_next_blocks
            # Cancel global phase
            Ph(-phase_of_blocks[0]) | qureg[-1]
            # Remove amplitudes from states which contain a bit value 1:
            abs_of_blocks = []
            for amplitude in final_state:
                abs_of_blocks.append(abs(amplitude))
            for qubit_idx, qubit in enumerate(qureg):
                angles = []
                abs_of_next_blocks = []
                for block in range(2**(len(qureg) - qubit_idx - 1)):
                    a0 = abs_of_blocks[2 * block]  # pylint: disable=invalid-name
                    a1 = abs_of_blocks[2 * block + 1]  # pylint: disable=invalid-name
                    if a0 == 0 and a1 == 0:
                        angles.append(0)
                    else:
                        angles.append(-2.0 *
                                      math.acos(a0 / math.sqrt(a0**2 + a1**2)))
                    abs_of_next_blocks.append(math.sqrt(a0**2 + a1**2))
                UniformlyControlledRy(angles) | (
                    qureg[(qubit_idx + 1):],  # noqa: E203
                    qubit,
                )
                abs_of_blocks = abs_of_next_blocks
コード例 #8
0
def run_teleport(eng, state_creation_function, verbose=False):
    """
    Runs quantum teleportation on the provided main compiler engine.

    Creates a state from |0> using the state_creation_function, teleports this
    state to Bob who then tries to uncompute his qubit using the inverse of
    the state_creation_function. If successful, deleting the qubit won't raise
    an error in the underlying Simulator back-end (else it will).

    Args:
        eng (MainEngine): Main compiler engine to run the circuit on.
        state_creation_function (function): Function which accepts the main
            engine and a qubit in state |0>, which it then transforms to the
            state that Alice would like to send to Bob.
        verbose (bool): If True, info messages will be printed.

    """
    # make a Bell-pair
    b1, b2 = create_bell_pair(eng)

    # Alice creates a nice state to send
    psi = eng.allocate_qubit()
    if verbose:
        print("Alice is creating her state from scratch, i.e., |0>.")
    state_creation_function(eng, psi)

    # entangle it with Alice's b1
    CNOT | (psi, b1)
    if verbose:
        print("Alice entangled her qubit with her share of the Bell-pair.")

    # measure two values (once in Hadamard basis) and send the bits to Bob
    H | psi
    Measure | psi
    Measure | b1
    msg_to_bob = [int(psi), int(b1)]
    if verbose:
        print("Alice is sending the message {} to Bob.".format(msg_to_bob))

    # Bob may have to apply up to two operation depending on the message sent
    # by Alice:
    with Control(eng, b1):
        X | b2
    with Control(eng, psi):
        Z | b2

    # try to uncompute the psi state
    if verbose:
        print("Bob is trying to uncompute the state.")
    with Dagger(eng):
        state_creation_function(eng, b2)

    # check whether the uncompute was successful. The simulator only allows to
    # delete qubits which are in a computational basis state.
    del b2
    eng.flush()

    if verbose:
        print("Bob successfully arrived at |0>")
コード例 #9
0
ファイル: multiply.py プロジェクト: Dreamonic/shor-algorithm
def CMultModN(eng, circuit, c, x, qubits, ancilla, a, N):
    n = len(x)
    _CMultModN(eng, circuit, c, x, qubits, ancilla, a, N)
    for i in range(n):
        Swap(eng, circuit, x[i], qubits[i])
    # All(Swap) | zip(x, qubits)
    with Dagger(eng):
        _CMultModN(eng, circuit, c, x, qubits, ancilla, modinv(a, N), N)
コード例 #10
0
ファイル: multiply.py プロジェクト: Dreamonic/shor-algorithm
def CMultModN(eng, circuit, c, x, qubits, ancilla, a, N):
    n = len(x)
    _CMultModN(eng, circuit, c, x, qubits, ancilla, a, N)
    for i in range(n):
        circuit.apply_ld_two_qubit_gate(Swap, x[i], qubits[i])
    # All(Swap) | zip(x, qubits)
    with Dagger(eng):
        _CMultModN(eng, circuit, c, x, qubits, ancilla, modinv(a, N), N)
コード例 #11
0
ファイル: gates.py プロジェクト: Dreamonic/shor-algorithm
def add_inverse(eng, qubits, value):
    """
    The inverse adder gate, which effectively performs a subtraction of the classical value.
    :param eng: The engine used for computations.
    :param qubits: The qubits representing the quantum value (superposition of classical values).
    :param value: The classical value which should be subtracted.
    """
    with Dagger(eng):
        add(eng, qubits, value)
コード例 #12
0
def adder(eng, xa, xb):

    # On passe de a a phi(a) : QTF
    QFT | xa

    phi_adder(eng, xb, xa)

    # On passe de phi(a+b) à a+b QFT^-1
    with Dagger(eng):
        QFT | xa
コード例 #13
0
def _decompose_state_preparation(cmd):
    """
    Implements state preparation based on arXiv:quant-ph/0407010v1.
    """
    eng = cmd.engine
    assert len(cmd.qubits) == 1
    num_qubits = len(cmd.qubits[0])
    qureg = cmd.qubits[0]
    final_state = cmd.gate.final_state
    if len(final_state) != 2**num_qubits:
        raise ValueError("Length of final_state is invalid.")
    norm = 0.
    for amplitude in final_state:
        norm += abs(amplitude)**2
    if norm < 1 - 1e-10 or norm > 1 + 1e-10:
        raise ValueError("final_state is not normalized.")
    with Control(eng, cmd.control_qubits):
        # As in the paper reference, we implement the inverse:
        with Dagger(eng):
            # Cancel all the relative phases
            phase_of_blocks = []
            for amplitude in final_state:
                phase_of_blocks.append(cmath.phase(amplitude))
            for target_qubit in range(len(qureg)):
                angles = []
                phase_of_next_blocks = []
                for block in range(2**(len(qureg) - target_qubit - 1)):
                    phase0 = phase_of_blocks[2 * block]
                    phase1 = phase_of_blocks[2 * block + 1]
                    angles.append(phase0 - phase1)
                    phase_of_next_blocks.append((phase0 + phase1) / 2.)
                UniformlyControlledRz(angles) | (qureg[(target_qubit + 1):],
                                                 qureg[target_qubit])
                phase_of_blocks = phase_of_next_blocks
            # Cancel global phase
            Ph(-phase_of_blocks[0]) | qureg[-1]
            # Remove amplitudes from states which contain a bit value 1:
            abs_of_blocks = []
            for amplitude in final_state:
                abs_of_blocks.append(abs(amplitude))
            for target_qubit in range(len(qureg)):
                angles = []
                abs_of_next_blocks = []
                for block in range(2**(len(qureg) - target_qubit - 1)):
                    a0 = abs_of_blocks[2 * block]
                    a1 = abs_of_blocks[2 * block + 1]
                    if a0 == 0 and a1 == 0:
                        angles.append(0)
                    else:
                        angles.append(-2. *
                                      math.acos(a0 / math.sqrt(a0**2 + a1**2)))
                    abs_of_next_blocks.append(math.sqrt(a0**2 + a1**2))
                UniformlyControlledRy(angles) | (qureg[(target_qubit + 1):],
                                                 qureg[target_qubit])
                abs_of_blocks = abs_of_next_blocks
コード例 #14
0
ファイル: gates.py プロジェクト: Dreamonic/shor-algorithm
def Cadd_inverse(eng, c, qubits, value):
    """
    Similar to the inverse adder gate, which effectively performs a subtraction of the classical value.
    However, this gate is controlled by a qubit c.
    :param eng: The engine used for computations.
    :param c: The qubit control of the gate.
    :param qubits: The qubits representing the quantum value (superposition of classical values).
    :param value: The classical value which should be subtracted.
    """
    with Dagger(eng):
        Cadd(eng, c, qubits, value)
コード例 #15
0
ファイル: qft_tests.py プロジェクト: cjliu20152/qsfe
    def run_iqft_with_waveform_samples(self, number_of_qubits, sample_rate,
                                       correct_frequency, prep_function, prep_args):
        """
        Tests my QFT implementation by comparing it to the classical DFT, ensuring it produces the
        same output as DFT when given the same input (after being normalized for quantum operations).

        Parameters:
            number_of_qubits (int): The size of the processing register to use, in qubits.
                This will be used to represent 2^N samples of the input signal.
            sample_rate (float): The sampling rate used by the prep opration. This is used to
                determine the actual frequency of the measured value once QFT is finished, which can
                vary based on the number of samples and the sample rate.
            correct_frequency (double): The correct answer that QFT should provide after running on
                the prepared input state.
            prep_function (function): The function that prepares the qubit register in the desired
                state for this test.
            prep_args (anything): Arguments to pass to the preparation function.
        """
        
        engine = MainEngine()
        qubits = engine.allocate_qureg(number_of_qubits)

        # Set up the register so it's in the correct state for the test
        if prep_args is None:
            prep_function(qubits)
        else:
            prep_function(qubits, prep_args)

        # Run the inverse QFT, which corresponds to the normal DFT
        with Dagger(engine):
            qft.qft(qubits)

        # Measure the result from QFT
        bitstring = ""
        for qubit in qubits:
            Measure | qubit
            bitstring += str(int(qubit))
        result = int(bitstring, 2)

        # QFT suffers from the same Nyquist-frequency mirroring as DFT, but we can't just
        # look at all of the output details and ignore the mirrored results. If we end up
		# measuring a mirrored result, this will flip it back to the proper result in the
		# 0 < X < N/2 space.
        number_of_states = 2 ** number_of_qubits
        if result > number_of_states / 2:
            result = number_of_states - result

        # Correct for the sample rate.
        total_time = number_of_states / sample_rate
        result = result / total_time

        # Verify we got the right result.
        if result != correct_frequency:
            raise ValueError(f"Expected frequency {correct_frequency} but measured {result}.")
コード例 #16
0
def test_quantummultiplication_size_mismatch_inverse(eng, qubit_idx):
    qureg_a = eng.allocate_qureg(4 if qubit_idx != 0 else 3)
    qureg_b = eng.allocate_qureg(4 if qubit_idx != 1 else 3)
    qureg_c = eng.allocate_qureg(4 if qubit_idx != 2 else 3)

    with pytest.raises(ValueError):
        with Dagger(eng):
            MultiplyQuantum | (qureg_a, qureg_b, qureg_c)

    All(Measure) | qureg_a
    All(Measure) | qureg_b
    All(Measure) | qureg_c
コード例 #17
0
ファイル: entanglement.py プロジェクト: cjliu20152/qsfe
    def phase_flip_function(self, qubits):
        """
        Flips the first of the provided qubits indirectly via entanglement.

        Parameters:
            qubits (Qureg): The qubit register being tested
        """

        self.create_ghz_state(qubits)
        Z | qubits[1]
        with Dagger(qubits.engine):     # This is how ProjectQ does adjoint code.
            self.create_ghz_state(qubits)
コード例 #18
0
def test_quantum_conditional_add_carry_size_mismatch(eng, qubit_idx, inverse):
    qureg_a = eng.allocate_qureg(4 if qubit_idx != 0 else 3)
    qureg_b = eng.allocate_qureg(4 if qubit_idx != 1 else 3)
    qureg_c = eng.allocate_qureg(2 if qubit_idx != 2 else 3)
    control = eng.allocate_qureg(1 if qubit_idx != 3 else 2)

    with pytest.raises(ValueError):
        with Control(eng, control):
            if inverse:
                with Dagger(eng):
                    AddQuantum | (qureg_a, qureg_b, qureg_c)
            else:
                AddQuantum | (qureg_a, qureg_b, qureg_c)
コード例 #19
0
    def run_test(self, description, iterations, prep_function):
        """
        Runs a unit test of the teleportation protocol with the provided state preparation function.

        Parameters:
            description (str): A description of the test, for logging.
            iterations (int): The number of times to run the program.
            prep_function (function): The function that can prepare (and un-prepare) the desired state
                to be teleported.
        """
        
        print(f"Running test: {description}")
        
        engine = MainEngine()
        original_qubit = engine.allocate_qubit()
        transfer_qubit = engine.allocate_qubit()
        reproduction_qubit = engine.allocate_qubit()

        # Try teleportation using all 4 of the Bell states for the entangled transfer qubit pair
        for entanglement_state in range(0, 4):
            for i in range(0, iterations):

                # Prepare the original qubit in the desired state, and the transfer qubits that will be used to teleport it
                prep_function(original_qubit)
                self.prepare_transfer_qubits(entanglement_state, transfer_qubit, reproduction_qubit)

                # Teleport the original qubit, turning the remote reproduction qubit's state into the original state 
                (original_measurement, transfer_measurement) = self.measure_message_parameters(original_qubit, transfer_qubit)
                self.reproduce_original(entanglement_state, original_measurement, transfer_measurement, reproduction_qubit)

                # Run the adjoint preparation function on the reproduction qubit, and measure it.
                # If it is now in the original state, this should turn it back into |0> every time.
                with Dagger(engine):
                    prep_function(reproduction_qubit)
                    
                # Make sure the result qubit is 0
                Measure | reproduction_qubit

                if int(reproduction_qubit) != 0:
                    self.fail(f"Test {description} failed with entanglement state {entanglement_state}. " +
                            f"Resulting state {result} had a 1 for the result, which means " +
                            "the qubit wasn't teleported properly.")

                reset([original_qubit, transfer_qubit, reproduction_qubit])
                engine.flush()

            print(f"Entanglement state {entanglement_state} passed.");
        
        print("Passed!")
        print()
コード例 #20
0
def inv_cMultModN_non_Dagger(eng, a, xb, xx, xN, aux, xc, N):
    """
    |b> --> |b+(ax) mod N> if xc=1; else |b> -> |b>
    :param eng:
    :param a:
    :param xc: control bit
    :param aux: auxiliary
    :param xx: multiplier
    :param xb: modified qubit
    :param xN: Mod
    :return:
    """
    # b-->phi(b)
    QFT | xb
    n = len(xx) - 1
    for i in range(n - 1, -1, -1):
        xa = initialisation_n(eng, ((2**i) * a) % N,
                              n + 1)  # both input of modularAdder must be <N
        # TODO define xa in a iterative way just by adding a new qubit 0 as LSB
        with Dagger(eng):
            modularAdder(eng, xa, xb, xN, xx[i], xc, aux)
    with Dagger(eng):
        QFT | xb
コード例 #21
0
def run_shor(eng, N, a, verbose=False):
    """
    Runs the quantum subroutine of Shor's algorithm for factoring. with 2n control qubits

    Args:
        eng (MainEngine): Main compiler engine to use.
        N (int): Number to factor.
        a (int): Relative prime to use as a base for a^x mod N.
        verbose (bool): If True, display intermediate measurement results.

    Returns:
        r (float): Potential period of a.
    """
    n = int(math.ceil(math.log(N, 2)))

    x = eng.allocate_qureg(n)
    xN = initialisation_n(eng, N, n)
    xb = initialisation_n(eng, 0, n)
    aux = initialisation_n(eng, 0, 1)
    X | x[0]  # set x to 1

    measurements = [0] * (2 * n)  # will hold the 2n measurement results

    ctrl_qubit = eng.allocate_qureg(2 * n)

    for k in range(2 * n):
        current_a = pow(a, 1 << k, N)
        # one iteration of 1-qubit QPE
        H | ctrl_qubit[k]
        gateUa(eng, current_a, mod_inv(current_a, N), x, xb, xN, aux,
               ctrl_qubit[k], N)

    with Dagger(eng):
        QFT | ctrl_qubit

    # and measure
    All(Measure) | ctrl_qubit
    eng.flush()
    for k in range(2 * n):
        measurements[k] = int(ctrl_qubit[k])

    All(Measure) | x
    # turn the measured values into a number in [0,1)
    y = sum([(measurements[i] * 1. / (1 << (i + 1))) for i in range(2 * n)])

    # continued fraction expansion to get denominator (the period?)
    r = Fraction(y).limit_denominator(N - 1).denominator

    # return the (potential) period
    return r
コード例 #22
0
def test_quantumadder_size_mismatch(eng, qubit_idx, inverse, carry):
    qureg_a = eng.allocate_qureg(4 if qubit_idx != 0 else 3)
    qureg_b = eng.allocate_qureg(4 if qubit_idx != 1 else 3)
    qureg_c = eng.allocate_qureg(1 if qubit_idx != 2 else 2)

    if carry and inverse:
        pytest.skip('Inverse addition with carry not supported')
    elif not carry and qubit_idx == 2:
        pytest.skip('Invalid test parameter combination')

    with pytest.raises(ValueError):
        if inverse:
            with Dagger(eng):
                AddQuantum | (qureg_a, qureg_b, qureg_c if carry else [])
        else:
            AddQuantum | (qureg_a, qureg_b, qureg_c if carry else [])
コード例 #23
0
ファイル: teleport_mpi.py プロジェクト: i2000s/HiQsimulator-1
def run_teleport(eng, state_creation_function):
    """
    Runs quantum teleportation on the provided main compiler engine.
    Args:
        eng (MainEngine): Main compiler engine to run the circuit on.
        state_creation_function (function): Function which accepts the main
            engine and a qubit in state |0>, which it then transforms to the
            state that Alice would like to send to Bob.
    """
    # make a Bell-pair
    b1, b2 = _create_bell_pair(eng)

    # Alice creates a nice state to send
    psi = eng.allocate_qubit()
    print("= Step 1. Alice creates the state to be sent from |0>")
    state_creation_function(eng, psi)

    # entangle it with Alice's b1
    CNOT | (psi, b1)
    print("= Step 2. Alice entangles the state with her share of the Bell-pair")

    # measure two values (once in Hadamard basis) and send the bits to Bob
    H | psi
    Measure | psi
    Measure | b1
    msg_to_bob = [int(psi), int(b1)]
    print("= Step 3. Alice sends the classical message {} to Bob".format(msg_to_bob))

    # Bob may have to apply up to two operation depending on the message sent
    # by Alice:
    with Control(eng, b1):
        X | b2
    with Control(eng, psi):
        Z | b2

    # try to uncompute the psi state
    print("= Step 4. Bob tries to recover the state created by Alice")
    with Dagger(eng):
        state_creation_function(eng, b2)

    # check whether the uncompute was successful. The simulator only allows to
    # delete qubits which are in a computational basis state.
    del b2
    eng.flush()

    print("\t Bob successfully arrived at |0>")
コード例 #24
0
ファイル: gates.py プロジェクト: Dreamonic/shor-algorithm
def CMultModN(eng, c, x, qubits, ancilla, a, N):
    """
    This gate performs the operation (ax)mod(N), where x is stored in the qubits and a is a classical value.
    This gate also has a control.
    :param eng: The engine used for computations.
    :param c: A qubit control of the gate.
    :param qubits: The qubits representing the quantum value (superposition of classical values).
    :param ancilla: This is needed to check for overflows.
    :param a: The classical value 'a' which is used in (a + b)mod(N).
    :param N: The number to be factored into primes.
    """
    n = len(x)
    _CMultModN(eng, c, x, qubits, ancilla, a, N)
    for i in range(n):
        Swap | (x[i], qubits[i])
    # All(Swap) | zip(x, qubits)
    with Dagger(eng):
        _CMultModN(eng, c, x, qubits, ancilla, modinv(a, N), N)
コード例 #25
0
def lcu_fpoaa(eng, list_of_unitaries, coefts, ctrl, sys, ctrl_dim, sys_dim,
              depth):
    phi = math.pi / 3.0
    gate_seq = fpoaa_string(depth)
    t = len(gate_seq)
    # the rightmost operator is always W
    # which has already been applied above in the lcu step
    for i in range(1, t):
        if (gate_seq[t - 1 - i] == 'W'):
            lcu_basic(eng, list_of_unitaries, coefts, ctrl, sys, ctrl_dim,
                      sys_dim)
        elif (gate_seq[t - 1 - i] == 'M'):
            with Dagger(eng):
                lcu_basic(eng, list_of_unitaries, coefts, ctrl, sys, ctrl_dim,
                          sys_dim)
        elif (gate_seq[t - 1 - i] == 'R'):
            cond_phase(eng, ctrl, sys, phi)
        elif (gate_seq[t - 1 - i] == 'S'):
            cond_phase(eng, ctrl, sys, -1 * phi)
コード例 #26
0
def run_teleport(eng, state_creation_function, verbose=False):
    # make a Bell-pair
    b1, b2 = create_bell_pair(eng)

    # Alice creates a nice state to send
    psi = eng.allocate_qubit()
    if verbose:
        print("Alice is creating her state from scratch, i.e., |0>.")
    state_creation_function(eng, psi)

    # entangle it with Alice's b1
    CNOT | (psi, b1)
    if verbose:
        print("Alice entangled her qubit with her share of the Bell-pair.")

    # measure two values (once in Hadamard basis) and send the bits to Bob
    H | psi
    Measure | psi
    Measure | b1
    msg_to_bob = [int(psi), int(b1)]
    if verbose:
        print("Alice is sending the message {} to Bob.".format(msg_to_bob))

    # Bob may have to apply up to two operation depending on the message sent
    # by Alice:
    with Control(eng, b1):
        X | b2
    with Control(eng, psi):
        Z | b2

    # try to uncompute the psi state
    if verbose:
        print("Bob is trying to uncompute the state.")
    with Dagger(eng):
        state_creation_function(eng, b2)

    # check whether the uncompute was successful. The simulator only allows to
    # delete qubits which are in a computational basis state.
    del b2
    eng.flush()

    if verbose:
        print("Bob successfully arrived at |0>")
コード例 #27
0
def W(eng, individual_terms, initial_wavefunction, ancilla_qubits,
      system_qubits):
    """
    Applies the W operator as defined in arXiv:1711.11025.

    Args:
        eng(MainEngine): compiler engine
        individual_terms(list<QubitOperator>): list of individual unitary
                                               QubitOperators. It applies
                                               individual_terms[0] if ancilla
                                               qubits are in state |0> where
                                               ancilla_qubits[0] is the least
                                               significant bit.
        initial_wavefunction: Initial wavefunction of the ancilla qubits
        ancilla_qubits(Qureg): ancilla quantum register in state |0>
        system_qubits(Qureg): system quantum register
    """
    # Apply V:
    for ancilla_state in range(len(individual_terms)):
        with Compute(eng):
            for bit_pos in range(len(ancilla_qubits)):
                if not (ancilla_state >> bit_pos) & 1:
                    X | ancilla_qubits[bit_pos]
        with Control(eng, ancilla_qubits):
            individual_terms[ancilla_state] | system_qubits
        Uncompute(eng)
    # Apply S: 1) Apply B^dagger
    with Compute(eng):
        with Dagger(eng):
            StatePreparation(initial_wavefunction) | ancilla_qubits
    # Apply S: 2) Apply I-2|0><0|
    with Compute(eng):
        All(X) | ancilla_qubits
    with Control(eng, ancilla_qubits[:-1]):
        Z | ancilla_qubits[-1]
    Uncompute(eng)
    # Apply S: 3) Apply B
    Uncompute(eng)
    # Could also be omitted and added when calculating the eigenvalues:
    Ph(math.pi) | system_qubits[0]
コード例 #28
0
def test_simulator_kqubit_gate(sim):
    m1 = Rx(0.3).matrix
    m2 = Rx(0.8).matrix
    m3 = Ry(0.1).matrix
    m4 = Rz(0.9).matrix.dot(Ry(-0.1).matrix)
    m = numpy.kron(m4, numpy.kron(m3, numpy.kron(m2, m1)))

    class KQubitGate(BasicGate):
        @property
        def matrix(self):
            return m

    eng = HiQMainEngine(sim, [GreedyScheduler()])
    qureg = eng.allocate_qureg(4)
    qubit = eng.allocate_qubit()
    Rx(-0.3) | qureg[0]
    Rx(-0.8) | qureg[1]
    Ry(-0.1) | qureg[2]
    Rz(-0.9) | qureg[3]
    Ry(0.1) | qureg[3]
    X | qubit
    with Control(eng, qubit):
        KQubitGate() | qureg
    X | qubit
    with Control(eng, qubit):
        with Dagger(eng):
            KQubitGate() | qureg
    assert sim.get_amplitude('0' * 5, qubit + qureg) == pytest.approx(1.)

    class LargerGate(BasicGate):
        @property
        def matrix(self):
            return numpy.eye(2**6)

    with pytest.raises(Exception):
        LargerGate() | (qureg + qubit)
        eng.flush()
コード例 #29
0
def run_teleport(eng, state_creation_function, verbose=False):
    b1, b2 = create_bell_pair(eng)

    psi = eng.allocate_qubit()
    if verbose:
        print("Alice is creating her state from scratch, i.e., |0>.")
    state_creation_function(eng, psi)

    CNOT | (psi, b1)
    if verbose:
        print("Alice entangled her qubit with her share of the Bell-pair.")

    H | psi
    Measure | psi
    Measure | b1

    msg_to_bob = [int(psi), int(b1)]
    if verbose:
        print("Alice is sending the message {} to Bob.".format(msg_to_bob))

    with Control(eng, b1):
        X | b2

    with Control(eng, psi):
        Z | b2

    if verbose:
        print("Bob is trying to uncompute the state.")
    with Dagger(eng):
        state_creation_function(eng, b2)

    del b2
    eng.flush()

    if verbose:
        print("Bob successfully arrived at |0>")
コード例 #30
0
def CCadd_inverse(eng, circuit, c1, c2, qubits, value):
    with Dagger(eng):
        CCadd(eng, circuit, c1, c2, qubits, value)