示例#1
0
def run_grover(eng, n, Ox):
    # start in uniform superposition
    x = eng.allocate_qureg(n)
    All(H) | x

    # the auxiliary indicator qbit, prepare it as '|->'
    y = eng.allocate_qubit()
    X | y
    H | y

    # number of iterations we have to run:
    ITER = int(math.pi / 4.0 * math.sqrt(1 << n))
    with Loop(eng, ITER):
        # oracle adds a (-1)-phase to the solution(s)
        Ox(eng, x, y)

        # reflection across uniform superposition
        with Compute(eng):
            All(H) | x
            All(X) | x

        with Control(eng, x[:-1]):  # Z == H-CNOT(x[-1])-H ??
            Z | x[-1]

        Uncompute(eng)

    All(Measure) | x
    Measure | y

    eng.flush()
    return ''.join([str(int(q)) for q in x])
示例#2
0
def run_bv_circuit(eng, input_size, s_int):
    """Run the quantum circuit."""
    s = ('{0:0' + str(input_size) + 'b}').format(s_int)
    print("Secret string: ", s)
    print("Number of qubits: ", str(input_size + 1))
    circuit = eng.allocate_qureg(input_size + 1)
    All(H) | circuit
    Z | circuit[input_size]

    Barrier | circuit

    oracle(circuit, input_size, s)

    Barrier | circuit

    qubits = circuit[:input_size]
    All(H) | qubits
    All(Measure) | qubits
    eng.flush()

    # return a random answer from our results
    histogram(eng.backend, qubits)
    plt.show()

    # return a random answer from our results
    probabilities = eng.backend.get_probabilities(qubits)
    random_answer = random.choice(list(probabilities.keys()))
    print("Probability of getting correct string: ", probabilities[s[::-1]])
    return [int(s) for s in random_answer]
示例#3
0
def test_addition_with_control_carry(eng):
    qunum_a = eng.allocate_qureg(4)  # 4-qubit number
    qunum_b = eng.allocate_qureg(4)  # 4-qubit number
    control_bit = eng.allocate_qubit()
    qunum_c = eng.allocate_qureg(2)

    X | qunum_a[1]  # qunum is now equal to 2
    All(X) | qunum_b[0:4]  # qunum is now equal to 15
    X | control_bit

    with Control(eng, control_bit):
        AddQuantum | (qunum_a, qunum_b, qunum_c)
    # qunum_a and ctrl don't change, qunum_b and qunum_c are now both equal
    # to 1 so in binary together 10001 (2 + 15 = 17)

    eng.flush()

    assert 1.0 == pytest.approx(
        eng.backend.get_probability([0, 1, 0, 0], qunum_a))
    assert 1.0 == pytest.approx(
        eng.backend.get_probability([1, 0, 0, 0], qunum_b))
    assert 1.0 == pytest.approx(eng.backend.get_probability([1], control_bit))
    assert 1.0 == pytest.approx(eng.backend.get_probability([1, 0], qunum_c))

    All(Measure) | qunum_a
    All(Measure) | qunum_b
示例#4
0
def test_simulator_probability(sim, mapper):
    engine_list = [LocalOptimizer()]
    if mapper is not None:
        engine_list.append(mapper)
    eng = MainEngine(sim, engine_list=engine_list)
    qubits = eng.allocate_qureg(6)
    All(H) | qubits
    eng.flush()
    bits = [0, 0, 1, 0, 1, 0]
    for i in range(6):
        assert eng.backend.get_probability(bits[:i],
                                           qubits[:i]) == pytest.approx(0.5**i)
    extra_qubit = eng.allocate_qubit()
    with pytest.raises(RuntimeError):
        eng.backend.get_probability([0], extra_qubit)
    del extra_qubit
    All(H) | qubits
    Ry(2 * math.acos(math.sqrt(0.3))) | qubits[0]
    eng.flush()
    assert eng.backend.get_probability([0], [qubits[0]]) == pytest.approx(0.3)
    Ry(2 * math.acos(math.sqrt(0.4))) | qubits[2]
    eng.flush()
    assert eng.backend.get_probability([0], [qubits[2]]) == pytest.approx(0.4)
    assert eng.backend.get_probability([0, 0],
                                       qubits[:3:2]) == pytest.approx(0.12)
    assert eng.backend.get_probability([0, 1],
                                       qubits[:3:2]) == pytest.approx(0.18)
    assert eng.backend.get_probability([1, 0],
                                       qubits[:3:2]) == pytest.approx(0.28)
    All(Measure) | qubits
def test_simulator_collapse_wavefunction(sim, mapper):
    engine_list = [LocalOptimizer()]
    if mapper is not None:
        engine_list.append(mapper)

    engine_list.append(GreedyScheduler())
    eng = HiQMainEngine(sim, engine_list=engine_list)
    qubits = eng.allocate_qureg(4)
    # unknown qubits: raises
    with pytest.raises(RuntimeError):
        eng.backend.collapse_wavefunction(qubits, [0] * 4)
    eng.flush()
    eng.backend.collapse_wavefunction(qubits, [0] * 4)
    assert pytest.approx(eng.backend.get_probability([0] * 4, qubits)) == 1.
    All(H) | qubits[1:]
    eng.flush()
    assert pytest.approx(eng.backend.get_probability([0] * 4, qubits)) == .125
    # impossible outcome: raises
    with pytest.raises(RuntimeError):
        eng.backend.collapse_wavefunction(qubits, [1] + [0] * 3)
    eng.backend.collapse_wavefunction(qubits[:-1], [0, 1, 0])
    probability = eng.backend.get_probability([0, 1, 0, 1], qubits)
    assert probability == pytest.approx(.5)

    # reinitialize qubits
    All(Measure) | qubits
    del qubits
    qubits = eng.allocate_qureg(4)

    H | qubits[0]
    CNOT | (qubits[0], qubits[1])
    eng.flush()
    eng.backend.collapse_wavefunction([qubits[0]], [1])
    probability = eng.backend.get_probability([1, 1], qubits[0:2])
    assert probability == pytest.approx(1.)
示例#6
0
    def __exit__(self, exc_type, exc_val, traceback):
        '''
        exit, meanwhile cheat and get wave function.

        Attributes:
            wf (1darray): for 'simulate' task, the wave function vector.
            res (1darray): for 'ibm' task, the measurements output.
        '''
        if traceback is not None:
            return False
        if self.task == 'draw':
            self._viz_circuit()
        elif self.task == 'simulate':
            self.eng.flush()
            order, qvec = self.backend.cheat()
            self.wf = np.array(qvec)
            order = [order[i] for i in range(len(self.qureg))]
            self.wf = np.transpose(self.wf.reshape([2] * len(self.qureg),
                                                   order='F'),
                                   axes=order).ravel(order='F')
            All(Measure) | self.qureg
            self.eng.flush()
        elif self.task == 'ibm':
            All(Measure) | self.qureg
            self.eng.flush()
            self.res = self.backend.get_probabilities(self.qureg)
        else:
            raise
        return self
def test_comparator(eng):
    qureg_a = eng.allocate_qureg(3)
    qureg_b = eng.allocate_qureg(3)
    compare_qubit = eng.allocate_qubit()

    init(eng, qureg_a, 5)
    init(eng, qureg_b, 3)

    ComparatorQuantum | (qureg_a, qureg_b, compare_qubit)

    assert 1.0 == pytest.approx(eng.backend.get_probability([1],
                                                            compare_qubit))

    # Size mismatch in qubit registers
    with pytest.raises(ValueError):
        ComparatorQuantum | (qureg_a, qureg_b[:-1], compare_qubit)

    # Only single qubit for compare qubit
    with pytest.raises(ValueError):
        ComparatorQuantum | (qureg_a, qureg_b,
                             [*compare_qubit, *compare_qubit])

    All(Measure) | qureg_a
    All(Measure) | qureg_b
    Measure | compare_qubit
示例#8
0
def ExecuteGrover(engine, n, oracle):
    x = engine.allocate_qureg(n)

    All(H) | x

    num_it = int(math.pi/4.*math.sqrt(1 << n))

    oracle_out = engine.allocate_qubit()
    X | oracle_out
    H | oracle_out

    with Loop(engine, num_it):
        oracle(engine, x, oracle_out)
        with Compute(engine):
            All(H) | x
            All(X) | x

        with Control(engine, x[0:-1]):
            Z | x[-1]

        Uncompute(engine)

    All(Measure) | x
    Measure | oracle_out

    engine.flush()
    return [int(qubit) for qubit in x]
示例#9
0
def cost(param, target_state, p, eng):
    '''
    VQE core part
    '''
    tolerance=0.001
    assert np.abs(sum([np.abs(i)**2 for i in target_state])-1)<tolerance, "Invalid Target State"

    n=int(np.log2(len(target_state))) 
    assert len(param)==3*n*p
    param=param.reshape((n,3*p))

    count = 0
    all_string = bitstring(n)

    qureg = eng.allocate_qureg(n)
    All(H) | qureg
    for m in range(p):
        for i in range(n):
            Rx(param[i, 3*m+0]) | qureg[i]
            Ry(param[i, 3*m+1]) | qureg[i]
            Rz(param[i, 3*m+2]) | qureg[i]

        CNOT | (qureg[n-1], qureg[0])
        for i in range(n-1):
            CNOT | (qureg[i], qureg[i+1])

    eng.flush()
    for i in range(len(target_state)):
        count += target_state[i] * eng.backend.get_amplitude(all_string[i], qureg)
    All(Measure) | qureg

    return 1-np.abs(count)
示例#10
0
def test_simulator_amplitude(sim):
    eng = MainEngine(sim)
    qubits = eng.allocate_qureg(6)
    All(X) | qubits
    All(H) | qubits
    eng.flush()
    bits = [0, 0, 1, 0, 1, 0]
    assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(1. / 8.)
    bits = [0, 0, 0, 0, 1, 0]
    assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(-1. / 8.)
    bits = [0, 1, 1, 0, 1, 0]
    assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(-1. / 8.)
    All(H) | qubits
    All(X) | qubits
    Ry(2 * math.acos(0.3)) | qubits[0]
    eng.flush()
    bits = [0] * 6
    assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(0.3)
    bits[0] = 1
    assert (eng.backend.get_amplitude(bits, qubits) == pytest.approx(
        math.sqrt(0.91)))
    Measure | qubits
    # raises if not all qubits are in the list:
    with pytest.raises(RuntimeError):
        eng.backend.get_amplitude(bits, qubits[:-1])
    # doesn't just check for length:
    with pytest.raises(RuntimeError):
        eng.backend.get_amplitude(bits, qubits[:-1] + [qubits[0]])
    extra_qubit = eng.allocate_qubit()
    eng.flush()
    # there is a new qubit now!
    with pytest.raises(RuntimeError):
        eng.backend.get_amplitude(bits, qubits)
示例#11
0
def test_simulator_probability(sim):
    eng = MainEngine(sim)
    qubits = eng.allocate_qureg(6)
    All(H) | qubits
    eng.flush()
    bits = [0, 0, 1, 0, 1, 0]
    for i in range(6):
        assert (eng.backend.get_probability(
            bits[:i], qubits[:i]) == pytest.approx(0.5**i))
    extra_qubit = eng.allocate_qubit()
    with pytest.raises(RuntimeError):
        eng.backend.get_probability([0], extra_qubit)
    del extra_qubit
    All(H) | qubits
    Ry(2 * math.acos(math.sqrt(0.3))) | qubits[0]
    eng.flush()
    assert eng.backend.get_probability([0], [qubits[0]]) == pytest.approx(0.3)
    Ry(2 * math.acos(math.sqrt(0.4))) | qubits[2]
    eng.flush()
    assert eng.backend.get_probability([0], [qubits[2]]) == pytest.approx(0.4)
    assert (eng.backend.get_probability([0, 0],
                                        qubits[:3:2]) == pytest.approx(0.12))
    assert (eng.backend.get_probability([0, 1],
                                        qubits[:3:2]) == pytest.approx(0.18))
    assert (eng.backend.get_probability([1, 0],
                                        qubits[:3:2]) == pytest.approx(0.28))
    Measure | qubits
示例#12
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]
示例#13
0
def test_quantummultiplication(eng):
    qureg_a = eng.allocate_qureg(3)
    qureg_b = eng.allocate_qureg(3)
    qureg_c = eng.allocate_qureg(7)

    init(eng, qureg_a, 7)
    init(eng, qureg_b, 3)

    MultiplyQuantum | (qureg_a, qureg_b, qureg_c)

    assert 1.0 == pytest.approx(eng.backend.get_probability([1, 1, 1], qureg_a))
    assert 1.0 == pytest.approx(eng.backend.get_probability([1, 1, 0], qureg_b))
    assert 1.0 == pytest.approx(eng.backend.get_probability([1, 0, 1, 0, 1, 0, 0], qureg_c))

    All(Measure) | qureg_a
    All(Measure) | qureg_b
    All(Measure) | qureg_c

    init(eng, qureg_a, 7)
    init(eng, qureg_b, 3)
    init(eng, qureg_c, 21)

    assert 1.0 == pytest.approx(eng.backend.get_probability([0, 0, 0, 0, 0, 0, 0], qureg_c))
    init(eng, qureg_a, 2)
    init(eng, qureg_b, 3)

    with Compute(eng):
        MultiplyQuantum | (qureg_a, qureg_b, qureg_c)
    Uncompute(eng)

    assert 1.0 == pytest.approx(eng.backend.get_probability([0, 1, 0], qureg_a))
    assert 1.0 == pytest.approx(eng.backend.get_probability([1, 1, 0], qureg_b))
    assert 1.0 == pytest.approx(eng.backend.get_probability([0, 0, 0, 0, 0, 0, 0], qureg_c))
示例#14
0
def runDeutsch(eng, n, oracle):
    drawing_engine = CircuitDrawer(
    )  # Esto nos permite que se registre todo el circuito ejecutado.
    # Instanciamos dos qubits, estos se inicializan con valor |0>
    x = eng.allocate_qureg(
        n
    )  #on esta instruccion instanciamos un array de qubits, x. (Entrada superior)
    q2 = eng.allocate_qubit()  # qubit de la entrada inferior
    #Aplicamos la puerta H a todos los qubits de x, dejandolos en una superposicion.
    All(H) | x
    #Ponemos el estado |1> en la entrada inferior y luego aplicamos la puerta H para dejarlo en superposicion.
    #De este modo hacemos la inversion de fase.
    X | q2
    H | q2

    oracle(x, q2)

    # Volvemos a aplicar H a todos los qubits de x para retirar la superposicion.
    # En funicion del oraculo algunos pueden estar en inversion de fase y anularse entre si.
    All(H) | x

    #Mediciones
    All(Measure) | x
    Measure | q2
    eng.flush()

    #Imprimimos cada qubit de la cadena
    # Si medimos |0> para todo x, el oraculo implementa una funcion constnate.
    # Si encontramos cualquier otra cosa sera balanceada.
    for qb in x:
        print("Measured: {}".format(int(qb)))
示例#15
0
def test_simple_test_X_eigenvectors():
    rule_set = DecompositionRuleSet(modules=[pe, dqft])
    eng = MainEngine(
        backend=Simulator(),
        engine_list=[
            AutoReplacer(rule_set),
        ],
    )
    N = 150
    results = np.array([])
    for i in range(N):
        autovector = eng.allocate_qureg(1)
        X | autovector
        H | autovector
        unit = X
        ancillas = eng.allocate_qureg(1)
        QPE(unit) | (ancillas, autovector)
        All(Measure) | ancillas
        fasebinlist = [int(q) for q in ancillas]
        fasebin = ''.join(str(j) for j in fasebinlist)
        faseint = int(fasebin, 2)
        phase = faseint / (2.0**(len(ancillas)))
        results = np.append(results, phase)
        All(Measure) | autovector
        eng.flush()

    num_phase = (results == 0.5).sum()
    assert num_phase / N >= 0.35, "Statistics phase calculation are not correct (%f vs. %f)" % (
        num_phase / N,
        0.35,
    )
示例#16
0
def test_inverse_addition_with_control_carry(eng):
    qunum_a = eng.allocate_qureg(4)
    qunum_b = eng.allocate_qureg(4)

    control_bit = eng.allocate_qubit()
    qunum_c = eng.allocate_qureg(2)

    X | qunum_a[1]
    All(X) | qunum_b[0:4]
    X | control_bit
    with Compute(eng):
        with Control(eng, control_bit):
            AddQuantum | (qunum_a, qunum_b, qunum_c)
    Uncompute(eng)

    eng.flush()

    assert 1.0 == pytest.approx(eng.backend.get_probability([0, 1, 0, 0], qunum_a))
    assert 1.0 == pytest.approx(eng.backend.get_probability([1, 1, 1, 1], qunum_b))
    assert 1.0 == pytest.approx(eng.backend.get_probability([1], control_bit))
    assert 1.0 == pytest.approx(eng.backend.get_probability([0, 0], qunum_c))

    All(Measure) | qunum_a
    All(Measure) | qunum_b
    Measure | control_bit
    All(Measure) | qunum_c
示例#17
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]))
示例#18
0
def test_simulator_probability(mapper, capsys):
    sim = StabilizerSimulator(6)
    engine_list = [LocalOptimizer()]
    if mapper is not None:
        engine_list.append(mapper)
    eng = MainEngine(sim, engine_list=engine_list)
    qubits = eng.allocate_qureg(6)
    All(H) | qubits
    eng.flush()
    bits = [0, 0, 1, 0, 1, 0]
    for i in range(6):
        assert (eng.backend.get_probability(
            bits[:i], qubits[:i]) == pytest.approx(0.5**i))
    extra_qubit = eng.allocate_qubit()
    with pytest.raises(RuntimeError):
        eng.backend.get_probability([0], extra_qubit)
    del extra_qubit

    All(H) | qubits
    eng.flush()
    assert eng.backend.get_probability('0' * len(qubits),
                                       qubits) == pytest.approx(1.0)
    assert eng.backend.get_probability('1' * len(qubits),
                                       qubits) == pytest.approx(0.0)
    All(Measure) | qubits
示例#19
0
def test_Ph_eigenvectors():
    rule_set = DecompositionRuleSet(modules=[pe, dqft])
    eng = MainEngine(backend=Simulator(),
                     engine_list=[
                         AutoReplacer(rule_set),
                     ])
    results = np.array([])
    for i in range(100):
        autovector = eng.allocate_qureg(1)
        theta = cmath.pi * 2. * 0.125
        unit = Ph(theta)
        ancillas = eng.allocate_qureg(3)
        QPE(unit) | (ancillas, autovector)
        All(Measure) | ancillas
        fasebinlist = [int(q) for q in ancillas]
        fasebin = ''.join(str(j) for j in fasebinlist)
        faseint = int(fasebin, 2)
        phase = faseint / (2.**(len(ancillas)))
        results = np.append(results, phase)
        All(Measure) | autovector
        eng.flush()

    num_phase = (results == 0.125).sum()
    assert num_phase / 100. >= 0.35, "Statistics phase calculation are not correct (%f vs. %f)" % (
        num_phase / 100., 0.35)
示例#20
0
def run_BV_algorithm(eng, n, oracle):
    """
    Args:
        eng (MainEngine): the Main engine on which we run the BV algorithm
        n (int): number of qubits
        oracle (function): oracle used by the BV algorithm
    """
    x = eng.allocate_qureg(n)

    # start in uniform superposition
    All(H) | x

    oracle_out = eng.allocate_qubit()
    X | oracle_out
    H | oracle_out

    oracle(eng, x, oracle_out)

    All(H) | x

    All(Measure) | x
    Measure | oracle_out

    eng.flush()

    return [int(qubit) for qubit in x]
示例#21
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]
示例#22
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
def oracale(q):
    All(H) | q

    All(Z) | q

    CZ | (q[0], q[1])

    return q
示例#24
0
 def _refresh(self):
     qureg = self.qureg
     All(Measure) | qureg
     for z, q in zip(self.z0, qureg):
         if int(q) != z:
             ops.X | q
     qureg.engine.flush()
     All(Measure) | qureg
示例#25
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
示例#26
0
def test_decomposition():
    for basis_state_index in range(0, 16):
        basis_state = [0] * 16
        basis_state[basis_state_index] = 1.0
        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(test_eng, test_ctrl_qureg):
            X | 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
        with Control(correct_eng, correct_ctrl_qureg):
            X | correct_qb

        test_eng.flush()
        correct_eng.flush()

        assert len(correct_dummy_eng.received_commands) == 9
        assert len(test_dummy_eng.received_commands) == 25

        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)

        All(Measure) | test_qb + test_ctrl_qureg
        All(Measure) | correct_qb + correct_ctrl_qureg
        test_eng.flush(deallocate_qubits=True)
        correct_eng.flush(deallocate_qubits=True)
示例#27
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]
示例#28
0
def test_aqt_backend_functional_test(monkeypatch):
    correct_info = {
        'circuit': '[["Y", 0.5, [1]], ["X", 0.5, [1]], ["X", 0.5, [1]], '
        '["Y", 0.5, [1]], ["MS", 0.5, [1, 2]], ["X", 3.5, [1]], '
        '["Y", 3.5, [1]], ["X", 3.5, [2]]]',
        'nq': 3,
        'shots': 10,
        'backend': {'name': 'simulator'},
    }

    def mock_send(*args, **kwargs):
        assert args[0] == correct_info
        return [0, 6, 0, 6, 0, 0, 0, 6, 0, 6]

    monkeypatch.setattr(_aqt, "send", mock_send)

    backend = _aqt.AQTBackend(verbose=True, num_runs=10)
    # no circuit has been executed -> raises exception
    with pytest.raises(RuntimeError):
        backend.get_probabilities([])

    mapper = BasicMapperEngine()
    res = {}
    for i in range(4):
        res[i] = i
    mapper.current_mapping = res

    eng = MainEngine(backend=backend, engine_list=[mapper])

    unused_qubit = eng.allocate_qubit()
    qureg = eng.allocate_qureg(2)
    # entangle the qureg
    Ry(math.pi / 2) | qureg[0]
    Rx(math.pi / 2) | qureg[0]
    Rx(math.pi / 2) | qureg[0]
    Ry(math.pi / 2) | qureg[0]
    Rxx(math.pi / 2) | (qureg[0], qureg[1])
    Rx(7 * math.pi / 2) | qureg[0]
    Ry(7 * math.pi / 2) | qureg[0]
    Rx(7 * math.pi / 2) | qureg[1]
    All(Barrier) | qureg
    del unused_qubit
    # measure; should be all-0 or all-1
    All(Measure) | qureg
    # run the circuit
    eng.flush()
    prob_dict = eng.backend.get_probabilities([qureg[0], qureg[1]])
    assert prob_dict['11'] == pytest.approx(0.4)
    assert prob_dict['00'] == pytest.approx(0.6)

    # Unknown qubit and no mapper
    invalid_qubit = [WeakQubitRef(eng, 10)]
    with pytest.raises(RuntimeError):
        eng.backend.get_probabilities(invalid_qubit)

    with pytest.raises(RuntimeError):
        eng.backend.get_probabilities(eng.allocate_qubit())
示例#29
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
示例#30
0
 def D():
     # Apply Hadamards
     All(H) | qubits
     # Apply U_0
     All(X) | qubits
     with Control(engine, qubits):
         X | ancilla
     All(X) | qubits
     # Apply Hadamards
     All(H) | qubits