Esempio n. 1
0
    def simulate(self, variables, *args, **kwargs):
        """
        Simulate the expectationvalue.

        Parameters
        ----------
        variables:
            variables to supply to the unitary.
        args
        kwargs

        Returns
        -------
        numpy array:
            the result of simulation.
        """
        self.update_variables(variables)
        result = []
        for H in self.H:
            final_E = 0.0
            # The hamiltonian can be defined on more qubits as the unitaries
            qubits_h = H.qubits
            qubits_u = self.U.abstract_qubits
            all_qubits = list(
                set(qubits_h) | set(qubits_u)
                | set(range(self.U.abstract_circuit.max_qubit() + 1)))
            keymap = KeyMapSubregisterToRegister(subregister=qubits_u,
                                                 register=all_qubits)
            # TODO inefficient, let the backend do it if possible or interface some library
            simresult = self.U.simulate(variables=variables, *args, **kwargs)
            wfn = simresult.apply_keymap(keymap=keymap)
            final_E += wfn.compute_expectationvalue(operator=H)

            result.append(to_float(final_E))
        return numpy.asarray(result)
Esempio n. 2
0
    def make_excitation_generator(
            self,
            indices: typing.Iterable[typing.Tuple[int,
                                                  int]]) -> QubitHamiltonian:
        """
        Notes
        ----------
        Creates the transformed hermitian generator of UCC type unitaries:
              M(a^\dagger_{a_0} a_{i_0} a^\dagger{a_1}a_{i_1} ... - h.c.)
              where the qubit map M depends is self.transformation

        Parameters
        ----------
        indices : typing.Iterable[typing.Tuple[int, int]] :
            List of tuples [(a_0, i_0), (a_1, i_1), ... ] - recommended format, in spin-orbital notation (alpha odd numbers, beta even numbers)
            can also be given as one big list: [a_0, i_0, a_1, i_1 ...]
        Returns
        -------
        type
            1j*Transformed qubit excitation operator, depends on self.transformation
        """
        # check indices and convert to list of tuples if necessary
        if len(indices) == 0:
            raise TequilaException(
                "make_excitation_operator: no indices given")
        elif not isinstance(indices[0], typing.Iterable):
            if len(indices) % 2 != 0:
                raise TequilaException(
                    "make_excitation_generator: unexpected input format of indices\n"
                    "use list of tuples as [(a_0, i_0),(a_1, i_1) ...]\n"
                    "or list as [a_0, i_0, a_1, i_1, ... ]\n"
                    "you gave: {}".format(indices))
            converted = [(indices[2 * i], indices[2 * i + 1])
                         for i in range(len(indices) // 2)]
        else:
            converted = indices

        # convert to openfermion input format
        ofi = []
        dag = []
        for pair in converted:
            assert (len(pair) == 2)
            ofi += [
                (int(pair[0]), 1), (int(pair[1]), 0)
            ]  # openfermion does not take other types of integers like numpy.int64
            dag += [(int(pair[0]), 0), (int(pair[1]), 1)]

        op = openfermion.FermionOperator(tuple(ofi),
                                         1.j)  # 1j makes it hermitian
        op += openfermion.FermionOperator(tuple(reversed(dag)), -1.j)
        qop = QubitHamiltonian(qubit_hamiltonian=self.transformation(op))

        # check if the operator is hermitian and cast coefficients to floats
        # in order to avoid trouble with the simulation backends
        assert qop.is_hermitian()
        for k, v in qop.qubit_operator.terms.items():
            qop.qubit_operator.terms[k] = to_float(v)

        qop = qop.simplify()
        return qop
Esempio n. 3
0
    def __init__(self, abstract_circuit: QCircuit, variables, use_mapping=True, noise=None, *args, **kwargs):
        self.op_lookup = {
            'I': (pyquil.gates.I),
            'X': (pyquil.gates.X, pyquil.gates.CNOT, pyquil.gates.CCNOT),
            'Y': (pyquil.gates.Y,),
            'Z': (pyquil.gates.Z, pyquil.gates.CZ),
            'H': (pyquil.gates.H,),
            'Rx': pyquil.gates.RX,
            'Ry': pyquil.gates.RY,
            'Rz': pyquil.gates.RZ,
            'Phase': pyquil.gates.PHASE,
            'SWAP': (pyquil.gates.SWAP, pyquil.gates.CSWAP),
        }
        self.match_par_to_dummy = {}
        self.counter = 0
        super().__init__(abstract_circuit=abstract_circuit, variables=variables, noise=noise,
                         use_mapping=use_mapping, *args, **kwargs)
        if self.noise is not None:
            self.noise_lookup = {
                'amplitude damp': amp_damp_map,
                'phase damp': phase_damp_map,
                'bit flip': bit_flip_map,
                'phase flip': phase_flip_map,
                'phase-amplitude damp': phase_amp_damp_map,
                'depolarizing': depolarizing_map
            }

            self.circuit = self.build_noisy_circuit(self.circuit, self.noise)
        if len(self.match_par_to_dummy.keys()) is None:
            self.match_dummy_to_value = None
            self.resolver = None
        else:
            self.match_dummy_to_value = {'theta_{}'.format(str(i)): k for i, k in
                                         enumerate(self.match_par_to_dummy.keys())}
            self.resolver = {k: [to_float(v(variables))] for k, v in self.match_dummy_to_value.items()}
Esempio n. 4
0
    def simulate(self, variables, *args, **kwargs):
        self.update_variables(variables)
        result = []
        for H in self.H:
            final_E = 0.0
            if self.use_mapping:
                # The hamiltonian can be defined on more qubits as the unitaries
                qubits_h = H.qubits
                qubits_u = self.U.qubits
                all_qubits = list(
                    set(qubits_h) | set(qubits_u)
                    | set(range(self.U.abstract_circuit.max_qubit() + 1)))
                keymap = KeyMapSubregisterToRegister(subregister=qubits_u,
                                                     register=all_qubits)
            else:
                if H.qubits != self.U.qubits:
                    raise TequilaException(
                        "Can not compute expectation value without using qubit mappings."
                        " Your Hamiltonian and your Unitary do not act on the same set of qubits. "
                        "Hamiltonian acts on {}, Unitary acts on {}".format(
                            H.qubits, self.U.qubits))
                keymap = KeyMapSubregisterToRegister(subregister=self.U.qubits,
                                                     register=self.U.qubits)
            # TODO inefficient, let the backend do it if possible or interface some library
            simresult = self.U.simulate(variables=variables, *args, **kwargs)
            wfn = simresult.apply_keymap(keymap=keymap)
            final_E += wfn.compute_expectationvalue(operator=H)

            result.append(to_float(final_E))
        return numpy.asarray(result)
Esempio n. 5
0
def do_compile_trotterized_gate(generator, steps, factor, randomize, control):
    """
    Todo: Jakob, plz write
    """
    assert (generator.is_hermitian())
    circuit = QCircuit()
    factor = factor / steps
    for index in range(steps):
        paulistrings = generator.paulistrings
        if randomize:
            numpy.random.shuffle(paulistrings)
        for ps in paulistrings:
            coeff = to_float(ps.coeff)
            if len(ps._data) == 0 and len(control) > 0:
                circuit += Phase(target=control[0],
                                 control=control[1:],
                                 phi=-factor * coeff / 2)
            elif len(ps._data) > 0:
                circuit += ExpPauli(paulistring=ps.naked(),
                                    angle=factor * coeff,
                                    control=control)
            else:
                # ignore global phases
                pass
    return circuit
Esempio n. 6
0
 def is_hermitian(self):
     try:
         for k, v in self.qubit_operator.terms.items():
             self.qubit_operator.terms[k] = to_float(v)
         return True
     except TypeError:
         return False
Esempio n. 7
0
def array_to_objective_dict(objective,
                            array,
                            passives=None) -> typing.Dict[Variable, float]:
    """
    reformats a numpy array of parameters to a dictionary in so that objective might use it as variables.

    Parameters
    ----------
    objective: Objective:
        an Objective, whose parameters the array is meant to represent
    array: numpy.ndarray
        a numpy array of parameters.
    passives: optional:
        a dictionary of passive parameters to suppled the suggested parameters of array.
        Default means no passives involved.

    Returns
    -------
    dict:
        dictinary of formatted parameters for use by objective
    """
    op = objective.extract_variables()
    if passives is not None:
        for i, thing in enumerate(op):
            if thing in passives.keys():
                op.remove(thing)
    back = {v: array[:, i] for i, v in enumerate(op)}
    if passives is not None:
        for k, v in passives.items():
            back[k] = v
    back = {k: to_float(v) for k, v in back.items()}
    return back
Esempio n. 8
0
    def simulate(self, variables, *args, **kwargs):
        """
        Simulate the expectationvalue.

        Parameters
        ----------
        variables:
            variables to supply to the unitary.
        args
        kwargs

        Returns
        -------
        numpy array:
            the result of simulation.
        """
        self.update_variables(variables)
        result = []
        for H in self.H:
            final_E = 0.0
            # TODO inefficient,
            # Always better to overwrite this function
            wfn = self.U.simulate(variables=variables, *args, **kwargs)
            final_E += wfn.compute_expectationvalue(operator=H)
            result.append(to_float(final_E))
        return numpy.asarray(result)
Esempio n. 9
0
    def update_variables(self, variables):
        """
        overwriting the underlying code so that noise gets added when present
        """

        if self.match_dummy_to_value is not None:
            self.resolver = {k: [to_float(v(variables))] for k, v in self.match_dummy_to_value.items()}
        else:
            self.resolver = None
Esempio n. 10
0
    def sample(self, variables, samples, *args, **kwargs) -> numpy.array:
        self.update_variables(variables)

        result = []
        for H in self.H:
            E = 0.0
            for ps in H.paulistrings:
                E += self.sample_paulistring(samples=samples, paulistring=ps, *args, **kwargs)
            result.append(to_float(E))
        return numpy.asarray(result)
Esempio n. 11
0
 def update_variables(self, variables):
     """
     overriding the underlying base to make sure this stuff remains noisy
     """
     if self.sympy_to_tq is not None:
         self.resolver = {
             k: to_float(v(variables))
             for k, v in self.sympy_to_tq.items()
         }
     else:
         self.resolver = None
    def update_variables(self, variables):
        """
        Update circuit variables for use in simulation or sampling
        Parameters
        ----------
        variables:
             a new set of variables for use in the circuit.

        Returns
        -------
        None
        """

        if self.pars_to_tq is not None:
            self.resolver = {k: to_float(v(variables)) for k, v in self.pars_to_tq.items()}
        else:
            self.resolver = None
Esempio n. 13
0
def do_compile_trotterized_gate(generator, steps, factor, randomize, control):
    assert (generator.is_hermitian())
    circuit = QCircuit()
    factor = factor / steps
    for index in range(steps):
        paulistrings = generator.paulistrings
        if randomize:
            numpy.random.shuffle(paulistrings)
        for ps in paulistrings:
            if len(ps._data) == 0:
                print("ignoring constant term in trotterized gate")
                continue
            coeff = to_float(ps.coeff)
            circuit += ExpPauli(paulistring=ps.naked(),
                                angle=factor * coeff,
                                control=control)

    return circuit
Esempio n. 14
0
    def update_variables(self, variables):
        """
        Update the variables for resolution in simulation or sampling.
        Parameters
        ----------
        variables: dict:
            dictionary of tequila variables and values to resolve for simulation.

        Returns
        -------
        None
        """

        if self.match_dummy_to_value is not None:
            self.resolver = {
                k: [to_float(v(variables))]
                for k, v in self.match_dummy_to_value.items()
            }
        else:
            self.resolver = None
Esempio n. 15
0
    def sample(self, variables, samples, *args, **kwargs) -> numpy.array:
        """
        sample the expectationvalue.

        Parameters
        ----------
        variables: dict:
            variables to supply to the unitary.
        samples: int:
            number of samples to perform.
        args
        kwargs

        Returns
        -------
        numpy.ndarray:
            a numpy array, the result of sampling.
        """
        self.update_variables(variables)

        result = []
        for H in self._reduced_hamiltonians:
            E = 0.0
            if len(H.qubits) == 0:
                E = sum([ps.coeff for ps in H.paulistrings])
            elif H.is_all_z():
                E = self.U.sample_all_z_hamiltonian(samples=samples,
                                                    hamiltonian=H,
                                                    variables=variables,
                                                    *args,
                                                    **kwargs)
            else:
                for ps in H.paulistrings:
                    E += self.U.sample_paulistring(samples=samples,
                                                   paulistring=ps,
                                                   variables=variables,
                                                   *args,
                                                   **kwargs)
            result.append(to_float(E))
        return numpy.asarray(result)
Esempio n. 16
0
    def __init__(self,
                 abstract_circuit: QCircuit,
                 variables,
                 qubit_map=None,
                 noise=None,
                 device=None,
                 *args,
                 **kwargs):
        """

        Parameters
        ----------
        abstract_circuit: QCircuit:
            the circuit to be compiled to qiskit.
        variables: dict:
            variables to compile the circuit with
        qubit_map: dictionary:
            a qubit map which maps the abstract qubits in the abstract_circuit to the qubits on the backend
            there is no need to initialize the corresponding backend types
            the dictionary should simply be {int:int} (preferred) or {int:name}
            if None the default will map to qubits 0 ... n_qubits -1 in the backend
        noise:
            noise to apply to the circuit.
        device:
            device on which to (perhaps, via emulation) execute the circuit.
        args
        kwargs
        """
        self.op_lookup = {
            'I': (lambda c: c.iden),
            'X': (lambda c: c.x, lambda c: c.cx, lambda c: c.ccx),
            'Y': (lambda c: c.y, lambda c: c.cy, lambda c: c.ccy),
            'Z': (lambda c: c.z, lambda c: c.cz, lambda c: c.ccz),
            'H': (lambda c: c.h, lambda c: c.ch, lambda c: c.cch),
            'Rx': (lambda c: c.rx, lambda c: c.mcrx),
            'Ry': (lambda c: c.ry, lambda c: c.mcry),
            'Rz': (lambda c: c.rz, lambda c: c.mcrz),
            'Phase': (lambda c: c.u1, lambda c: c.cu1),
            'SWAP': (lambda c: c.swap, lambda c: c.cswap),
        }

        self.resolver = {}
        self.tq_to_pars = {}
        self.counter = 0

        if qubit_map is None:
            n_qubits = len(abstract_circuit.qubits)
        else:
            n_qubits = max(qubit_map.values()) + 1

        self.q = qiskit.QuantumRegister(n_qubits, "q")
        self.c = qiskit.ClassicalRegister(n_qubits, "c")

        super().__init__(abstract_circuit=abstract_circuit,
                         variables=variables,
                         noise=noise,
                         device=device,
                         qubit_map=qubit_map,
                         *args,
                         **kwargs)

        self.classical_map = self.make_classical_map(qubit_map=self.qubit_map)

        if noise != None:
            self.noise_lookup = {
                'phase damp': qiskitnoise.phase_damping_error,
                'amplitude damp': qiskitnoise.amplitude_damping_error,
                'bit flip': get_bit_flip,
                'phase flip': get_phase_flip,
                'phase-amplitude damp':
                qiskitnoise.phase_amplitude_damping_error,
                'depolarizing': qiskitnoise.depolarizing_error
            }

            if isinstance(noise, str):
                if noise == 'device':
                    if device is not None:
                        self.noise_model = qiskitnoise.NoiseModel.from_backend(
                            self.device)
                    else:
                        raise TequilaException(
                            'cannot get device noise without specifying a device!'
                        )
                else:
                    raise TequilaException(
                        'The only allowed string for noise is \'device\'; recieved {}. Please try again!'
                        .format(str(noise)))
            else:
                nm = self.noise_model_converter(noise)
                self.noise_model = nm
        else:
            self.noise_model = None

        if len(self.tq_to_pars.keys()) is None:
            self.pars_to_tq = None
            self.resolver = None
        else:
            self.pars_to_tq = {v: k for k, v in self.tq_to_pars.items()}
            self.resolver = {
                k: to_float(v(variables))
                for k, v in self.pars_to_tq.items()
            }
Esempio n. 17
0
    def __init__(self,
                 abstract_circuit: QCircuit,
                 variables,
                 qubit_map=None,
                 noise=None,
                 device=None,
                 *args,
                 **kwargs):
        """
        Parameters
        ----------
        abstract_circuit: QCircuit:
            Tequila unitary to compile to Pyquil.
        variables: dict:
            values of all variables in the circuit, to compile with.
        qubit_map: dictionary:
            a qubit map which maps the abstract qubits in the abstract_circuit to the qubits on the backend
            there is no need to initialize the corresponding backend types
            the dictionary should simply be {int:int} (preferred) or {int:name}
            if None the default will map to qubits 0 ... n_qubits -1 in the backend
        noise:
            Noise to apply to the circuit.
        device:
            device on which to emulatedly execute all sampling.
        args
        kwargs
        """

        self.op_lookup = {
            'I': (pyquil.gates.I),
            'X': (pyquil.gates.X, pyquil.gates.CNOT, pyquil.gates.CCNOT),
            'Y': (pyquil.gates.Y, ),
            'Z': (pyquil.gates.Z, pyquil.gates.CZ),
            'H': (pyquil.gates.H, ),
            'Rx': pyquil.gates.RX,
            'Ry': pyquil.gates.RY,
            'Rz': pyquil.gates.RZ,
            'Phase': pyquil.gates.PHASE,
            'SWAP': (pyquil.gates.SWAP, pyquil.gates.CSWAP),
        }
        self.match_par_to_dummy = {}
        self.counter = 0
        if device is not None:
            self.compiler_arguments['cc_max'] = True
        super().__init__(abstract_circuit=abstract_circuit,
                         variables=variables,
                         noise=noise,
                         device=device,
                         qubit_map=qubit_map,
                         *args,
                         **kwargs)
        if self.noise is not None:
            self.noise_lookup = {
                'amplitude damp': amp_damp_map,
                'phase damp': phase_damp_map,
                'bit flip': bit_flip_map,
                'phase flip': phase_flip_map,
                'phase-amplitude damp': phase_amp_damp_map,
                'depolarizing': depolarizing_map
            }

            if isinstance(self.noise, str):
                if self.noise == 'device':
                    pass
                else:
                    raise TequilaException(
                        'noise was a string: {}, which is not \'device\'. This is not allowed!'
                        .format(self.noise))

            else:
                self.circuit = self.build_noisy_circuit(
                    self.circuit, self.noise)

        if len(self.match_par_to_dummy.keys()) is None:
            self.match_dummy_to_value = None
            self.resolver = None
        else:
            self.match_dummy_to_value = {
                'theta_{}'.format(str(i)): k
                for i, k in enumerate(self.match_par_to_dummy.keys())
            }
            self.resolver = {
                k: [to_float(v(variables))]
                for k, v in self.match_dummy_to_value.items()
            }
Esempio n. 18
0
    def __init__(self,
                 abstract_circuit: QCircuit,
                 variables,
                 use_mapping=True,
                 noise=None,
                 *args,
                 **kwargs):

        self.op_lookup = {
            'I': (lambda c: c.iden),
            'X': (lambda c: c.x, lambda c: c.cx, lambda c: c.ccx),
            'Y': (lambda c: c.y, lambda c: c.cy, lambda c: c.ccy),
            'Z': (lambda c: c.z, lambda c: c.cz, lambda c: c.ccz),
            'H': (lambda c: c.h, lambda c: c.ch, lambda c: c.cch),
            'Rx': (lambda c: c.rx, lambda c: c.mcrx),
            'Ry': (lambda c: c.ry, lambda c: c.mcry),
            'Rz': (lambda c: c.rz, lambda c: c.mcrz),
            'Phase': (lambda c: c.u1, lambda c: c.cu1),
            'SWAP': (lambda c: c.swap, lambda c: c.cswap),
        }

        if use_mapping:
            qubits = abstract_circuit.qubits
        else:
            qubits = range(abstract_circuit.n_qubits)

        if noise != None:
            self.noise_lookup = {
                'phase damp': qiskitnoise.phase_damping_error,
                'amplitude damp': qiskitnoise.amplitude_damping_error,
                'bit flip': get_bit_flip,
                'phase flip': get_phase_flip,
                'phase-amplitude damp':
                qiskitnoise.phase_amplitude_damping_error,
                'depolarizing': qiskitnoise.depolarizing_error
            }
        nm = self.noise_model_converter(noise)
        self.noise_model = nm
        n_qubits = len(qubits)
        self.q = qiskit.QuantumRegister(n_qubits, "q")
        self.c = qiskit.ClassicalRegister(n_qubits, "c")
        self.classical_map = {i: self.c[j] for j, i in enumerate(qubits)}
        self.qubit_map = {i: self.q[j] for j, i in enumerate(qubits)}
        self.resolver = {}
        self.tq_to_sympy = {}
        self.counter = 0
        super().__init__(abstract_circuit=abstract_circuit,
                         variables=variables,
                         noise=self.noise_model,
                         use_mapping=use_mapping,
                         *args,
                         **kwargs)
        if len(self.tq_to_sympy.keys()) is None:
            self.sympy_to_tq = None
            self.resolver = None
        else:
            self.sympy_to_tq = {v: k for k, v in self.tq_to_sympy.items()}
            self.resolver = {
                k: to_float(v(variables))
                for k, v in self.sympy_to_tq.items()
            }
        if self.noise_model is None:
            self.ol = 1
        else:
            self.ol = 0
Esempio n. 19
0
    def __init__(self,
                 abstract_circuit: QCircuit,
                 variables,
                 use_mapping=True,
                 noise=None,
                 device=None,
                 *args,
                 **kwargs):
        """

        Parameters
        ----------
        abstract_circuit: QCircuit:
            the circuit to be compiled to qiskit.
        variables: dict:
            variables to compile the circuit with
        use_mapping: bool:
            whether or not to build mappings.
        noise:
            noise to apply to the circuit.
        device:
            device on which to (perhaps, via emulation) execute the circuit.
        args
        kwargs
        """
        self.op_lookup = {
            'I': (lambda c: c.iden),
            'X': (lambda c: c.x, lambda c: c.cx, lambda c: c.ccx),
            'Y': (lambda c: c.y, lambda c: c.cy, lambda c: c.ccy),
            'Z': (lambda c: c.z, lambda c: c.cz, lambda c: c.ccz),
            'H': (lambda c: c.h, lambda c: c.ch, lambda c: c.cch),
            'Rx': (lambda c: c.rx, lambda c: c.mcrx),
            'Ry': (lambda c: c.ry, lambda c: c.mcry),
            'Rz': (lambda c: c.rz, lambda c: c.mcrz),
            'Phase': (lambda c: c.u1, lambda c: c.cu1),
            'SWAP': (lambda c: c.swap, lambda c: c.cswap),
        }

        if use_mapping:
            qubits = abstract_circuit.qubits
        else:
            qubits = range(abstract_circuit.n_qubits)

        n_qubits = len(qubits)
        self.q = qiskit.QuantumRegister(n_qubits, "q")
        self.c = qiskit.ClassicalRegister(n_qubits, "c")
        self.classical_map = {i: self.c[j] for j, i in enumerate(qubits)}
        self.qubit_map = {i: self.q[j] for j, i in enumerate(qubits)}
        self.resolver = {}
        self.tq_to_pars = {}
        self.counter = 0

        super().__init__(abstract_circuit=abstract_circuit,
                         variables=variables,
                         noise=noise,
                         device=device,
                         use_mapping=use_mapping,
                         *args,
                         **kwargs)

        if noise != None:
            self.noise_lookup = {
                'phase damp': qiskitnoise.phase_damping_error,
                'amplitude damp': qiskitnoise.amplitude_damping_error,
                'bit flip': get_bit_flip,
                'phase flip': get_phase_flip,
                'phase-amplitude damp':
                qiskitnoise.phase_amplitude_damping_error,
                'depolarizing': qiskitnoise.depolarizing_error
            }

            if isinstance(noise, str):
                if noise == 'device':
                    if device is not None:
                        self.noise_model = qiskitnoise.NoiseModel.from_backend(
                            self.device)
                    else:
                        raise TequilaException(
                            'cannot get device noise without specifying a device!'
                        )
                else:
                    raise TequilaException(
                        'The only allowed string for noise is \'device\'; recieved {}. Please try again!'
                        .format(str(noise)))
            else:
                nm = self.noise_model_converter(noise)
                self.noise_model = nm
        else:
            self.noise_model = None

        if len(self.tq_to_pars.keys()) is None:
            self.pars_to_tq = None
            self.resolver = None
        else:
            self.pars_to_tq = {v: k for k, v in self.tq_to_pars.items()}
            self.resolver = {
                k: to_float(v(variables))
                for k, v in self.pars_to_tq.items()
            }
Esempio n. 20
0
    def __init__(self,
                 abstract_circuit: QCircuit,
                 variables,
                 use_mapping=True,
                 noise=None,
                 device=None,
                 *args,
                 **kwargs):
        """
        Parameters
        ----------
        abstract_circuit: QCircuit:
            Tequila unitary to compile to Pyquil.
        variables: dict:
            values of all variables in the circuit, to compile with.
        use_mapping: bool:
            whether or not to use a mapping that eliminates unnecessary qubits from the circuit.
        noise:
            Noise to apply to the circuit.
        device:
            device on which to emulatedly execute all sampling.
        args
        kwargs
        """

        self.op_lookup = {
            'I': (pyquil.gates.I),
            'X': (pyquil.gates.X, pyquil.gates.CNOT, pyquil.gates.CCNOT),
            'Y': (pyquil.gates.Y, ),
            'Z': (pyquil.gates.Z, pyquil.gates.CZ),
            'H': (pyquil.gates.H, ),
            'Rx': pyquil.gates.RX,
            'Ry': pyquil.gates.RY,
            'Rz': pyquil.gates.RZ,
            'Phase': pyquil.gates.PHASE,
            'SWAP': (pyquil.gates.SWAP, pyquil.gates.CSWAP),
        }
        self.match_par_to_dummy = {}
        self.counter = 0
        if device is not None:
            self.compiler_arguments['cc_max'] = True
        super().__init__(abstract_circuit=abstract_circuit,
                         variables=variables,
                         noise=noise,
                         device=device,
                         use_mapping=use_mapping,
                         *args,
                         **kwargs)
        if self.noise is not None:
            self.noise_lookup = {
                'amplitude damp': amp_damp_map,
                'phase damp': phase_damp_map,
                'bit flip': bit_flip_map,
                'phase flip': phase_flip_map,
                'phase-amplitude damp': phase_amp_damp_map,
                'depolarizing': depolarizing_map
            }

            if isinstance(self.noise, str):
                if self.noise == 'device':
                    pass
                else:
                    raise TequilaException(
                        'noise was a string: {}, which is not \'device\'. This is not allowed!'
                        .format(self.noise))

            else:
                self.circuit = self.build_noisy_circuit(
                    self.circuit, self.noise)

        if len(self.match_par_to_dummy.keys()) is None:
            self.match_dummy_to_value = None
            self.resolver = None
        else:
            self.match_dummy_to_value = {
                'theta_{}'.format(str(i)): k
                for i, k in enumerate(self.match_par_to_dummy.keys())
            }
            self.resolver = {
                k: [to_float(v(variables))]
                for k, v in self.match_dummy_to_value.items()
            }