Exemple #1
0
    def test_correct_resorting_selective(self):
        """Same circuit as non-selective test:
        000 -> 0
        1 = 100 CZ[0, 2]-> 100 Z[1]-> 100 Swap[1, 2]-> 100 Z[0]-> -100
            Swap[0, 1]-> 010 = -2
        2 = 010 Z[1]-> -010 Swap[1, 2]-> -001 = -4
        3 = 110 Z[1]-> -110 Swap[1, 2]-> -101 -Z[0]-> 101 Swap[0, 1]-> 6
        4 = 001 Swap[1, 2]-> 010 Swap[0, 1]-> 100 = 1
        5 = 101 CZ[0, 2]-> -101 Swap[1, 2]-> -110 -Z[0]-> 110 = 3
        6 = 011 Z[1]-> -011 CZ[1, 2]-> 011 Swap[0, 1] -> 101 = 5
        7 = 111 CZ[1, 2]-> -111 Z[1]-> 111 CZ[1, 2]-> -111 Z[0]-> 111 = 7

        so the correct signs at the output are +, +, -, +, -, +, +, +.
        """
        All(H) | self.reg3
        C(Z) | (self.reg3[0], self.reg3[2])
        Z | self.reg3[1]
        Swap | (self.reg3[1], self.reg3[2])
        C(Z) | (self.reg3[1], self.reg3[2])
        Z | self.reg3[0]
        Swap | (self.reg3[1], self.reg3[0])
        self.eng3.flush()

        expected = numpy.array([-1, -1]) / (2 * numpy.sqrt(2))

        self.assertTrue(
            numpy.allclose(
                numpy.array(ordered_wavefunction(self.eng3, [2, 4])),
                expected))
Exemple #2
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
Exemple #3
0
def _decompose_CRz(cmd):
    """ Decompose the controlled Rz gate (into CNOT and Rz). """
    qubit = cmd.qubits[0]
    ctrl = cmd.control_qubits
    gate = cmd.gate
    n = get_control_count(cmd)

    Rz(0.5 * gate._angle) | qubit
    C(NOT, n) | (ctrl, qubit)
    Rz(-0.5 * gate._angle) | qubit
    C(NOT, n) | (ctrl, qubit)
Exemple #4
0
def _decompose_CRz(cmd):  # pylint: disable=invalid-name
    """Decompose the controlled Rz gate (into CNOT and Rz)."""
    qubit = cmd.qubits[0]
    ctrl = cmd.control_qubits
    gate = cmd.gate
    n_controls = get_control_count(cmd)

    Rz(0.5 * gate.angle) | qubit
    C(NOT, n_controls) | (ctrl, qubit)
    Rz(-0.5 * gate.angle) | qubit
    C(NOT, n_controls) | (ctrl, qubit)
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)
def test_body():
    drawer = _drawer.CircuitDrawer()
    eng = MainEngine(drawer, [])
    old_tolatex = _drawer.to_latex
    _drawer.to_latex = lambda x: x

    qubit1 = eng.allocate_qubit()
    qubit2 = eng.allocate_qubit()
    qubit3 = eng.allocate_qubit()
    H | qubit1
    H | qubit2
    CNOT | (qubit1, qubit2)
    X | qubit2
    Measure | qubit2
    CNOT | (qubit2, qubit1)
    Z | qubit2
    C(Z) | (qubit1, qubit2)
    C(Swap) | (qubit1, qubit2, qubit3)
    SqrtX | qubit1
    SqrtSwap | (qubit1, qubit2)
    get_inverse(SqrtX) | qubit1
    C(SqrtSwap) | (qubit1, qubit2, qubit3)
    get_inverse(SqrtSwap) | (qubit1, qubit2)
    C(Swap) | (qubit3, qubit1, qubit2)
    C(SqrtSwap) | (qubit3, qubit1, qubit2)

    del qubit1
    eng.flush()

    circuit_lines = drawer.get_latex()
    _drawer.to_latex = old_tolatex

    settings = _to_latex.get_default_settings()
    settings['gates']['AllocateQubitGate']['draw_id'] = True
    code = _to_latex._body(circuit_lines, settings)

    # swap draws 2 nodes + 2 lines each, so is sqrtswap gate, csqrtswap,
    # inv(sqrt_swap), and cswap.
    assert code.count("swapstyle") == 36
    # CZ is two phases plus 2 from CNOTs + 2 from cswap + 2 from csqrtswap
    assert code.count("phase") == 8
    assert code.count("{{{}}}".format(str(H))) == 2  # 2 hadamard gates
    assert code.count("{$\Ket{0}") == 3  # 3 qubits allocated
    # 1 cnot, 1 not gate, 3 SqrtSwap, 1 inv(SqrtSwap)
    assert code.count("xstyle") == 7
    assert code.count("measure") == 1  # 1 measurement
    assert code.count("{{{}}}".format(str(Z))) == 1  # 1 Z gate
    assert code.count("{red}") == 3
def fermionic_reorder(register, input_order, target_order=None):
    """Fermionically reorder the given register.

    Maps the input Jordan-Wigner order to the output order.

    Args:
        register (projectq.QuReg): Quantum register to reorder.
        input_order (list): The initial Jordan-Wigner canonical order.
        target_order (list): The desired Jordan-Wigner canonical order.
    """
    if not target_order:
        target_order = list(range(len(input_order)))

    key = (index_of_position_in_1d_array, [0])

    input_swaps = parallel_bubble_sort(list(itertools.product(input_order)),
                                       key, len(input_order))
    input_swaps = [
        swap[0] for swap_layer in input_swaps for swap in swap_layer
    ]

    output_swaps = parallel_bubble_sort(list(itertools.product(target_order)),
                                        key, len(input_order))
    output_swaps = [
        swap[0] for swap_layer in output_swaps for swap in swap_layer
    ]

    # Invert the output swaps to go from the input to the target.
    swaps = input_swaps + output_swaps[::-1]

    # Swap adjacent modes for all swaps in both rounds.
    for mode in swaps:
        C(Z) | (register[mode], register[mode + 1])
        Swap | (register[mode], register[mode + 1])
Exemple #8
0
def find_period(engine, N):
    n = int(np.ceil(np.log2(N)))

    a = shor.find_co_prime_stochastic(N)
    if a < 0:
        print("Factor is", -a)
        exit(0)
    print("a =", a)
    qubits = engine.allocate_qureg(3 * n)

    All(H) | qubits[0:(2 * n)]

    for i in range(2 * n):
        C(MultiplyByConstantModN(pow(a, 2**i, N),
                                 N)) | (qubits[i], qubits[(2 * n):(3 * n)])

    qft.qft_inverse(engine, qubits[0:(2 * n)])

    All(Measure) | qubits

    engine.flush()
    measurements = [int(q) for q in qubits[0:(2 * n)]]
    y = sum([(measurements[2 * n - 1 - i] * 1. / (1 << (i + 1)))
             for i in range(2 * n)])
    period = Fraction(y).limit_denominator(N - 1).denominator
    print("period found =", period)
    if period % 2 != 0:
        period *= 2

    if np.mod(period, 2) == 0:
        print(shor.find_prime_factors(N, pow(a, int(period / 2))))
    print('\nMeasured: {0}'.format([int(q) for q in qubits]))
def test_qureg(matplotlib_setup):
    sim = Simulator()
    eng = MainEngine(sim)
    qureg = eng.allocate_qureg(3)
    eng.flush()
    _, _, prob = histogram(sim, qureg)
    assert prob["000"] == pytest.approx(1)
    assert prob["110"] == pytest.approx(0)
    H | qureg[0]
    C(X, 1) | (qureg[0], qureg[1])
    H | qureg[2]
    eng.flush()
    _, _, prob = histogram(sim, qureg)
    assert prob["110"] == pytest.approx(0.25)
    assert prob["100"] == pytest.approx(0)
    All(Measure) | qureg
    eng.flush()
    _, _, prob = histogram(sim, qureg)
    assert (
        prob["000"] == pytest.approx(1)
        or prob["001"] == pytest.approx(1)
        or prob["110"] == pytest.approx(1)
        or prob["111"] == pytest.approx(1)
    )
    assert prob["000"] + prob["001"] + prob["110"] + prob["111"] == pytest.approx(1)
def Fn(f=Qureg(), p=Qureg(), x=Qureg()):
    n = len(x)
    X | f  #1
    CNOT | (x[0], f)  #2
    C(X, 2) | (f, x[1], p[0])  #3
    CNOT | (p[0], f)  #4
    for i in range(1, len(p)):
        if n < 2**(i + 1): max = n
        else: max = 2**(i + 1)
        for j in range(2**i, max):
            a = get_binrep(j, 2**(i))
            ones_place = []
            for k in range(len(a)):
                if a[k] == 1:
                    C(X, 2) | (f, x[j], p[k])
                    ones_place = ones_place + [k]
            C(X, len(ones_place)) | ([p[k] for k in ones_place], f)
def qft(qubits):
    n = len(qubits)
    for i in reversed(range(n)):
        H | qubits[i]
        for d in range(1, i + 1):
            C(R(np.pi / (2**d))) | (qubits[i - d], qubits[i])
    for i in range(int(n / 2)):
        Swap | (qubits[i], qubits[n - i - 1])
Exemple #12
0
def ffft_2d(engine, register, system_size):
    """Apply the 2D fermionic fast Fourier transform to a register.

    Args:
        engine (projectq.MainEngine): The simulator engine with the
                                      register.
        register (projectq.QuReg): The register to apply the 2D FFFT to.
        system_size (int): The side length of the system. register must
                           thus have system_size ** 2 qubits.

    Notes:
        This algorithm uses radix-2 decimation-in-time, so system_size
        must be a binary power. This decimation is head recursive (the
        2-mode FFFT is applied as the first part of the 4-mode FFFT,
        which is applied as the first part of the 8-mode FFFT, etc).
    """
    # Apply the FFFT along one axis of the register.
    for i in range(system_size):
        ffft(engine, register[system_size * i:system_size * i + system_size],
             system_size)
        Ph(3 * numpy.pi / 4) | register[0]

    # To apply the FFFT along the second axis, we must fermionically
    # swap qubits into the correct positions. In 2D this is equivalent
    # to flipping all qubits across the "diagonal" of the grid.
    key_2d = (index_of_position_in_1d_array, (0, 1))
    arr = [(i, j) for i in range(system_size) for j in range(system_size)]
    swaps = parallel_bubble_sort(arr, key_2d, system_size)
    all_swaps = [swap for swap_layer in swaps for swap in swap_layer]

    # Fermionically swap into position to FFFT along the second axis.
    for swap in all_swaps:
        Swap | (register[swap[0]], register[swap[1]])
        C(Z) | (register[swap[0]], register[swap[1]])

    # Perform the FFFT along the second axis.
    for i in range(system_size):
        ffft(engine, register[system_size * i:system_size * i + system_size],
             system_size)
        Ph(3 * numpy.pi / 4) | register[0]

    # Undo the fermionic swap network to restore the original ordering.
    for swap in all_swaps[::-1]:
        Swap | (register[swap[0]], register[swap[1]])
        C(Z) | (register[swap[0]], register[swap[1]])
def RSHIFT(s=Qureg(), x=Qureg()):
    '''shift x to the right by s bits
    https://arxiv.org/pdf/1807.02023.pdf'''
    j = len(s)
    for k in range(j):
        i = 0
        while i + 2**k <= 2**j - 1:
            C(Swap, 1) | (s[k], x[-1 * i], x[-1 * (i + (2**k))])
            i += 1
Exemple #14
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
Exemple #15
0
def test_simulator_triangle_increment_cycle():
    sim = ClassicalSimulator()
    eng = MainEngine(sim, [])

    a = eng.allocate_qureg(6)
    for t in range(1 << 6):
        assert sim.read_register(a) == t
        for i in range(6)[::-1]:
            C(X, i) | (a[:i], a[i])
    assert sim.read_register(a) == 0
Exemple #16
0
def test_tensored_controlled_gate():
    saving_backend = DummyEngine(save_commands=True)
    main_engine = MainEngine(backend=saving_backend, engine_list=[DummyEngine()])
    gate = Rx(0.6)
    qubit0 = Qubit(main_engine, 0)
    qubit1 = Qubit(main_engine, 1)
    qubit2 = Qubit(main_engine, 2)
    target_qubits = [qubit1, qubit2]
    C(All(gate)) | (qubit0, target_qubits)

    assert saving_backend.received_commands[-1].gate == gate
    assert len(saving_backend.received_commands[-1].control_qubits) == 1
def ancillary_add(trans_state, ori_state):
    '''
    parameters
        trans_state: (qureg) state a after QFT
        ori_state: (qureg) original state b, allocated in the same engine
    '''
    assert len(trans_state) == len(ori_state)
    n = len(trans_state)

    for i in range(n):
        for j in range(i, n):
            C(Rz(np.pi / (2**j))) | (ori_state[j], trans_state[i])
Exemple #18
0
def test_simulator_triangle_increment_cycle(mapper):
    engine_list = []
    if mapper is not None:
        engine_list.append(mapper)
    sim = ClassicalSimulator()
    eng = MainEngine(sim, engine_list)

    a = eng.allocate_qureg(6)
    for t in range(1 << 6):
        assert sim.read_register(a) == t
        for i in range(6)[::-1]:
            C(X, i) | (a[:i], a[i])
    assert sim.read_register(a) == 0
def quantum_fourier_transform(state):
    '''
    parameters
        state: (qureg) quantum register representing a quantum state
    '''
    assert type(state) == projectq.types.Qureg

    n = len(state)

    for i in range(n):
        H | state[i]
        for j in range(i + 1, n):
            C(Rz(np.pi / (2**j))) | (state[j], state[i])
Exemple #20
0
def Update(eng, Y_reg, D_reg, L_reg):
    
    print("Running Update")
    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_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))]
        for j in range(n):
            C(X, 2) | (Y_reg[j], L_reg[i], D_reg_Y_i[j])
    print("Finished Update")
    
    return D_reg
Exemple #21
0
def CRightShift_resources(k):
    #___________________initial__________________
    resource_counter = ResourceCounter()
    eng = MainEngine(resource_counter)
    control = list_to_reg([0],eng)
    m = k #case when mantissa is 13 bits
    x = list_to_reg([0 for i in range(m)],eng)
    x = x[::-1]#for right swap
    print('Getting resources for ' + str(len(x)) + ' controlled shift by 1 circuit.')
    for i in range(0,m-1): C(Swap,1)|(control,x[i],x[i+1] )
    Measure | control
    Measure | x #for tex purposes
    eng.flush()
    print(resource_counter)
Exemple #22
0
def Cleanup(eng, Y_reg, D_reg, L_reg, A_reg):
    
    print("Running Locate")
    
    # Get registers of database
    D_reg_Y = [qubit for qubit in D_reg if (D_reg.index(qubit) % (m + n) >= m)]
    
    # Initialize auxiliary register B
    B_reg = eng.allocate_qureg(n)
    All(X) | B_reg
    
    for i in range(q):
        
        # Get registers of database
        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))]
        
        # Compute difference in Y values
        for j in range(n):
            C(X, 1) | (Y_reg[j], B_reg[j])
            C(X, 1) | (D_reg_Y_i[j], B_reg[j])
            
        # Check if D_i equals the query
        C(X, n + 1) | ([L_reg[i]] + B_reg, A_reg)
        
        # Uncompute B
        for j in range(n):
            C(X, 1) | (Y_reg[j], B_reg[j])
            C(X, 1) | (D_reg_Y_i[j], B_reg[j])
    
    # Clean up
    All(X) | B_reg
    del B_reg
    
    print("Finished Locate")        
    return A_reg
Exemple #23
0
def Locate(eng, X_reg, D_reg, L_reg):
    
    print("Running Locate")
    
    # 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)]
    
    # Initialize auxiliary registers A,B
    A_reg = eng.allocate_qureg(m)
    B_reg = eng.allocate_qubit()
    
    All(X) | A_reg
    All(X) | B_reg
    
    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))]
        
        # Compute difference
        for j in range(m):
            C(X, 1) | (X_reg[j], A_reg[j])
            C(X, 1) | (D_reg_X_i[j], A_reg[j])
            
        # Check if D_i^Y =/= 0 and save location if difference is also 0
        All(X) | D_reg_Y_i
        C(X, n) | (D_reg_Y_i, B_reg)
        C(X, m + 1) | (B_reg + A_reg, L_reg[i])
        C(X, n) | (D_reg_Y_i, B_reg)
        All(X) | D_reg_Y_i
        
        # Uncompute A
        for j in range(m):
            C(X, 1) | (X_reg[j], A_reg[j])
            C(X, 1) | (D_reg_X_i[j], A_reg[j])
    
    # Clean up
    All(X) | A_reg
    All(X) | B_reg
    del A_reg
    del B_reg
    print("Finished Locate")        
    
    return L_reg
def test_combination(matplotlib_setup):
    sim = Simulator()
    eng = MainEngine(sim)
    qureg = eng.allocate_qureg(2)
    qubit = eng.allocate_qubit()
    eng.flush()
    _, _, prob = histogram(sim, [qureg, qubit])
    assert prob["000"] == pytest.approx(1)
    H | qureg[0]
    C(X, 1) | (qureg[0], qureg[1])
    H | qubit
    Measure | qureg[0]
    eng.flush()
    _, _, prob = histogram(sim, [qureg, qubit])
    assert (prob["000"] == pytest.approx(0.5) and prob["001"] == pytest.approx(0.5)) \
        or (prob["110"] == pytest.approx(0.5) and prob["111"] == pytest.approx(0.5))
    assert prob["100"] == pytest.approx(0)
    Measure | qubit
Exemple #25
0
    def block1(self, parameters, qubits, engine):
        ''' Applies LiH block 1.'''

        for i, qubit in enumerate(qubits):
            Rx(parameters[2 * i]) | qubit
            Rz(parameters[2 * i + 1]) | qubit

        C(Ry(parameters[12])) | (qubits[0], qubits[1])
        C(Ry(parameters[13])) | (qubits[1], qubits[2])
        C(Ry(parameters[14])) | (qubits[2], qubits[3])
        C(Ry(parameters[15])) | (qubits[3], qubits[4])
        C(Ry(parameters[16])) | (qubits[4], qubits[5])
        C(Ry(parameters[17])) | (qubits[5], qubits[0])

        engine.flush()

        return
Exemple #26
0
    def block2(self, parameters, qubits, engine):
        ''' Applies LiH block 2.'''

        for i, qubit in enumerate(qubits):
            Rz(parameters[3 * i]) | qubit
            Rx(parameters[3 * i + 1]) | qubit
            Rz(parameters[3 * i + 2]) | qubit

        C(Ry(parameters[18])) | (qubits[0], qubits[2])
        C(Ry(parameters[19])) | (qubits[1], qubits[3])
        C(Ry(parameters[20])) | (qubits[2], qubits[4])
        C(Ry(parameters[21])) | (qubits[3], qubits[5])
        C(Ry(parameters[22])) | (qubits[4], qubits[0])
        C(Ry(parameters[23])) | (qubits[5], qubits[1])

        engine.flush()

        return
def test_InverseMultiplyModN():
    ### 4 qubits, s=1 --> len(A) = 3
    eng = MainEngine()
    R = eng.allocate_qureg(4)
    A = eng.allocate_qureg(3)
    output_reg = eng.allocate_qureg(4)
    All(X) | R[0:4]
    C(X, 1) | (R[1], A[0])
    C(X, 1) | (R[2], A[1])
    C(X, 1) | (R[3], A[2])
    All(X) | output_reg[0:3]
    InverseMultiplyModN(2) | (A, R, output_reg)
    C(X, 1) | (R[1], A[0])
    C(X, 1) | (R[2], A[1])
    C(X, 1) | (R[3], A[2])
    All(X) | R[0:4]
    eng.flush()
    Measure | R
    Measure | A
    Measure | output_reg
def implementGate(device, gate, qubit, script, frac=0):

    # *This function contains SDK specific code.*
    #
    # Input:
    # * *device* - String specifying the device on which the game is played.
    #              Details about the device will be obtained using getLayout.
    # * *gate* - String that specifies gate type.
    # * *qubit* - Qubit, list of two qubits or qubit register on which the gate is applied.
    # * *script* -
    # * *frac* -
    #
    # Process:
    # * For gates of type 'X', 'Z' and 'XX', the gate $U = \exp(-i \,\times\, gate \,\times\, frac )$ is implemented on the qubit or pair of qubits in *qubit*.
    # * *gate='Finish'* implements the measurement command on the qubit register required for ProjectQ to not complain.
    #
    # Output:
    # * None are returned, but modifications are made to the classes that contain the quantum program.

    num, area, entangleType, pairs, pos, example, sdk, runs = getLayout(device)

    if sdk in ["QISKit", "ManualQISKit"]:
        if gate == 'X':
            script.u3(frac * math.pi, -math.pi / 2, math.pi / 2, qubit)
        elif gate == 'Z':  # actually a Y axis rotation
            script.u3(frac * math.pi, 0, 0, qubit)
        elif gate == 'XX':
            if entangleType == 'CX':
                script.cx(qubit[0], qubit[1])
                script.u3(frac * math.pi, -math.pi / 2, math.pi / 2, qubit[0])
                script.cx(qubit[0], qubit[1])
            elif entangleType == 'CZ':
                script.h(qubit[1])
                script.cz(qubit[0], qubit[1])
                script.u3(frac * math.pi, -math.pi / 2, math.pi / 2, qubit[0])
                script.cz(qubit[0], qubit[1])
                script.h(qubit[1])
            else:
                print("Support for this is yet to be added")

    elif sdk == "ProjectQ":
        if gate == 'X':
            Rx(frac * math.pi) | qubit
        elif gate == 'Z':  # actually a Y axis rotation
            Ry(frac * math.pi) | qubit
        elif gate == 'XX':
            if entangleType == 'CX':
                CNOT | (qubit[0], qubit[1])
                Rx(frac * math.pi) | qubit[0]
                CNOT | (qubit[0], qubit[1])
            elif entangleType == 'CZ':
                H | qubit[1]
                C(Z) | (qubit[0], qubit[1])
                Rx(frac * math.pi) | qubit[0]
                C(Z) | (qubit[0], qubit[1])
                H | qubit[1]
            else:
                print("Support for this is yet to be added")
        elif gate == 'finish':
            Measure | qubit

    elif sdk == "Forest":
        if gate == 'X':
            if qubit in pos.keys():  # only if qubit is active
                script.inst(RX(frac * math.pi, qubit))
        elif gate == 'Z':  # actually a Y axis rotation
            if qubit in pos.keys():  # only if qubit is active
                script.inst(RY(frac * math.pi, qubit))
        elif gate == 'XX':
            if entangleType == 'CX':
                script.inst(CNOT(qubit[0], qubit[1]))
                script.inst(RX(frac * math.pi, qubit[0]))
                script.inst(CNOT(qubit[0], qubit[1]))
            elif entangleType == 'CZ':
                script.inst(H(qubit[1]))
                script.inst(CZ(qubit[0], qubit[1]))
                script.inst(RX(frac * math.pi, qubit[0]))
                script.inst(CZ(qubit[0], qubit[1]))
                script.inst(H(qubit[1]))
            elif entangleType == 'none':
                script.inst(RX(frac * math.pi, qubit[0]))
                script.inst(RX(frac * math.pi, qubit[1]))
            else:
                print("Support for this is yet to be added")
    def apply_gate(self,
                   gate: BasicGate,
                   qubit_index: int,
                   parameter: float = None):
        """Receives command information and implements the gate on the
        corresponding qubit.

        Parameters
        ----------
        gate : BasicGate
            ProjectQ gate to be applied.
        qubit_index : int
            Index of qubit for gate to be applied to.
        parameter : float
            Angle of gate if parametrised.
        """
        if self._qubit_register is not None:

            if gate is C:
                # add qubit index to self.control_qubit_indices, store
                # in memory until a gate is called, which is run controlled
                # on these qubits.

                if qubit_index in self._control_qubit_indices:
                    raise ValueError(
                        f"Qubit {qubit_index} already set-up as control qubit!"
                    )

                if len(self._control_qubit_indices) + 1 \
                        == self._qubit_register_size:

                    raise ValueError(
                        "Too many control qubits for register size of " +
                        "f{self._qubit_register_size}!"
                    )

                self._control_qubit_indices += [qubit_index]

            else:
                if len(self._control_qubit_indices) == 0:  # single qubit gate
                    if parameter is not None:
                        gate(parameter) | self._qubit_register[qubit_index]
                    else:
                        gate | self._qubit_register[qubit_index]

                else:  # controlled gate
                    if qubit_index in self._control_qubit_indices:
                        raise ValueError(
                            f"Target qubit {qubit_index} already set-up as " +
                            "control qubit!"
                        )

                    control_number = len(self._control_qubit_indices)
                    control_qubits = [
                        self._qubit_register[index] for
                        index in self._control_qubit_indices
                    ]

                    control_reg = tuple(
                        [control_qubits, self._qubit_register[qubit_index]]
                    )
                    if parameter is not None:
                        C(gate(parameter), n=control_number) | control_reg
                    else:
                        C(gate, n=control_number) | control_reg

                    # reset control indices
                    self._control_qubit_indices = []

                self._engine.flush()
Exemple #30
0
def s2(eng, qubits, R):

    A = qubits[5:7]
    output_reg = qubits[7:11]
    test_carrier_1 = qubits[11]
    test_carrier_2 = qubits[12]
    test_carrier_3 = qubits[13]

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

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

    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)

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

    modular_increment_gate() | (R, output_reg)

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

    C(Z, 2) | (test_carrier_1, test_carrier_2, test_carrier_3)

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

    modular_decrement_gate() | (R, output_reg)
    InverseMultiplyModN(2) | (A, 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)

    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)

    X | output_reg[0]
    X | test_carrier_1
    X | test_carrier_2
    X | test_carrier_3
    C(X, 1) | (R[3], A[1])
    C(X, 1) | (R[2], A[0])