コード例 #1
0
def test_openqasm_test_qasm_single_qubit_gates_controls():
    backend = OpenQASMEngine()
    eng = MainEngine(backend=backend, engine_list=[], verbose=True)
    qubit = eng.allocate_qubit()
    ctrls = eng.allocate_qureg(2)

    with Control(eng, ctrls):
        X | qubit
        NOT | qubit
    eng.flush()

    qasm = [l for l in backend.circuit.qasm().split('\n')[2:] if l]

    assert qasm == [
        'qreg q0[1];',
        'qreg q1[1];',
        'qreg q2[1];',
        'creg c0[1];',
        'creg c1[1];',
        'creg c2[1];',
        'ccx q1[0],q2[0],q0[0];',
        'ccx q1[0],q2[0],q0[0];',
    ]

    with pytest.raises(RuntimeError):
        with Control(eng, ctrls):
            Y | qubit
        eng.flush()
コード例 #2
0
ファイル: time_evolution.py プロジェクト: willyxq/ProjectQ
def _decompose_time_evolution_individual_terms(cmd):
    """
    Implements a TimeEvolution gate with a hamiltonian having only one term.

    To implement exp(-i * t * hamiltonian), where the hamiltonian is only one
    term, e.g., hamiltonian = X0 x Y1 X Z2, we first perform local
    transformations to in order that all Pauli operators in the hamiltonian
    are Z. We then implement  exp(-i * t * (Z1 x Z2 x Z3) and transform the
    basis back to the original. For more details see, e.g.,

    James D. Whitfield, Jacob Biamonte & Aspuru-Guzik
    Simulation of electronic structure Hamiltonians using quantum computers,
    Molecular Physics, 109:5, 735-750 (2011).

    or

    Nielsen and Chuang, Quantum Computation and Information.
    """
    assert len(cmd.qubits) == 1
    qureg = cmd.qubits[0]
    eng = cmd.engine
    time = cmd.gate.time
    hamiltonian = cmd.gate.hamiltonian
    assert len(hamiltonian.terms) == 1
    term = list(hamiltonian.terms)[0]
    coefficient = hamiltonian.terms[term]
    check_indices = set()

    # Check that hamiltonian is not identity term,
    # Previous or operator should have apply a global phase instead:
    assert not term == ()

    # hamiltonian has only a single local operator
    if len(term) == 1:
        with Control(eng, cmd.control_qubits):
            if term[0][1] == 'X':
                Rx(time * coefficient * 2.) | qureg[term[0][0]]
            elif term[0][1] == 'Y':
                Ry(time * coefficient * 2.) | qureg[term[0][0]]
            else:
                Rz(time * coefficient * 2.) | qureg[term[0][0]]
    # hamiltonian has more than one local operator
    else:
        with Control(eng, cmd.control_qubits):
            with Compute(eng):
                # Apply local basis rotations
                for index, action in term:
                    check_indices.add(index)
                    if action == 'X':
                        H | qureg[index]
                    elif action == 'Y':
                        Rx(math.pi / 2.) | qureg[index]
                # Check that qureg had exactly as many qubits as indices:
                assert check_indices == set((range(len(qureg))))
                # Compute parity
                for i in range(len(qureg) - 1):
                    CNOT | (qureg[i], qureg[i + 1])
            Rz(time * coefficient * 2.) | qureg[-1]
            # Uncompute parity and basis change
            Uncompute(eng)
コード例 #3
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>")
コード例 #4
0
def complex_algorithm(eng, qreg):
    All(H) | qreg
    with Control(eng, qreg[0]):
        All(X) | qreg[1:]
    All(Ry(math.pi / 4)) | qreg[1:]
    with Control(eng, qreg[-1]):
        All(X) | qreg[1:-1]
コード例 #5
0
def _decompose_QPE(cmd):  # pylint: disable=invalid-name
    """Decompose the Quantum Phase Estimation gate."""
    eng = cmd.engine

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

    # Hadamard on the ancillas
    Tensor(H) | qpe_ancillas

    # The Unitary Operator
    unitary = cmd.gate.unitary

    # Control U on the system_qubits
    if callable(unitary):
        # If U is a function
        for i, ancilla in enumerate(qpe_ancillas):
            with Control(eng, ancilla):
                unitary(system_qubits, time=2**i)
    else:
        for i, ancilla in enumerate(qpe_ancillas):
            ipower = int(2**i)
            with Loop(eng, ipower):
                with Control(eng, ancilla):
                    unitary | system_qubits

    # Inverse QFT on the ancillas
    get_inverse(QFT) | qpe_ancillas
コード例 #6
0
def lcu_controlled_unitary(eng, list_of_U, coefts, ctrl, sys, sys_dim):
    size = len(list_of_U)
    if not size:
        print('Error in lcu - I got an empty list of unitaries!')
    ctrl_dim = math.ceil(math.log(size, 2))

    for i in range(0, size):
        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]

        # if unitaries passed are qubitoperator, directly apply them, no unpacking required
        if isinstance(list_of_U[0], QubitOperator):
            with Control(eng, ctrl):
                list_of_U[i] | sys
            Uncompute(eng)

        else:
            with Control(eng, ctrl):
                if (isinstance(coefts[i], complex)):  # can be i, or -1
                    Ph(0.5 * math.pi) | sys[j]  # apply global phase i
                    if (np.sign(-1j * coefts[i]) < 0):
                        Ph(math.pi) | sys[j]  # global phase is actually -i
                elif (np.sign(coefts[i]) < 0):
                    Ph(math.pi) | sys[j]  # apply global phase -1
                for j in range(0, sys_dim):
                    if (list_of_U[i][j] == I):
                        continue
                    list_of_U[i][j] | sys[j]
            Uncompute(eng)
コード例 #7
0
def mul_by_constant_modN(eng, c, N, quint_in):
    """
    Multiplies a quantum integer by a classical number a modulo N, i.e.,

    |x> -> |a*x mod N>

    (only works if a and N are relative primes, otherwise the modular inverse
    does not exist).
    """
    assert (c < N and c >= 0)
    assert (gcd(c, N) == 1)

    n = len(quint_in)
    quint_out = eng.allocate_qureg(n + 1)

    for i in range(n):
        with Control(eng, quint_in[i]):
            AddConstantModN((c << i) % N, N) | quint_out

    for i in range(n):
        Swap | (quint_out[i], quint_in[i])

    cinv = inv_mod_N(c, N)

    for i in range(n):
        with Control(eng, quint_in[i]):
            SubConstantModN((cinv << i) % N, N) | quint_out
    del quint_out
コード例 #8
0
ファイル: _constantmath.py プロジェクト: Takishima/ProjectQ
def mul_by_constant_modN(eng, constant, N, quint_in):  # pylint: disable=invalid-name
    """
    Multiply a quantum integer by a classical number a modulo N.

    i.e.,

    |x> -> |a*x mod N>

    (only works if a and N are relative primes, otherwise the modular inverse
    does not exist).
    """
    if constant < 0 or constant > N:
        raise ValueError('Pre-condition failed: 0 <= constant < N')
    if gcd(constant, N) != 1:
        raise ValueError('Pre-condition failed: gcd(constant, N) == 1')

    n_qubits = len(quint_in)
    quint_out = eng.allocate_qureg(n_qubits + 1)

    for i in range(n_qubits):
        with Control(eng, quint_in[i]):
            AddConstantModN((constant << i) % N, N) | quint_out

    for i in range(n_qubits):
        Swap | (quint_out[i], quint_in[i])

    cinv = inv_mod_N(constant, N)

    for i in range(n_qubits):
        with Control(eng, quint_in[i]):
            SubConstantModN((cinv << i) % N, N) | quint_out
    del quint_out
コード例 #9
0
def _decompose_QPE(cmd):
    """ Decompose the Quantum Phase Estimation gate. """
    eng = cmd.engine

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

    # Hadamard on the ancillas
    Tensor(H) | qpe_ancillas

    # The Unitary Operator
    U = cmd.gate.unitary

    # Control U on the system_qubits
    if (callable(U)):
        # If U is a function
        for i in range(len(qpe_ancillas)):
            with Control(eng, qpe_ancillas[i]):
                U(system_qubits, time=2**i)
    else:
        for i in range(len(qpe_ancillas)):
            ipower = int(2**i)
            with Loop(eng, ipower):
                with Control(eng, qpe_ancillas[i]):
                    U | system_qubits

    # Inverse QFT on the ancillas
    get_inverse(QFT) | qpe_ancillas
コード例 #10
0
def _decompose_parity_measurement(cmd):
    ancilla = cmd.engine.allocate_qubit()
    for pos, action in cmd.gate._bases:
        qureg = Qureg([cmd.qubits[0][pos]])
        if action == "X":
            H | cmd.qubits[0][pos]
            with Control(cmd.engine, qureg):
                X | ancilla
            H | cmd.qubits[0][pos]

        elif action == "Y":
            H | cmd.qubits[0][pos]
            S | cmd.qubits[0][pos]
            with Control(cmd.engine, qureg):
                X | ancilla
            get_inverse(S) | cmd.qubits[0][pos]
            H | cmd.qubits[0][pos]
        elif action == "Z":
            with Control(cmd.engine, qureg):
                X | ancilla

    # if there is a minus sign
    if (cmd.gate._is_inverted):
        X | ancilla

    # at last measure the parity:
    Measure | ancilla
コード例 #11
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>")
コード例 #12
0
def s1(eng, qubits, R):
    A = qubits[5:8]
    output_reg = qubits[8:12]
    test_carrier_1 = qubits[12]
    test_carrier_2 = qubits[13]

    C(X, 1) | (R[1], A[0])
    C(X, 1) | (R[2], A[1])
    C(X, 1) | (R[3], A[2])

    X | output_reg[0]
    X | test_carrier_1
    X | test_carrier_2

    MultiplyModN(2) | (A, R, output_reg)
    modular_decrement_gate() | (R, output_reg)

    with Compute(eng):
        All(X) | output_reg
    with Control(eng, output_reg):
        X | test_carrier_1
    Uncompute(eng)

    modular_increment_gate() | (R, output_reg)
    modular_increment_gate() | (R, output_reg)

    with Compute(eng):
        All(X) | output_reg
    with Control(eng, output_reg):
        X | test_carrier_2
    Uncompute(eng)

    C(Z, 1) | (test_carrier_2, test_carrier_1)

    with Compute(eng):
        All(X) | output_reg
    with Control(eng, output_reg):
        X | test_carrier_2
    Uncompute(eng)

    modular_decrement_gate() | (R, output_reg)
    modular_decrement_gate() | (R, output_reg)

    with Compute(eng):
        All(X) | output_reg
    with Control(eng, output_reg):
        X | test_carrier_1
    Uncompute(eng)

    modular_increment_gate() | (R, output_reg)
    InverseMultiplyModN(2) | (A, R, output_reg)

    C(X, 1) | (R[3], A[2])
    C(X, 1) | (R[2], A[1])
    C(X, 1) | (R[1], A[0])

    X | output_reg[0]
    X | test_carrier_1
    X | test_carrier_2
コード例 #13
0
def subtract_quantum(eng, quint_a, quint_b):
    """
    Subtract two quantum integers.

    i.e.,

    |a>|b> -> |a>|b-a>

    (only works if quint_a and quint_b are the same size)

    Args:
        eng (MainEngine): ProjectQ MainEngine
        quint_a (list): Quantum register (or list of qubits)
        quint_b (list): Quantum register (or list of qubits)

    Notes:
        Quantum subtraction using bitwise complementation of quantum adder: b-a = (a + b')'. Same as the quantum
        addition circuit except that the steps involving the carry qubit are left out and complement b at the start
        and at the end of the circuit is added.

        Ancilla: 0, size: 9n-8, toffoli: 2n-2, depth: 5n-5.


    .. rubric:: References

    Quantum addition using ripple carry from:
    https://arxiv.org/pdf/0910.2530.pdf
    """
    # pylint: disable = pointless-statement, expression-not-assigned

    if len(quint_a) != len(quint_b):
        raise ValueError('quint_a and quint_b must have the same size!')
    n_qubits = len(quint_a) + 1

    All(X) | quint_b

    for i in range(1, n_qubits - 1):
        CNOT | (quint_a[i], quint_b[i])

    for j in range(n_qubits - 3, 0, -1):
        CNOT | (quint_a[j], quint_a[j + 1])

    for k in range(0, n_qubits - 2):
        with Control(eng, [quint_a[k], quint_b[k]]):
            X | (quint_a[k + 1])

    for i in range(n_qubits - 2, 0, -1):  # noqa: E741
        CNOT | (quint_a[i], quint_b[i])
        with Control(eng, [quint_a[i - 1], quint_b[i - 1]]):
            X | quint_a[i]

    for j in range(1, n_qubits - 2):
        CNOT | (quint_a[j], quint_a[j + 1])

    for n_qubits in range(0, n_qubits - 1):
        CNOT | (quint_a[n_qubits], quint_b[n_qubits])

    All(X) | quint_b
コード例 #14
0
def quantum_conditional_add(eng, quint_a, quint_b, conditional):
    """
    Add up two quantum integers if conditional is high.

    i.e.,

    |a>|b>|c> -> |a>|b+a>|c>
    (without a carry out qubit)

    if conditional is low, no operation is performed, i.e.,
    |a>|b>|c> -> |a>|b>|c>

    Args:
        eng (MainEngine): ProjectQ MainEngine
        quint_a (list): Quantum register (or list of qubits)
        quint_b (list): Quantum register (or list of qubits)
        conditional (list): Conditional qubit

    Notes:
        Ancilla: 0, Size: 7n-7, Toffoli: 3n-3, Depth: 5n-3.

    .. rubric:: References

    Quantum Conditional Add from https://arxiv.org/pdf/1609.01241.pdf
    """
    # pylint: disable = pointless-statement, expression-not-assigned

    if len(quint_a) != len(quint_b):
        raise ValueError('quint_a and quint_b must have the same size!')
    if len(conditional) != 1:
        raise ValueError('Conditional qubit must be a single qubit!')

    n_qubits = len(quint_a) + 1

    for i in range(1, n_qubits - 1):
        CNOT | (quint_a[i], quint_b[i])

    for i in range(n_qubits - 2, 1, -1):
        CNOT | (quint_a[i - 1], quint_a[i])

    for k in range(0, n_qubits - 2):
        with Control(eng, [quint_a[k], quint_b[k]]):
            X | (quint_a[k + 1])

    with Control(eng, [quint_a[n_qubits - 2], conditional[0]]):
        X | quint_b[n_qubits - 2]

    for i in range(n_qubits - 2, 0, -1):  # noqa: E741
        with Control(eng, [quint_a[i - 1], quint_b[i - 1]]):
            X | quint_a[i]
        with Control(eng, [quint_a[i - 1], conditional[0]]):
            X | (quint_b[i - 1])

    for j in range(1, n_qubits - 2):
        CNOT | (quint_a[j], quint_a[j + 1])

    for k in range(1, n_qubits - 1):
        CNOT | (quint_a[k], quint_b[k])
コード例 #15
0
ファイル: entangle.py プロジェクト: silky/ProjectQ
def _decompose_entangle(cmd):
    """ Decompose the entangle gate. """
    qr = cmd.qubits[0]
    eng = cmd.engine

    with Control(eng, cmd.control_qubits):
        H | qr[0]
        with Control(eng, qr[0]):
            All(X) | qr[1:]
コード例 #16
0
def _decompose_QFT(cmd):
    qb = cmd.qubits[0]
    eng = cmd.engine
    with Control(eng, cmd.control_qubits):
        for i in range(len(qb)):
            H | qb[-1 - i]
            for j in range(len(qb) - 1 - i):
                with Control(eng, qb[-1 - (j + i + 1)]):
                    R(math.pi / (1 << (1 + j))) | qb[-1 - i]
コード例 #17
0
    def active_fun(self, train_or_test):
        """

        :param train_or_test: bool, True or False
        :return: loss
        """
        if train_or_test == 'train':
            x_epoch = self.train_x
            y_epoch = self.train_y
            return_test_label = False
        elif train_or_test == 'test':
            x_epoch = self.test_x
            y_epoch = self.test_y
            return_test_label = True
        else:
            print('error!!!')

        y_sim = []
        for encoded_data in x_epoch:
            self.eng.backend.set_wavefunction(self.init_wavefun, self.qureg)
            for w in range(2):  # represent the data with same weight
                for i in range(len(encoded_data[0])):
                    if encoded_data[w][i]:
                        X | self.qureg[self.n_qubits1data * w + i]
                    with Control(self.eng,
                                 self.qureg[self.n_qubits1data * w + i]):
                        Ry(2 * encoded_data[-1] * self.alpha[w] /
                           2**i) | self.qureg[-2]
            # add bios
            Ry(2 * self.alpha[-1]) | self.qureg[-2]

            with Control(self.eng, self.qureg[-2]):
                Y | self.qureg[-1]

            Rz(-np.pi / 2) | self.qureg[2]

            Ry(-2 * self.alpha[-1]) | self.qureg[-2]

            for w in range(2):  # represent the data with same weight
                for i in range(len(encoded_data[0])):
                    with Control(self.eng,
                                 self.qureg[self.n_qubits1data * w + i]):
                        Ry(-2 * encoded_data[-1] * self.alpha[w] /
                           2**i) | self.qureg[-2]

            self.eng.flush()
            # self.eng.backend.collapse_wavefunction([self.qureg[-2]], [0])
            result = self.eng.backend.get_probability('0', [self.qureg[-1]])

            Measure | self.qureg
            y_sim.append(np.arccos(np.sqrt(result)) / (np.pi / 2))
            # y_sim.append(result)
        loss = self.cal_loss(y_epoch, y_sim)
        if return_test_label:
            return loss, y_sim
        else:
            return loss
コード例 #18
0
def test_simulator_functional_entangle(sim):
    eng = HiQMainEngine(sim, [GreedyScheduler()])
    qubits = eng.allocate_qureg(5)
    # entangle all qubits:
    H | qubits[0]
    for qb in qubits[1:]:
        CNOT | (qubits[0], qb)

    eng.flush()

    id2pos, vec = sim.cheat()

    # check the state vector:
    assert .5 == pytest.approx(abs(vec[0])**2)  # amplitudes 00000 and 11111
    assert .5 == pytest.approx(abs(
        vec[31])**2)  # are never moved even if qubit reordering made
    for i in range(1, 31):
        assert 0. == pytest.approx(abs(vec[i]))

    # unentangle all except the first 2
    for qb in qubits[2:]:
        CNOT | (qubits[0], qb)

    # entangle using Toffolis
    for qb in qubits[2:]:
        Toffoli | (qubits[0], qubits[1], qb)

    eng.flush()

    # check the state vector:
    id2pos, vec = sim.cheat()
    assert .5 == pytest.approx(abs(vec[0])**2)
    assert .5 == pytest.approx(abs(vec[31])**2)
    for i in range(1, 31):
        assert 0. == pytest.approx(abs(vec[i]))

    # uncompute using multi-controlled NOTs
    with Control(eng, qubits[0:-1]):
        X | qubits[-1]
    with Control(eng, qubits[0:-2]):
        X | qubits[-2]
    with Control(eng, qubits[0:-3]):
        X | qubits[-3]
    CNOT | (qubits[0], qubits[1])
    H | qubits[0]

    eng.flush()

    id2pos, vec = sim.cheat()

    # check the state vector:
    assert 1. == pytest.approx(abs(vec[0])**2)
    for i in range(1, 32):
        assert 0. == pytest.approx(abs(vec[i]))

    All(Measure) | qubits
コード例 #19
0
def Add(eng, X_reg, D_reg, L_reg):
    
    print("Running Add")
    
    # Initialize auxiliary register A
    A_reg = eng.allocate_qureg(q)
    
    # Get registers of database
    D_reg_X = [qubit for qubit in D_reg if (D_reg.index(qubit) % (m + n) < m)]
    D_reg_Y = [qubit for qubit in D_reg if (D_reg.index(qubit) % (m + n) >= m)]
    
    for i in range(q):
        
        # Get registers of database
        D_reg_X_i = [qubit for qubit in D_reg_X if (D_reg_X.index(qubit) >= m * i \
                     and D_reg_X.index(qubit) < m * (i + 1))]
        D_reg_Y_i = [qubit for qubit in D_reg_Y if (D_reg_Y.index(qubit) >= n * i \
                     and D_reg_Y.index(qubit) < n * (i + 1))]
        
        # Look for where the database entries are larger than the query
        A_reg[i] = Larger(eng, D_reg_X_i, X_reg, A_reg[i])
        
        # Correct for empty entries
        All(X) | D_reg_Y_i
        C(X, n) | (D_reg_Y_i, A_reg[i])
        All(X) | D_reg_Y_i
        
        # Flip all higher bits, such that Hamming weight of A becomes 1
        for j in range(i + 1, q):
            C(X, 1) | (A_reg[i], A_reg[j])
            
    # Permute the database into the correct order
    D_reg = Permute_inv(eng, D_reg, A_reg)
    
    for i in range(q):
        with Control(eng, A_reg[i]):
            
            # Get registers of database
            D_reg_X_i = [qubit for qubit in D_reg_X if (D_reg_X.index(qubit) >= m * i \
                         and D_reg_X.index(qubit) < m * (i + 1))]
            
            # Add to the database and update register L
            for j in range(m):
                C(X, 1) | (X_reg[j], D_reg_X_i[j])
            X | L_reg[i] 
    
    # Clean Up
    All(X) | X_reg
    with Control(eng, X_reg):
        for i in range(q):
            C(X, 1) | (L_reg[i], A_reg[i])
    All(X) | X_reg
    del A_reg
    print("Finished Add")            
    
    return D_reg, L_reg
コード例 #20
0
def test_decomposition():
    for basis_state_index in range(0, 16):
        basis_state = [0] * 16
        basis_state[basis_state_index] = 1.
        correct_dummy_eng = DummyEngine(save_commands=True)
        correct_eng = MainEngine(backend=Simulator(),
                                 engine_list=[correct_dummy_eng])
        rule_set = DecompositionRuleSet(modules=[cnu2toffoliandcu])
        test_dummy_eng = DummyEngine(save_commands=True)
        test_eng = MainEngine(backend=Simulator(),
                              engine_list=[
                                  AutoReplacer(rule_set),
                                  InstructionFilter(_decomp_gates),
                                  test_dummy_eng
                              ])
        test_sim = test_eng.backend
        correct_sim = correct_eng.backend
        correct_qb = correct_eng.allocate_qubit()
        correct_ctrl_qureg = correct_eng.allocate_qureg(3)
        correct_eng.flush()
        test_qb = test_eng.allocate_qubit()
        test_ctrl_qureg = test_eng.allocate_qureg(3)
        test_eng.flush()

        correct_sim.set_wavefunction(basis_state,
                                     correct_qb + correct_ctrl_qureg)
        test_sim.set_wavefunction(basis_state, test_qb + test_ctrl_qureg)

        with Control(test_eng, test_ctrl_qureg[:2]):
            Rx(0.4) | test_qb
        with Control(test_eng, test_ctrl_qureg):
            Ry(0.6) | test_qb

        with Control(correct_eng, correct_ctrl_qureg[:2]):
            Rx(0.4) | correct_qb
        with Control(correct_eng, correct_ctrl_qureg):
            Ry(0.6) | correct_qb

        test_eng.flush()
        correct_eng.flush()

        assert len(correct_dummy_eng.received_commands) == 8
        assert len(test_dummy_eng.received_commands) == 20

        for fstate in range(16):
            binary_state = format(fstate, '04b')
            test = test_sim.get_amplitude(binary_state,
                                          test_qb + test_ctrl_qureg)
            correct = correct_sim.get_amplitude(
                binary_state, correct_qb + correct_ctrl_qureg)
            assert correct == pytest.approx(test, rel=1e-12, abs=1e-12)

        Measure | test_qb + test_ctrl_qureg
        Measure | correct_qb + correct_ctrl_qureg
        test_eng.flush(deallocate_qubits=True)
        correct_eng.flush(deallocate_qubits=True)
コード例 #21
0
def test_decomposition(gate_matrix):
    # Create single qubit gate with gate_matrix
    test_gate = MatrixGate()
    test_gate.matrix = np.matrix(gate_matrix)

    for basis_state in ([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0,
                                                                   1]):
        correct_dummy_eng = DummyEngine(save_commands=True)
        correct_eng = MainEngine(backend=Simulator(),
                                 engine_list=[correct_dummy_eng])

        rule_set = DecompositionRuleSet(modules=[carb1q])
        test_dummy_eng = DummyEngine(save_commands=True)
        test_eng = MainEngine(
            backend=Simulator(),
            engine_list=[
                AutoReplacer(rule_set),
                InstructionFilter(_decomp_gates),
                test_dummy_eng,
            ],
        )
        test_sim = test_eng.backend
        correct_sim = correct_eng.backend

        correct_qb = correct_eng.allocate_qubit()
        correct_ctrl_qb = correct_eng.allocate_qubit()
        correct_eng.flush()
        test_qb = test_eng.allocate_qubit()
        test_ctrl_qb = test_eng.allocate_qubit()
        test_eng.flush()

        correct_sim.set_wavefunction(basis_state, correct_qb + correct_ctrl_qb)
        test_sim.set_wavefunction(basis_state, test_qb + test_ctrl_qb)

        with Control(test_eng, test_ctrl_qb):
            test_gate | test_qb
        with Control(correct_eng, correct_ctrl_qb):
            test_gate | correct_qb

        test_eng.flush()
        correct_eng.flush()

        assert correct_dummy_eng.received_commands[3].gate == test_gate
        assert test_dummy_eng.received_commands[3].gate != test_gate

        for fstate in ['00', '01', '10', '11']:
            test = test_sim.get_amplitude(fstate, test_qb + test_ctrl_qb)
            correct = correct_sim.get_amplitude(fstate,
                                                correct_qb + correct_ctrl_qb)
            assert correct == pytest.approx(test, rel=1e-12, abs=1e-12)

        All(Measure) | test_qb + test_ctrl_qb
        All(Measure) | correct_qb + correct_ctrl_qb
        test_eng.flush(deallocate_qubits=True)
        correct_eng.flush(deallocate_qubits=True)
コード例 #22
0
ファイル: n_5.py プロジェクト: peter-janderks/bachelor-thesis
def grover_iteration(qubits, R):
    control_qubit = qubits[0]

    All(X) | R[0:5]
    All(H) | R[0:5]

    ####
    C(X, 2) | (R[0:2], control_qubit)
    with Control(eng, control_qubit):
        s1(eng, qubits, R)
    C(X, 2) | (R[0:2], control_qubit)
    ####
    X | R[1]
    C(X, 3) | (R[0:3], control_qubit)
    X | R[1]

    with Control(eng, control_qubit):
        s2(eng, qubits, R)

    X | R[1]
    C(X, 3) | (R[0:3], control_qubit)
    X | R[1]
    ###

    All(X) | R[1:3]
    C(X, 4) | (R[0:4], control_qubit)
    All(X) | R[1:3]

    with Control(eng, control_qubit):
        s3(eng, qubits, R)

    All(X) | R[1:3]
    C(X, 4) | (R[0:4], control_qubit)
    All(X) | R[1:3]

    ###

    All(X) | R[1:4]
    C(X, 4) | (R[0:4], control_qubit)
    All(X) | R[1:4]

    with Control(eng, control_qubit):
        s4(eng, qubits, R)

    All(X) | R[1:4]
    C(X, 4) | (R[0:4], control_qubit)
    All(X) | R[1:4]

    ###
    Z | R[0]
    All(H) | R[0:5]
    C(Z, 4) | (R[0:4], R[4])
    All(H) | R[0:5]
    return (qubits, R)
コード例 #23
0
def complex_oracle(eng, system_q, control):
    # This oracle selects the subspace |000000>+|111111> as the good one
    with Compute(eng):
        with Control(eng, system_q[0]):
            All(X) | system_q[1:]
        H | system_q[0]
        All(X) | system_q

    with Control(eng, system_q):
        X | control

    Uncompute(eng)
コード例 #24
0
ファイル: _default_rules.py プロジェクト: Takishima/ProjectQ
def _replace_inverse_add_quantum(cmd):
    eng = cmd.engine
    quint_a = cmd.qubits[0]
    quint_b = cmd.qubits[1]

    if len(cmd.qubits) == 3:
        quint_c = cmd.qubits[2]
        with Control(eng, cmd.control_qubits):
            inverse_add_quantum_carry(eng, quint_a, [quint_b, quint_c])
    else:
        with Control(eng, cmd.control_qubits):
            subtract_quantum(eng, quint_a, quint_b)
コード例 #25
0
def test_qubitop2singlequbit():
    num_qubits = 4
    random_initial_state = [
        0.2 + 0.1 * x * cmath.exp(0.1j + 0.2j * x)
        for x in range(2**(num_qubits + 1))
    ]
    rule_set = DecompositionRuleSet(modules=[qubitop2onequbit])
    test_eng = MainEngine(
        backend=Simulator(),
        engine_list=[AutoReplacer(rule_set),
                     InstructionFilter(_decomp_gates)],
    )
    test_qureg = test_eng.allocate_qureg(num_qubits)
    test_ctrl_qb = test_eng.allocate_qubit()
    test_eng.flush()
    test_eng.backend.set_wavefunction(random_initial_state,
                                      test_qureg + test_ctrl_qb)
    correct_eng = MainEngine()
    correct_qureg = correct_eng.allocate_qureg(num_qubits)
    correct_ctrl_qb = correct_eng.allocate_qubit()
    correct_eng.flush()
    correct_eng.backend.set_wavefunction(random_initial_state,
                                         correct_qureg + correct_ctrl_qb)

    qubit_op_0 = QubitOperator("X0 Y1 Z3", -1.0j)
    qubit_op_1 = QubitOperator("Z0 Y1 X3", cmath.exp(0.6j))

    qubit_op_0 | test_qureg
    with Control(test_eng, test_ctrl_qb):
        qubit_op_1 | test_qureg
    test_eng.flush()

    correct_eng.backend.apply_qubit_operator(qubit_op_0, correct_qureg)
    with Control(correct_eng, correct_ctrl_qb):
        Ph(0.6) | correct_qureg[0]
        Z | correct_qureg[0]
        Y | correct_qureg[1]
        X | correct_qureg[3]
    correct_eng.flush()

    for fstate in range(2**(num_qubits + 1)):
        binary_state = format(fstate, '0' + str(num_qubits + 1) + 'b')
        test = test_eng.backend.get_amplitude(binary_state,
                                              test_qureg + test_ctrl_qb)
        correct = correct_eng.backend.get_amplitude(
            binary_state, correct_qureg + correct_ctrl_qb)
        assert correct == pytest.approx(test, rel=1e-10, abs=1e-10)

    All(Measure) | correct_qureg + correct_ctrl_qb
    All(Measure) | test_qureg + test_ctrl_qb
    correct_eng.flush()
    test_eng.flush()
コード例 #26
0
ファイル: _unitary_test.py プロジェクト: Takishima/ProjectQ
    def apply_gates(eng, qureg):
        MatrixGate(mat1) | qureg[0]
        MatrixGate(mat2) | qureg[1:]
        MatrixGate(mat3) | qureg

        with Control(eng, qureg[1]):
            MatrixGate(mat2) | (qureg[0], qureg[2])
            MatrixGate(mat4) | qureg[0]

        with Control(eng, qureg[1], ctrl_state='0'):
            MatrixGate(mat1) | qureg[0]
            with Control(eng, qureg[2], ctrl_state='0'):
                MatrixGate(mat1) | qureg[0]
コード例 #27
0
def test_recognize():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend, engine_list=[])
    ctrl_qureg = eng.allocate_qureg(2)
    qureg = eng.allocate_qureg(2)
    with Control(eng, ctrl_qureg):
        QubitOperator("X0 Y1") | qureg
    with Control(eng, ctrl_qureg[0]):
        QubitOperator("X0 Y1") | qureg
    eng.flush()
    cmd0 = saving_backend.received_commands[4]
    cmd1 = saving_backend.received_commands[5]
    assert not qubitop2onequbit._recognize_qubitop(cmd0)
    assert qubitop2onequbit._recognize_qubitop(cmd1)
コード例 #28
0
def quantum_multiplication(eng, quint_a, quint_b, product):
    """
    Multiplies two quantum integers.

    i.e,

    |a>|b>|0> -> |a>|b>|a*b>

    (only works if quint_a and quint_b are of the same size, n qubits and product has size 2n+1).

    Args:
        eng (MainEngine): ProjectQ MainEngine
        quint_a (list): Quantum register (or list of qubits)
        quint_b (list): Quantum register (or list of qubits)
        product (list): Quantum register (or list of qubits) storing
            the result

    Notes:
        Ancilla: 2n + 1, size: 7n^2 - 9n + 4, toffoli: 5n^2 - 4n, depth: 3n^2 - 2.

    .. rubric:: References

    Quantum multiplication from: https://arxiv.org/abs/1706.05113.

    """
    n_a = len(quint_a)

    if len(quint_a) != len(quint_b):
        raise ValueError('quint_a and quint_b must have the same size!')
    if len(product) != ((2 * n_a) + 1):
        raise ValueError('product size must be 2*n + 1')

    for i in range(0, n_a):
        with Control(eng, [quint_a[i], quint_b[0]]):
            X | product[i]

    with Control(eng, quint_b[1]):
        AddQuantum | (
            quint_a[0:(n_a - 1)],  # noqa: E203
            product[1:n_a],
            [product[n_a + 1], product[n_a + 2]],
        )

    for j in range(2, n_a):
        with Control(eng, quint_b[j]):
            AddQuantum | (
                quint_a[0:(n_a - 1)],  # noqa: E203
                product[(0 + j):(n_a - 1 + j)],  # noqa: E203
                [product[n_a + j], product[n_a + j + 1]],
            )
コード例 #29
0
ファイル: _factoring_test.py プロジェクト: silky/ProjectQ
def test_factoring(sim):
    eng = get_main_engine(sim)

    ctrl_qubit = eng.allocate_qubit()

    N = 15
    a = 2

    x = eng.allocate_qureg(4)
    X | x[0]

    H | ctrl_qubit
    with Control(eng, ctrl_qubit):
        MultiplyByConstantModN(pow(a, 2**7, N), N) | x

    H | ctrl_qubit
    eng.flush()
    cheat_tpl = sim.cheat()
    idx = cheat_tpl[0][ctrl_qubit[0].id]
    vec = cheat_tpl[1]

    for i in range(len(vec)):
        if abs(vec[i]) > 1.e-8:
            assert ((i >> idx) & 1) == 0

    Measure | ctrl_qubit
    assert int(ctrl_qubit) == 0
    del vec, cheat_tpl

    H | ctrl_qubit
    with Control(eng, ctrl_qubit):
        MultiplyByConstantModN(pow(a, 2, N), N) | x

    H | ctrl_qubit
    eng.flush()
    cheat_tpl = sim.cheat()
    idx = cheat_tpl[0][ctrl_qubit[0].id]
    vec = cheat_tpl[1]

    probability = 0.
    for i in range(len(vec)):
        if abs(vec[i]) > 1.e-8:
            if ((i >> idx) & 1) == 0:
                probability += abs(vec[i])**2

    assert probability == pytest.approx(.5)

    Measure | ctrl_qubit
    Measure | x
コード例 #30
0
def test_recognize_incorrect_gates():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend)
    qubit = eng.allocate_qubit()
    ctrl_qubit = eng.allocate_qubit()
    ctrl_qureg = eng.allocate_qureg(2)
    eng.flush()
    with Control(eng, ctrl_qubit):
        Rx(0.3) | qubit
    X | qubit
    with Control(eng, ctrl_qureg):
        X | qubit
    eng.flush(deallocate_qubits=True)
    for cmd in saving_backend.received_commands:
        assert not cnu2toffoliandcu._recognize_CnU(cmd)