Example #1
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)
def test_toffoli_size_of_modular_offset():
    rec = DummyEngine(save_commands=True)
    eng = MainEngine(backend=rec,
                     engine_list=[
                         AutoReplacerEx(
                             DecompositionRuleSet(modules=[
                                 pivot_flip_rules,
                                 offset_rules,
                                 addition_rules,
                                 swap2cnot,
                                 increment_rules,
                                 multi_not_rules,
                                 modular_addition_rules,
                                 comparison_rules,
                             ])),
                         LimitedCapabilityEngine(allow_toffoli=True),
                     ])
    controls = eng.allocate_qureg(15)
    target = eng.allocate_qureg(16)
    dirty = eng.allocate_qureg(2)
    modulus = 0xAEFD
    offset = 0x9E0A

    ModularOffsetGate(offset, modulus) & controls | target

    assert dirty is not None
    assert 5000 < len(rec.received_commands) < 15000
def test_toffoli_size_of_modular_addition():
    rec = DummyEngine(save_commands=True)
    eng = MainEngine(backend=rec,
                     engine_list=[
                         AutoReplacerEx(
                             DecompositionRuleSet(modules=[
                                 pivot_flip_rules,
                                 offset_rules,
                                 addition_rules,
                                 swap2cnot,
                                 increment_rules,
                                 multi_not_rules,
                                 modular_addition_rules,
                                 comparison_rules,
                             ])),
                         LimitedCapabilityEngine(allow_toffoli=True),
                     ])
    controls = eng.allocate_qureg(15)
    target1 = eng.allocate_qureg(16)
    target2 = eng.allocate_qureg(16)
    modulus = 0xAEFD

    ModularAdditionGate(modulus) & controls | (target1, target2)

    assert 10000 < len(rec.received_commands) < 15000
def test_toffoli_size_of_modular_negate():
    rec = DummyEngine(save_commands=True)
    eng = MainEngine(backend=rec,
                     engine_list=[
                         AutoReplacerEx(
                             DecompositionRuleSet(modules=[
                                 swap2cnot,
                                 multi_not_rules,
                                 addition_rules,
                                 increment_rules,
                                 pivot_flip_rules,
                                 offset_rules,
                                 comparison_rules,
                                 modular_negate_rules,
                             ])),
                         LimitedCapabilityEngine(allow_toffoli=True, ),
                     ])

    t = eng.allocate_qureg(5)
    controls = eng.allocate_qureg(1)
    workspace = eng.allocate_qureg(2)
    modulus = 29

    ModularNegate(modulus) & controls | t

    assert 100 < len(rec.received_commands) < 200
    assert workspace is not None
Example #5
0
def test_simulator_is_available():
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend, [])
    qureg = eng.allocate_qureg(2)
    X | qureg[0]
    S | qureg[0]
    H | qureg[0]
    CNOT | (qureg[0], qureg[1])
    Measure | qureg[0]
    qureg[0].__del__()
    qureg[1].__del__()
    assert len(backend.received_commands) == 9

    # Test that allocate, measure, and deallocate are available.
    sim = StabilizerSimulator(3)
    for cmd in backend.received_commands:
        assert sim.is_available(cmd)

    eng = MainEngine(sim, [])
    qureg = eng.allocate_qureg(3)
    X | qureg[0]
    S | qureg[0]
    H | qureg[0]
    CNOT | (qureg[0], qureg[1])
    All(Measure) | qureg

    with pytest.raises(Exception):
        Toffoli | (qureg[0], qureg[1], qureg[2])
        eng.flush()

    with pytest.raises(Exception):
        with Control(eng, qureg[1:]):
            X | qureg[0]
        eng.flush()
def record_decomposition(gate,
                         decomposition_rule,
                         register_sizes,
                         control_size=0,
                         workspace=0):
    """
    Args:
        gate (projectq.ops.BasicMathGate|
              dirty_period_finding.extensions.BasicGateEx):
        decomposition_rule (projectq.cengines.DecompositionRule):
        register_sizes (list[int]):
        control_size (int):
        workspace (int):
    """
    assert isinstance(gate, decomposition_rule.gate_class)

    rec = DummyEngine(save_commands=True)
    eng = MainEngine(backend=rec, engine_list=[])
    controls = eng.allocate_qureg(control_size)
    regs = tuple(eng.allocate_qureg(size) for size in register_sizes)
    junk = eng.allocate_qureg(workspace)
    if len(junk):
        JunkGate() | junk

    command = CommandEx(eng, gate, regs, controls)
    assert decomposition_rule.gate_recognizer(command)
    decomposition_rule.gate_decomposer(command)
    return rec.received_commands
Example #7
0
def test_toffoli_size_of_bimultiplication():
    rec = DummyEngine(save_commands=True)
    eng = MainEngine(backend=rec,
                     engine_list=[
                         AutoReplacerEx(
                             DecompositionRuleSet(modules=[
                                 swap2cnot,
                                 multi_not_rules,
                                 addition_rules,
                                 increment_rules,
                                 modular_addition_rules,
                                 modular_bimultiplication_rules,
                                 modular_scaled_addition_rules,
                                 pivot_flip_rules,
                                 offset_rules,
                                 modular_double_rules,
                                 rotate_bits_rules,
                                 reverse_bits_rules,
                                 modular_negate_rules,
                                 comparison_rules,
                             ])),
                         LimitedCapabilityEngine(allow_toffoli=True),
                     ])

    t1 = eng.allocate_qureg(5)
    t2 = eng.allocate_qureg(5)
    controls = eng.allocate_qureg(1)
    modulus = 29
    factor = 17

    ModularBimultiplicationGate(factor, modulus) & controls | (t1, t2)

    assert 5000 < len(rec.received_commands) < 10000
Example #8
0
def test_swapandcnotflipper_is_available():
    flipper = _swapandcnotflipper.SwapAndCNOTFlipper(set())
    dummy = DummyEngine()
    dummy.is_available = lambda x: False
    flipper.next_engine = dummy
    eng = MainEngine(DummyEngine(save_commands=True), [])
    qubit1, qubit2 = eng.allocate_qureg(2)
    Swap | (qubit1, qubit2)
    swap_count = 0
    for cmd in eng.backend.received_commands:
        if cmd.gate == Swap:
            swap_count += 1
            assert flipper.is_available(cmd)
    assert swap_count == 1

    eng = MainEngine(DummyEngine(save_commands=True), [])
    qubit1, qubit2, qubit3 = eng.allocate_qureg(3)
    with Control(eng, qubit3):
        Swap | (qubit1, qubit2)
    swap_count = 0
    for cmd in eng.backend.received_commands:
        if cmd.gate == Swap:
            swap_count += 1
            assert not flipper.is_available(cmd)
    assert swap_count == 1
def simulate_sample_period(base, modulus):
    sim = Simulator()
    eng = MainEngine(backend=sim,
                     engine_list=[
                         AutoReplacerEx(
                             DecompositionRuleSet(modules=[decompositions])),
                         LimitedCapabilityEngine(
                             allow_arithmetic=
                             not DECOMPOSE_INTO_TOFFOLIS_AND_GO_VERY_VERY_SLOW,
                             allow_toffoli=True,
                             allow_single_qubit_gates=True),
                     ])

    n = int(math.ceil(math.log(modulus, 2)))

    ancilla_qureg = eng.allocate_qureg(n)
    for q in ancilla_qureg[:-1]:
        if random.random() < 0.5:
            X | q
    before = ancilla_qureg.measure()

    result = shor_find_period(base=base,
                              modulus=modulus,
                              precision=n * 2,
                              phase_qubit=eng.allocate_qubit(),
                              work_qureg=eng.allocate_qureg(n),
                              ancilla_qureg=ancilla_qureg)
    after = ancilla_qureg.measure()
    assert after == before

    return result
def test_or_two_quregs_error():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend, engine_list=[])
    qureg = eng.allocate_qureg(2)
    qureg2 = eng.allocate_qureg(2)
    hamiltonian = QubitOperator("Z0", 2)
    with pytest.raises(TypeError):
        te.TimeEvolution(2.1, hamiltonian) | (qureg, qureg2)
Example #11
0
def simon_quantum_step(function, input_size):
    """
    Performs the quantum portion of Simon's algorithm, by finding an input
	string X where (X · S) % 2 = 0 (AKA x0*s0 ⊕ x1*s1 ⊕ ... ⊕ xN*sN = 0).

    Parameters:
        function (function): The black-box function to run the algorithm on (the function being
	        evaluated). It should take a Program as its first input, an input Qureg
            as its second argument, and an output Qureg as its third argument.

        input_size (int): The number of bits that the function expects in its input and output
	        registers.

    Returns:
        A bit string representing the measured result of the function. This bit
	    string is a vector X where (X · S) % 2 = 0. Note that this will be the
	    measured result of the INPUT register after it's been evaluated. The OUTPUT
	    register is thrown away, because it doesn't actually matter to the algorithm
	    at all.

    Remarks:
        A lot of literature out there will say that this returns a string where
	    s · x = 0. This is misleading, because what they really mean is
	    "dot product mod-2" and they don't usually say the "mod-2" part.
	    Basically, this finds an input value that, when dot product'd with S,
	    gives an even number.
    """

    # Construct the engine and registers
    engine = MainEngine()
    input = engine.allocate_qureg(input_size)
    output = engine.allocate_qureg(input_size)

    # Run the function with |+...+> as the input and |0...0> as the output
    All(H) | input
    function(input, output)
    All(H) | input

    # At this point, the input bit string has been transformed
    # from |0...0> into X, where X is some string that is guaranteed
    # to be even when dot product'd with S. The math behind why this
    # is true is way beyond an explanation here - you have to look
    # at the literature to see why this is the case.

    # Measure the resulting input register and return it as a list[bool] for
    # classical postprocessing
    measurement = [False] * input_size
    for i in range(0, input_size):
        Measure | input[i]
        measurement[i] = (int(input[i]) == 1)

    reset(output
          )  # This isn't strictly necessary, but the simulator will complain
    engine.flush(
    )  # about deleting qubits that are still in a superposition even
    return measurement  # though the program is finished.
def test_uniformly_controlled_ry(n, gate_classes):
    random_angles = [
        0.5, 0.8, 1.2, 2.5, 4.4, 2.32, 6.6, 15.12, 1, 2, 9.54, 2.1, 3.1415,
        1.1, 0.01, 0.99
    ]
    angles = random_angles[:2**n]
    for basis_state_index in range(0, 2**(n + 1)):
        basis_state = [0] * 2**(n + 1)
        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=[ucr2cnot])
        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(n)
        correct_eng.flush()
        test_qb = test_eng.allocate_qubit()
        test_ctrl_qureg = test_eng.allocate_qureg(n)
        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)

        gate_classes[1](angles) | (test_ctrl_qureg, test_qb)
        slow_implementation(angles=angles,
                            control_qubits=correct_ctrl_qureg,
                            target_qubit=correct_qb,
                            eng=correct_eng,
                            gate_class=gate_classes[0])
        test_eng.flush()
        correct_eng.flush()

        for fstate in range(2**(n + 1)):
            binary_state = format(fstate, '0' + str(n + 1) + 'b')
            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-10, abs=1e-10)

        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)
Example #13
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()
Example #14
0
def test_simulator_bit_repositioning():
    sim = ClassicalSimulator()
    eng = MainEngine(sim, [])
    a = eng.allocate_qureg(4)
    b = eng.allocate_qureg(5)
    c = eng.allocate_qureg(6)
    sim.write_register(a, 9)
    sim.write_register(b, 17)
    sim.write_register(c, 33)
    for q in b:
        eng.deallocate_qubit(q)
    assert sim.read_register(a) == 9
    assert sim.read_register(c) == 33
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)
    def test_ffft_2d_4x4_equal_expectation_values(self):
        system_size = 4
        n_qubits = 16
        grid = Grid(dimensions=2, length=system_size, scale=1.0)
        dual_basis = jellium_model(grid, spinless=True, plane_wave=False)
        ffft_result = operator_2d_fft_with_reordering(dual_basis, system_size)

        jw_dual_basis = jordan_wigner(dual_basis)
        jw_plane_wave = jordan_wigner(ffft_result)

        # Do plane wave and dual basis calculations together.
        pw_engine = MainEngine()
        pw_wavefunction = pw_engine.allocate_qureg(system_size ** 2)
        db_engine = MainEngine()
        db_wavefunction = db_engine.allocate_qureg(system_size ** 2)

        pw_engine.flush()
        db_engine.flush()

        # Choose random state.
        state = numpy.zeros(2 ** n_qubits, dtype=complex)
        for i in range(len(state)):
            state[i] = (random.random() *
                        numpy.exp(1j * 2 * numpy.pi * random.random()))
        state /= numpy.linalg.norm(state)

        # Put randomly chosen state in the registers.
        pw_engine.backend.set_wavefunction(state, pw_wavefunction)
        db_engine.backend.set_wavefunction(state, db_wavefunction)

        # Apply the FFFT to the dual basis wave function.
        ffft_2d(db_engine, db_wavefunction, system_size)

        # Flush the engine and compute expectation values and eigenvalues.
        pw_engine.flush()
        db_engine.flush()

        plane_wave_expectation_value = (
            pw_engine.backend.get_expectation_value(
                jw_dual_basis, pw_wavefunction))
        dual_basis_expectation_value = (
            db_engine.backend.get_expectation_value(
                jw_plane_wave, db_wavefunction))

        All(Measure) | pw_wavefunction
        All(Measure) | db_wavefunction

        self.assertAlmostEqual(plane_wave_expectation_value,
                               dual_basis_expectation_value)
Example #17
0
def test_control():
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend, engine_list=[DummyEngine()])
    qureg = eng.allocate_qureg(2)
    with _control.Control(eng, qureg):
        qubit = eng.allocate_qubit()
        with Compute(eng):
            Rx(0.5) | qubit
        H | qubit
        Uncompute(eng)
    with _control.Control(eng, qureg[0]):
        H | qubit
    eng.flush()
    assert len(backend.received_commands) == 8
    assert len(backend.received_commands[0].control_qubits) == 0
    assert len(backend.received_commands[1].control_qubits) == 0
    assert len(backend.received_commands[2].control_qubits) == 0
    assert len(backend.received_commands[3].control_qubits) == 0
    assert len(backend.received_commands[4].control_qubits) == 2
    assert len(backend.received_commands[5].control_qubits) == 0
    assert len(backend.received_commands[6].control_qubits) == 1
    assert len(backend.received_commands[7].control_qubits) == 0
    assert backend.received_commands[4].control_qubits[0].id == qureg[0].id
    assert backend.received_commands[4].control_qubits[1].id == qureg[1].id
    assert backend.received_commands[6].control_qubits[0].id == qureg[0].id
Example #18
0
def test_drawer_getlatex(ordered):
    old_latex = _drawer.to_latex
    _drawer.to_latex = lambda x, drawing_order, draw_gates_in_parallel: x

    drawer = CircuitDrawer()
    drawer.set_qubit_locations({0: 1, 1: 0})

    drawer2 = CircuitDrawer()

    eng = MainEngine(drawer, [drawer2])
    qureg = eng.allocate_qureg(2)
    H | qureg[1]
    H | qureg[0]
    X | qureg[0]
    CNOT | (qureg[0], qureg[1])

    lines = drawer2.get_latex(ordered=ordered)
    assert len(lines) == 2
    assert len(lines[0]) == 4
    assert len(lines[1]) == 3

    # check if it was sent on correctly:
    lines = drawer.get_latex(ordered=ordered)
    assert len(lines) == 2
    assert len(lines[0]) == 3
    assert len(lines[1]) == 4

    _drawer.to_latex = old_latex
Example #19
0
def test_simulator_read_write(mapper):
    engine_list = []
    if mapper is not None:
        engine_list.append(mapper)
    sim = ClassicalSimulator()
    eng = MainEngine(sim, engine_list)
    a = eng.allocate_qureg(32)
    b = eng.allocate_qureg(32)

    assert sim.read_register(a) == 0
    assert sim.read_register(b) == 0
    assert sim.read_bit(a[0]) == 0
    assert sim.read_bit(b[0]) == 0

    sim.write_register(a, 123)
    sim.write_register(b, 456)
    assert sim.read_register(a) == 123
    assert sim.read_register(b) == 456
    assert sim.read_bit(a[0]) == 1
    assert sim.read_bit(b[0]) == 0

    sim.write_bit(b[0], 1)
    assert sim.read_register(a) == 123
    assert sim.read_register(b) == 457
    assert sim.read_bit(a[0]) == 1
    assert sim.read_bit(b[0]) == 1
def test_or_not_enough_qubits():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend, engine_list=[])
    qureg = eng.allocate_qureg(2)
    hamiltonian = QubitOperator("Z0 X3", 2)
    with pytest.raises(ValueError):
        te.TimeEvolution(2.1, hamiltonian) | qureg
Example #21
0
def test_simulator_bit_repositioning(mapper):
    engine_list = []
    if mapper is not None:
        engine_list.append(mapper)
    sim = ClassicalSimulator()
    eng = MainEngine(sim, engine_list)
    a = eng.allocate_qureg(4)
    b = eng.allocate_qureg(5)
    c = eng.allocate_qureg(6)
    sim.write_register(a, 9)
    sim.write_register(b, 17)
    sim.write_register(c, 33)
    for q in b:
        eng.deallocate_qubit(q)
    assert sim.read_register(a) == 9
    assert sim.read_register(c) == 33
Example #22
0
def test_or_one_qubit():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend, engine_list=[])
    qureg = eng.allocate_qureg(3)
    eng.flush()
    identity = qo.QubitOperator("", 1j)
    x = qo.QubitOperator("X1", cmath.exp(0.5j))
    y = qo.QubitOperator("Y2", cmath.exp(0.6j))
    z = qo.QubitOperator("Z0", cmath.exp(4.5j))
    identity | qureg
    eng.flush()
    x | qureg
    eng.flush()
    y | qureg
    eng.flush()
    z | qureg
    eng.flush()
    assert saving_backend.received_commands[4].gate == Ph(math.pi / 2.)

    assert saving_backend.received_commands[6].gate == X
    assert saving_backend.received_commands[6].qubits == ([qureg[1]], )
    assert saving_backend.received_commands[7].gate == Ph(0.5)
    assert saving_backend.received_commands[7].qubits == ([qureg[1]], )

    assert saving_backend.received_commands[9].gate == Y
    assert saving_backend.received_commands[9].qubits == ([qureg[2]], )
    assert saving_backend.received_commands[10].gate == Ph(0.6)
    assert saving_backend.received_commands[10].qubits == ([qureg[2]], )

    assert saving_backend.received_commands[12].gate == Z
    assert saving_backend.received_commands[12].qubits == ([qureg[0]], )
    assert saving_backend.received_commands[13].gate == Ph(4.5)
    assert saving_backend.received_commands[13].qubits == ([qureg[0]], )
def test_qubit_allocations_at_zero():
    drawer = _drawer.CircuitDrawer()
    eng = MainEngine(drawer, [])
    old_tolatex = _drawer.to_latex
    _drawer.to_latex = lambda x: x

    a = eng.allocate_qureg(4)

    CNOT | (a[0], a[2])
    CNOT | (a[0], a[3])
    CNOT | (a[0], a[2])
    CNOT | (a[1], a[3])

    del a
    eng.flush()

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

    settings = _to_latex.get_default_settings()
    settings['gates']['AllocateQubitGate']['allocate_at_zero'] = True
    code = _to_latex._body(copy.deepcopy(circuit_lines), settings)
    assert code.count("gate0) at (0") == 4

    settings['gates']['AllocateQubitGate']['allocate_at_zero'] = False
    code = _to_latex._body(copy.deepcopy(circuit_lines), settings)
    assert code.count("gate0) at (0") == 3

    del settings['gates']['AllocateQubitGate']['allocate_at_zero']
    code = _to_latex._body(copy.deepcopy(circuit_lines), settings)
    assert code.count("gate0) at (0") == 3
def circuit_no_ancilla(param=0, M=1):

    Engine = MainEngine()

    q1 = Engine.allocate_qureg(1)

    Rx(param) | q1

    # [R * c-Pi * R^\dag * P * R * c-Pi * R^\dag * P]
    for _ in range(int(M / 2)):
        Z | q1

        DaggeredGate(Rx(param)) | q1

        Z | q1

        Rx(param) | q1

        Z | q1

        DaggeredGate(Rx(param)) | q1

        Z | q1

        Rx(param) | q1

    DaggeredGate(Rx(param)) | q1

    Measure | q1

    Engine.flush()

    return (int(q1))
Example #25
0
def test_simulator_collapse_wavefunction(sim):
    eng = MainEngine(sim)
    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])
    assert (pytest.approx(eng.backend.get_probability([0, 1, 0, 1],
                                                      qubits)) == .5)
    eng.backend.set_wavefunction([1.] + [0.] * 15, qubits)
    H | qubits[0]
    CNOT | (qubits[0], qubits[1])
    eng.flush()
    eng.backend.collapse_wavefunction([qubits[0]], [1])
    assert (pytest.approx(eng.backend.get_probability([1, 1],
                                                      qubits[0:2])) == 1.)
Example #26
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)
Example #27
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
Example #28
0
def test_ibm_backend_is_available_control_not(num_ctrl_qubits, is_available):
    eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()])
    qubit1 = eng.allocate_qubit()
    qureg = eng.allocate_qureg(num_ctrl_qubits)
    ibm_backend = _ibm.IBMBackend()
    cmd = Command(eng, NOT, (qubit1, ), controls=qureg)
    assert ibm_backend.is_available(cmd) == is_available
Example #29
0
def test_flip_bits_can_be_applied_to_various_qubit_qureg_formats():
    eng = MainEngine()
    qubits = eng.allocate_qureg(4)
    eng.flush()
    assert pytest.approx(eng.backend.get_probability('0000', qubits)) == 1.
    FlipBits([0, 1, 1, 0]) | qubits
    eng.flush()
    assert pytest.approx(eng.backend.get_probability('0110', qubits)) == 1.
    FlipBits([1]) | qubits[0]
    eng.flush()
    assert pytest.approx(eng.backend.get_probability('1110', qubits)) == 1.
    FlipBits([1]) | (qubits[0], )
    eng.flush()
    assert pytest.approx(eng.backend.get_probability('0110', qubits)) == 1.
    FlipBits([1, 1]) | [qubits[0], qubits[1]]
    eng.flush()
    assert pytest.approx(eng.backend.get_probability('1010', qubits)) == 1.
    FlipBits(-1) | qubits
    eng.flush()
    assert pytest.approx(eng.backend.get_probability('0101', qubits)) == 1.
    FlipBits(-4) | [qubits[0], qubits[1], qubits[2], qubits[3]]
    eng.flush()
    assert pytest.approx(eng.backend.get_probability('0110', qubits)) == 1.
    FlipBits(2) | [qubits[0]] + [qubits[1], qubits[2]]
    eng.flush()
    assert pytest.approx(eng.backend.get_probability('0010', qubits)) == 1.
    All(Measure) | qubits
Example #30
0
def test_simulator_flip_bits(bits_to_flip, result):
    eng = MainEngine()
    qubits = eng.allocate_qureg(4)
    FlipBits(bits_to_flip) | qubits
    eng.flush()
    assert pytest.approx(eng.backend.get_probability(result, qubits)) == 1.
    All(Measure) | qubits
    def run_circuit(self, circuit):
        """Run a circuit and return a single Result.

        Args:
            circuit (dict): JSON circuit from qobj circuits list

        Returns:
            dict: A dictionary of results which looks something like::

                {
                "data":
                    {  #### DATA CAN BE A DIFFERENT DICTIONARY FOR EACH BACKEND ####
                    "counts": {'00000': XXXX, '00001': XXXXX},
                    "time"  : xx.xxxxxxxx
                    },
                "status": --status (string)--
                }
        Raises:
            SimulatorError: if an error occurred.
        """
        # pylint: disable=expression-not-assigned,pointless-statement
        ccircuit = circuit['compiled_circuit']
        self._number_of_qubits = ccircuit['header']['number_of_qubits']
        self._number_of_clbits = ccircuit['header']['number_of_clbits']
        self._statevector = 0
        self._classical_state = 0
        cl_reg_index = []  # starting bit index of classical register
        cl_reg_nbits = []  # number of bits in classical register
        clbit_index = 0
        qobj_quregs = OrderedDict(_get_register_specs(
            ccircuit['header']['qubit_labels']))
        eng = MainEngine(backend=self._sim)
        for cl_reg in ccircuit['header']['clbit_labels']:
            cl_reg_nbits.append(cl_reg[1])
            cl_reg_index.append(clbit_index)
            clbit_index += cl_reg[1]
        # let circuit seed override qobj default
        if 'config' in circuit:
            if 'seed' in circuit['config']:
                if circuit['config']['seed'] is not None:
                    self._sim._simulator = CppSim(circuit['config']['seed'])
        outcomes = []
        start = time.time()
        for _ in range(self._shots):
            self._statevector = np.zeros(1 << self._number_of_qubits,
                                         dtype=complex)
            self._statevector[0] = 1
            # initialize starting state
            self._classical_state = 0
            unmeasured_qubits = list(range(self._number_of_qubits))
            projq_qureg_dict = OrderedDict(((key, eng.allocate_qureg(size))
                                            for key, size in
                                            qobj_quregs.items()))
            qureg = [qubit for sublist in projq_qureg_dict.values()
                     for qubit in sublist]
            # Do each operation in this shot
            for operation in ccircuit['operations']:
                if 'conditional' in operation:
                    mask = int(operation['conditional']['mask'], 16)
                    if mask > 0:
                        value = self._classical_state & mask
                        while (mask & 0x1) == 0:
                            mask >>= 1
                            value >>= 1
                        if value != int(operation['conditional']['val'], 16):
                            continue
                # Check if single  gate
                if operation['name'] in ['U', 'u3']:
                    params = operation['params']
                    qubit = qureg[operation['qubits'][0]]
                    Rz(params[2]) | qubit
                    Ry(params[0]) | qubit
                    Rz(params[1]) | qubit
                elif operation['name'] in ['u1']:
                    params = operation['params']
                    qubit = qureg[operation['qubits'][0]]
                    Rz(params[0]) | qubit
                elif operation['name'] in ['u2']:
                    params = operation['params']
                    qubit = qureg[operation['qubits'][0]]
                    Rz(params[1] - np.pi/2) | qubit
                    Rx(np.pi/2) | qubit
                    Rz(params[0] + np.pi/2) | qubit
                elif operation['name'] == 't':
                    qubit = qureg[operation['qubits'][0]]
                    T | qubit
                elif operation['name'] == 'h':
                    qubit = qureg[operation['qubits'][0]]
                    H | qubit
                elif operation['name'] == 's':
                    qubit = qureg[operation['qubits'][0]]
                    S | qubit
                elif operation['name'] in ['CX', 'cx']:
                    qubit0 = qureg[operation['qubits'][0]]
                    qubit1 = qureg[operation['qubits'][1]]
                    CX | (qubit0, qubit1)
                elif operation['name'] in ['id', 'u0']:
                    pass
                # Check if measure
                elif operation['name'] == 'measure':
                    qubit_index = operation['qubits'][0]
                    qubit = qureg[qubit_index]
                    clbit = operation['clbits'][0]
                    Measure | qubit
                    bit = 1 << clbit
                    self._classical_state = (
                        self._classical_state & (~bit)) | (int(qubit)
                                                           << clbit)
                    # check whether we already measured this qubit
                    if operation['qubits'][0] in unmeasured_qubits:
                        unmeasured_qubits.remove(operation['qubits'][0])
                # Check if reset
                elif operation['name'] == 'reset':
                    qubit = operation['qubits'][0]
                    raise SimulatorError('Reset operation not yet implemented '
                                         'for ProjectQ C++ backend')
                elif operation['name'] == 'barrier':
                    pass
                else:
                    backend = self._configuration['name']
                    err_msg = '{0} encountered unrecognized operation "{1}"'
                    raise SimulatorError(err_msg.format(backend,
                                                        operation['name']))
            for ind in unmeasured_qubits:
                qubit = qureg[ind]
                Measure | qubit
            eng.flush()
            # Turn classical_state (int) into bit string
            state = format(self._classical_state, 'b')
            outcomes.append(state.zfill(self._number_of_clbits))
        # Return the results
        counts = dict(Counter(outcomes))
        data = {'counts': _format_result(
            counts, cl_reg_index, cl_reg_nbits)}
        if self._shots == 1:
            # TODO: deprecated -- remove in v0.6
            data['statevector'] = self._statevector
            data['quantum_state'] = self._statevector
            data['classical_state'] = self._classical_state
        end = time.time()
        return {'name': circuit['name'],
                'seed': self._seed,
                'shots': self._shots,
                'data': data,
                'status': 'DONE',
                'success': True,
                'time_taken': (end-start)}