#   Copyright 2017 ProjectQ-Framework (www.projectq.ch)
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

"""
Tests for projectq.backends._sim._simulator.py, using both the Python
and the C++ simulator as backends.
"""

import copy
import math
import cmath
import numpy
import pytest
import random
import scipy
import scipy.sparse
import scipy.sparse.linalg

from projectq import MainEngine
from projectq.cengines import (BasicEngine, BasicMapperEngine, DummyEngine,
                               LocalOptimizer, NotYetMeasuredError)
from projectq.ops import (All, Allocate, BasicGate, BasicMathGate, CNOT, C,
                          Command, H, Measure, QubitOperator, Rx, Ry, Rz, S,
                          TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap,
                          UniformlyControlledRy, UniformlyControlledRz)
from projectq.libs.math import (AddConstant,
                                AddConstantModN,
                                SubConstant,
                                SubConstantModN,
                                MultiplyByConstantModN)
from projectq.meta import Compute, Uncompute, Control, Dagger, LogicalQubitIDTag
from projectq.types import WeakQubitRef

from projectq.backends import Simulator


tolerance = 1e-6


def test_is_qrack_simulator_present():
    _qracksim = pytest.importorskip("projectq.backends._qracksim._qracksim")
    import projectq.backends._qracksim._qracksim as _


def get_available_simulators():
    result = []
    try:
        test_is_qrack_simulator_present()
        result.append("qrack_simulator_qengine")
        result.append("qrack_simulator_qunit")
    except:
        pass
    return result


@pytest.fixture(params=get_available_simulators())
def sim(request):
    if request.param == "qrack_simulator_qengine":
        from projectq.backends._qracksim._qracksim import QrackSimulator as QrackSim
        sim = Simulator()
        sim._simulator = QrackSim(1, -1, 1)
    elif request.param == "qrack_simulator_qunit":
        from projectq.backends._qracksim._qracksim import QrackSimulator as QrackSim
        sim = Simulator()
        sim._simulator = QrackSim(1, -1, 2)
    return sim


@pytest.fixture(params=["mapper", "no_mapper"])
def mapper(request):
    """
    Adds a mapper which changes qubit ids by adding 1
    """
    if request.param == "mapper":

        class TrivialMapper(BasicMapperEngine):
            def __init__(self):
                BasicEngine.__init__(self)
                self.current_mapping = dict()

            def receive(self, command_list):
                for cmd in command_list:
                    for qureg in cmd.all_qubits:
                        for qubit in qureg:
                            if qubit.id == -1:
                                continue
                            elif qubit.id not in self.current_mapping:
                                previous_map = self.current_mapping
                                previous_map[qubit.id] = qubit.id + 1
                                self.current_mapping = previous_map
                    self._send_cmd_with_mapped_ids(cmd)

        return TrivialMapper()
    if request.param == "no_mapper":
        return None


class Mock1QubitGate(BasicGate):
        def __init__(self):
            BasicGate.__init__(self)
            self.cnt = 0

        @property
        def matrix(self):
            self.cnt += 1
            return numpy.matrix([[0, 1],
                                 [1, 0]])


class Mock6QubitGate(BasicGate):
        def __init__(self):
            BasicGate.__init__(self)
            self.cnt = 0

        @property
        def matrix(self):
            self.cnt += 1
            return numpy.eye(2 ** 6)


class MockNoMatrixGate(BasicGate):
        def __init__(self):
            BasicGate.__init__(self)
            self.cnt = 0

        @property
        def matrix(self):
            self.cnt += 1
            raise AttributeError


def test_simulator_is_available(sim):
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend, [])
    qubit = eng.allocate_qubit()
    Measure | qubit
    qubit[0].__del__()
    assert len(backend.received_commands) == 3

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

    new_cmd = backend.received_commands[-1]

    new_cmd.gate = Mock6QubitGate()
    assert not sim.is_available(new_cmd)

    new_cmd.gate = MockNoMatrixGate()
    assert not sim.is_available(new_cmd)

    new_cmd.gate = Mock1QubitGate()
    assert sim.is_available(new_cmd)

    new_cmd = backend.received_commands[-2]
    assert len(new_cmd.qubits) == 1

    new_cmd.gate = AddConstantModN(1, 2)
    assert sim.is_available(new_cmd)

    new_cmd.gate = MultiplyByConstantModN(1, 2)
    assert sim.is_available(new_cmd)

    #new_cmd.gate = DivideByConstantModN(1, 2)
    #assert sim.is_available(new_cmd)


def test_simulator_cheat(sim):
    # cheat function should return a tuple
    assert isinstance(sim.cheat(), tuple)
    # first entry is the qubit mapping.
    # should be empty:
    assert len(sim.cheat()[0]) == 0
    # state vector should only have 1 entry:
    assert len(sim.cheat()[1]) == 1

    eng = MainEngine(sim, [])
    qubit = eng.allocate_qubit()

    # one qubit has been allocated
    assert len(sim.cheat()[0]) == 1
    assert sim.cheat()[0][0] == 0
    assert len(sim.cheat()[1]) == 2
    assert 1. == pytest.approx(abs(sim.cheat()[1][0]))

    qubit[0].__del__()
    # should be empty:
    assert len(sim.cheat()[0]) == 0
    # state vector should only have 1 entry:
    assert len(sim.cheat()[1]) == 1


def test_simulator_functional_measurement(sim):
    eng = MainEngine(sim, [])
    qubits = eng.allocate_qureg(5)
    # entangle all qubits:
    H | qubits[0]
    for qb in qubits[1:]:
        CNOT | (qubits[0], qb)

    All(Measure) | qubits

    bit_value_sum = sum([int(qubit) for qubit in qubits])
    assert bit_value_sum == 0 or bit_value_sum == 5


def test_simulator_measure_mapped_qubit(sim):
    eng = MainEngine(sim, [])
    qb1 = WeakQubitRef(engine=eng, idx=1)
    qb2 = WeakQubitRef(engine=eng, idx=2)
    cmd0 = Command(engine=eng, gate=Allocate, qubits=([qb1],))
    cmd1 = Command(engine=eng, gate=X, qubits=([qb1],))
    cmd2 = Command(engine=eng, gate=Measure, qubits=([qb1],), controls=[],
                   tags=[LogicalQubitIDTag(2)])
    with pytest.raises(NotYetMeasuredError):
        int(qb1)
    with pytest.raises(NotYetMeasuredError):
        int(qb2)
    eng.send([cmd0, cmd1, cmd2])
    eng.flush()
    with pytest.raises(NotYetMeasuredError):
        int(qb1)
    assert int(qb2) == 1


def test_simulator_kqubit_exception(sim):
    m1 = Rx(0.3).matrix
    m2 = Rx(0.8).matrix
    m3 = Ry(0.1).matrix
    m4 = Rz(0.9).matrix.dot(Ry(-0.1).matrix)
    m = numpy.kron(m4, numpy.kron(m3, numpy.kron(m2, m1)))

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

    eng = MainEngine(sim, [])
    qureg = eng.allocate_qureg(3)
    with pytest.raises(Exception):
        KQubitGate() | qureg
    with pytest.raises(Exception):
        H | qureg


def test_simulator_swap(sim):
    eng = MainEngine(sim, [])
    qubits1 = eng.allocate_qureg(1)
    qubits2 = eng.allocate_qureg(1)

    X | qubits1

    Swap | (qubits1, qubits2)
    All(Measure) | qubits1
    All(Measure) | qubits2
    assert (int(qubits1[0]) == 0) and (int(qubits2[0]) == 1)

    SqrtSwap | (qubits1, qubits2)
    SqrtSwap | (qubits1, qubits2)
    All(Measure) | qubits1
    All(Measure) | qubits2
    assert (int(qubits1[0]) == 1) and (int(qubits2[0]) == 0)


def test_simulator_math(sim):
    eng = MainEngine(sim, [])
    qubits = eng.allocate_qureg(8)

    AddConstant(1) | qubits;
    All(Measure) | qubits
    value = 0
    for i in range(len(qubits)):
        value += int(qubits[i]) << i
    assert value == 1

    AddConstantModN(10, 256) | qubits;
    All(Measure) | qubits
    value = 0
    for i in range(len(qubits)):
        value += int(qubits[i]) << i
    assert value == 11

    controls = eng.allocate_qureg(1)

    # Control is off
    C(AddConstantModN(10, 256)) | (controls, qubits)
    All(Measure) | qubits
    value = 0
    for i in range(len(qubits)):
        value += int(qubits[i]) << i
    assert value == 11

    # Turn control on
    X | controls

    C(AddConstantModN(10, 256)) | (controls, qubits)
    All(Measure) | qubits
    value = 0
    for i in range(len(qubits)):
        value += int(qubits[i]) << i
    assert value == 21

    SubConstant(5) | qubits;
    All(Measure) | qubits
    value = 0
    for i in range(len(qubits)):
        value += int(qubits[i]) << i
    assert value == 16

    C(SubConstantModN(10, 256)) | (controls, qubits)
    All(Measure) | qubits
    value = 0
    for i in range(len(qubits)):
        value += int(qubits[i]) << i
    assert value == 6

    # Turn control off
    X | controls

    C(SubConstantModN(10, 256)) | (controls, qubits)
    All(Measure) | qubits
    value = 0
    for i in range(len(qubits)):
        value += int(qubits[i]) << i
    assert value == 6

    MultiplyByConstantModN(2, 256) | qubits;
    All(Measure) | qubits
    value = 0
    for i in range(len(qubits)):
        value += int(qubits[i]) << i
    assert value == 12

    # Control is off

    C(MultiplyByConstantModN(2, 256)) | (controls, qubits)
    All(Measure) | qubits
    value = 0
    for i in range(len(qubits)):
        value += int(qubits[i]) << i
    assert value == 12

    # Turn control on
    X | controls

    C(MultiplyByConstantModN(10, 256)) | (controls, qubits)
    All(Measure) | qubits
    value = 0
    for i in range(len(qubits)):
        value += int(qubits[i]) << i
    assert value == 120


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 (numpy.isclose(0.12, eng.backend.get_probability([0, 0], qubits[:3:2]), rtol=tolerance, atol=tolerance))
    assert (numpy.isclose(0.18, eng.backend.get_probability([0, 1], qubits[:3:2]), rtol=tolerance, atol=tolerance))
    assert (numpy.isclose(0.28, eng.backend.get_probability([1, 0], qubits[:3:2]), rtol=tolerance, atol=tolerance))
    All(Measure) | qubits


def test_simulator_amplitude(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(X) | qubits
    All(H) | qubits
    eng.flush()
    bits = [0, 0, 1, 0, 1, 0]
    polR, polPhi = cmath.polar(eng.backend.get_amplitude(bits, qubits))
    while polPhi < 0:
        polPhi += 2 * math.pi
    assert polR == pytest.approx(1. / 8.)
    bits = [0, 0, 0, 0, 1, 0]
    polR2, polPhi2 = cmath.polar(eng.backend.get_amplitude(bits, qubits))
    while polPhi2 < math.pi:
        polPhi2 += 2 * math.pi
    assert polR2 == pytest.approx(polR)
    assert (polPhi2 - math.pi) == pytest.approx(polPhi)
    bits = [0, 1, 1, 0, 1, 0]
    polR3, polPhi3 = cmath.polar(eng.backend.get_amplitude(bits, qubits))
    while polPhi3 < math.pi:
        polPhi3 += 2 * math.pi
    assert polR3 == pytest.approx(polR)
    assert (polPhi3 - math.pi) == pytest.approx(polPhi)
    All(H) | qubits
    All(X) | qubits
    Ry(2 * math.acos(0.3)) | qubits[0]
    eng.flush()
    bits = [0] * 6
    polR, polPhi = cmath.polar(eng.backend.get_amplitude(bits, qubits))
    assert polR == pytest.approx(0.3)
    bits[0] = 1
    polR, polPhi = cmath.polar(eng.backend.get_amplitude(bits, qubits))
    assert (polR ==
            pytest.approx(math.sqrt(0.91)))
    All(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)


def test_simulator_set_wavefunction(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(2)
    wf = [0., 0., math.sqrt(0.2), math.sqrt(0.8)]
    with pytest.raises(RuntimeError):
        eng.backend.set_wavefunction(wf, qubits)
    eng.flush()
    eng.backend.set_wavefunction(wf, qubits)
    assert pytest.approx(eng.backend.get_probability('1', [qubits[0]])) == .8
    assert pytest.approx(eng.backend.get_probability('01', qubits)) == .2
    assert pytest.approx(eng.backend.get_probability('1', [qubits[1]])) == 1.
    All(Measure) | qubits


def test_simulator_set_wavefunction_always_complex(sim):
    """ Checks that wavefunction is always complex """
    eng = MainEngine(sim)
    qubit = eng.allocate_qubit()
    eng.flush()
    wf = [1., 0]
    eng.backend.set_wavefunction(wf, qubit)
    Y | qubit
    eng.flush()
    amplitude = eng.backend.get_amplitude('1', qubit)
    assert amplitude == pytest.approx(1j) or amplitude == pytest.approx(-1j)


def test_simulator_collapse_wavefunction(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(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)
    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])
    probability = eng.backend.get_probability([1, 1], qubits[0:2])
    assert probability == pytest.approx(1.)


def test_simulator_no_uncompute_exception(sim):
    eng = MainEngine(sim, [])
    qubit = eng.allocate_qubit()
    H | qubit
    with pytest.raises(RuntimeError):
        qubit[0].__del__()
    # If you wanted to keep using the qubit, you shouldn't have deleted it.
    assert qubit[0].id == -1


def test_simulator_functional_entangle(sim):
    eng = MainEngine(sim, [])
    qubits = eng.allocate_qureg(5)
    # entangle all qubits:
    H | qubits[0]
    for qb in qubits[1:]:
        CNOT | (qubits[0], qb)

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

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

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

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

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

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

    All(Measure) | qubits


def test_simulator_convert_logical_to_mapped_qubits(sim):
    mapper = BasicMapperEngine()

    def receive(command_list):
        pass

    mapper.receive = receive
    eng = MainEngine(sim, [mapper])
    qubit0 = eng.allocate_qubit()
    qubit1 = eng.allocate_qubit()
    mapper.current_mapping = {qubit0[0].id: qubit1[0].id,
                              qubit1[0].id: qubit0[0].id}
    assert (sim._convert_logical_to_mapped_qureg(qubit0 + qubit1) ==
            qubit1 + qubit0)


def slow_implementation(angles, control_qubits, target_qubit, eng, gate_class):
    """
    Assumption is that control_qubits[0] is lowest order bit
    We apply angles[0] to state |0>
    """
    assert len(angles) == 2**len(control_qubits)
    for index in range(2**len(control_qubits)):
        with Compute(eng):
            for bit_pos in range(len(control_qubits)):
                if not (index >> bit_pos) & 1:
                    X | control_qubits[bit_pos]
        with Control(eng, control_qubits):
            gate_class(angles[index]) | target_qubit
        Uncompute(eng)


@pytest.mark.parametrize("gate_classes", [(Ry, UniformlyControlledRy),
                                          (Rz, UniformlyControlledRz)])
def test_uniformly_controlled_r(sim, gate_classes):
    n = 2
    random_angles = [3.0, 0.8, 1.2, 0.7]

    basis_state_index = 2
    basis_state = [0] * 2**(n+1)
    basis_state[basis_state_index] = 1.

    correct_eng = MainEngine(backend=Simulator())
    test_eng = MainEngine(backend=sim)

    correct_sim = correct_eng.backend
    correct_qb = correct_eng.allocate_qubit()
    correct_ctrl_qureg = correct_eng.allocate_qureg(n)
    correct_eng.flush()

    test_sim = test_eng.backend
    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)
    test_eng.flush()
    correct_eng.flush()

    gate_classes[1](random_angles) | (test_ctrl_qureg, test_qb)
    slow_implementation(angles=random_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)
        print(test, "==", correct)
        assert correct == pytest.approx(test, rel=tolerance, abs=tolerance)

    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)

def test_qubit_operator(sim):
    test_eng = MainEngine(sim)
    test_qureg = test_eng.allocate_qureg(1)
    test_eng.flush()

    qubit_op = QubitOperator("X0 X1", 1)
    with pytest.raises(Exception):
        sim.get_expectation_value(qubit_op, test_qureg)

    test_eng.backend.set_wavefunction([1, 0],
                                      test_qureg)
    test_eng.flush()
    qubit_op = QubitOperator("X0", 1)
    qubit_op | test_qureg[0]
    test_eng.flush()

    amplitude = test_eng.backend.get_amplitude('0', test_qureg)
    assert amplitude == pytest.approx(0.)
    amplitude = test_eng.backend.get_amplitude('1', test_qureg)
    assert amplitude == pytest.approx(1.)

def test_get_expectation_value(sim):
    num_qubits = 2
    test_eng = MainEngine(sim)
    test_qureg = test_eng.allocate_qureg(num_qubits)
    test_eng.flush()

    qubit_op = QubitOperator("X0 X1 X2", 1)
    with pytest.raises(Exception):
        sim.get_expectation_value(qubit_op, test_qureg)

    qubit_op = QubitOperator("X0", 1)
    test_eng.backend.set_wavefunction([1 / math.sqrt(2), 1 / math.sqrt(2), 0, 0],
                                      test_qureg)
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(1, rel=tolerance, abs=tolerance))
    test_eng.backend.set_wavefunction([1 / math.sqrt(2), -1 / math.sqrt(2), 0, 0],
                                      test_qureg)
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(-1, rel=tolerance, abs=tolerance))

    qubit_op = QubitOperator("Y0", 1)
    test_eng.backend.set_wavefunction([1 / math.sqrt(2), 1j / math.sqrt(2), 0, 0],
                                      test_qureg)
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(1, rel=tolerance, abs=tolerance))
    test_eng.backend.set_wavefunction([1 / math.sqrt(2), -1j / math.sqrt(2), 0, 0],
                                      test_qureg)
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(-1, rel=tolerance, abs=tolerance))

    qubit_op = QubitOperator("Z0", 1)
    test_eng.backend.set_wavefunction([1, 0, 0, 0],
                                      test_qureg)
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(1, rel=tolerance, abs=tolerance))
    test_eng.backend.set_wavefunction([0, 1, 0, 0],
                                      test_qureg)
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(-1, rel=tolerance, abs=tolerance))

    qubit_op = QubitOperator("Z0", 0.25)
    test_eng.backend.set_wavefunction([1, 0, 0, 0],
                                      test_qureg)
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(0.25, rel=tolerance, abs=tolerance))
    test_eng.backend.set_wavefunction([0, 1, 0, 0],
                                      test_qureg)
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(-0.25, rel=tolerance, abs=tolerance))

    qubit_op = QubitOperator("Z0 Z1", 1)
    test_eng.backend.set_wavefunction([1, 0, 0, 0],
                                      test_qureg)
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(1, rel=tolerance, abs=tolerance))
    X | test_qureg[0]
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(-1, rel=tolerance, abs=tolerance))
    X | test_qureg[1]
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(1, rel=tolerance, abs=tolerance))
    X | test_qureg[0]
    test_eng.flush()
    assert(sim.get_expectation_value(qubit_op, test_qureg) == pytest.approx(-1, rel=tolerance, abs=tolerance))

[((80, 1, 80, 47), 'pytest.fixture', 'pytest.fixture', (), '', False, 'import pytest\n'), ((593, 1, 594, 71), 'pytest.mark.parametrize', 'pytest.mark.parametrize', ({(593, 25, 593, 39): '"""gate_classes"""', (593, 41, 594, 70): '[(Ry, UniformlyControlledRy), (Rz, UniformlyControlledRz)]'}, {}), "('gate_classes', [(Ry, UniformlyControlledRy), (Rz,\n    UniformlyControlledRz)])", False, 'import pytest\n'), ((52, 16, 52, 76), 'pytest.importorskip', 'pytest.importorskip', ({(52, 36, 52, 75): '"""projectq.backends._qracksim._qracksim"""'}, {}), "('projectq.backends._qracksim._qracksim')", False, 'import pytest\n'), ((144, 14, 144, 45), 'projectq.cengines.DummyEngine', 'DummyEngine', (), '', False, 'from projectq.cengines import BasicEngine, BasicMapperEngine, DummyEngine, LocalOptimizer, NotYetMeasuredError\n'), ((145, 10, 145, 33), 'projectq.MainEngine', 'MainEngine', ({(145, 21, 145, 28): 'backend', (145, 30, 145, 32): '[]'}, {}), '(backend, [])', False, 'from projectq import MainEngine\n'), ((169, 19, 169, 40), 'projectq.libs.math.AddConstantModN', 'AddConstantModN', ({(169, 35, 169, 36): '1', (169, 38, 169, 39): '2'}, {}), '(1, 2)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((172, 19, 172, 47), 'projectq.libs.math.MultiplyByConstantModN', 'MultiplyByConstantModN', ({(172, 42, 172, 43): '1', (172, 45, 172, 46): '2'}, {}), '(1, 2)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((188, 10, 188, 29), 'projectq.MainEngine', 'MainEngine', ({(188, 21, 188, 24): 'sim', (188, 26, 188, 28): '[]'}, {}), '(sim, [])', False, 'from projectq import MainEngine\n'), ((205, 10, 205, 29), 'projectq.MainEngine', 'MainEngine', ({(205, 21, 205, 24): 'sim', (205, 26, 205, 28): '[]'}, {}), '(sim, [])', False, 'from projectq import MainEngine\n'), ((219, 10, 219, 29), 'projectq.MainEngine', 'MainEngine', ({(219, 21, 219, 24): 'sim', (219, 26, 219, 28): '[]'}, {}), '(sim, [])', False, 'from projectq import MainEngine\n'), ((220, 10, 220, 41), 'projectq.types.WeakQubitRef', 'WeakQubitRef', (), '', False, 'from projectq.types import WeakQubitRef\n'), ((221, 10, 221, 41), 'projectq.types.WeakQubitRef', 'WeakQubitRef', (), '', False, 'from projectq.types import WeakQubitRef\n'), ((222, 11, 222, 62), 'projectq.ops.Command', 'Command', (), '', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((223, 11, 223, 55), 'projectq.ops.Command', 'Command', (), '', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((249, 10, 249, 29), 'projectq.MainEngine', 'MainEngine', ({(249, 21, 249, 24): 'sim', (249, 26, 249, 28): '[]'}, {}), '(sim, [])', False, 'from projectq import MainEngine\n'), ((258, 10, 258, 29), 'projectq.MainEngine', 'MainEngine', ({(258, 21, 258, 24): 'sim', (258, 26, 258, 28): '[]'}, {}), '(sim, [])', False, 'from projectq import MainEngine\n'), ((277, 10, 277, 29), 'projectq.MainEngine', 'MainEngine', ({(277, 21, 277, 24): 'sim', (277, 26, 277, 28): '[]'}, {}), '(sim, [])', False, 'from projectq import MainEngine\n'), ((369, 10, 369, 50), 'projectq.MainEngine', 'MainEngine', (), '', False, 'from projectq import MainEngine\n'), ((398, 10, 398, 50), 'projectq.MainEngine', 'MainEngine', (), '', False, 'from projectq import MainEngine\n'), ((449, 10, 449, 50), 'projectq.MainEngine', 'MainEngine', (), '', False, 'from projectq import MainEngine\n'), ((464, 10, 464, 25), 'projectq.MainEngine', 'MainEngine', ({(464, 21, 464, 24): 'sim'}, {}), '(sim)', False, 'from projectq import MainEngine\n'), ((479, 10, 479, 50), 'projectq.MainEngine', 'MainEngine', (), '', False, 'from projectq import MainEngine\n'), ((506, 10, 506, 29), 'projectq.MainEngine', 'MainEngine', ({(506, 21, 506, 24): 'sim', (506, 26, 506, 28): '[]'}, {}), '(sim, [])', False, 'from projectq import MainEngine\n'), ((516, 10, 516, 29), 'projectq.MainEngine', 'MainEngine', ({(516, 21, 516, 24): 'sim', (516, 26, 516, 28): '[]'}, {}), '(sim, [])', False, 'from projectq import MainEngine\n'), ((562, 13, 562, 32), 'projectq.cengines.BasicMapperEngine', 'BasicMapperEngine', ({}, {}), '()', False, 'from projectq.cengines import BasicEngine, BasicMapperEngine, DummyEngine, LocalOptimizer, NotYetMeasuredError\n'), ((568, 10, 568, 35), 'projectq.MainEngine', 'MainEngine', ({(568, 21, 568, 24): 'sim', (568, 26, 568, 34): '[mapper]'}, {}), '(sim, [mapper])', False, 'from projectq import MainEngine\n'), ((604, 15, 604, 38), 'projectq.MainEngine', 'MainEngine', (), '', False, 'from projectq import MainEngine\n'), ((645, 15, 645, 30), 'projectq.MainEngine', 'MainEngine', ({(645, 26, 645, 29): 'sim'}, {}), '(sim)', False, 'from projectq import MainEngine\n'), ((649, 15, 649, 40), 'projectq.ops.QubitOperator', 'QubitOperator', ({(649, 29, 649, 36): '"""X0 X1"""', (649, 38, 649, 39): '1'}, {}), "('X0 X1', 1)", False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((656, 15, 656, 37), 'projectq.ops.QubitOperator', 'QubitOperator', ({(656, 29, 656, 33): '"""X0"""', (656, 35, 656, 36): '1'}, {}), "('X0', 1)", False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((667, 15, 667, 30), 'projectq.MainEngine', 'MainEngine', ({(667, 26, 667, 29): 'sim'}, {}), '(sim)', False, 'from projectq import MainEngine\n'), ((671, 15, 671, 43), 'projectq.ops.QubitOperator', 'QubitOperator', ({(671, 29, 671, 39): '"""X0 X1 X2"""', (671, 41, 671, 42): '1'}, {}), "('X0 X1 X2', 1)", False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((675, 15, 675, 37), 'projectq.ops.QubitOperator', 'QubitOperator', ({(675, 29, 675, 33): '"""X0"""', (675, 35, 675, 36): '1'}, {}), "('X0', 1)", False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((685, 15, 685, 37), 'projectq.ops.QubitOperator', 'QubitOperator', ({(685, 29, 685, 33): '"""Y0"""', (685, 35, 685, 36): '1'}, {}), "('Y0', 1)", False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((695, 15, 695, 37), 'projectq.ops.QubitOperator', 'QubitOperator', ({(695, 29, 695, 33): '"""Z0"""', (695, 35, 695, 36): '1'}, {}), "('Z0', 1)", False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((705, 15, 705, 40), 'projectq.ops.QubitOperator', 'QubitOperator', ({(705, 29, 705, 33): '"""Z0"""', (705, 35, 705, 39): '0.25'}, {}), "('Z0', 0.25)", False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((715, 15, 715, 40), 'projectq.ops.QubitOperator', 'QubitOperator', ({(715, 29, 715, 36): '"""Z0 Z1"""', (715, 38, 715, 39): '1'}, {}), "('Z0 Z1', 1)", False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((71, 14, 71, 25), 'projectq.backends.Simulator', 'Simulator', ({}, {}), '()', False, 'from projectq.backends import Simulator\n'), ((72, 25, 72, 43), 'projectq.backends._qracksim._qracksim.QrackSimulator', 'QrackSim', ({(72, 34, 72, 35): '1', (72, 37, 72, 39): '-1', (72, 41, 72, 42): '1'}, {}), '(1, -1, 1)', True, 'from projectq.backends._qracksim._qracksim import QrackSimulator as QrackSim\n'), ((111, 12, 111, 36), 'projectq.ops.BasicGate.__init__', 'BasicGate.__init__', ({(111, 31, 111, 35): 'self'}, {}), '(self)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((117, 19, 118, 41), 'numpy.matrix', 'numpy.matrix', ({(117, 32, 118, 40): '[[0, 1], [1, 0]]'}, {}), '([[0, 1], [1, 0]])', False, 'import numpy\n'), ((123, 12, 123, 36), 'projectq.ops.BasicGate.__init__', 'BasicGate.__init__', ({(123, 31, 123, 35): 'self'}, {}), '(self)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((129, 19, 129, 36), 'numpy.eye', 'numpy.eye', ({(129, 29, 129, 35): '(2 ** 6)'}, {}), '(2 ** 6)', False, 'import numpy\n'), ((134, 12, 134, 36), 'projectq.ops.BasicGate.__init__', 'BasicGate.__init__', ({(134, 31, 134, 35): 'self'}, {}), '(self)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((212, 4, 212, 16), 'projectq.ops.All', 'All', ({(212, 8, 212, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((226, 9, 226, 43), 'pytest.raises', 'pytest.raises', ({(226, 23, 226, 42): 'NotYetMeasuredError'}, {}), '(NotYetMeasuredError)', False, 'import pytest\n'), ((228, 9, 228, 43), 'pytest.raises', 'pytest.raises', ({(228, 23, 228, 42): 'NotYetMeasuredError'}, {}), '(NotYetMeasuredError)', False, 'import pytest\n'), ((232, 9, 232, 43), 'pytest.raises', 'pytest.raises', ({(232, 23, 232, 42): 'NotYetMeasuredError'}, {}), '(NotYetMeasuredError)', False, 'import pytest\n'), ((238, 9, 238, 16), 'projectq.ops.Rx', 'Rx', ({(238, 12, 238, 15): '(0.3)'}, {}), '(0.3)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((239, 9, 239, 16), 'projectq.ops.Rx', 'Rx', ({(239, 12, 239, 15): '(0.8)'}, {}), '(0.8)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((240, 9, 240, 16), 'projectq.ops.Ry', 'Ry', ({(240, 12, 240, 15): '(0.1)'}, {}), '(0.1)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((251, 9, 251, 33), 'pytest.raises', 'pytest.raises', ({(251, 23, 251, 32): 'Exception'}, {}), '(Exception)', False, 'import pytest\n'), ((253, 9, 253, 33), 'pytest.raises', 'pytest.raises', ({(253, 23, 253, 32): 'Exception'}, {}), '(Exception)', False, 'import pytest\n'), ((265, 4, 265, 16), 'projectq.ops.All', 'All', ({(265, 8, 265, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((266, 4, 266, 16), 'projectq.ops.All', 'All', ({(266, 8, 266, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((271, 4, 271, 16), 'projectq.ops.All', 'All', ({(271, 8, 271, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((272, 4, 272, 16), 'projectq.ops.All', 'All', ({(272, 8, 272, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((280, 4, 280, 18), 'projectq.libs.math.AddConstant', 'AddConstant', ({(280, 16, 280, 17): '(1)'}, {}), '(1)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((281, 4, 281, 16), 'projectq.ops.All', 'All', ({(281, 8, 281, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((287, 4, 287, 28), 'projectq.libs.math.AddConstantModN', 'AddConstantModN', ({(287, 20, 287, 22): '(10)', (287, 24, 287, 27): '(256)'}, {}), '(10, 256)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((288, 4, 288, 16), 'projectq.ops.All', 'All', ({(288, 8, 288, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((298, 4, 298, 16), 'projectq.ops.All', 'All', ({(298, 8, 298, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((308, 4, 308, 16), 'projectq.ops.All', 'All', ({(308, 8, 308, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((314, 4, 314, 18), 'projectq.libs.math.SubConstant', 'SubConstant', ({(314, 16, 314, 17): '(5)'}, {}), '(5)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((315, 4, 315, 16), 'projectq.ops.All', 'All', ({(315, 8, 315, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((322, 4, 322, 16), 'projectq.ops.All', 'All', ({(322, 8, 322, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((332, 4, 332, 16), 'projectq.ops.All', 'All', ({(332, 8, 332, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((338, 4, 338, 34), 'projectq.libs.math.MultiplyByConstantModN', 'MultiplyByConstantModN', ({(338, 27, 338, 28): '(2)', (338, 30, 338, 33): '(256)'}, {}), '(2, 256)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((339, 4, 339, 16), 'projectq.ops.All', 'All', ({(339, 8, 339, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((348, 4, 348, 16), 'projectq.ops.All', 'All', ({(348, 8, 348, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((358, 4, 358, 16), 'projectq.ops.All', 'All', ({(358, 8, 358, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((366, 19, 366, 35), 'projectq.cengines.LocalOptimizer', 'LocalOptimizer', ({}, {}), '()', False, 'from projectq.cengines import BasicEngine, BasicMapperEngine, DummyEngine, LocalOptimizer, NotYetMeasuredError\n'), ((371, 4, 371, 10), 'projectq.ops.All', 'All', ({(371, 8, 371, 9): 'H'}, {}), '(H)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((378, 9, 378, 36), 'pytest.raises', 'pytest.raises', ({(378, 23, 378, 35): 'RuntimeError'}, {}), '(RuntimeError)', False, 'import pytest\n'), ((381, 4, 381, 10), 'projectq.ops.All', 'All', ({(381, 8, 381, 9): 'H'}, {}), '(H)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((384, 60, 384, 78), 'pytest.approx', 'pytest.approx', ({(384, 74, 384, 77): '(0.3)'}, {}), '(0.3)', False, 'import pytest\n'), ((387, 60, 387, 78), 'pytest.approx', 'pytest.approx', ({(387, 74, 387, 77): '(0.4)'}, {}), '(0.4)', False, 'import pytest\n'), ((391, 4, 391, 16), 'projectq.ops.All', 'All', ({(391, 8, 391, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((395, 19, 395, 35), 'projectq.cengines.LocalOptimizer', 'LocalOptimizer', ({}, {}), '()', False, 'from projectq.cengines import BasicEngine, BasicMapperEngine, DummyEngine, LocalOptimizer, NotYetMeasuredError\n'), ((400, 4, 400, 10), 'projectq.ops.All', 'All', ({(400, 8, 400, 9): 'X'}, {}), '(X)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((401, 4, 401, 10), 'projectq.ops.All', 'All', ({(401, 8, 401, 9): 'H'}, {}), '(H)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((407, 19, 407, 41), 'pytest.approx', 'pytest.approx', ({(407, 33, 407, 40): '(1.0 / 8.0)'}, {}), '(1.0 / 8.0)', False, 'import pytest\n'), ((412, 20, 412, 39), 'pytest.approx', 'pytest.approx', ({(412, 34, 412, 38): 'polR'}, {}), '(polR)', False, 'import pytest\n'), ((413, 34, 413, 55), 'pytest.approx', 'pytest.approx', ({(413, 48, 413, 54): 'polPhi'}, {}), '(polPhi)', False, 'import pytest\n'), ((418, 20, 418, 39), 'pytest.approx', 'pytest.approx', ({(418, 34, 418, 38): 'polR'}, {}), '(polR)', False, 'import pytest\n'), ((419, 34, 419, 55), 'pytest.approx', 'pytest.approx', ({(419, 48, 419, 54): 'polPhi'}, {}), '(polPhi)', False, 'import pytest\n'), ((420, 4, 420, 10), 'projectq.ops.All', 'All', ({(420, 8, 420, 9): 'H'}, {}), '(H)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((421, 4, 421, 10), 'projectq.ops.All', 'All', ({(421, 8, 421, 9): 'X'}, {}), '(X)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((426, 19, 426, 37), 'pytest.approx', 'pytest.approx', ({(426, 33, 426, 36): '(0.3)'}, {}), '(0.3)', False, 'import pytest\n'), ((431, 4, 431, 16), 'projectq.ops.All', 'All', ({(431, 8, 431, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((433, 9, 433, 36), 'pytest.raises', 'pytest.raises', ({(433, 23, 433, 35): 'RuntimeError'}, {}), '(RuntimeError)', False, 'import pytest\n'), ((436, 9, 436, 36), 'pytest.raises', 'pytest.raises', ({(436, 23, 436, 35): 'RuntimeError'}, {}), '(RuntimeError)', False, 'import pytest\n'), ((441, 9, 441, 36), 'pytest.raises', 'pytest.raises', ({(441, 23, 441, 35): 'RuntimeError'}, {}), '(RuntimeError)', False, 'import pytest\n'), ((446, 19, 446, 35), 'projectq.cengines.LocalOptimizer', 'LocalOptimizer', ({}, {}), '()', False, 'from projectq.cengines import BasicEngine, BasicMapperEngine, DummyEngine, LocalOptimizer, NotYetMeasuredError\n'), ((451, 18, 451, 32), 'math.sqrt', 'math.sqrt', ({(451, 28, 451, 31): '(0.2)'}, {}), '(0.2)', False, 'import math\n'), ((451, 34, 451, 48), 'math.sqrt', 'math.sqrt', ({(451, 44, 451, 47): '(0.8)'}, {}), '(0.8)', False, 'import math\n'), ((452, 9, 452, 36), 'pytest.raises', 'pytest.raises', ({(452, 23, 452, 35): 'RuntimeError'}, {}), '(RuntimeError)', False, 'import pytest\n'), ((459, 4, 459, 16), 'projectq.ops.All', 'All', ({(459, 8, 459, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((476, 19, 476, 35), 'projectq.cengines.LocalOptimizer', 'LocalOptimizer', ({}, {}), '()', False, 'from projectq.cengines import BasicEngine, BasicMapperEngine, DummyEngine, LocalOptimizer, NotYetMeasuredError\n'), ((482, 9, 482, 36), 'pytest.raises', 'pytest.raises', ({(482, 23, 482, 35): 'RuntimeError'}, {}), '(RuntimeError)', False, 'import pytest\n'), ((487, 4, 487, 10), 'projectq.ops.All', 'All', ({(487, 8, 487, 9): 'H'}, {}), '(H)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((491, 9, 491, 36), 'pytest.raises', 'pytest.raises', ({(491, 23, 491, 35): 'RuntimeError'}, {}), '(RuntimeError)', False, 'import pytest\n'), ((495, 26, 495, 43), 'pytest.approx', 'pytest.approx', ({(495, 40, 495, 42): '(0.5)'}, {}), '(0.5)', False, 'import pytest\n'), ((502, 26, 502, 43), 'pytest.approx', 'pytest.approx', ({(502, 40, 502, 42): '(1.0)'}, {}), '(1.0)', False, 'import pytest\n'), ((509, 9, 509, 36), 'pytest.raises', 'pytest.raises', ({(509, 23, 509, 35): 'RuntimeError'}, {}), '(RuntimeError)', False, 'import pytest\n'), ((544, 9, 544, 35), 'projectq.meta.Control', 'Control', ({(544, 17, 544, 20): 'eng', (544, 22, 544, 34): 'qubits[0:-1]'}, {}), '(eng, qubits[0:-1])', False, 'from projectq.meta import Compute, Uncompute, Control, Dagger, LogicalQubitIDTag\n'), ((546, 9, 546, 35), 'projectq.meta.Control', 'Control', ({(546, 17, 546, 20): 'eng', (546, 22, 546, 34): 'qubits[0:-2]'}, {}), '(eng, qubits[0:-2])', False, 'from projectq.meta import Compute, Uncompute, Control, Dagger, LogicalQubitIDTag\n'), ((548, 9, 548, 35), 'projectq.meta.Control', 'Control', ({(548, 17, 548, 20): 'eng', (548, 22, 548, 34): 'qubits[0:-3]'}, {}), '(eng, qubits[0:-3])', False, 'from projectq.meta import Compute, Uncompute, Control, Dagger, LogicalQubitIDTag\n'), ((558, 4, 558, 16), 'projectq.ops.All', 'All', ({(558, 8, 558, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((590, 8, 590, 22), 'projectq.meta.Uncompute', 'Uncompute', ({(590, 18, 590, 21): 'eng'}, {}), '(eng)', False, 'from projectq.meta import Compute, Uncompute, Control, Dagger, LogicalQubitIDTag\n'), ((639, 4, 639, 16), 'projectq.ops.All', 'All', ({(639, 8, 639, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((640, 4, 640, 16), 'projectq.ops.All', 'All', ({(640, 8, 640, 15): 'Measure'}, {}), '(Measure)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((650, 9, 650, 33), 'pytest.raises', 'pytest.raises', ({(650, 23, 650, 32): 'Exception'}, {}), '(Exception)', False, 'import pytest\n'), ((661, 24, 661, 41), 'pytest.approx', 'pytest.approx', ({(661, 38, 661, 40): '(0.0)'}, {}), '(0.0)', False, 'import pytest\n'), ((663, 24, 663, 41), 'pytest.approx', 'pytest.approx', ({(663, 38, 663, 40): '(1.0)'}, {}), '(1.0)', False, 'import pytest\n'), ((672, 9, 672, 33), 'pytest.raises', 'pytest.raises', ({(672, 23, 672, 32): 'Exception'}, {}), '(Exception)', False, 'import pytest\n'), ((679, 62, 679, 108), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((683, 62, 683, 109), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((689, 62, 689, 108), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((693, 62, 693, 109), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((699, 62, 699, 108), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((703, 62, 703, 109), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((709, 62, 709, 111), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((713, 62, 713, 112), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((719, 62, 719, 108), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((722, 62, 722, 109), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((725, 62, 725, 108), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((728, 62, 728, 109), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((75, 14, 75, 25), 'projectq.backends.Simulator', 'Simulator', ({}, {}), '()', False, 'from projectq.backends import Simulator\n'), ((76, 25, 76, 43), 'projectq.backends._qracksim._qracksim.QrackSimulator', 'QrackSim', ({(76, 34, 76, 35): '1', (76, 37, 76, 39): '-1', (76, 41, 76, 42): '2'}, {}), '(1, -1, 2)', True, 'from projectq.backends._qracksim._qracksim import QrackSimulator as QrackSim\n'), ((241, 28, 241, 36), 'projectq.ops.Ry', 'Ry', ({(241, 31, 241, 35): '-0.1'}, {}), '(-0.1)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((242, 38, 242, 56), 'numpy.kron', 'numpy.kron', ({(242, 49, 242, 51): 'm2', (242, 53, 242, 55): 'm1'}, {}), '(m2, m1)', False, 'import numpy\n'), ((297, 6, 297, 30), 'projectq.libs.math.AddConstantModN', 'AddConstantModN', ({(297, 22, 297, 24): '(10)', (297, 26, 297, 29): '(256)'}, {}), '(10, 256)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((307, 6, 307, 30), 'projectq.libs.math.AddConstantModN', 'AddConstantModN', ({(307, 22, 307, 24): '(10)', (307, 26, 307, 29): '(256)'}, {}), '(10, 256)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((321, 6, 321, 30), 'projectq.libs.math.SubConstantModN', 'SubConstantModN', ({(321, 22, 321, 24): '(10)', (321, 26, 321, 29): '(256)'}, {}), '(10, 256)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((331, 6, 331, 30), 'projectq.libs.math.SubConstantModN', 'SubConstantModN', ({(331, 22, 331, 24): '(10)', (331, 26, 331, 29): '(256)'}, {}), '(10, 256)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((347, 6, 347, 36), 'projectq.libs.math.MultiplyByConstantModN', 'MultiplyByConstantModN', ({(347, 29, 347, 30): '(2)', (347, 32, 347, 35): '(256)'}, {}), '(2, 256)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((357, 6, 357, 37), 'projectq.libs.math.MultiplyByConstantModN', 'MultiplyByConstantModN', ({(357, 29, 357, 31): '(10)', (357, 33, 357, 36): '(256)'}, {}), '(10, 256)', False, 'from projectq.libs.math import AddConstant, AddConstantModN, SubConstant, SubConstantModN, MultiplyByConstantModN\n'), ((376, 16, 376, 37), 'pytest.approx', 'pytest.approx', ({(376, 30, 376, 36): '(0.5 ** i)'}, {}), '(0.5 ** i)', False, 'import pytest\n'), ((430, 26, 430, 41), 'math.sqrt', 'math.sqrt', ({(430, 36, 430, 40): '(0.91)'}, {}), '(0.91)', False, 'import math\n'), ((472, 24, 472, 41), 'pytest.approx', 'pytest.approx', ({(472, 38, 472, 40): '(1.0j)'}, {}), '(1.0j)', False, 'import pytest\n'), ((472, 58, 472, 76), 'pytest.approx', 'pytest.approx', ({(472, 72, 472, 75): '(-1.0j)'}, {}), '(-1.0j)', False, 'import pytest\n'), ((584, 13, 584, 25), 'projectq.meta.Compute', 'Compute', ({(584, 21, 584, 24): 'eng'}, {}), '(eng)', False, 'from projectq.meta import Compute, Uncompute, Control, Dagger, LogicalQubitIDTag\n'), ((588, 13, 588, 41), 'projectq.meta.Control', 'Control', ({(588, 21, 588, 24): 'eng', (588, 26, 588, 40): 'control_qubits'}, {}), '(eng, control_qubits)', False, 'from projectq.meta import Compute, Uncompute, Control, Dagger, LogicalQubitIDTag\n'), ((603, 37, 603, 48), 'projectq.backends.Simulator', 'Simulator', ({}, {}), '()', False, 'from projectq.backends import Simulator\n'), ((637, 26, 637, 75), 'pytest.approx', 'pytest.approx', (), '', False, 'import pytest\n'), ((89, 16, 89, 42), 'projectq.cengines.BasicEngine.__init__', 'BasicEngine.__init__', ({(89, 37, 89, 41): 'self'}, {}), '(self)', False, 'from projectq.cengines import BasicEngine, BasicMapperEngine, DummyEngine, LocalOptimizer, NotYetMeasuredError\n'), ((225, 25, 225, 45), 'projectq.meta.LogicalQubitIDTag', 'LogicalQubitIDTag', ({(225, 43, 225, 44): '2'}, {}), '(2)', False, 'from projectq.meta import Compute, Uncompute, Control, Dagger, LogicalQubitIDTag\n'), ((241, 9, 241, 16), 'projectq.ops.Rz', 'Rz', ({(241, 12, 241, 15): '0.9'}, {}), '(0.9)', False, 'from projectq.ops import All, Allocate, BasicGate, BasicMathGate, CNOT, C, Command, H, Measure, QubitOperator, Rx, Ry, Rz, S, TimeEvolution, Toffoli, X, Y, Z, Swap, SqrtSwap, UniformlyControlledRy, UniformlyControlledRz\n'), ((422, 11, 422, 25), 'math.acos', 'math.acos', ({(422, 21, 422, 24): '(0.3)'}, {}), '(0.3)', False, 'import math\n'), ((676, 43, 676, 55), 'math.sqrt', 'math.sqrt', ({(676, 53, 676, 54): '(2)'}, {}), '(2)', False, 'import math\n'), ((676, 61, 676, 73), 'math.sqrt', 'math.sqrt', ({(676, 71, 676, 72): '(2)'}, {}), '(2)', False, 'import math\n'), ((680, 43, 680, 55), 'math.sqrt', 'math.sqrt', ({(680, 53, 680, 54): '(2)'}, {}), '(2)', False, 'import math\n'), ((680, 62, 680, 74), 'math.sqrt', 'math.sqrt', ({(680, 72, 680, 73): '(2)'}, {}), '(2)', False, 'import math\n'), ((686, 43, 686, 55), 'math.sqrt', 'math.sqrt', ({(686, 53, 686, 54): '(2)'}, {}), '(2)', False, 'import math\n'), ((686, 62, 686, 74), 'math.sqrt', 'math.sqrt', ({(686, 72, 686, 73): '(2)'}, {}), '(2)', False, 'import math\n'), ((690, 43, 690, 55), 'math.sqrt', 'math.sqrt', ({(690, 53, 690, 54): '(2)'}, {}), '(2)', False, 'import math\n'), ((690, 63, 690, 75), 'math.sqrt', 'math.sqrt', ({(690, 73, 690, 74): '(2)'}, {}), '(2)', False, 'import math\n'), ((382, 21, 382, 35), 'math.sqrt', 'math.sqrt', ({(382, 31, 382, 34): '(0.3)'}, {}), '(0.3)', False, 'import math\n'), ((385, 21, 385, 35), 'math.sqrt', 'math.sqrt', ({(385, 31, 385, 34): '(0.4)'}, {}), '(0.4)', False, 'import math\n')]